From c16808c38024f04f0a401adf84dd0c9cf03daed0 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Fri, 11 Jul 2014 17:01:28 +0000 Subject: [PATCH] Adjust list of items for deferred deletion/removal if wxPG property item is actually deleted/removed. When property is actually deleted/removed it must be also removed from the respective list of items for deferred deletion/removal in order to avoid crashes when it would be attempted to delete/remove it again at next wxPG idle state. Because lists of items for deferred operations can be updated at every actual deletion/removal it is necessary to rearrange iteration through these lists in wxPG::OnIdle. See #16222. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@76889 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/propgrid/propgrid.cpp | 42 ++++++++++++++++++++---------- src/propgrid/propgridpagestate.cpp | 31 ++++++++++++++++++++++ 2 files changed, 59 insertions(+), 14 deletions(-) diff --git a/src/propgrid/propgrid.cpp b/src/propgrid/propgrid.cpp index dc1e1b2837..2dc4688772 100644 --- a/src/propgrid/propgrid.cpp +++ b/src/propgrid/propgrid.cpp @@ -5798,23 +5798,37 @@ void wxPropertyGrid::OnIdle( wxIdleEvent& WXUNUSED(event) ) // // Resolve pending property removals - if ( m_deletedProperties.size() > 0 ) + // In order to determine whether deletion/removal + // was done we need to track the size of the list + // before and after the operation. + // (Note that lists are changed at every operation.) + size_t cntAfter = m_deletedProperties.size(); + while ( cntAfter > 0 ) { - wxArrayPGProperty& arr = m_deletedProperties; - for ( unsigned int i=0; i= cntBefore ) + break; } - if ( m_removedProperties.size() > 0 ) + cntAfter = m_removedProperties.size(); + while ( cntAfter > 0 ) { - wxArrayPGProperty& arr = m_removedProperties; - for ( unsigned int i=0; i= cntBefore ) + break; } } diff --git a/src/propgrid/propgridpagestate.cpp b/src/propgrid/propgridpagestate.cpp index c5f5789a29..4c8f482fa8 100644 --- a/src/propgrid/propgridpagestate.cpp +++ b/src/propgrid/propgridpagestate.cpp @@ -1964,9 +1964,40 @@ void wxPropertyGridPageState::DoDelete( wxPGProperty* item, bool doDelete ) // We can actually delete it now if ( doDelete ) + { + // Remove the item from both lists of pending operations. + // (Deleted item cannot be also the subject of further removal.) + int index = pg->m_deletedProperties.Index(item); + if ( index != wxNOT_FOUND ) + { + pg->m_deletedProperties.RemoveAt(index); + } + wxASSERT_MSG( pg->m_deletedProperties.Index(item) == wxNOT_FOUND, + wxT("Too many occurences of the item")); + + index = pg->m_removedProperties.Index(item); + if ( index != wxNOT_FOUND ) + { + pg->m_removedProperties.RemoveAt(index); + } + wxASSERT_MSG( pg->m_removedProperties.Index(item) == wxNOT_FOUND, + wxT("Too many occurences of the item")); + delete item; + } else + { + // Remove the item from the list of pending removals. + int index = pg->m_removedProperties.Index(item); + if ( index != wxNOT_FOUND ) + { + pg->m_removedProperties.RemoveAt(index); + } + wxASSERT_MSG( pg->m_removedProperties.Index(item) == wxNOT_FOUND, + wxT("Too many occurences of the item")); + item->OnDetached(this, pg); + } m_itemsAdded = 1; // Not a logical assignment (but required nonetheless).