From c234f5078f3815ef2d65d3efbe2b9b013f111493 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Thu, 16 Oct 2014 22:49:01 +0000 Subject: [PATCH] Fix deleting editor controls associated with wxPG properties from within event handler. Editor controls (and their event handlers) deleted from within wxPG event handler shouldn't by deleted in global idle event handler but only in local wxPG event handler because global idle events can be generated also by calling e.g. wxYield when wxPG is not in the real idle state. Closes #16617 git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@78030 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/propgrid/propgrid.h | 7 +++++++ include/wx/propgrid/propgriddefs.h | 4 ++++ src/propgrid/propgrid.cpp | 32 ++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/include/wx/propgrid/propgrid.h b/include/wx/propgrid/propgrid.h index ccb43d2f2a..faec9d147e 100644 --- a/include/wx/propgrid/propgrid.h +++ b/include/wx/propgrid/propgrid.h @@ -1896,6 +1896,11 @@ protected: wxArrayPGProperty m_deletedProperties; wxArrayPGProperty m_removedProperties; +#if !WXWIN_COMPATIBILITY_3_0 + /** List of editors and their event handlers to be deleted in idle event handler. */ + wxArrayPGObject m_deletedEditorObjects; +#endif + /** List of key codes that will not be handed over to editor controls. */ // FIXME: Make this a hash set once there is template-based wxHashSet. wxVector m_dedicatedKeys; @@ -2228,6 +2233,8 @@ protected: bool DoHideProperty( wxPGProperty* p, bool hide, int flags ); + void DeletePendingObjects(); + private: bool ButtonTriggerKeyTest( int action, wxKeyEvent& event ); diff --git a/include/wx/propgrid/propgriddefs.h b/include/wx/propgrid/propgriddefs.h index a28cc69289..40311f851f 100644 --- a/include/wx/propgrid/propgriddefs.h +++ b/include/wx/propgrid/propgriddefs.h @@ -315,6 +315,10 @@ WX_DECLARE_HASH_MAP_WITH_DECL(wxInt32, wxPGHashMapI2I, class WXDLLIMPEXP_PROPGRID); +WX_DEFINE_TYPEARRAY_WITH_DECL_PTR(wxObject*, wxArrayPGObject, + wxBaseArrayPtrVoid, + class WXDLLIMPEXP_PROPGRID); + // Utility to find if specific item is in a vector. Returns index to // the item, or wxNOT_FOUND if not present. template diff --git a/src/propgrid/propgrid.cpp b/src/propgrid/propgrid.cpp index 370ec00289..111624837a 100644 --- a/src/propgrid/propgrid.cpp +++ b/src/propgrid/propgrid.cpp @@ -539,6 +539,9 @@ wxPropertyGrid::~wxPropertyGrid() wxS("Close(false).)") ); } + // Delete pending editor controls + DeletePendingObjects(); + if ( m_doubleBuffer ) delete m_doubleBuffer; @@ -3924,6 +3927,20 @@ void wxPropertyGrid::SetupChildEventHandling( wxWindow* argWnd ) NULL, this); } +void wxPropertyGrid::DeletePendingObjects() +{ +#if !WXWIN_COMPATIBILITY_3_0 + // Delete pending property editors and their event handlers. + while ( !m_deletedEditorObjects.empty() ) + { + wxObject* obj = m_deletedEditorObjects.back(); + m_deletedEditorObjects.pop_back(); + + delete obj; + } +#endif +} + void wxPropertyGrid::DestroyEditorWnd( wxWindow* wnd ) { if ( !wnd ) @@ -3932,7 +3949,11 @@ void wxPropertyGrid::DestroyEditorWnd( wxWindow* wnd ) wnd->Hide(); // Do not free editors immediately (for sake of processing events) +#if WXWIN_COMPATIBILITY_3_0 wxPendingDelete.Append(wnd); +#else + m_deletedEditorObjects.push_back(wnd); +#endif } void wxPropertyGrid::FreeEditors() @@ -3948,7 +3969,11 @@ void wxPropertyGrid::FreeEditors() { wxEvtHandler* handler = m_wndEditor2->PopEventHandler(false); m_wndEditor2->Hide(); +#if WXWIN_COMPATIBILITY_3_0 wxPendingDelete.Append( handler ); +#else + m_deletedEditorObjects.push_back(handler); +#endif DestroyEditorWnd(m_wndEditor2); m_wndEditor2 = NULL; } @@ -3957,7 +3982,11 @@ void wxPropertyGrid::FreeEditors() { wxEvtHandler* handler = m_wndEditor->PopEventHandler(false); m_wndEditor->Hide(); +#if WXWIN_COMPATIBILITY_3_0 wxPendingDelete.Append( handler ); +#else + m_deletedEditorObjects.push_back(handler); +#endif DestroyEditorWnd(m_wndEditor); m_wndEditor = NULL; } @@ -5804,6 +5833,9 @@ void wxPropertyGrid::OnIdle( wxIdleEvent& WXUNUSED(event) ) OnTLPChanging(tlp); } + // Delete pending property editors and their event handlers. + DeletePendingObjects(); + // // Resolve pending property removals // In order to determine whether deletion/removal