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
This commit is contained in:
Jaakko Salli
2009-06-22 17:02:53 +00:00
parent 9aeace31b7
commit 6edd8829ef
3 changed files with 51 additions and 29 deletions

View File

@@ -894,8 +894,9 @@ public:
bool IsFrozen() const { return (m_frozen>0)?true:false; } bool IsFrozen() const { return (m_frozen>0)?true:false; }
/** /**
Call this any time your code causes wxPropertyGrid's top-level parent It is recommended that you call this function any time your code causes
to change. 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 @param newTLP
New top-level parent that is about to be set. Old top-level parent New top-level parent that is about to be set. Old top-level parent
@@ -1630,6 +1631,12 @@ protected:
// Last known top-level parent // Last known top-level parent
wxWindow* m_tlp; wxWindow* m_tlp;
// Last closed top-level parent
wxWindow* m_tlpClosed;
// Local time ms when tlp was closed.
wxLongLong m_tlpClosedTime;
// Sort function // Sort function
wxPGSortCallback m_sortFunction; wxPGSortCallback m_sortFunction;

View File

@@ -698,8 +698,9 @@ public:
bool IsFrozen() const; bool IsFrozen() const;
/** /**
Call this any time your code causes wxPropertyGrid's top-level parent It is recommended that you call this function any time your code causes
to change. 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 @param newTLP
New top-level parent that is about to be set. Old top-level parent New top-level parent that is about to be set. Old top-level parent

View File

@@ -551,7 +551,9 @@ void wxPropertyGrid::Init2()
// Hook the top-level parent // Hook the top-level parent
m_tlp = NULL; m_tlp = NULL;
OnTLPChanging(NULL); m_tlpClosed = NULL;
m_tlpClosedTime = 0;
OnTLPChanging(::wxGetTopLevelParent(this));
// set virtual size to this window size // set virtual size to this window size
wxSize wndsize = GetSize(); wxSize wndsize = GetSize();
@@ -588,20 +590,8 @@ wxPropertyGrid::~wxPropertyGrid()
if ( m_iFlags & wxPG_FL_MOUSE_CAPTURED ) if ( m_iFlags & wxPG_FL_MOUSE_CAPTURED )
m_canvas->ReleaseMouse(); m_canvas->ReleaseMouse();
// Do TLP check, recommend use of OnTLPChanging() // Call with NULL to disconnect event handling
wxWindow* tlp = ::wxGetTopLevelParent(this); OnTLPChanging(NULL);
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(), wxASSERT_MSG( !IsEditorsValueModified(),
wxS("Most recent change in property editor was lost!!! ") wxS("Most recent change in property editor was lost!!! ")
@@ -816,31 +806,42 @@ wxSize wxPropertyGrid::DoGetBestSize() const
return sz; return sz;
} }
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
void wxPropertyGrid::OnTLPChanging( wxWindow* newTLP ) void wxPropertyGrid::OnTLPChanging( wxWindow* newTLP )
{ {
wxLongLong currentTime = ::wxGetLocalTimeMillis();
// //
// Parent changed so let's redetermine and re-hook the // Parent changed so let's redetermine and re-hook the
// correct top-level window. // correct top-level window.
if ( m_tlp ) 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, m_tlp->Disconnect( wxEVT_CLOSE_WINDOW,
wxCloseEventHandler(wxPropertyGrid::OnTLPClose), wxCloseEventHandler(wxPropertyGrid::OnTLPClose),
NULL, this ); NULL, this );
m_tlpClosed = m_tlp;
m_tlpClosedTime = currentTime;
} }
if ( !newTLP ) if ( newTLP )
newTLP = ::wxGetTopLevelParent(this); {
// 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 = newTLP;
m_tlp->Connect( wxEVT_CLOSE_WINDOW,
wxCloseEventHandler(wxPropertyGrid::OnTLPClose),
NULL, this );
} }
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@@ -854,6 +855,11 @@ void wxPropertyGrid::OnTLPClose( wxCloseEvent& event )
return; 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(); event.Skip();
} }
@@ -4957,6 +4963,14 @@ void wxPropertyGrid::OnIdle( wxIdleEvent& WXUNUSED(event) )
if ( newFocused != m_curFocused ) if ( newFocused != m_curFocused )
HandleFocusChange( newFocused ); HandleFocusChange( newFocused );
//
// Check if top-level parent has changed
wxWindow* tlp = ::wxGetTopLevelParent(this);
if ( tlp != m_tlp )
{
OnTLPChanging(tlp);
}
} }
bool wxPropertyGrid::IsEditorFocused() const bool wxPropertyGrid::IsEditorFocused() const