Fix event handling order in doc/view framework.

Ensure that the events are always (provided there is an open document)
processed in the following order:

1. wxDocument
2. wxView
3. wxDocManager
4. wxDocChildFrame
5. wxDocParentFrame
6. wxApp

Do this by forwarding the events from wxDocParentFrame to wxDocChildFrame
first and forward them from there to wxDocManager which -- and this part
remains unchanged -- in turn forwards them to the active wxView which finally
forwards them to wxDocument. This requires another condition in the event
handling code as we still must forward from wxDocParentFrame to wxDocManager
itself if there are no active children at all, but this is the only way to
have the same event order in all cases, whether the event is originally
received by wxDocChildFrame or wxDocParentFrame.

Document this and add a unit test verifying that things indeed work like this.

See #14314.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@73928 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2013-05-04 23:59:56 +00:00
parent 80dcb89812
commit a7c0de8a98
4 changed files with 204 additions and 10 deletions

View File

@@ -643,10 +643,7 @@ protected:
// we're not a wxEvtHandler but we provide this wxEvtHandler-like function
// which is called from TryBefore() of the derived classes to give our view
// a chance to process the message before the frame event handlers are used
bool TryProcessEvent(wxEvent& event)
{
return m_childView && m_childView->ProcessEventLocally(event);
}
bool TryProcessEvent(wxEvent& event);
// called from EVT_CLOSE handler in the frame: check if we can close and do
// cleanup if so; veto the event otherwise
@@ -830,11 +827,22 @@ private:
class WXDLLIMPEXP_CORE wxDocParentFrameAnyBase
{
public:
wxDocParentFrameAnyBase() { m_docManager = NULL; }
wxDocParentFrameAnyBase(wxWindow* frame)
: m_frame(frame)
{
m_docManager = NULL;
}
wxDocManager *GetDocumentManager() const { return m_docManager; }
protected:
// This is similar to wxDocChildFrameAnyBase method with the same name:
// while we're not an event handler ourselves and so can't override
// TryBefore(), we provide a helper that the derived template class can use
// from its TryBefore() implementation.
bool TryProcessEvent(wxEvent& event);
wxWindow* const m_frame;
wxDocManager *m_docManager;
wxDECLARE_NO_COPY_CLASS(wxDocParentFrameAnyBase);
@@ -847,7 +855,7 @@ class WXDLLIMPEXP_CORE wxDocParentFrameAny : public BaseFrame,
public wxDocParentFrameAnyBase
{
public:
wxDocParentFrameAny() { }
wxDocParentFrameAny() : wxDocParentFrameAnyBase(this) { }
wxDocParentFrameAny(wxDocManager *manager,
wxFrame *frame,
wxWindowID id,
@@ -856,6 +864,7 @@ public:
const wxSize& size = wxDefaultSize,
long style = wxDEFAULT_FRAME_STYLE,
const wxString& name = wxFrameNameStr)
: wxDocParentFrameAnyBase(this)
{
Create(manager, frame, id, title, pos, size, style, name);
}
@@ -886,10 +895,7 @@ protected:
// hook the document manager into event handling chain here
virtual bool TryBefore(wxEvent& event)
{
if ( m_docManager && m_docManager->ProcessEventLocally(event) )
return true;
return BaseFrame::TryBefore(event);
return TryProcessEvent(event) || BaseFrame::TryBefore(event);
}
private: