From 8a971c12ad6fb0396c79932a0e2176334e1db3ea Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Fri, 31 Oct 2014 16:04:44 +0000 Subject: [PATCH] Fix deleting wxPG properties with sub-properties. If property contains sub-properties they should be deselected prior deleting the property. See #16617. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@78083 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/propgrid/propgridpagestate.h | 7 ++ src/propgrid/propgridpagestate.cpp | 97 +++++++++++++++++++------ 2 files changed, 82 insertions(+), 22 deletions(-) diff --git a/include/wx/propgrid/propgridpagestate.h b/include/wx/propgrid/propgridpagestate.h index 8eb910bceb..b57efe3d81 100644 --- a/include/wx/propgrid/propgridpagestate.h +++ b/include/wx/propgrid/propgridpagestate.h @@ -697,6 +697,13 @@ protected: wxPGProperty* BaseGetPropertyByLabel( const wxString& label, wxPGProperty* parent = NULL ) const; + /** Unselect sub-properties */ + void DoRemoveChildrenFromSelection(wxPGProperty* p, bool recursive, + int selFlags); + + /** Mark sub-properties as being deleted */ + void DoMarkChildrenAsDeleted(wxPGProperty* p, bool recursive); + /** If visible, then this is pointer to wxPropertyGrid. This shall *never* be NULL to indicate that this state is not visible. */ diff --git a/src/propgrid/propgridpagestate.cpp b/src/propgrid/propgridpagestate.cpp index cc58ff3b8a..541f785a24 100644 --- a/src/propgrid/propgridpagestate.cpp +++ b/src/propgrid/propgridpagestate.cpp @@ -1853,16 +1853,90 @@ wxPGProperty* wxPropertyGridPageState::DoInsert( wxPGProperty* parent, int index // ----------------------------------------------------------------------- +void wxPropertyGridPageState::DoRemoveChildrenFromSelection(wxPGProperty* p, + bool recursive, + int selFlags) +{ + wxPropertyGrid* pg = GetGrid(); + + for( unsigned int i = 0; i < p->GetChildCount(); i++ ) + { + wxPGProperty* child = p->Item(i); + if ( DoIsPropertySelected(child) ) + { + if ( pg && pg->GetState() == this ) + { + pg->DoRemoveFromSelection(child, selFlags); + } + else + { + DoRemoveFromSelection(child); + } + } + + if ( recursive ) + { + DoRemoveChildrenFromSelection(child, recursive, selFlags); + } + } +} + +void wxPropertyGridPageState::DoMarkChildrenAsDeleted(wxPGProperty* p, + bool recursive) +{ + for( unsigned int i = 0; i < p->GetChildCount(); i++ ) + { + wxPGProperty* child = p->Item(i); + + child->SetFlag(wxPG_PROP_BEING_DELETED); + + if ( recursive ) + { + DoMarkChildrenAsDeleted(child, recursive); + } + } +} + void wxPropertyGridPageState::DoDelete( wxPGProperty* item, bool doDelete ) { wxCHECK_RET( item->GetParent(), - wxT("this property was already deleted") ); + wxT("wxPropertyGrid: This property was already deleted.") ); wxCHECK_RET( item != &m_regularArray && item != m_abcArray, wxT("wxPropertyGrid: Do not attempt to remove the root item.") ); + wxPGProperty* parent = item->GetParent(); + + wxCHECK_RET( !parent->HasFlag(wxPG_PROP_AGGREGATE), + 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 + { + DoRemoveFromSelection(item); + } + } + + if ( item->IsChildSelected(true) ) + { + DoRemoveChildrenFromSelection(item, true, + wxPG_SEL_DELETING|wxPG_SEL_NOVALIDATE); + } + + // Prevent property and its children from being re-selected + item->SetFlag(wxPG_PROP_BEING_DELETED); + DoMarkChildrenAsDeleted(item, true); + // Must defer deletion? Yes, if handling a wxPG event. if ( pg && pg->m_processedEvent ) { @@ -1899,27 +1973,6 @@ void wxPropertyGridPageState::DoDelete( wxPGProperty* item, bool doDelete ) unsigned int indinparent = item->GetIndexInParent(); wxPGProperty* pwc = (wxPGProperty*)item; - wxPGProperty* parent = item->GetParent(); - - wxCHECK_RET( !parent->HasFlag(wxPG_PROP_AGGREGATE), - wxT("wxPropertyGrid: Do not attempt to remove sub-properties.") ); - - wxASSERT( item->GetParentState() == this ); - - if ( DoIsPropertySelected(item) ) - { - if ( pg && pg->GetState() == this ) - { - pg->DoRemoveFromSelection(item, - wxPG_SEL_DELETING|wxPG_SEL_NOVALIDATE); - } - else - { - DoRemoveFromSelection(item); - } - } - - item->SetFlag(wxPG_PROP_BEING_DELETED); // Delete children if ( item->GetChildCount() && !item->HasFlag(wxPG_PROP_AGGREGATE) )