From: Jaakko Salli Date: Mon, 22 Jun 2009 17:02:53 +0000 (+0000) Subject: Significantly improved wxPropertyGrid's top-level parent change detection code (fixes... X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/6edd8829ef3d6f29a73590d99abb121942e77100 Significantly improved wxPropertyGrid's top-level parent change detection code (fixes #10919) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@61164 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/propgrid/propgrid.h b/include/wx/propgrid/propgrid.h index 29d257b336..e7bfde366e 100644 --- a/include/wx/propgrid/propgrid.h +++ b/include/wx/propgrid/propgrid.h @@ -894,8 +894,9 @@ public: bool IsFrozen() const { return (m_frozen>0)?true:false; } /** - Call this any time your code causes wxPropertyGrid's top-level parent - to change. + It is recommended that you call this function any time your code causes + wxPropertyGrid's top-level parent to change. wxPropertyGrid's OnIdle() + handler should be able to detect most changes, but it is not perfect. @param newTLP New top-level parent that is about to be set. Old top-level parent @@ -1630,6 +1631,12 @@ protected: // Last known top-level parent wxWindow* m_tlp; + // Last closed top-level parent + wxWindow* m_tlpClosed; + + // Local time ms when tlp was closed. + wxLongLong m_tlpClosedTime; + // Sort function wxPGSortCallback m_sortFunction; diff --git a/interface/wx/propgrid/propgrid.h b/interface/wx/propgrid/propgrid.h index c953f58541..1437c07abd 100644 --- a/interface/wx/propgrid/propgrid.h +++ b/interface/wx/propgrid/propgrid.h @@ -698,8 +698,9 @@ public: bool IsFrozen() const; /** - Call this any time your code causes wxPropertyGrid's top-level parent - to change. + It is recommended that you call this function any time your code causes + wxPropertyGrid's top-level parent to change. wxPropertyGrid's OnIdle() + handler should be able to detect most changes, but it is not perfect. @param newTLP New top-level parent that is about to be set. Old top-level parent diff --git a/src/propgrid/propgrid.cpp b/src/propgrid/propgrid.cpp index 964afd9c90..305f246cc2 100644 --- a/src/propgrid/propgrid.cpp +++ b/src/propgrid/propgrid.cpp @@ -551,7 +551,9 @@ void wxPropertyGrid::Init2() // Hook the top-level parent m_tlp = NULL; - OnTLPChanging(NULL); + m_tlpClosed = NULL; + m_tlpClosedTime = 0; + OnTLPChanging(::wxGetTopLevelParent(this)); // set virtual size to this window size wxSize wndsize = GetSize(); @@ -588,20 +590,8 @@ wxPropertyGrid::~wxPropertyGrid() if ( m_iFlags & wxPG_FL_MOUSE_CAPTURED ) m_canvas->ReleaseMouse(); - // Do TLP check, recommend use of OnTLPChanging() - wxWindow* tlp = ::wxGetTopLevelParent(this); - if ( tlp == m_tlp ) - { - m_tlp->Disconnect( wxEVT_CLOSE_WINDOW, - wxCloseEventHandler(wxPropertyGrid::OnTLPClose), - NULL, this ); - } - else if ( tlp ) - { - wxLogError("Top-level parent of wxPropertyGrid has changed. " - "Consider calling wxPropertyGrid::OnTLPChanging() " - "when appropriate."); - } + // Call with NULL to disconnect event handling + OnTLPChanging(NULL); wxASSERT_MSG( !IsEditorsValueModified(), wxS("Most recent change in property editor was lost!!! ") @@ -816,31 +806,42 @@ wxSize wxPropertyGrid::DoGetBestSize() const return sz; } - // ----------------------------------------------------------------------- +// ----------------------------------------------------------------------- void wxPropertyGrid::OnTLPChanging( wxWindow* newTLP ) { + wxLongLong currentTime = ::wxGetLocalTimeMillis(); + // // Parent changed so let's redetermine and re-hook the // correct top-level window. if ( m_tlp ) { - wxASSERT_MSG( m_tlp == ::wxGetTopLevelParent(this), - "You must call OnTLPChanging() before the " - "top-level parent has changed."); - m_tlp->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler(wxPropertyGrid::OnTLPClose), NULL, this ); + m_tlpClosed = m_tlp; + m_tlpClosedTime = currentTime; } - if ( !newTLP ) - newTLP = ::wxGetTopLevelParent(this); + if ( newTLP ) + { + // Only accept new tlp if same one was not just dismissed. + if ( newTLP != m_tlpClosed || + m_tlpClosedTime+250 < currentTime ) + { + newTLP->Connect( wxEVT_CLOSE_WINDOW, + wxCloseEventHandler(wxPropertyGrid::OnTLPClose), + NULL, this ); + m_tlpClosed = NULL; + } + else + { + newTLP = NULL; + } + } m_tlp = newTLP; - m_tlp->Connect( wxEVT_CLOSE_WINDOW, - wxCloseEventHandler(wxPropertyGrid::OnTLPClose), - NULL, this ); } // ----------------------------------------------------------------------- @@ -854,6 +855,11 @@ void wxPropertyGrid::OnTLPClose( wxCloseEvent& event ) return; } + // Ok, it can close, set tlp pointer to NULL. Some other event + // handler can of course veto the close, but our OnIdle() should + // then be able to regain the tlp pointer. + OnTLPChanging(NULL); + event.Skip(); } @@ -4957,6 +4963,14 @@ void wxPropertyGrid::OnIdle( wxIdleEvent& WXUNUSED(event) ) if ( newFocused != m_curFocused ) HandleFocusChange( newFocused ); + + // + // Check if top-level parent has changed + wxWindow* tlp = ::wxGetTopLevelParent(this); + if ( tlp != m_tlp ) + { + OnTLPChanging(tlp); + } } bool wxPropertyGrid::IsEditorFocused() const