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
This commit is contained in:
parent
3048aa50af
commit
c16808c380
@ -5798,23 +5798,37 @@ void wxPropertyGrid::OnIdle( wxIdleEvent& WXUNUSED(event) )
|
|||||||
|
|
||||||
//
|
//
|
||||||
// Resolve pending property removals
|
// 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;
|
size_t cntBefore = cntAfter;
|
||||||
for ( unsigned int i=0; i<arr.size(); i++ )
|
|
||||||
{
|
DeleteProperty(m_deletedProperties[0]);
|
||||||
DeleteProperty(arr[i]);
|
|
||||||
}
|
cntAfter = m_deletedProperties.size();
|
||||||
arr.clear();
|
wxASSERT_MSG( cntAfter <= cntBefore,
|
||||||
|
wxT("Increased number of pending items after deletion") );
|
||||||
|
// Break if deletion was not done
|
||||||
|
if ( cntAfter >= cntBefore )
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if ( m_removedProperties.size() > 0 )
|
cntAfter = m_removedProperties.size();
|
||||||
|
while ( cntAfter > 0 )
|
||||||
{
|
{
|
||||||
wxArrayPGProperty& arr = m_removedProperties;
|
size_t cntBefore = cntAfter;
|
||||||
for ( unsigned int i=0; i<arr.size(); i++ )
|
|
||||||
{
|
RemoveProperty(m_removedProperties[0]);
|
||||||
RemoveProperty(arr[i]);
|
|
||||||
}
|
cntAfter = m_removedProperties.size();
|
||||||
arr.clear();
|
wxASSERT_MSG( cntAfter <= cntBefore,
|
||||||
|
wxT("Increased number of pending items after removal") );
|
||||||
|
// Break if removal was not done
|
||||||
|
if ( cntAfter >= cntBefore )
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1964,9 +1964,40 @@ void wxPropertyGridPageState::DoDelete( wxPGProperty* item, bool doDelete )
|
|||||||
|
|
||||||
// We can actually delete it now
|
// We can actually delete it now
|
||||||
if ( doDelete )
|
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;
|
delete item;
|
||||||
|
}
|
||||||
else
|
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);
|
item->OnDetached(this, pg);
|
||||||
|
}
|
||||||
|
|
||||||
m_itemsAdded = 1; // Not a logical assignment (but required nonetheless).
|
m_itemsAdded = 1; // Not a logical assignment (but required nonetheless).
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user