Added multiple selection feature to wxPropertyGrid (enabled by setting wxPG_EX_MULTIPLE_SELECTION style)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@61681 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Jaakko Salli
2009-08-17 18:36:00 +00:00
parent 17a5460272
commit fc72fab6c6
15 changed files with 663 additions and 197 deletions

View File

@@ -491,6 +491,12 @@ public:
*/ */
bool IsPageModified( size_t index ) const; bool IsPageModified( size_t index ) const;
/**
Returns true if property is selected. Since selection is page
based, this function checks every page in the manager.
*/
virtual bool IsPropertySelected( wxPGPropArg id ) const;
virtual void Refresh( bool eraseBackground = true, virtual void Refresh( bool eraseBackground = true,
const wxRect* rect = (const wxRect*) NULL ); const wxRect* rect = (const wxRect*) NULL );

View File

@@ -435,7 +435,11 @@ wxPG_PROP_CLASS_SPECIFIC_1 = 0x00080000,
/** Indicates the bit useable by derived properties. /** Indicates the bit useable by derived properties.
*/ */
wxPG_PROP_CLASS_SPECIFIC_2 = 0x00100000 wxPG_PROP_CLASS_SPECIFIC_2 = 0x00100000,
/** Indicates that the property is being deleted and should be ignored.
*/
wxPG_PROP_BEING_DELETED = 0x00200000
}; };

View File

@@ -247,7 +247,20 @@ wxPG_EX_WRITEONLY_BUILTIN_ATTRIBUTES = 0x00400000,
/** Hides page selection buttons from toolbar. /** Hides page selection buttons from toolbar.
*/ */
wxPG_EX_HIDE_PAGE_BUTTONS = 0x01000000 wxPG_EX_HIDE_PAGE_BUTTONS = 0x01000000,
/** Allows multiple properties to be selected by user (by pressing SHIFT
when clicking on a property, or by dragging with left mouse button
down).
You can get array of selected properties with
wxPropertyGridInterface::GetSelectedProperties(). In multiple selection
mode wxPropertyGridInterface::GetSelection() returns
property which has editor active (usually the first one
selected). Other useful member functions are ClearSelection(),
AddToSelection() and RemoveFromSelection().
*/
wxPG_EX_MULTIPLE_SELECTION = 0x02000000
}; };
@@ -839,12 +852,6 @@ public:
/** Returns currently selected property. */ /** Returns currently selected property. */
wxPGProperty* GetSelectedProperty() const { return GetSelection(); } wxPGProperty* GetSelectedProperty() const { return GetSelection(); }
/** Returns currently selected property. */
wxPGProperty* GetSelection() const
{
return m_selected;
}
/** Returns current selection background colour. */ /** Returns current selection background colour. */
wxColour GetSelectionBackgroundColour() const { return m_colSelBack; } wxColour GetSelectionBackgroundColour() const { return m_colSelBack; }
@@ -953,10 +960,46 @@ public:
wxEVT_PG_SELECTED. In wxWidgets 2.9 and later, it no longer wxEVT_PG_SELECTED. In wxWidgets 2.9 and later, it no longer
does that. does that.
@see wxPropertyGrid::Unselect @remarks This clears any previous selection.
*/ */
bool SelectProperty( wxPGPropArg id, bool focus = false ); bool SelectProperty( wxPGPropArg id, bool focus = false );
/**
Set entire new selection from given list of properties.
*/
void SetSelection( const wxArrayPGProperty& newSelection )
{
DoSetSelection( newSelection, wxPG_SEL_DONT_SEND_EVENT );
}
/**
Adds given property into selection. If wxPG_EX_MULTIPLE_SELECTION
extra style is not used, then this has same effect as
calling SelectProperty().
@remarks Multiple selection is not supported for categories. This
means that if you have properties selected, you cannot
add category to selection, and also if you have category
selected, you cannot add other properties to selection.
This member function will fail silently in these cases,
even returning true.
*/
bool AddToSelection( wxPGPropArg id )
{
wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
return DoAddToSelection(p, wxPG_SEL_DONT_SEND_EVENT);
}
/**
Removes given property from selection. If property is not selected,
an assertion failure will occur.
*/
bool RemoveFromSelection( wxPGPropArg id )
{
wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
return DoRemoveFromSelection(p, wxPG_SEL_DONT_SEND_EVENT);
}
/** Sets category caption background colour. */ /** Sets category caption background colour. */
void SetCaptionBackgroundColour(const wxColour& col); void SetCaptionBackgroundColour(const wxColour& col);
@@ -1443,7 +1486,6 @@ public:
// //
// Public methods for semi-public use // Public methods for semi-public use
// (not protected for optimization)
// //
bool DoSelectProperty( wxPGProperty* p, unsigned int flags = 0 ); bool DoSelectProperty( wxPGProperty* p, unsigned int flags = 0 );
@@ -1635,12 +1677,6 @@ protected:
/** When drawing next time, clear this many item slots at the end. */ /** When drawing next time, clear this many item slots at the end. */
int m_clearThisMany; int m_clearThisMany;
/** Pointer to selected property. Note that this is duplicated in
m_state for better transiency between pages so that the selected
item can be retained.
*/
wxPGProperty* m_selected;
// pointer to property that has mouse hovering // pointer to property that has mouse hovering
wxPGProperty* m_propHover; wxPGProperty* m_propHover;
@@ -1767,6 +1803,10 @@ protected:
protected: protected:
bool AddToSelectionFromInputEvent( wxPGProperty* prop,
wxMouseEvent* event = NULL,
int selFlags = 0 );
/** /**
Adjust the centering of the bitmap icons (collapse / expand) when the Adjust the centering of the bitmap icons (collapse / expand) when the
caption font changes. caption font changes.
@@ -1786,14 +1826,6 @@ protected:
*/ */
void CorrectEditorWidgetPosY(); void CorrectEditorWidgetPosY();
/** Deselect current selection, if any. Returns true if success
(ie. validator did not intercept).
Unlike ClearSelection(), DoClearSelection() sends the
wxEVT_PG_SELECTED event.
*/
bool DoClearSelection();
int DoDrawItems( wxDC& dc, int DoDrawItems( wxDC& dc,
const wxRect* clipRect, const wxRect* clipRect,
bool isBuffered ) const; bool isBuffered ) const;
@@ -1826,6 +1858,15 @@ protected:
bool DoEditorValidate(); bool DoEditorValidate();
void DoSetSelection( const wxArrayPGProperty& newSelection,
int selFlags = 0 );
bool DoAddToSelection( wxPGProperty* prop,
int selFlags = 0 );
bool DoRemoveFromSelection( wxPGProperty* prop,
int selFlags = 0 );
wxPGProperty* DoGetItemAtY( int y ) const; wxPGProperty* DoGetItemAtY( int y ) const;
void DoSetSplitterPosition_( int newxpos, void DoSetSplitterPosition_( int newxpos,

View File

@@ -591,10 +591,23 @@ public:
} }
#endif #endif
/** Returns currently selected property. */ /**
wxPGProperty* GetSelection() const Returns currently selected property. NULL if none.
@remarks When wxPG_EX_MULTIPLE_SELECTION extra style is used, this
member function returns the focused property, that is the
one which can have active editor.
*/
wxPGProperty* GetSelection() const;
/**
Returns list of currently selected properties.
@remarks wxArrayPGProperty should be compatible with std::vector API.
*/
const wxArrayPGProperty& GetSelectedProperties() const
{ {
return m_pState->GetSelection(); return m_pState->m_selection;
} }
#ifndef SWIG #ifndef SWIG
@@ -724,10 +737,19 @@ public:
return ( (p->GetFlags() & wxPG_PROP_MODIFIED) ? true : false ); return ( (p->GetFlags() & wxPG_PROP_MODIFIED) ? true : false );
} }
/**
Returns true if property is selected.
*/
bool IsPropertySelected( wxPGPropArg id ) const
{
wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
return m_pState->DoIsPropertySelected(p);
}
/** /**
Returns true if property is shown (ie hideproperty with true not Returns true if property is shown (ie hideproperty with true not
called for it). called for it).
*/ */
bool IsPropertyShown( wxPGPropArg id ) const bool IsPropertyShown( wxPGPropArg id ) const
{ {
wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false) wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
@@ -1269,6 +1291,9 @@ public:
protected: protected:
bool DoClearSelection( bool validation = false,
int selFlags = 0 );
/** /**
In derived class, implement to set editable state component with In derived class, implement to set editable state component with
given name to given value. given name to given value.

View File

@@ -475,11 +475,6 @@ public:
return (unsigned int) m_colWidths.size(); return (unsigned int) m_colWidths.size();
} }
wxPGProperty* GetSelection() const
{
return m_selected;
}
int GetColumnMinWidth( int column ) const; int GetColumnMinWidth( int column ) const;
int GetColumnWidth( unsigned int column ) const int GetColumnWidth( unsigned int column ) const
@@ -500,6 +495,28 @@ public:
return ((wxPropertyGridPageState*)this)->GetLastItem(flags); return ((wxPropertyGridPageState*)this)->GetLastItem(flags);
} }
/**
Returns currently selected property.
*/
wxPGProperty* GetSelection() const
{
if ( m_selection.size() == 0 )
return NULL;
return m_selection[0];
}
void DoSetSelection( wxPGProperty* prop )
{
m_selection.clear();
if ( prop )
m_selection.push_back(prop);
}
bool DoClearSelection()
{
return DoSelectProperty(NULL);
}
wxPropertyCategory* GetPropertyCategory( const wxPGProperty* p ) const; wxPropertyCategory* GetPropertyCategory( const wxPGProperty* p ) const;
wxPGProperty* GetPropertyByLabel( const wxString& name, wxPGProperty* GetPropertyByLabel( const wxString& name,
@@ -590,8 +607,6 @@ public:
bool PrepareAfterItemsAdded(); bool PrepareAfterItemsAdded();
void SetSelection( wxPGProperty* p ) { m_selected = p; }
/** Called after virtual height needs to be recalculated. /** Called after virtual height needs to be recalculated.
*/ */
void VirtualHeightChanged() void VirtualHeightChanged()
@@ -605,14 +620,11 @@ public:
/** Returns property by its name. */ /** Returns property by its name. */
wxPGProperty* BaseGetPropertyByName( const wxString& name ) const; wxPGProperty* BaseGetPropertyByName( const wxString& name ) const;
void DoClearSelection()
{
m_selected = NULL;
}
/** Called in, for example, wxPropertyGrid::Clear. */ /** Called in, for example, wxPropertyGrid::Clear. */
void DoClear(); void DoClear();
bool DoIsPropertySelected( wxPGProperty* prop ) const;
bool DoCollapse( wxPGProperty* p ); bool DoCollapse( wxPGProperty* p );
bool DoExpand( wxPGProperty* p ); bool DoExpand( wxPGProperty* p );
@@ -659,8 +671,8 @@ protected:
/** Most recently added category. */ /** Most recently added category. */
wxPropertyCategory* m_currentCategory; wxPropertyCategory* m_currentCategory;
/** Pointer to selected property. */ /** Array of selected property. */
wxPGProperty* m_selected; wxArrayPGProperty m_selection;
/** Virtual width. */ /** Virtual width. */
int m_width; int m_width;

View File

@@ -388,6 +388,12 @@ public:
*/ */
bool IsPageModified( size_t index ) const; bool IsPageModified( size_t index ) const;
/**
Returns true if property is selected. Since selection is page
based, this function checks every page in the manager.
*/
virtual bool IsPropertySelected( wxPGPropArg id ) const;
/** /**
Removes a page. Removes a page.

View File

@@ -152,7 +152,20 @@ wxPG_EX_WRITEONLY_BUILTIN_ATTRIBUTES = 0x00400000,
/** /**
Hides page selection buttons from tool bar. Hides page selection buttons from tool bar.
*/ */
wxPG_EX_HIDE_PAGE_BUTTONS = 0x01000000 wxPG_EX_HIDE_PAGE_BUTTONS = 0x01000000,
/** Allows multiple properties to be selected by user (by pressing SHIFT
when clicking on a property, or by dragging with left mouse button
down).
You can get array of selected properties with
wxPropertyGridInterface::GetSelectedProperties(). In multiple selection
mode wxPropertyGridInterface::GetSelection() returns
property which has editor active (usually the first one
selected). Other useful member functions are ClearSelection(),
AddToSelection() and RemoveFromSelection().
*/
wxPG_EX_MULTIPLE_SELECTION = 0x02000000
}; };
@@ -394,6 +407,20 @@ public:
*/ */
void AddActionTrigger( int action, int keycode, int modifiers = 0 ); void AddActionTrigger( int action, int keycode, int modifiers = 0 );
/**
Adds given property into selection. If wxPG_EX_MULTIPLE_SELECTION
extra style is not used, then this has same effect as
calling SelectProperty().
@remarks Multiple selection is not supported for categories. This
means that if you have properties selected, you cannot
add category to selection, and also if you have category
selected, you cannot add other properties to selection.
This member function will fail silently in these cases,
even returning true.
*/
bool AddToSelection( wxPGPropArg id );
/** /**
This static function enables or disables automatic use of This static function enables or disables automatic use of
wxGetTranslation() for following strings: wxEnumProperty list labels, wxGetTranslation() for following strings: wxEnumProperty list labels,
@@ -708,6 +735,12 @@ public:
*/ */
void ResetColours(); void ResetColours();
/**
Removes given property from selection. If property is not selected,
an assertion failure will occur.
*/
bool RemoveFromSelection( wxPGPropArg id );
/** /**
Selects a property. Editor widget is automatically created, but Selects a property. Editor widget is automatically created, but
not focused unless focus is true. not focused unless focus is true.
@@ -725,6 +758,8 @@ public:
wxEVT_PG_SELECTED. In wxWidgets 2.9 and later, it no longer wxEVT_PG_SELECTED. In wxWidgets 2.9 and later, it no longer
does that. does that.
@remarks This clears any previous selection.
@see wxPropertyGridInterface::ClearSelection() @see wxPropertyGridInterface::ClearSelection()
*/ */
bool SelectProperty( wxPGPropArg id, bool focus = false ); bool SelectProperty( wxPGPropArg id, bool focus = false );
@@ -790,6 +825,11 @@ public:
*/ */
void SetMarginColour(const wxColour& col); void SetMarginColour(const wxColour& col);
/**
Set entire new selection from given list of properties.
*/
void SetSelection( const wxArrayPGProperty& newSelection );
/** /**
Sets selection background colour - applies to selected property name Sets selection background colour - applies to selected property name
background. background.

View File

@@ -418,7 +418,20 @@ public:
wxVariant GetPropertyValues( const wxString& listname = wxEmptyString, wxVariant GetPropertyValues( const wxString& listname = wxEmptyString,
wxPGProperty* baseparent = NULL, long flags = 0 ) const; wxPGProperty* baseparent = NULL, long flags = 0 ) const;
/** Returns currently selected property. */ /**
Returns list of currently selected properties.
@remarks wxArrayPGProperty should be compatible with std::vector API.
*/
const wxArrayPGProperty& GetSelectedProperties() const;
/**
Returns currently selected property. NULL if none.
@remarks When wxPG_EX_MULTIPLE_SELECTION extra style is used, this
member function returns the focused property, that is the
one which can have active editor.
*/
wxPGProperty* GetSelection() const; wxPGProperty* GetSelection() const;
/** /**
@@ -538,6 +551,11 @@ public:
*/ */
bool IsPropertyModified( wxPGPropArg id ) const; bool IsPropertyModified( wxPGPropArg id ) const;
/**
Returns true if property is selected.
*/
virtual bool IsPropertySelected( wxPGPropArg id ) const;
/** /**
Returns @true if property is shown (ie. HideProperty() with @true not Returns @true if property is shown (ie. HideProperty() with @true not
called for it). called for it).

View File

@@ -2045,7 +2045,8 @@ void FormMain::CreateGrid( int style, int extraStyle )
if ( extraStyle == -1 ) if ( extraStyle == -1 )
// default extra style // default extra style
extraStyle = wxPG_EX_MODE_BUTTONS; extraStyle = wxPG_EX_MODE_BUTTONS |
wxPG_EX_MULTIPLE_SELECTION;
//| wxPG_EX_AUTO_UNSPECIFIED_VALUES //| wxPG_EX_AUTO_UNSPECIFIED_VALUES
//| wxPG_EX_GREY_LABEL_WHEN_DISABLED //| wxPG_EX_GREY_LABEL_WHEN_DISABLED
//| wxPG_EX_NATIVE_DOUBLE_BUFFERING //| wxPG_EX_NATIVE_DOUBLE_BUFFERING
@@ -2140,7 +2141,8 @@ FormMain::FormMain(const wxString& title, const wxPoint& pos, const wxSize& size
wxPG_TOOLBAR | wxPG_TOOLBAR |
wxPG_DESCRIPTION, wxPG_DESCRIPTION,
// extra style // extra style
wxPG_EX_MODE_BUTTONS wxPG_EX_MODE_BUTTONS |
wxPG_EX_MULTIPLE_SELECTION
//| wxPG_EX_AUTO_UNSPECIFIED_VALUES //| wxPG_EX_AUTO_UNSPECIFIED_VALUES
//| wxPG_EX_GREY_LABEL_WHEN_DISABLED //| wxPG_EX_GREY_LABEL_WHEN_DISABLED
//| wxPG_EX_NATIVE_DOUBLE_BUFFERING //| wxPG_EX_NATIVE_DOUBLE_BUFFERING
@@ -2928,6 +2930,8 @@ void FormMain::OnSelectStyle( wxCommandEvent& WXUNUSED(event) )
ADD_FLAG(wxPG_EX_NATIVE_DOUBLE_BUFFERING) ADD_FLAG(wxPG_EX_NATIVE_DOUBLE_BUFFERING)
ADD_FLAG(wxPG_EX_AUTO_UNSPECIFIED_VALUES) ADD_FLAG(wxPG_EX_AUTO_UNSPECIFIED_VALUES)
ADD_FLAG(wxPG_EX_WRITEONLY_BUILTIN_ATTRIBUTES) ADD_FLAG(wxPG_EX_WRITEONLY_BUILTIN_ATTRIBUTES)
ADD_FLAG(wxPG_EX_HIDE_PAGE_BUTTONS)
ADD_FLAG(wxPG_EX_MULTIPLE_SELECTION)
wxMultiChoiceDialog dlg( this, wxT("Select extra window styles to use"), wxMultiChoiceDialog dlg( this, wxT("Select extra window styles to use"),
wxT("wxPropertyGrid Extra Style"), chs ); wxT("wxPropertyGrid Extra Style"), chs );
dlg.SetSelections(sel); dlg.SetSelections(sel);

View File

@@ -249,6 +249,10 @@ protected:
failures++; \ failures++; \
} }
#define RT_ASSERT(COND) \
if (!(COND)) \
RT_FAILURE()
#define RT_FAILURE_MSG(MSG) \ #define RT_FAILURE_MSG(MSG) \
{ \ { \
wxString s1 = wxString::Format(wxT("Test failure in tests.cpp, line %i."),__LINE__-1); \ wxString s1 = wxString::Format(wxT("Test failure in tests.cpp, line %i."),__LINE__-1); \
@@ -714,6 +718,63 @@ bool FormMain::RunTests( bool fullTest, bool interactive )
#endif #endif
} }
{
//
// Test multiple selection
RT_START_TEST(MULTIPLE_SELECTION)
if ( !(pgman->GetExtraStyle() & wxPG_EX_MULTIPLE_SELECTION) )
CreateGrid( -1, wxPG_EX_MULTIPLE_SELECTION);
pgman = m_pPropGridManager;
wxPropertyGrid* pg = pgman->GetGrid();
wxPGProperty* prop1 = pg->GetProperty(wxT("Label"));
wxPGProperty* prop2 = pg->GetProperty(wxT("Cell Text Colour"));
wxPGProperty* prop3 = pg->GetProperty(wxT("Height"));
wxPGProperty* catProp = pg->GetProperty(wxT("Appearance"));
RT_ASSERT( prop1 && prop2 && prop3 );
pg->ClearSelection();
pg->AddToSelection(prop1);
pg->AddToSelection(prop2);
pg->AddToSelection(prop3);
// Adding category to selection should fail silently
pg->AddToSelection(catProp);
wxArrayPGProperty selectedProperties = pg->GetSelectedProperties();
RT_ASSERT( selectedProperties.size() == 3 )
RT_ASSERT( pg->IsPropertySelected(prop1) )
RT_ASSERT( pg->IsPropertySelected(prop2) )
RT_ASSERT( pg->IsPropertySelected(prop3) )
RT_ASSERT( !pg->IsPropertySelected(catProp) )
pg->RemoveFromSelection(prop1);
wxArrayPGProperty selectedProperties2 = pg->GetSelectedProperties();
RT_ASSERT( selectedProperties2.size() == 2 )
RT_ASSERT( !pg->IsPropertySelected(prop1) )
RT_ASSERT( pg->IsPropertySelected(prop2) )
RT_ASSERT( pg->IsPropertySelected(prop3) )
pg->ClearSelection();
wxArrayPGProperty selectedProperties3 = pg->GetSelectedProperties();
RT_ASSERT( selectedProperties3.size() == 0 )
RT_ASSERT( !pg->IsPropertySelected(prop1) )
RT_ASSERT( !pg->IsPropertySelected(prop2) )
RT_ASSERT( !pg->IsPropertySelected(prop3) )
pg->SelectProperty(prop2);
RT_ASSERT( !pg->IsPropertySelected(prop1) )
RT_ASSERT( pg->IsPropertySelected(prop2) )
RT_ASSERT( !pg->IsPropertySelected(prop3) )
}
{ {
RT_START_TEST(Attributes) RT_START_TEST(Attributes)
@@ -985,8 +1046,7 @@ bool FormMain::RunTests( bool fullTest, bool interactive )
pgman = m_pPropGridManager; pgman = m_pPropGridManager;
} }
/* /*{
{
// TODO: This test fails. // TODO: This test fails.
RT_START_TEST(SetSplitterPosition) RT_START_TEST(SetSplitterPosition)
@@ -1023,8 +1083,7 @@ bool FormMain::RunTests( bool fullTest, bool interactive )
// Recreate the original grid // Recreate the original grid
CreateGrid( -1, -1 ); CreateGrid( -1, -1 );
pgman = m_pPropGridManager; pgman = m_pPropGridManager;
} }*/
*/
{ {
RT_START_TEST(HideProperty) RT_START_TEST(HideProperty)
@@ -1034,7 +1093,7 @@ bool FormMain::RunTests( bool fullTest, bool interactive )
srand(0x1234); srand(0x1234);
wxArrayPGProperty arr1; wxArrayPGProperty arr1;
arr1 = GetPropertiesInRandomOrder(page); arr1 = GetPropertiesInRandomOrder(page);
if ( !_failed_ ) if ( !_failed_ )
@@ -1178,7 +1237,7 @@ bool FormMain::RunTests( bool fullTest, bool interactive )
wxASSERT(wxPG_EX_INIT_NOCAT == 0x00001000); wxASSERT(wxPG_EX_INIT_NOCAT == 0x00001000);
for ( i=12; i<24; i++ ) for ( i=12; i<26; i++ )
{ {
int flag = 1<<i; int flag = 1<<i;
RT_MSG(wxString::Format(wxT("ExStyle: 0x%X"),flag)); RT_MSG(wxString::Format(wxT("ExStyle: 0x%X"),flag));

View File

@@ -608,7 +608,7 @@ void wxPropertyGrid::OnComboItemPaint( const wxPGComboBox* pCb,
// Sanity check // Sanity check
wxASSERT( IsKindOf(CLASSINFO(wxPropertyGrid)) ); wxASSERT( IsKindOf(CLASSINFO(wxPropertyGrid)) );
wxPGProperty* p = m_selected; wxPGProperty* p = GetSelection();
wxString text; wxString text;
const wxPGChoices& choices = p->GetChoices(); const wxPGChoices& choices = p->GetChoices();
@@ -1576,9 +1576,9 @@ void wxPropertyGrid::CorrectEditorWidgetPosY()
if ( m_selColumn == -1 ) if ( m_selColumn == -1 )
return; return;
if ( m_selected && (m_wndEditor || m_wndEditor2) ) if ( GetSelection() && (m_wndEditor || m_wndEditor2) )
{ {
wxRect r = GetEditorWidgetRect(m_selected, m_selColumn); wxRect r = GetEditorWidgetRect(GetSelection(), m_selColumn);
if ( m_wndEditor ) if ( m_wndEditor )
{ {
@@ -1637,7 +1637,7 @@ wxWindow* wxPropertyGrid::GenerateEditorTextCtrl( const wxPoint& pos,
int maxLen ) int maxLen )
{ {
wxWindowID id = wxPG_SUBID1; wxWindowID id = wxPG_SUBID1;
wxPGProperty* prop = m_selected; wxPGProperty* prop = GetSelection();
wxASSERT(prop); wxASSERT(prop);
int tcFlags = wxTE_PROCESS_ENTER | extraStyle; int tcFlags = wxTE_PROCESS_ENTER | extraStyle;
@@ -1708,7 +1708,7 @@ wxWindow* wxPropertyGrid::GenerateEditorTextCtrl( const wxPoint& pos,
wxWindow* wxPropertyGrid::GenerateEditorButton( const wxPoint& pos, const wxSize& sz ) wxWindow* wxPropertyGrid::GenerateEditorButton( const wxPoint& pos, const wxSize& sz )
{ {
wxWindowID id = wxPG_SUBID2; wxWindowID id = wxPG_SUBID2;
wxPGProperty* selected = m_selected; wxPGProperty* selected = GetSelection();
wxASSERT(selected); wxASSERT(selected);
#ifdef __WXMAC__ #ifdef __WXMAC__

View File

@@ -423,8 +423,9 @@ wxPropertyGridManager::~wxPropertyGridManager()
{ {
END_MOUSE_CAPTURE END_MOUSE_CAPTURE
m_pPropGrid->DoSelectProperty(NULL); //m_pPropGrid->ClearSelection();
m_pPropGrid->m_pState = NULL; delete m_pPropGrid;
m_pPropGrid = NULL;
size_t i; size_t i;
for ( i=0; i<m_arrPages.size(); i++ ) for ( i=0; i<m_arrPages.size(); i++ )
@@ -553,7 +554,7 @@ bool wxPropertyGridManager::DoSelectPage( int index )
if ( m_selPage == index ) if ( m_selPage == index )
return true; return true;
if ( m_pPropGrid->m_selected ) if ( m_pPropGrid->GetSelection() )
{ {
if ( !m_pPropGrid->ClearSelection() ) if ( !m_pPropGrid->ClearSelection() )
return false; return false;
@@ -883,6 +884,19 @@ bool wxPropertyGridManager::IsPageModified( size_t index ) const
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
bool wxPropertyGridManager::IsPropertySelected( wxPGPropArg id ) const
{
wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
for ( unsigned int i=0; i<GetPageCount(); i++ )
{
if ( GetPageState(i)->DoIsPropertySelected(p) )
return true;
}
return false;
}
// -----------------------------------------------------------------------
wxPGProperty* wxPropertyGridManager::GetPageRoot( int index ) const wxPGProperty* wxPropertyGridManager::GetPageRoot( int index ) const
{ {
wxASSERT( index >= 0 ); wxASSERT( index >= 0 );

View File

@@ -428,7 +428,6 @@ void wxPropertyGrid::Init1()
m_iFlags = 0; m_iFlags = 0;
m_pState = NULL; m_pState = NULL;
m_wndEditor = m_wndEditor2 = NULL; m_wndEditor = m_wndEditor2 = NULL;
m_selected = NULL;
m_selColumn = -1; m_selColumn = -1;
m_propHover = NULL; m_propHover = NULL;
m_eventObject = this; m_eventObject = this;
@@ -582,7 +581,7 @@ wxPropertyGrid::~wxPropertyGrid()
{ {
size_t i; size_t i;
DoSelectProperty(NULL); DoSelectProperty(NULL, wxPG_SEL_NOVALIDATE|wxPG_SEL_DONT_SEND_EVENT);
// This should do prevent things from going too badly wrong // This should do prevent things from going too badly wrong
m_iFlags &= ~(wxPG_FL_INITIALIZED); m_iFlags &= ~(wxPG_FL_INITIALIZED);
@@ -603,8 +602,6 @@ wxPropertyGrid::~wxPropertyGrid()
delete m_doubleBuffer; delete m_doubleBuffer;
#endif #endif
//m_selected = NULL;
if ( m_iFlags & wxPG_FL_CREATEDSTATE ) if ( m_iFlags & wxPG_FL_CREATEDSTATE )
delete m_pState; delete m_pState;
@@ -731,13 +728,153 @@ void wxPropertyGrid::Thaw()
#endif #endif
// Force property re-selection // Force property re-selection
if ( m_selected ) // NB: We must copy the selection.
DoSelectProperty(m_selected, wxPG_SEL_FORCE); wxArrayPGProperty selection = m_pState->m_selection;
DoSetSelection(selection, wxPG_SEL_FORCE);
} }
} }
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
bool wxPropertyGrid::DoAddToSelection( wxPGProperty* prop, int selFlags )
{
wxCHECK( prop, false );
if ( !(GetExtraStyle() & wxPG_EX_MULTIPLE_SELECTION) )
return DoSelectProperty(prop, selFlags);
wxArrayPGProperty& selection = m_pState->m_selection;
if ( !selection.size() )
{
return DoSelectProperty(prop, selFlags);
}
else
{
// For categories, only one can be selected at a time
if ( prop->IsCategory() || selection[0]->IsCategory() )
return true;
selection.push_back(prop);
if ( !(selFlags & wxPG_SEL_DONT_SEND_EVENT) )
{
SendEvent( wxEVT_PG_SELECTED, prop, NULL, selFlags );
}
// For some reason, if we use RefreshProperty(prop) here,
// we may go into infinite drawing loop.
Refresh();
}
return true;
}
// -----------------------------------------------------------------------
bool wxPropertyGrid::DoRemoveFromSelection( wxPGProperty* prop, int selFlags )
{
wxCHECK( prop, false );
bool res;
wxArrayPGProperty& selection = m_pState->m_selection;
if ( selection.size() <= 1 )
{
res = DoSelectProperty(NULL, selFlags);
}
else
{
selection.Remove(prop);
RefreshProperty(prop);
res = true;
}
return res;
}
// -----------------------------------------------------------------------
bool wxPropertyGrid::AddToSelectionFromInputEvent( wxPGProperty* prop,
wxMouseEvent* mouseEvent,
int selFlags )
{
bool alreadySelected = m_pState->DoIsPropertySelected(prop);
bool res = true;
bool addToExistingSelection;
if ( GetExtraStyle() & wxPG_EX_MULTIPLE_SELECTION )
{
if ( mouseEvent )
{
if ( mouseEvent->GetEventType() == wxEVT_RIGHT_DOWN ||
mouseEvent->GetEventType() == wxEVT_RIGHT_UP )
{
// Allow right-click for context menu without
// disturbing the selection.
if ( GetSelectedProperties().size() <= 1 ||
!alreadySelected )
return DoSelectProperty(prop, selFlags);
return true;
}
else
{
addToExistingSelection = mouseEvent->ShiftDown();
}
}
else
{
addToExistingSelection = false;
}
}
else
{
addToExistingSelection = false;
}
if ( addToExistingSelection )
{
if ( !alreadySelected )
{
res = DoAddToSelection(prop, selFlags);
}
else if ( GetSelectedProperties().size() > 1 )
{
res = DoRemoveFromSelection(prop, selFlags);
}
}
else
{
res = DoSelectProperty(prop, selFlags);
}
return res;
}
// -----------------------------------------------------------------------
void wxPropertyGrid::DoSetSelection( const wxArrayPGProperty& newSelection,
int selFlags )
{
if ( newSelection.size() > 0 )
{
if ( !DoSelectProperty(newSelection[0], selFlags) )
return;
}
else
{
DoClearSelection(false, selFlags);
}
for ( unsigned int i = 1; i < newSelection.size(); i++ )
{
DoAddToSelection(newSelection[i], selFlags);
}
Refresh();
}
// -----------------------------------------------------------------------
void wxPropertyGrid::SetExtraStyle( long exStyle ) void wxPropertyGrid::SetExtraStyle( long exStyle )
{ {
if ( exStyle & wxPG_EX_NATIVE_DOUBLE_BUFFERING ) if ( exStyle & wxPG_EX_NATIVE_DOUBLE_BUFFERING )
@@ -1684,7 +1821,7 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
bool reallyFocused = (m_iFlags & wxPG_FL_FOCUSED) != 0; bool reallyFocused = (m_iFlags & wxPG_FL_FOCUSED) != 0;
bool isEnabled = IsEnabled(); bool isPgEnabled = IsEnabled();
// //
// Prepare some pens and brushes that are often changed to. // Prepare some pens and brushes that are often changed to.
@@ -1695,6 +1832,12 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
wxBrush capbgbrush(m_colCapBack,wxSOLID); wxBrush capbgbrush(m_colCapBack,wxSOLID);
wxPen linepen(m_colLine,1,wxSOLID); wxPen linepen(m_colLine,1,wxSOLID);
wxColour selBackCol;
if ( isPgEnabled )
selBackCol = m_colSelBack;
else
selBackCol = m_colMargin;
// pen that has same colour as text // pen that has same colour as text
wxPen outlinepen(m_colPropFore,1,wxSOLID); wxPen outlinepen(m_colPropFore,1,wxSOLID);
@@ -1708,7 +1851,7 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
dc.DrawRectangle(-1-xRelMod,firstItemTopY-1,x+2,lastItemBottomY-firstItemTopY+2); dc.DrawRectangle(-1-xRelMod,firstItemTopY-1,x+2,lastItemBottomY-firstItemTopY+2);
} }
const wxPGProperty* selected = m_selected; const wxPGProperty* firstSelected = GetSelection();
const wxPropertyGridPageState* state = m_pState; const wxPropertyGridPageState* state = m_pState;
#if wxPG_REFRESH_CONTROLS_AFTER_REPAINT #if wxPG_REFRESH_CONTROLS_AFTER_REPAINT
@@ -1808,7 +1951,9 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
wxColour rowFgCol; wxColour rowFgCol;
wxColour rowBgCol; wxColour rowBgCol;
if ( p != selected ) bool isSelected = state->DoIsPropertySelected(p);
if ( !isSelected )
{ {
// Disabled may get different colour. // Disabled may get different colour.
if ( !p->IsEnabled() ) if ( !p->IsEnabled() )
@@ -1820,6 +1965,11 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
} }
else else
{ {
#if wxPG_REFRESH_CONTROLS_AFTER_REPAINT
if ( p == firstSelected )
wasSelectedPainted = true;
#endif
renderFlags |= wxPGCellRenderer::Selected; renderFlags |= wxPGCellRenderer::Selected;
if ( !p->IsCategory() ) if ( !p->IsCategory() )
@@ -1827,25 +1977,23 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
renderFlags |= wxPGCellRenderer::DontUseCellFgCol | renderFlags |= wxPGCellRenderer::DontUseCellFgCol |
wxPGCellRenderer::DontUseCellBgCol; wxPGCellRenderer::DontUseCellBgCol;
#if wxPG_REFRESH_CONTROLS_AFTER_REPAINT if ( reallyFocused && p == firstSelected )
wasSelectedPainted = true;
#endif
// Selected gets different colour.
if ( reallyFocused )
{ {
rowFgCol = m_colSelFore; rowFgCol = m_colSelFore;
rowBgCol = m_colSelBack; rowBgCol = selBackCol;
} }
else if ( isEnabled ) else if ( isPgEnabled )
{ {
rowFgCol = m_colPropFore; rowFgCol = m_colPropFore;
rowBgCol = m_colMargin; if ( p == firstSelected )
rowBgCol = m_colMargin;
else
rowBgCol = selBackCol;
} }
else else
{ {
rowFgCol = m_colDisPropFore; rowFgCol = m_colDisPropFore;
rowBgCol = m_colSelBack; rowBgCol = selBackCol;
} }
} }
} }
@@ -1934,16 +2082,31 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
DrawExpanderButton( dc, butRect, p ); DrawExpanderButton( dc, butRect, p );
// Background // Background
if ( p == selected && m_wndEditor && ci == 1 ) if ( isSelected && ci == 1 )
{ {
wxColour editorBgCol = GetEditorControl()->GetBackgroundColour(); if ( p == firstSelected && m_wndEditor )
dc.SetBrush(editorBgCol); {
dc.SetPen(editorBgCol); wxColour editorBgCol =
dc.SetTextForeground(m_colPropFore); GetEditorControl()->GetBackgroundColour();
dc.DrawRectangle(cellRect); dc.SetBrush(editorBgCol);
dc.SetPen(editorBgCol);
dc.SetTextForeground(m_colPropFore);
dc.DrawRectangle(cellRect);
if ( m_dragStatus == 0 && !(m_iFlags & wxPG_FL_CUR_USES_CUSTOM_IMAGE) ) if ( m_dragStatus == 0 &&
ctrlCell = true; !(m_iFlags & wxPG_FL_CUR_USES_CUSTOM_IMAGE) )
ctrlCell = true;
}
else
{
dc.SetBrush(m_colPropBack);
dc.SetPen(m_colPropBack);
dc.SetTextForeground(m_colDisPropFore);
if ( p->IsEnabled() )
dc.SetTextForeground(rowFgCol);
else
dc.SetTextForeground(m_colDisPropFore);
}
} }
else else
{ {
@@ -2038,7 +2201,7 @@ wxRect wxPropertyGrid::GetPropertyRect( const wxPGProperty* p1, const wxPGProper
// If seleced property is inside the range, we'll extend the range to include // If seleced property is inside the range, we'll extend the range to include
// control's size. // control's size.
wxPGProperty* selected = m_selected; wxPGProperty* selected = GetSelection();
if ( selected ) if ( selected )
{ {
int selectedY = selected->GetY(); int selectedY = selected->GetY();
@@ -2078,8 +2241,12 @@ void wxPropertyGrid::DrawItems( const wxPGProperty* p1, const wxPGProperty* p2 )
void wxPropertyGrid::RefreshProperty( wxPGProperty* p ) void wxPropertyGrid::RefreshProperty( wxPGProperty* p )
{ {
if ( p == m_selected ) if ( m_pState->DoIsPropertySelected(p) )
DoSelectProperty(p, wxPG_SEL_FORCE); {
// NB: We must copy the selection.
wxArrayPGProperty selection = m_pState->m_selection;
DoSetSelection(selection, wxPG_SEL_FORCE);
}
DrawItemAndChildren(p); DrawItemAndChildren(p);
} }
@@ -2118,7 +2285,8 @@ void wxPropertyGrid::DrawItemAndChildren( wxPGProperty* p )
return; return;
// Update child control. // Update child control.
if ( m_selected && m_selected->GetParent() == p ) wxPGProperty* selected = GetSelection();
if ( selected && selected->GetParent() == p )
RefreshEditor(); RefreshEditor();
const wxPGProperty* lastDrawn = p->GetLastVisibleSubItem(); const wxPGProperty* lastDrawn = p->GetLastVisibleSubItem();
@@ -2218,11 +2386,13 @@ void wxPropertyGrid::SwitchState( wxPropertyGridPageState* pNewState )
if ( pNewState == m_pState ) if ( pNewState == m_pState )
return; return;
wxPGProperty* oldSelection = m_selected; wxArrayPGProperty oldSelection = m_pState->m_selection;
DoClearSelection(); // Call ClearSelection() instead of DoClearSelection()
// so that selection clear events are not sent.
ClearSelection();
m_pState->m_selected = oldSelection; m_pState->m_selection = oldSelection;
bool orig_mode = m_pState->IsInNonCatMode(); bool orig_mode = m_pState->IsInNonCatMode();
bool new_state_mode = pNewState->IsInNonCatMode(); bool new_state_mode = pNewState->IsInNonCatMode();
@@ -2263,9 +2433,9 @@ void wxPropertyGrid::SwitchState( wxPropertyGridPageState* pNewState )
// Refresh, if not frozen. // Refresh, if not frozen.
m_pState->PrepareAfterItemsAdded(); m_pState->PrepareAfterItemsAdded();
// Reselect // Reselect (Use SetSelection() instead of Do-variant so that
if ( m_pState->m_selected ) // events won't be sent).
DoSelectProperty( m_pState->m_selected ); SetSelection(m_pState->m_selection);
RecalculateVirtualSize(0); RecalculateVirtualSize(0);
Refresh(); Refresh();
@@ -2289,7 +2459,7 @@ void wxPropertyGrid::DoSetSplitterPosition_( int newxpos, bool refresh, int spli
if ( refresh ) if ( refresh )
{ {
if ( m_selected ) if ( GetSelection() )
CorrectEditorWidgetSizeX(); CorrectEditorWidgetSizeX();
Refresh(); Refresh();
@@ -2360,14 +2530,16 @@ bool wxPropertyGrid::CommitChangesFromEditor( wxUint32 flags )
return false; return false;
} }
wxPGProperty* selected = GetSelection();
if ( m_wndEditor && if ( m_wndEditor &&
IsEditorsValueModified() && IsEditorsValueModified() &&
(m_iFlags & wxPG_FL_INITIALIZED) && (m_iFlags & wxPG_FL_INITIALIZED) &&
m_selected ) selected )
{ {
m_inCommitChangesFromEditor = 1; m_inCommitChangesFromEditor = 1;
wxVariant variant(m_selected->GetValueRef()); wxVariant variant(selected->GetValueRef());
bool valueIsPending = false; bool valueIsPending = false;
// JACS - necessary to avoid new focus being found spuriously within OnIdle // JACS - necessary to avoid new focus being found spuriously within OnIdle
@@ -2380,10 +2552,13 @@ bool wxPropertyGrid::CommitChangesFromEditor( wxUint32 flags )
m_chgInfo_changedProperty = NULL; m_chgInfo_changedProperty = NULL;
// If truly modified, schedule value as pending. // If truly modified, schedule value as pending.
if ( m_selected->GetEditorClass()->GetValueFromControl( variant, m_selected, GetEditorControl() ) ) if ( selected->GetEditorClass()->
GetValueFromControl( variant,
selected,
GetEditorControl() ) )
{ {
if ( DoEditorValidate() && if ( DoEditorValidate() &&
PerformValidation(m_selected, variant) ) PerformValidation(selected, variant) )
{ {
valueIsPending = true; valueIsPending = true;
} }
@@ -2409,18 +2584,18 @@ bool wxPropertyGrid::CommitChangesFromEditor( wxUint32 flags )
m_curFocused = oldFocus; m_curFocused = oldFocus;
} }
res = OnValidationFailure(m_selected, variant); res = OnValidationFailure(selected, variant);
// Now prevent further validation failure messages // Now prevent further validation failure messages
if ( res ) if ( res )
{ {
EditorsValueWasNotModified(); EditorsValueWasNotModified();
OnValidationFailureReset(m_selected); OnValidationFailureReset(selected);
} }
} }
else if ( valueIsPending ) else if ( valueIsPending )
{ {
DoPropertyChanged( m_selected, flags ); DoPropertyChanged( selected, flags );
EditorsValueWasNotModified(); EditorsValueWasNotModified();
} }
@@ -2523,7 +2698,7 @@ bool wxPropertyGrid::PerformValidation( wxPGProperty* p, wxVariant& pendingValue
if ( evtChangingProperty->HasFlag(wxPG_PROP_COMPOSED_VALUE) ) if ( evtChangingProperty->HasFlag(wxPG_PROP_COMPOSED_VALUE) )
{ {
if ( changedProperty == m_selected ) if ( changedProperty == GetSelection() )
{ {
wxWindow* editor = GetEditorControl(); wxWindow* editor = GetEditorControl();
wxASSERT( editor->IsKindOf(CLASSINFO(wxTextCtrl)) ); wxASSERT( editor->IsKindOf(CLASSINFO(wxTextCtrl)) );
@@ -2617,7 +2792,7 @@ bool wxPropertyGrid::OnValidationFailure( wxPGProperty* property,
// //
// For non-wxTextCtrl editors, we do need to revert the value // For non-wxTextCtrl editors, we do need to revert the value
if ( !editor->IsKindOf(CLASSINFO(wxTextCtrl)) && if ( !editor->IsKindOf(CLASSINFO(wxTextCtrl)) &&
property == m_selected ) property == GetSelection() )
{ {
property->GetEditorClass()->UpdateControl(property, editor); property->GetEditorClass()->UpdateControl(property, editor);
} }
@@ -2656,7 +2831,7 @@ bool wxPropertyGrid::DoOnValidationFailure( wxPGProperty* property, wxVariant& W
DrawItemAndChildren(property); DrawItemAndChildren(property);
if ( property == m_selected ) if ( property == GetSelection() )
{ {
SetInternalFlag(wxPG_FL_CELL_OVERRIDES_SEL); SetInternalFlag(wxPG_FL_CELL_OVERRIDES_SEL);
@@ -2695,7 +2870,7 @@ void wxPropertyGrid::DoOnValidationFailureReset( wxPGProperty* property )
ClearInternalFlag(wxPG_FL_CELL_OVERRIDES_SEL); ClearInternalFlag(wxPG_FL_CELL_OVERRIDES_SEL);
if ( property == m_selected && GetEditorControl() ) if ( property == GetSelection() && GetEditorControl() )
{ {
// Calling this will recreate the control, thus resetting its colour // Calling this will recreate the control, thus resetting its colour
RefreshProperty(property); RefreshProperty(property);
@@ -2716,6 +2891,7 @@ bool wxPropertyGrid::DoPropertyChanged( wxPGProperty* p, unsigned int selFlags )
return true; return true;
wxWindow* editor = GetEditorControl(); wxWindow* editor = GetEditorControl();
wxPGProperty* selected = GetSelection();
m_pState->m_anyModified = 1; m_pState->m_anyModified = 1;
@@ -2742,7 +2918,7 @@ bool wxPropertyGrid::DoPropertyChanged( wxPGProperty* p, unsigned int selFlags )
if ( !(p->m_flags & wxPG_PROP_MODIFIED) ) if ( !(p->m_flags & wxPG_PROP_MODIFIED) )
{ {
p->m_flags |= wxPG_PROP_MODIFIED; p->m_flags |= wxPG_PROP_MODIFIED;
if ( p == m_selected && (m_windowStyle & wxPG_BOLD_MODIFIED) ) if ( p == selected && (m_windowStyle & wxPG_BOLD_MODIFIED) )
{ {
if ( editor ) if ( editor )
SetCurControlBoldFont(); SetCurControlBoldFont();
@@ -2759,7 +2935,7 @@ bool wxPropertyGrid::DoPropertyChanged( wxPGProperty* p, unsigned int selFlags )
{ {
pwc->m_flags |= wxPG_PROP_MODIFIED; pwc->m_flags |= wxPG_PROP_MODIFIED;
if ( pwc == m_selected && (m_windowStyle & wxPG_BOLD_MODIFIED) ) if ( pwc == selected && (m_windowStyle & wxPG_BOLD_MODIFIED) )
{ {
if ( editor ) if ( editor )
SetCurControlBoldFont(); SetCurControlBoldFont();
@@ -2867,11 +3043,11 @@ bool wxPropertyGrid::DoEditorValidate()
void wxPropertyGrid::HandleCustomEditorEvent( wxEvent &event ) void wxPropertyGrid::HandleCustomEditorEvent( wxEvent &event )
{ {
wxPGProperty* selected = m_selected; wxPGProperty* selected = GetSelection();
// Somehow, event is handled after property has been deselected. // Somehow, event is handled after property has been deselected.
// Possibly, but very rare. // Possibly, but very rare.
if ( !selected ) if ( !selected || selected->HasFlag(wxPG_PROP_BEING_DELETED) )
return; return;
if ( m_iFlags & wxPG_FL_IN_HANDLECUSTOMEDITOREVENT ) if ( m_iFlags & wxPG_FL_IN_HANDLECUSTOMEDITOREVENT )
@@ -2939,7 +3115,7 @@ void wxPropertyGrid::HandleCustomEditorEvent( wxEvent &event )
if ( DoEditorValidate() ) if ( DoEditorValidate() )
{ {
if ( editor->GetValueFromControl( pendingValue, if ( editor->GetValueFromControl( pendingValue,
m_selected, selected,
wnd ) ) wnd ) )
valueIsPending = true; valueIsPending = true;
} }
@@ -2966,7 +3142,7 @@ void wxPropertyGrid::HandleCustomEditorEvent( wxEvent &event )
} }
if ( !validationFailure && valueIsPending ) if ( !validationFailure && valueIsPending )
if ( !PerformValidation(m_selected, pendingValue) ) if ( !PerformValidation(selected, pendingValue) )
validationFailure = true; validationFailure = true;
if ( validationFailure) if ( validationFailure)
@@ -3260,17 +3436,26 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
m_inDoSelectProperty = 1; m_inDoSelectProperty = 1;
wxPGProperty* prev = m_selected;
if ( !m_pState ) if ( !m_pState )
{ {
m_inDoSelectProperty = 0; m_inDoSelectProperty = 0;
return false; return false;
} }
wxArrayPGProperty prevSelection = m_pState->m_selection;
wxPGProperty* prevFirstSel;
if ( prevSelection.size() > 0 )
prevFirstSel = prevSelection[0];
else
prevFirstSel = NULL;
if ( prevFirstSel && prevFirstSel->HasFlag(wxPG_PROP_BEING_DELETED) )
prevFirstSel = NULL;
/* /*
if (m_selected) if ( prevFirstSel )
wxPrintf( "Selected %s\n", m_selected->GetClassInfo()->GetClassName() ); wxPrintf( "Selected %s\n", prevFirstSel->GetClassInfo()->GetClassName() );
else else
wxPrintf( "None selected\n" ); wxPrintf( "None selected\n" );
@@ -3285,9 +3470,8 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
{ {
m_iFlags &= ~(wxPG_FL_ABNORMAL_EDITOR); m_iFlags &= ~(wxPG_FL_ABNORMAL_EDITOR);
m_editorFocused = 0; m_editorFocused = 0;
m_selected = p;
m_selColumn = 1; m_selColumn = 1;
m_pState->m_selected = p; m_pState->DoSetSelection(p);
// If frozen, always free controls. But don't worry, as Thaw will // If frozen, always free controls. But don't worry, as Thaw will
// recall SelectProperty to recreate them. // recall SelectProperty to recreate them.
@@ -3299,7 +3483,9 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
else else
{ {
// Is it the same? // Is it the same?
if ( m_selected == p && !(flags & wxPG_SEL_FORCE) ) if ( prevFirstSel == p &&
prevSelection.size() <= 1 &&
!(flags & wxPG_SEL_FORCE) )
{ {
// Only set focus if not deselecting // Only set focus if not deselecting
if ( p ) if ( p )
@@ -3324,13 +3510,12 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
// //
// First, deactivate previous // First, deactivate previous
if ( m_selected ) if ( prevFirstSel )
{ {
OnValidationFailureReset(prevFirstSel);
OnValidationFailureReset(m_selected);
// Must double-check if this is an selected in case of forceswitch // Must double-check if this is an selected in case of forceswitch
if ( p != prev ) if ( p != prevFirstSel )
{ {
if ( !CommitChangesFromEditor(flags) ) if ( !CommitChangesFromEditor(flags) )
{ {
@@ -3345,9 +3530,6 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
FreeEditors(); FreeEditors();
m_selColumn = -1; m_selColumn = -1;
m_selected = NULL;
m_pState->m_selected = NULL;
// We need to always fully refresh the grid here // We need to always fully refresh the grid here
Refresh(false); Refresh(false);
@@ -3357,6 +3539,8 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
SetInternalFlag(wxPG_FL_IN_SELECT_PROPERTY); SetInternalFlag(wxPG_FL_IN_SELECT_PROPERTY);
m_pState->DoSetSelection(p);
// //
// Then, activate the one given. // Then, activate the one given.
if ( p ) if ( p )
@@ -3365,10 +3549,8 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
int splitterX = GetSplitterPosition(); int splitterX = GetSplitterPosition();
m_editorFocused = 0; m_editorFocused = 0;
m_selected = p;
m_pState->m_selected = p;
m_iFlags |= wxPG_FL_PRIMARY_FILLS_ENTIRE; m_iFlags |= wxPG_FL_PRIMARY_FILLS_ENTIRE;
if ( p != prev ) if ( p != prevFirstSel )
m_iFlags &= ~(wxPG_FL_VALIDATION_FAILED); m_iFlags &= ~(wxPG_FL_VALIDATION_FAILED);
wxASSERT( m_wndEditor == NULL ); wxASSERT( m_wndEditor == NULL );
@@ -3609,7 +3791,7 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
// call wx event handler (here so that it also occurs on deselection) // call wx event handler (here so that it also occurs on deselection)
if ( !(flags & wxPG_SEL_DONT_SEND_EVENT) ) if ( !(flags & wxPG_SEL_DONT_SEND_EVENT) )
SendEvent( wxEVT_PG_SELECTED, m_selected, NULL, flags ); SendEvent( wxEVT_PG_SELECTED, p, NULL, flags );
return true; return true;
} }
@@ -3618,14 +3800,16 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
bool wxPropertyGrid::UnfocusEditor() bool wxPropertyGrid::UnfocusEditor()
{ {
if ( !m_selected || !m_wndEditor || m_frozen ) wxPGProperty* selected = GetSelection();
if ( !selected || !m_wndEditor || m_frozen )
return true; return true;
if ( !CommitChangesFromEditor(0) ) if ( !CommitChangesFromEditor(0) )
return false; return false;
SetFocusOnCanvas(); SetFocusOnCanvas();
DrawItem(m_selected); DrawItem(selected);
return true; return true;
} }
@@ -3634,7 +3818,7 @@ bool wxPropertyGrid::UnfocusEditor()
void wxPropertyGrid::RefreshEditor() void wxPropertyGrid::RefreshEditor()
{ {
wxPGProperty* p = m_selected; wxPGProperty* p = GetSelection();
if ( !p ) if ( !p )
return; return;
@@ -3673,14 +3857,6 @@ bool wxPropertyGrid::SelectProperty( wxPGPropArg id, bool focus )
return DoSelectProperty(p, flags); return DoSelectProperty(p, flags);
} }
// -----------------------------------------------------------------------
bool wxPropertyGrid::DoClearSelection()
{
// Unlike ClearSelection(), here we send the wxEVT_PG_SELECTED event.
return DoSelectProperty(NULL, 0);
}
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// wxPropertyGrid expand/collapse state // wxPropertyGrid expand/collapse state
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@@ -3688,9 +3864,10 @@ bool wxPropertyGrid::DoClearSelection()
bool wxPropertyGrid::DoCollapse( wxPGProperty* p, bool sendEvents ) bool wxPropertyGrid::DoCollapse( wxPGProperty* p, bool sendEvents )
{ {
wxPGProperty* pwc = wxStaticCast(p, wxPGProperty); wxPGProperty* pwc = wxStaticCast(p, wxPGProperty);
wxPGProperty* selected = GetSelection();
// If active editor was inside collapsed section, then disable it // If active editor was inside collapsed section, then disable it
if ( m_selected && m_selected->IsSomeParent(p) ) if ( selected && selected->IsSomeParent(p) )
{ {
DoClearSelection(); DoClearSelection();
} }
@@ -3773,12 +3950,18 @@ bool wxPropertyGrid::DoHideProperty( wxPGProperty* p, bool hide, int flags )
if ( m_frozen ) if ( m_frozen )
return m_pState->DoHideProperty(p, hide, flags); return m_pState->DoHideProperty(p, hide, flags);
if ( m_selected && wxArrayPGProperty selection = m_pState->m_selection; // Must use a copy
( m_selected == p || m_selected->IsSomeParent(p) ) int selRemoveCount = 0;
) for ( unsigned int i=0; i<selection.size(); i++ )
{
wxPGProperty* selected = selection[i];
if ( selected == p || selected->IsSomeParent(p) )
{ {
DoClearSelection(); if ( !DoRemoveFromSelection(p, flags) )
return false;
selRemoveCount += 1;
} }
}
m_pState->DoHideProperty(p, hide, flags); m_pState->DoHideProperty(p, hide, flags);
@@ -3860,7 +4043,7 @@ void wxPropertyGrid::RecalculateVirtualSize( int forceXPos )
m_pState->CheckColumnWidths(); m_pState->CheckColumnWidths();
if ( m_selected ) if ( GetSelection() )
CorrectEditorWidgetSizeX(); CorrectEditorWidgetSizeX();
m_iFlags &= ~wxPG_FL_RECALCULATING_VIRTUAL_SIZE; m_iFlags &= ~wxPG_FL_RECALCULATING_VIRTUAL_SIZE;
@@ -4019,7 +4202,7 @@ bool wxPropertyGrid::HandleMouseClick( int x, unsigned int y, wxMouseEvent &even
) )
) )
{ {
if ( !DoSelectProperty( p ) ) if ( !AddToSelectionFromInputEvent( p, &event ) )
return res; return res;
// On double-click, expand/collapse. // On double-click, expand/collapse.
@@ -4039,7 +4222,7 @@ bool wxPropertyGrid::HandleMouseClick( int x, unsigned int y, wxMouseEvent &even
m_iFlags |= wxPG_FL_ACTIVATION_BY_CLICK; m_iFlags |= wxPG_FL_ACTIVATION_BY_CLICK;
selFlag = wxPG_SEL_FOCUS; selFlag = wxPG_SEL_FOCUS;
} }
if ( !DoSelectProperty( p, selFlag ) ) if ( !AddToSelectionFromInputEvent( p, &event, selFlag ) )
return res; return res;
m_iFlags &= ~(wxPG_FL_ACTIVATION_BY_CLICK); m_iFlags &= ~(wxPG_FL_ACTIVATION_BY_CLICK);
@@ -4130,15 +4313,15 @@ bool wxPropertyGrid::HandleMouseClick( int x, unsigned int y, wxMouseEvent &even
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
bool wxPropertyGrid::HandleMouseRightClick( int WXUNUSED(x), unsigned int WXUNUSED(y), bool wxPropertyGrid::HandleMouseRightClick( int WXUNUSED(x),
wxMouseEvent& WXUNUSED(event) ) unsigned int WXUNUSED(y),
wxMouseEvent& event )
{ {
if ( m_propHover ) if ( m_propHover )
{ {
// Select property here as well // Select property here as well
wxPGProperty* p = m_propHover; wxPGProperty* p = m_propHover;
if ( p != m_selected ) AddToSelectionFromInputEvent(p, &event);
DoSelectProperty( p );
// Send right click event. // Send right click event.
SendEvent( wxEVT_PG_RIGHT_CLICK, p ); SendEvent( wxEVT_PG_RIGHT_CLICK, p );
@@ -4150,16 +4333,16 @@ bool wxPropertyGrid::HandleMouseRightClick( int WXUNUSED(x), unsigned int WXUNUS
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
bool wxPropertyGrid::HandleMouseDoubleClick( int WXUNUSED(x), unsigned int WXUNUSED(y), bool wxPropertyGrid::HandleMouseDoubleClick( int WXUNUSED(x),
wxMouseEvent& WXUNUSED(event) ) unsigned int WXUNUSED(y),
wxMouseEvent& event )
{ {
if ( m_propHover ) if ( m_propHover )
{ {
// Select property here as well // Select property here as well
wxPGProperty* p = m_propHover; wxPGProperty* p = m_propHover;
if ( p != m_selected ) AddToSelectionFromInputEvent(p, &event);
DoSelectProperty( p );
// Send double-click event. // Send double-click event.
SendEvent( wxEVT_PG_DOUBLE_CLICK, m_propHover ); SendEvent( wxEVT_PG_DOUBLE_CLICK, m_propHover );
@@ -4226,7 +4409,7 @@ bool wxPropertyGrid::HandleMouseMove( int x, unsigned int y, wxMouseEvent &event
state->DoSetSplitterPosition( newSplitterX, m_draggedSplitter, false ); state->DoSetSplitterPosition( newSplitterX, m_draggedSplitter, false );
state->m_fSplitterX = (float) newSplitterX; state->m_fSplitterX = (float) newSplitterX;
if ( m_selected ) if ( GetSelection() )
CorrectEditorWidgetSizeX(); CorrectEditorWidgetSizeX();
Update(); Update();
@@ -4385,6 +4568,18 @@ bool wxPropertyGrid::HandleMouseMove( int x, unsigned int y, wxMouseEvent &event
CustomSetCursor( wxCURSOR_ARROW ); CustomSetCursor( wxCURSOR_ARROW );
} }
} }
//
// Multi select by dragging
//
if ( GetExtraStyle() & wxPG_EX_MULTIPLE_SELECTION &&
event.LeftIsDown() &&
m_propHover &&
GetSelection() &&
!state->DoIsPropertySelected(m_propHover) )
{
DoAddToSelection(m_propHover);
}
} }
return true; return true;
} }
@@ -4434,8 +4629,9 @@ bool wxPropertyGrid::HandleMouseUp( int x, unsigned int WXUNUSED(y),
m_dragStatus = 0; m_dragStatus = 0;
// Control background needs to be cleared // Control background needs to be cleared
if ( !(m_iFlags & wxPG_FL_PRIMARY_FILLS_ENTIRE) && m_selected ) wxPGProperty* selected = GetSelection();
DrawItem( m_selected ); if ( !(m_iFlags & wxPG_FL_PRIMARY_FILLS_ENTIRE) && selected )
DrawItem( selected );
if ( m_wndEditor ) if ( m_wndEditor )
{ {
@@ -4659,8 +4855,10 @@ void wxPropertyGrid::OnMouseRightClickChild( wxMouseEvent &event )
// but that should not matter (right click is about item, not position). // but that should not matter (right click is about item, not position).
wxPoint pt = m_wndEditor->GetPosition(); wxPoint pt = m_wndEditor->GetPosition();
CalcUnscrolledPosition( event.m_x + pt.x, event.m_y + pt.y, &x, &y ); CalcUnscrolledPosition( event.m_x + pt.x, event.m_y + pt.y, &x, &y );
wxASSERT( m_selected );
m_propHover = m_selected; // FIXME: Used to set m_propHover to selection here. Was it really
// necessary?
bool res = HandleMouseRightClick(x,y,event); bool res = HandleMouseRightClick(x,y,event);
if ( !res ) event.Skip(); if ( !res ) event.Skip();
} }
@@ -4758,6 +4956,7 @@ void wxPropertyGrid::HandleKeyEvent( wxKeyEvent &event, bool fromChild )
wxCHECK2(!m_frozen, return); wxCHECK2(!m_frozen, return);
// Travelsal between items, collapsing/expanding, etc. // Travelsal between items, collapsing/expanding, etc.
wxPGProperty* selected = GetSelection();
int keycode = event.GetKeyCode(); int keycode = event.GetKeyCode();
bool editorFocused = IsEditorFocused(); bool editorFocused = IsEditorFocused();
@@ -4774,7 +4973,7 @@ void wxPropertyGrid::HandleKeyEvent( wxKeyEvent &event, bool fromChild )
{ {
if ( !editorFocused && m_wndEditor ) if ( !editorFocused && m_wndEditor )
{ {
DoSelectProperty( m_selected, wxPG_SEL_FOCUS ); DoSelectProperty( selected, wxPG_SEL_FOCUS );
} }
else else
{ {
@@ -4833,12 +5032,13 @@ void wxPropertyGrid::HandleKeyEvent( wxKeyEvent &event, bool fromChild )
EditorsValueWasNotModified(); EditorsValueWasNotModified();
// Update the control as well // Update the control as well
m_selected->GetEditorClass()->SetControlStringValue( m_selected, selected->GetEditorClass()->
GetEditorControl(), SetControlStringValue( selected,
m_selected->GetDisplayedString() ); GetEditorControl(),
selected->GetDisplayedString() );
} }
OnValidationFailureReset(m_selected); OnValidationFailureReset(selected);
UnfocusEditor(); UnfocusEditor();
return; return;
@@ -4858,13 +5058,13 @@ void wxPropertyGrid::HandleKeyEvent( wxKeyEvent &event, bool fromChild )
bool wasHandled = false; bool wasHandled = false;
if ( m_selected ) if ( selected )
{ {
// Show dialog? // Show dialog?
if ( ButtonTriggerKeyTest(action, event) ) if ( ButtonTriggerKeyTest(action, event) )
return; return;
wxPGProperty* p = m_selected; wxPGProperty* p = selected;
// Travel and expand/collapse // Travel and expand/collapse
int selectDir = -2; int selectDir = -2;
@@ -5065,8 +5265,9 @@ void wxPropertyGrid::HandleFocusChange( wxWindow* newFocused )
} }
// Redraw selected // Redraw selected
if ( m_selected && (m_iFlags & wxPG_FL_INITIALIZED) ) wxPGProperty* selected = GetSelection();
DrawItem( m_selected ); if ( selected && (m_iFlags & wxPG_FL_INITIALIZED) )
DrawItem( selected );
} }
} }

View File

@@ -147,10 +147,6 @@ void wxPropertyGridInterface::DeleteProperty( wxPGPropArg id )
wxPG_PROP_ARG_CALL_PROLOG() wxPG_PROP_ARG_CALL_PROLOG()
wxPropertyGridPageState* state = p->GetParentState(); wxPropertyGridPageState* state = p->GetParentState();
wxPropertyGrid* grid = state->GetGrid();
if ( grid->GetState() == state )
grid->DoSelectProperty(NULL, wxPG_SEL_DELETING|wxPG_SEL_NOVALIDATE);
state->DoDelete( p, true ); state->DoDelete( p, true );
@@ -167,13 +163,6 @@ wxPGProperty* wxPropertyGridInterface::RemoveProperty( wxPGPropArg id )
wxNullProperty); wxNullProperty);
wxPropertyGridPageState* state = p->GetParentState(); wxPropertyGridPageState* state = p->GetParentState();
wxPropertyGrid* grid = state->GetGrid();
if ( grid->GetState() == state )
{
grid->DoSelectProperty(NULL,
wxPG_SEL_DELETING|wxPG_SEL_NOVALIDATE);
}
state->DoDelete( p, false ); state->DoDelete( p, false );
@@ -218,11 +207,25 @@ wxPGProperty* wxPropertyGridInterface::ReplaceProperty( wxPGPropArg id, wxPGProp
// wxPropertyGridInterface property operations // wxPropertyGridInterface property operations
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
wxPGProperty* wxPropertyGridInterface::GetSelection() const
{
return m_pState->GetSelection();
}
// -----------------------------------------------------------------------
bool wxPropertyGridInterface::ClearSelection( bool validation ) bool wxPropertyGridInterface::ClearSelection( bool validation )
{ {
int flags = wxPG_SEL_DONT_SEND_EVENT; return DoClearSelection(validation, wxPG_SEL_DONT_SEND_EVENT);
}
// -----------------------------------------------------------------------
bool wxPropertyGridInterface::DoClearSelection( bool validation,
int selFlags )
{
if ( !validation ) if ( !validation )
flags |= wxPG_SEL_NOVALIDATE; selFlags |= wxPG_SEL_NOVALIDATE;
wxPropertyGridPageState* state = m_pState; wxPropertyGridPageState* state = m_pState;
@@ -230,9 +233,9 @@ bool wxPropertyGridInterface::ClearSelection( bool validation )
{ {
wxPropertyGrid* pg = state->GetGrid(); wxPropertyGrid* pg = state->GetGrid();
if ( pg->GetState() == state ) if ( pg->GetState() == state )
return pg->DoSelectProperty(NULL, flags); return pg->DoSelectProperty(NULL, selFlags);
else else
state->SetSelection(NULL); state->DoSetSelection(NULL);
} }
return true; return true;
@@ -1026,7 +1029,7 @@ bool wxPropertyGridInterface::RestoreEditableState( const wxString& src, int res
else else
{ {
if ( values[0].length() ) if ( values[0].length() )
pageState->SetSelection(GetPropertyByName(value)); pageState->DoSetSelection(GetPropertyByName(value));
else else
pageState->DoClearSelection(); pageState->DoClearSelection();
} }

View File

@@ -206,7 +206,6 @@ wxPropertyGridPageState::wxPropertyGridPageState()
m_properties = &m_regularArray; m_properties = &m_regularArray;
m_abcArray = NULL; m_abcArray = NULL;
m_currentCategory = NULL; m_currentCategory = NULL;
m_selected = NULL;
m_width = 0; m_width = 0;
m_virtualHeight = 0; m_virtualHeight = 0;
m_lastCaptionBottomnest = 1; m_lastCaptionBottomnest = 1;
@@ -274,7 +273,7 @@ void wxPropertyGridPageState::DoClear()
} }
else else
{ {
m_selected = NULL; m_selection.clear();
} }
m_regularArray.Empty(); m_regularArray.Empty();
@@ -1150,7 +1149,8 @@ bool wxPropertyGridPageState::DoSetPropertyValueString( wxPGProperty* p, const w
if ( res ) if ( res )
{ {
p->SetValue(variant); p->SetValue(variant);
if ( m_selected==p && this==m_pPropGrid->GetState() ) if ( p == m_pPropGrid->GetSelection() &&
this == m_pPropGrid->GetState() )
m_pPropGrid->RefreshEditor(); m_pPropGrid->RefreshEditor();
} }
@@ -1166,7 +1166,8 @@ bool wxPropertyGridPageState::DoSetPropertyValue( wxPGProperty* p, wxVariant& va
if ( p ) if ( p )
{ {
p->SetValue(value); p->SetValue(value);
if ( m_selected==p && this==m_pPropGrid->GetState() ) if ( p == m_pPropGrid->GetSelection() &&
this == m_pPropGrid->GetState() )
m_pPropGrid->RefreshEditor(); m_pPropGrid->RefreshEditor();
return true; return true;
@@ -1192,6 +1193,21 @@ bool wxPropertyGridPageState::DoSetPropertyValueWxObjectPtr( wxPGProperty* p, wx
// wxPropertyGridPageState property operations // wxPropertyGridPageState property operations
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
bool wxPropertyGridPageState::DoIsPropertySelected( wxPGProperty* prop ) const
{
const wxArrayPGProperty& selection = m_selection;
for ( unsigned int i=0; i<selection.size(); i++ )
{
if ( selection[i] == prop )
return true;
}
return false;
}
// -----------------------------------------------------------------------
bool wxPropertyGridPageState::DoCollapse( wxPGProperty* p ) bool wxPropertyGridPageState::DoCollapse( wxPGProperty* p )
{ {
wxCHECK_MSG( p, false, wxT("invalid property id") ); wxCHECK_MSG( p, false, wxT("invalid property id") );
@@ -1231,7 +1247,7 @@ bool wxPropertyGridPageState::DoSelectProperty( wxPGProperty* p, unsigned int fl
if ( this == m_pPropGrid->GetState() ) if ( this == m_pPropGrid->GetState() )
return m_pPropGrid->DoSelectProperty( p, flags ); return m_pPropGrid->DoSelectProperty( p, flags );
m_selected = p; DoSetSelection(p);
return true; return true;
} }
@@ -1711,6 +1727,25 @@ void wxPropertyGridPageState::DoDelete( wxPGProperty* item, bool doDelete )
wxCHECK_RET( !parent->HasFlag(wxPG_PROP_AGGREGATE), wxCHECK_RET( !parent->HasFlag(wxPG_PROP_AGGREGATE),
wxT("wxPropertyGrid: Do not attempt to remove sub-properties.") ); wxT("wxPropertyGrid: Do not attempt to remove sub-properties.") );
wxASSERT( item->GetParentState() == this );
wxPropertyGrid* pg = GetGrid();
if ( DoIsPropertySelected(item) )
{
if ( pg && pg->GetState() == this )
{
pg->DoRemoveFromSelection(item,
wxPG_SEL_DELETING|wxPG_SEL_NOVALIDATE);
}
else
{
m_selection.Remove(item);
}
}
item->SetFlag(wxPG_PROP_BEING_DELETED);
// Delete children // Delete children
if ( item->GetChildCount() && !item->HasFlag(wxPG_PROP_AGGREGATE) ) if ( item->GetChildCount() && !item->HasFlag(wxPG_PROP_AGGREGATE) )
{ {
@@ -1780,8 +1815,6 @@ void wxPropertyGridPageState::DoDelete( wxPGProperty* item, bool doDelete )
(parent->IsCategory() || parent->IsRoot()) ) (parent->IsCategory() || parent->IsRoot()) )
m_dictName.erase(item->GetBaseName()); m_dictName.erase(item->GetBaseName());
wxPropertyGrid* pg = GetGrid();
// We need to clear parent grid's m_propHover, if it matches item // We need to clear parent grid's m_propHover, if it matches item
if ( pg && pg->m_propHover == item ) if ( pg && pg->m_propHover == item )
pg->m_propHover = NULL; pg->m_propHover = NULL;