Fix crash when deleting all wxTreeListCtrl items with wxGTK3
GTK+ 3 (but not the generic version nor even GTK+ 2, apparently) sends "selection changed" event from gtk_tree_model_row_deleted() when deleting the currently selected row, which resulted in sending of wxEVT_TREELIST_SELECTION_CHANGED events with invalid wxTreeListItem, containing a dangling pointer, and a crash in the treelist sample when trying to dump it. Avoid this by clearing the model (and hence generating these events) first and deleting the items only afterwards. Also add a trivial unit test for wxTreeListCtrl::DeleteAllItems(), which doesn't even allow to reproduce this bug, but is still probably better to have than not to. Closes #18045.
This commit is contained in:
parent
321c9d5f30
commit
1dd102d741
@ -572,12 +572,16 @@ void wxTreeListModel::DeleteItem(Node* item)
|
||||
|
||||
void wxTreeListModel::DeleteAllItems()
|
||||
{
|
||||
// Note that this must be called before actually deleting the items as
|
||||
// clearing GTK+ wxDataViewCtrl results in SELECTION_CHANGED events being
|
||||
// sent and these events contain pointers to the model items, so they must
|
||||
// still be valid.
|
||||
Cleared();
|
||||
|
||||
while ( m_root->GetChild() )
|
||||
{
|
||||
m_root->DeleteChild();
|
||||
}
|
||||
|
||||
Cleared();
|
||||
}
|
||||
|
||||
const wxString& wxTreeListModel::GetItemText(Node* item, unsigned col) const
|
||||
|
@ -39,6 +39,7 @@ private:
|
||||
CPPUNIT_TEST( Traversal );
|
||||
CPPUNIT_TEST( ItemText );
|
||||
CPPUNIT_TEST( ItemCheck );
|
||||
CPPUNIT_TEST( DeleteAll );
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
// Create the control with the given style.
|
||||
@ -55,6 +56,7 @@ private:
|
||||
void Traversal();
|
||||
void ItemText();
|
||||
void ItemCheck();
|
||||
void DeleteAll();
|
||||
|
||||
|
||||
// The control itself.
|
||||
@ -231,4 +233,11 @@ void TreeListCtrlTestCase::ItemCheck()
|
||||
m_treelist->GetCheckedState(m_code) );
|
||||
}
|
||||
|
||||
void TreeListCtrlTestCase::DeleteAll()
|
||||
{
|
||||
m_treelist->DeleteAllItems();
|
||||
|
||||
CHECK( !m_treelist->GetFirstChild(m_treelist->GetRootItem()).IsOk() );
|
||||
}
|
||||
|
||||
#endif // wxUSE_TREELISTCTRL
|
||||
|
Loading…
Reference in New Issue
Block a user