From 27c1f235ba00917cc3599ad8e40cdb95afef2c9e Mon Sep 17 00:00:00 2001 From: Jaakko Salli Date: Wed, 10 Jun 2009 20:36:56 +0000 Subject: [PATCH] Allow reparenting wxPropertyGrid(Manager) to work; Show error and suggest calling wxPropertyGrid::OnTLPChanging() if top-level parent changed indirectly. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@60989 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/propgrid/manager.h | 1 + include/wx/propgrid/propgrid.h | 23 ++++-- interface/wx/propgrid/propgrid.h | 14 ++++ src/propgrid/manager.cpp | 12 ++++ src/propgrid/propgrid.cpp | 118 ++++++++++++++++++------------- 5 files changed, 114 insertions(+), 54 deletions(-) diff --git a/include/wx/propgrid/manager.h b/include/wx/propgrid/manager.h index fa45ef7b0c..3371c5695e 100644 --- a/include/wx/propgrid/manager.h +++ b/include/wx/propgrid/manager.h @@ -592,6 +592,7 @@ public: virtual void SetExtraStyle ( long exStyle ); virtual bool SetFont ( const wxFont& font ); virtual void SetWindowStyleFlag ( long style ); + virtual bool Reparent( wxWindowBase *newParent ); protected: virtual wxSize DoGetBestSize() const; diff --git a/include/wx/propgrid/propgrid.h b/include/wx/propgrid/propgrid.h index b69292b00a..d0060f7cfa 100644 --- a/include/wx/propgrid/propgrid.h +++ b/include/wx/propgrid/propgrid.h @@ -893,6 +893,20 @@ public: */ bool IsFrozen() const { return (m_frozen>0)?true:false; } + /** + Call this any time your code causes wxPropertyGrid's top-level parent + to change. + + @param newTLP + New top-level parent that is about to be set. Old top-level parent + window should still exist as the current one. + + @remarks This function is automatically called from wxPropertyGrid:: + Reparent() and wxPropertyGridManager::Reparent(). You only + need to use it if you reparent wxPropertyGrid indirectly. + */ + void OnTLPChanging( wxWindow* newTLP ); + /** Redraws given property. */ virtual void RefreshProperty( wxPGProperty* p ); @@ -1416,7 +1430,7 @@ public: virtual void Freeze(); virtual void SetExtraStyle( long exStyle ); virtual void Thaw(); - + virtual bool Reparent( wxWindowBase *newParent ); protected: virtual wxSize DoGetBestSize() const; @@ -1606,10 +1620,7 @@ protected: // handling mess). wxWindow* m_curFocused; - // wxPGTLWHandler - wxEvtHandler* m_tlwHandler; - - // Top level parent + // Last known top-level parent wxWindow* m_tlp; // Sort function @@ -1715,6 +1726,8 @@ protected: void OnSysColourChanged( wxSysColourChangedEvent &event ); + void OnTLPClose( wxCloseEvent& event ); + protected: /** diff --git a/interface/wx/propgrid/propgrid.h b/interface/wx/propgrid/propgrid.h index 21de0b0708..c953f58541 100644 --- a/interface/wx/propgrid/propgrid.h +++ b/interface/wx/propgrid/propgrid.h @@ -697,6 +697,20 @@ public: */ bool IsFrozen() const; + /** + Call this any time your code causes wxPropertyGrid's top-level parent + to change. + + @param newTLP + New top-level parent that is about to be set. Old top-level parent + window should still exist as the current one. + + @remarks This function is automatically called from wxPropertyGrid:: + Reparent() and wxPropertyGridManager::Reparent(). You only + need to use it if you reparent wxPropertyGrid indirectly. + */ + void OnTLPChanging( wxWindow* newTLP ); + /** Refreshes any active editor control. */ diff --git a/src/propgrid/manager.cpp b/src/propgrid/manager.cpp index 096228ac54..444902899c 100644 --- a/src/propgrid/manager.cpp +++ b/src/propgrid/manager.cpp @@ -528,6 +528,18 @@ void wxPropertyGridManager::SetWindowStyleFlag( long style ) // ----------------------------------------------------------------------- +bool wxPropertyGridManager::Reparent( wxWindowBase *newParent ) +{ + if ( m_pPropGrid ) + m_pPropGrid->OnTLPChanging((wxWindow*)newParent); + + bool res = wxPanel::Reparent(newParent); + + return res; +} + +// ----------------------------------------------------------------------- + // Actually shows given page. bool wxPropertyGridManager::DoSelectPage( int index ) { diff --git a/src/propgrid/propgrid.cpp b/src/propgrid/propgrid.cpp index 8da3ca884c..9dd4764c22 100644 --- a/src/propgrid/propgrid.cpp +++ b/src/propgrid/propgrid.cpp @@ -237,46 +237,6 @@ void wxPropertyGridInitGlobalsIfNeeded() { } -// ----------------------------------------------------------------------- -// wxPGTLWHandler -// Intercepts Close-events sent to wxPropertyGrid's top-level parent, -// and tries to commit property value. -// ----------------------------------------------------------------------- - -class wxPGTLWHandler : public wxEvtHandler -{ -public: - - wxPGTLWHandler( wxPropertyGrid* pg ) - : wxEvtHandler() - { - m_pg = pg; - } - -protected: - - void OnClose( wxCloseEvent& event ) - { - // ClearSelection forces value validation/commit. - if ( event.CanVeto() && !m_pg->ClearSelection() ) - { - event.Veto(); - return; - } - - event.Skip(); - } - -private: - wxPropertyGrid* m_pg; - - DECLARE_EVENT_TABLE() -}; - -BEGIN_EVENT_TABLE(wxPGTLWHandler, wxEvtHandler) - EVT_CLOSE(wxPGTLWHandler::OnClose) -END_EVENT_TABLE() - // ----------------------------------------------------------------------- // wxPGCanvas // ----------------------------------------------------------------------- @@ -473,7 +433,6 @@ void wxPropertyGrid::Init1() m_propHover = NULL; m_eventObject = this; m_curFocused = NULL; - m_tlwHandler = NULL; m_sortFunction = NULL; m_inDoPropertyChanged = 0; m_inCommitChangesFromEditor = 0; @@ -590,11 +549,9 @@ void wxPropertyGrid::Init2() // This helps with flicker SetBackgroundStyle( wxBG_STYLE_CUSTOM ); - // Hook the TLW - wxPGTLWHandler* handler = new wxPGTLWHandler(this); - m_tlp = ::wxGetTopLevelParent(this); - m_tlwHandler = handler; - m_tlp->PushEventHandler(handler); + // Hook the top-level parent + m_tlp = NULL; + OnTLPChanging(NULL); // set virtual size to this window size wxSize wndsize = GetSize(); @@ -631,9 +588,20 @@ wxPropertyGrid::~wxPropertyGrid() if ( m_iFlags & wxPG_FL_MOUSE_CAPTURED ) m_canvas->ReleaseMouse(); - wxPGTLWHandler* handler = (wxPGTLWHandler*) m_tlwHandler; - m_tlp->RemoveEventHandler(handler); - delete handler; + // 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."); + } wxASSERT_MSG( !IsEditorsValueModified(), wxS("Most recent change in property editor was lost!!! ") @@ -848,6 +816,58 @@ wxSize wxPropertyGrid::DoGetBestSize() const return sz; } + // ----------------------------------------------------------------------- + +void wxPropertyGrid::OnTLPChanging( wxWindow* newTLP ) +{ + // + // 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 ); + } + + if ( !newTLP ) + newTLP = ::wxGetTopLevelParent(this); + + m_tlp = newTLP; + m_tlp->Connect( wxEVT_CLOSE_WINDOW, + wxCloseEventHandler(wxPropertyGrid::OnTLPClose), + NULL, this ); +} + +// ----------------------------------------------------------------------- + +void wxPropertyGrid::OnTLPClose( wxCloseEvent& event ) +{ + // ClearSelection forces value validation/commit. + if ( event.CanVeto() && !ClearSelection() ) + { + event.Veto(); + return; + } + + event.Skip(); +} + +// ----------------------------------------------------------------------- + +bool wxPropertyGrid::Reparent( wxWindowBase *newParent ) +{ + OnTLPChanging((wxWindow*)newParent); + + bool res = wxScrolledWindow::Reparent(newParent); + + return res; +} + // ----------------------------------------------------------------------- // wxPropertyGrid Font and Colour Methods // ----------------------------------------------------------------------- -- 2.47.2