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
This commit is contained in:
Jaakko Salli 2009-06-10 20:36:56 +00:00
parent 6de7047076
commit 27c1f235ba
5 changed files with 114 additions and 54 deletions

View File

@ -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;

View File

@ -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:
/**

View File

@ -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.
*/

View File

@ -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 )
{

View File

@ -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
// -----------------------------------------------------------------------