From 8cc208e39f61bca01cc23c339843891f099d47c5 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 26 Feb 2009 16:16:31 +0000 Subject: [PATCH] deprecate the old TryValidator/Parent() and replace them with the new and documented TryBefore/After() git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@59164 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 33 ++++++---- include/wx/docmdi.h | 4 +- include/wx/docview.h | 10 +-- include/wx/event.h | 46 ++++++++++---- include/wx/generic/mdig.h | 2 +- include/wx/msw/mdi.h | 2 +- include/wx/window.h | 4 +- interface/wx/event.h | 127 ++++++++++++++++++++++++++++++++------ src/common/docmdi.cpp | 8 +-- src/common/docview.cpp | 26 +++++--- src/common/event.cpp | 18 ++---- src/common/wincmn.cpp | 8 +-- src/generic/mdig.cpp | 4 +- src/msw/mdi.cpp | 4 +- 14 files changed, 206 insertions(+), 90 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index a26423663e..3e646ee496 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -119,7 +119,7 @@ Changes in behaviour which may result in compilation errors need to review them as wxDC doesn't have any virtual methods any longer and uses delegation instead of inheritance to present different behaviours. -- wxWindow::ProcessEvent() (and other wxEvtHandler functions inherited by wxWindow) +- wxWindow::ProcessEvent() (and other wxEvtHandler methods inherited by wxWindow) has been made protected to prevent wrongly using it instead of correct GetEventHandler()->ProcessEvent(). New ProcessWindowEvent() was added for convenience. @@ -217,6 +217,10 @@ Changes in behaviour which may result in compilation errors A correct implementation for MyCustomEventClass::Clone() is simply: virtual wxEvent *Clone() const { return new MyCustomEventClass(*this); } +- Global wxPendingEvents and wxPendingEventsLocker objects were removed. + You may use wxEventLoopBase::SuspendProcessingOfPendingEvents instead of + locking wxPendingEventsLocker now. + Deprecated methods and their replacements ----------------------------------------- @@ -234,14 +238,16 @@ Deprecated methods and their replacements "Attribute" instead of "Property" or "Prop" in their names. - wxConnection::OnExecute() is not formally deprecated yet but new code should use simpler OnExec() version which is called with wxString argument -- wxMenuItem::GetLabel has been deprecated in favour of wxMenuItem::GetItemLabelText -- wxMenuItem::GetText has been deprecated in favour of wxMenuItem::GetItemLabel -- wxMenuItem::GetLabelFromText has been deprecated in favour of wxMenuItem::GetLabelText -- wxMenuItem::SetText has been deprecated in favour of wxMenuItem::SetItemLabel -- wxBrush's, wxPen's SetStyle() and GetStyle() as well as the wxBrush/wxPen ctor now take - respectively a wxBrushStyle and a wxPenStyle value instead of a plain "int style"; - use the new wxBrush/wxPen style names (wxBRUSHSTYLE_XXX and wxPENSTYLE_XXX) instead - of the old deprecated wxXXX styles (which however are still available). +- Various wxMenuItem methods were deprecated in favour of more consisently + named new versions: + . GetLabel() is now GetItemLabelText() + . GetText() is not GetItemLabel() + . GetLabelFromText() is now GetLabelText() + . SetText() is now SetItemLabel() +- wxBrush's, wxPen's SetStyle() and GetStyle() as well as the wxBrush/wxPen + ctor now take respectively a wxBrushStyle and a wxPenStyle value instead of a + plain "int style"; use the new wxBrush/wxPen style names (wxBRUSHSTYLE_XXX + and wxPENSTYLE_XXX) instead of the old deprecated wxXXX styles. - EVT_GRID_CELL_CHANGE was deprecated, use EVT_GRID_CELL_CHANGED instead if you don't veto the event in its handler and EVT_GRID_CELL_CHANGING if you do. - EVT_CALENDAR_DAY event has been deprecated, use EVT_CALENDAR_SEL_CHANGED. @@ -256,13 +262,14 @@ Deprecated methods and their replacements it with SetDeviceClippingRegion() if this was the correct thing to do in your code. - wxTE_AUTO_SCROLL style is deprecated as it's always on by default anyhow. -- wxThreadHelper::Create() has been deprecated in favour of wxThreadHelper::CreateThread - which has a better name for a mix-in class, and allows setting the thread type. +- wxThreadHelper::Create() has been renamed to CreateThread which has a better + name for a mix-in class, and allows setting the thread type. - wxDos2UnixFilename, wxUnix2DosFilename, wxStripExtension, wxGetTempFileName, wxExpandPath, wxContractPath, wxRealPath, wxCopyAbsolutePath, wxSplitPath were deprecated in favour of wxFileName methods. See docs for more info. -- global wxPendingEvents and wxPendingEventsLocker objects were removed; now you may use - wxEventLoopBase::SuspendProcessingOfPendingEvents instead of locking wxPendingEventsLocker. +- wxEvtHandler::TryValidator/Parent() are deprecated, override the new and + documented TryBefore/After() methods if you used to override these ones. + Major new features in this release ---------------------------------- diff --git a/include/wx/docmdi.h b/include/wx/docmdi.h index e105fdcd50..e41e4e4e56 100644 --- a/include/wx/docmdi.h +++ b/include/wx/docmdi.h @@ -44,7 +44,7 @@ public: protected: void Init(); - virtual bool TryValidator(wxEvent& event); + virtual bool TryBefore(wxEvent& event); wxDocManager *m_docManager; @@ -89,7 +89,7 @@ public: protected: void Init(); - virtual bool TryValidator(wxEvent& event); + virtual bool TryBefore(wxEvent& event); wxDocument* m_childDocument; wxView* m_childView; diff --git a/include/wx/docview.h b/include/wx/docview.h index 821c7abc1c..d6f0e34784 100644 --- a/include/wx/docview.h +++ b/include/wx/docview.h @@ -107,7 +107,7 @@ public: // modified to false) virtual bool OnSaveModified(); - // if you override, remember to call the default + // if you override, remember to call the default // implementation (wxDocument::OnChangeFilename) virtual void OnChangeFilename(bool notifyViews); @@ -243,7 +243,7 @@ public: protected: // hook the document into event handlers chain here - virtual bool TryValidator(wxEvent& event); + virtual bool TryBefore(wxEvent& event); wxDocument* m_viewDocument; wxString m_viewTypeName; @@ -467,7 +467,7 @@ public: protected: // hook the currently active view into event handlers chain here - virtual bool TryValidator(wxEvent& event); + virtual bool TryBefore(wxEvent& event); // return the command processor for the current document, if any wxCommandProcessor *GetCurrentCommandProcessor() const; @@ -528,7 +528,7 @@ public: protected: // hook the child view into event handlers chain here - virtual bool TryValidator(wxEvent& event); + virtual bool TryBefore(wxEvent& event); wxDocument* m_childDocument; wxView* m_childView; @@ -573,7 +573,7 @@ public: protected: // hook the document manager into event handling chain here - virtual bool TryValidator(wxEvent& event); + virtual bool TryBefore(wxEvent& event); wxDocManager *m_docManager; diff --git a/include/wx/event.h b/include/wx/event.h index ee9d6b0b20..f737b25077 100644 --- a/include/wx/event.h +++ b/include/wx/event.h @@ -3067,7 +3067,7 @@ public: // // It is meant to be called from ProcessEvent() only and is not virtual, // additional event handlers can be hooked into the normal event processing - // logic using TryValidator() hook. + // logic using TryBefore() and TryAfter() hooks. bool ProcessEventHere(wxEvent& event); @@ -3090,21 +3090,42 @@ protected: // hooks for wxWindow used by ProcessEvent() // ----------------------------------------- - // This one is called before trying our own event table to allow plugging - // in the validators. - // - // NB: This method is intentionally *not* inside wxUSE_VALIDATORS! - // It is part of wxBase which doesn't use validators and the code - // is compiled out when building wxBase w/o GUI classes, which affects - // binary compatibility and wxBase library can't be used by GUI - // ports. - virtual bool TryValidator(wxEvent& WXUNUSED(event)) { return false; } + // this one is called before trying our own event table to allow plugging + // in the event handlers overriding the default logic, this is used by e.g. + // validators. + virtual bool TryBefore(wxEvent& event) + { +#ifdef WXWIN_COMPATIBILITY_2_8 + // call the old virtual function to keep the code overriding it working + return TryValidator(event); +#else + wxUnusedVar(event); + return false; +#endif + } // this one is called after failing to find the event handle in our own // table to give a chance to the other windows to process it // // base class implementation passes the event to wxTheApp - virtual bool TryParent(wxEvent& event); + virtual bool TryAfter(wxEvent& event) + { +#ifdef WXWIN_COMPATIBILITY_2_8 + // as above, call the old virtual function for compatibility + return TryParent(event); +#else + return DoTryApp(event); +#endif + } + +#ifdef WXWIN_COMPATIBILITY_2_8 + // deprecated method: override TryBefore() instead of this one + wxDEPRECATED_BUT_USED_INTERNALLY_INLINE( + virtual bool TryValidator(wxEvent& WXUNUSED(event)), return false; ) + + wxDEPRECATED_BUT_USED_INTERNALLY_INLINE( + virtual bool TryParent(wxEvent& event), return DoTryApp(event); ) +#endif // WXWIN_COMPATIBILITY_2_8 static const wxEventTable sm_eventTable; @@ -3152,6 +3173,9 @@ protected: wxEventConnectionRef *FindRefInTrackerList(wxEvtHandler *eventSink); private: + // pass the event to wxTheApp instance, called from TryAfter() + bool DoTryApp(wxEvent& event); + DECLARE_DYNAMIC_CLASS_NO_COPY(wxEvtHandler) }; diff --git a/include/wx/generic/mdig.h b/include/wx/generic/mdig.h index 46708ed6fc..a710c3f03b 100644 --- a/include/wx/generic/mdig.h +++ b/include/wx/generic/mdig.h @@ -172,7 +172,7 @@ public: virtual wxString GetTitle() const { return m_title; } virtual void SetTitle(const wxString& title); - virtual bool TryParent(wxEvent& event); + virtual bool TryAfter(wxEvent& event); // implementation only from now on diff --git a/include/wx/msw/mdi.h b/include/wx/msw/mdi.h index 63e42eb74b..0d4e4be6a5 100644 --- a/include/wx/msw/mdi.h +++ b/include/wx/msw/mdi.h @@ -109,7 +109,7 @@ public: protected: // override to pass menu/toolbar events to the active child first - virtual bool TryValidator(wxEvent& event); + virtual bool TryBefore(wxEvent& event); #if wxUSE_MENUS_NATIVE virtual void InternalSetMenuBar(); diff --git a/include/wx/window.h b/include/wx/window.h index 214833cd5d..d956ab0d5c 100644 --- a/include/wx/window.h +++ b/include/wx/window.h @@ -1408,8 +1408,8 @@ public: protected: // event handling specific to wxWindow - virtual bool TryValidator(wxEvent& event); - virtual bool TryParent(wxEvent& event); + virtual bool TryBefore(wxEvent& event); + virtual bool TryAfter(wxEvent& event); enum WindowOrder { diff --git a/interface/wx/event.h b/interface/wx/event.h index 021e0da342..0be6ec0a8e 100644 --- a/interface/wx/event.h +++ b/interface/wx/event.h @@ -453,22 +453,29 @@ public: (such as a new control) where you define new event types, as opposed to allowing the user to override virtual functions. - An instance where you might actually override the ProcessEvent() function is where - you want to direct event processing to event handlers not normally noticed by - wxWidgets. For example, in the document/view architecture, documents and views - are potential event handlers. When an event reaches a frame, ProcessEvent() will - need to be called on the associated document and view in case event handler functions - are associated with these objects. The property classes library (wxProperty) also - overrides ProcessEvent() for similar reasons. + Notice that you don't usually need to override ProcessEvent() to + customize the event handling, overriding the specially provided + TryBefore() and TryAfter() functions is usually enough. For example, + wxMDIParentFrame may override TryBefore() to ensure that the menu + events are processed in the active child frame before being processed + in the parent frame itself. The normal order of event table searching is as follows: + -# wxApp::FilterEvent() is called. If it returns anything but @c -1 + (default) the processing stops here. -# If the object is disabled (via a call to wxEvtHandler::SetEvtHandlerEnabled) - the function skips to step (6). - -# If the object is a wxWindow, ProcessEvent() is recursively called on the - window's wxValidator. If this returns @true, the function exits. - -# SearchEventTable() is called for this event handler. If this fails, the base - class table is tried, and so on until no more tables exist or an appropriate - function was found, in which case the function exits. + the function skips to step (7). + -# TryBefore() is called (this is where wxValidator are taken into + account for wxWindow objects). If this returns @true, the function exits. + -# Dynamic event table of the handlers connected using Connect() is + searched. If a handler is found, it is executed and the function + returns @true unless the handler used wxEvent::Skip() to indicate + that it didn't handle the event in which case the search continues. + -# Static events table of the handlers connected using event table + macros is searched for this event handler. If this fails, the base + class event table table is tried, and so on until no more tables + exist or an appropriate function was found. If a handler is found, + the same logic as in the previous step applies. -# The search is applied down the entire chain of event handlers (usually the chain has a length of one). This chain can be formed using wxEvtHandler::SetNextHandler(): @image html overview_events_chain.png @@ -477,21 +484,41 @@ public: Note that in the case of wxWindow you can build a stack of event handlers (see wxWindow::PushEventHandler() for more info). If any of the handlers of the chain return @true, the function exits. - -# If the object is a wxWindow and the event is a wxCommandEvent, ProcessEvent() - is recursively applied to the parent window's event handler. - If this returns @true, the function exits. - -# Finally, ProcessEvent() is called on the wxApp object. + -# TryAfter() is called: for the wxWindow object this may propagate the + event to the window parent (recursively). If the event is still not + processed, ProcessEvent() on wxTheApp object is called as the last + step. + + Notice that steps (2)-(6) are performed in ProcessEventHere() which is + called by this function. @param event Event to process. - - @return @true if a suitable event handler function was found and - executed, and the function did not call wxEvent::Skip. + @return + @true if a suitable event handler function was found and executed, + and the function did not call wxEvent::Skip. @see SearchEventTable() */ virtual bool ProcessEvent(wxEvent& event); + /** + Try to process the event in this event handler. + + This method is called from ProcessEvent(), please see the detailed + description of the event processing logic there. + + It is @em not virtual and so may not be overridden but it does call + virtual TryBefore() which may be overridden. + + @param event + Event to process. + @return + @true if this object itself defines a handler for this event and + the handler didn't skip the event. + */ + bool ProcessEventHere(wxEvent& event); + /** Processes an event by calling ProcessEvent() and handles any exceptions that occur in the process. @@ -821,6 +848,66 @@ public: bool IsUnlinked() const; //@} + +protected: + /** + Method called by ProcessEvent() before examining this object event + tables. + + This method can be overridden to hook into the event processing logic + as early as possible. You should usually call the base class version + when overriding this method, even if wxEvtHandler itself does nothing + here, some derived classes do use this method, e.g. wxWindow implements + support for wxValidator in it. + + Example: + @code + class MyClass : public BaseClass // inheriting from wxEvtHandler + { + ... + protected: + virtual bool TryBefore(wxEvent& event) + { + if ( MyPreProcess(event) ) + return true; + + return BaseClass::TryBefore(event); + } + }; + @endcode + + @see ProcessEvent(), ProcessEventHere() + */ + virtual bool TryBefore(wxEvent& event); + + /** + Method called by ProcessEvent() as last resort. + + This method can be overridden to implement post-processing for the + events which were not processed anywhere else. + + The base class version handles forwarding the unprocessed events to + wxApp at wxEvtHandler level and propagating them upwards the window + child-parent chain at wxWindow level and so should usually be called + when overriding this method: + @code + class MyClass : public BaseClass // inheriting from wxEvtHandler + { + ... + protected: + virtual bool TryAfter(wxEvent& event) + { + if ( BaseClass::TryAfter(event) ) + return true; + + return MyPostProcess(event); + } + }; + @endcode + + @see ProcessEvent(), ProcessEventHere() + */ + virtual bool TryAfter(wxEvent& event); }; diff --git a/src/common/docmdi.cpp b/src/common/docmdi.cpp index 6d3d3bb2da..95b9627c38 100644 --- a/src/common/docmdi.cpp +++ b/src/common/docmdi.cpp @@ -68,12 +68,12 @@ void wxDocMDIParentFrame::OnMRUFile(wxCommandEvent& event) (void)m_docManager->CreateDocument(f, wxDOC_SILENT); } -bool wxDocMDIParentFrame::TryValidator(wxEvent& event) +bool wxDocMDIParentFrame::TryBefore(wxEvent& event) { if ( m_docManager && m_docManager->ProcessEventHere(event) ) return true; - return wxMDIParentFrame::TryValidator(event); + return wxMDIParentFrame::TryBefore(event); } void wxDocMDIParentFrame::OnCloseWindow(wxCloseEvent& event) @@ -136,12 +136,12 @@ wxDocMDIChildFrame::~wxDocMDIChildFrame(void) m_childView = NULL; } -bool wxDocMDIChildFrame::TryValidator(wxEvent& event) +bool wxDocMDIChildFrame::TryBefore(wxEvent& event) { if ( m_childView && m_childView->ProcessEventHere(event) ) return true; - return wxMDIChildFrame::TryValidator(event); + return wxMDIChildFrame::TryBefore(event); } void wxDocMDIChildFrame::OnActivate(wxActivateEvent& event) diff --git a/src/common/docview.cpp b/src/common/docview.cpp index dc27049995..aca0828ee3 100644 --- a/src/common/docview.cpp +++ b/src/common/docview.cpp @@ -650,7 +650,7 @@ wxView::~wxView() m_viewDocument->RemoveView(this); } -bool wxView::TryValidator(wxEvent& event) +bool wxView::TryBefore(wxEvent& event) { wxDocument * const doc = GetDocument(); return doc && doc->ProcessEventHere(event); @@ -1165,7 +1165,7 @@ wxView *wxDocManager::GetActiveView() const return view; } -bool wxDocManager::TryValidator(wxEvent& event) +bool wxDocManager::TryBefore(wxEvent& event) { wxView * const view = GetActiveView(); return view && view->ProcessEventHere(event); @@ -1801,15 +1801,18 @@ wxDocChildFrame::wxDocChildFrame(wxDocument *doc, view->SetFrame(this); } -bool wxDocChildFrame::TryValidator(wxEvent& event) +bool wxDocChildFrame::TryBefore(wxEvent& event) { - if ( !m_childView ) - return false; + if ( m_childView ) + { + // FIXME: why is this needed here? + m_childView->Activate(true); - // FIXME: why is this needed here? - m_childView->Activate(true); + if ( m_childView->ProcessEventHere(event) ) + return true; + } - return m_childView->ProcessEventHere(event); + return wxFrame::TryBefore(event); } void wxDocChildFrame::OnActivate(wxActivateEvent& event) @@ -1920,9 +1923,12 @@ void wxDocParentFrame::OnMRUFile(wxCommandEvent& event) } // Extend event processing to search the view's event table -bool wxDocParentFrame::TryValidator(wxEvent& event) +bool wxDocParentFrame::TryBefore(wxEvent& event) { - return m_docManager && m_docManager->ProcessEventHere(event); + if ( m_docManager && m_docManager->ProcessEventHere(event) ) + return true; + + return wxFrame::TryBefore(event); } // Define the behaviour for the frame closing diff --git a/src/common/event.cpp b/src/common/event.cpp index 3c67d098f7..70248469f0 100644 --- a/src/common/event.cpp +++ b/src/common/event.cpp @@ -1279,15 +1279,8 @@ wxEvtHandler::ProcessEventIfMatchesId(const wxEventTableEntryBase& entry, return false; } -bool wxEvtHandler::TryParent(wxEvent& event) +bool wxEvtHandler::DoTryApp(wxEvent& event) { - if ( GetNextHandler() ) - { - // the next handler will pass it to wxTheApp if it doesn't process it, - // so return from here to avoid doing it again - return GetNextHandler()->TryParent(event); - } - if ( wxTheApp && (this != wxTheApp) ) { // Special case: don't pass wxEVT_IDLE to wxApp, since it'll always @@ -1330,14 +1323,14 @@ bool wxEvtHandler::ProcessEvent(wxEvent& event) return true; // pass the event to the next handler, notice that we shouldn't call - // TryParent() even if it doesn't handle the event as the last handler in + // TryAfter() even if it doesn't handle the event as the last handler in // the chain will do it if ( GetNextHandler() ) return GetNextHandler()->ProcessEvent(event); // propagate the event upwards the window chain and/or to the application // object if it wasn't processed at this level - return TryParent(event); + return TryAfter(event); } bool wxEvtHandler::ProcessEventHere(wxEvent& event) @@ -1346,9 +1339,8 @@ bool wxEvtHandler::ProcessEventHere(wxEvent& event) if ( !GetEvtHandlerEnabled() ) return false; - // If we have a validator, it has higher priority than our own event - // handlers - if ( TryValidator(event) ) + // Try the hooks which should be called before our own handlers + if ( TryBefore(event) ) return true; // Handle per-instance dynamic event tables first diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp index 013f3b2a4b..2413ca4fa5 100644 --- a/src/common/wincmn.cpp +++ b/src/common/wincmn.cpp @@ -2861,7 +2861,7 @@ bool wxWindowBase::UnregisterHotKey(int WXUNUSED(hotkeyId)) // event processing // ---------------------------------------------------------------------------- -bool wxWindowBase::TryValidator(wxEvent& wxVALIDATOR_PARAM(event)) +bool wxWindowBase::TryBefore(wxEvent& event) { #if wxUSE_VALIDATORS // Can only use the validator of the window which @@ -2876,10 +2876,10 @@ bool wxWindowBase::TryValidator(wxEvent& wxVALIDATOR_PARAM(event)) } #endif // wxUSE_VALIDATORS - return false; + return wxEvtHandler::TryBefore(event); } -bool wxWindowBase::TryParent(wxEvent& event) +bool wxWindowBase::TryAfter(wxEvent& event) { // carry on up the parent-child hierarchy if the propagation count hasn't // reached zero yet @@ -2901,7 +2901,7 @@ bool wxWindowBase::TryParent(wxEvent& event) } } - return wxEvtHandler::TryParent(event); + return wxEvtHandler::TryAfter(event); } // ---------------------------------------------------------------------------- diff --git a/src/generic/mdig.cpp b/src/generic/mdig.cpp index 3326c0592c..591bae2bc4 100644 --- a/src/generic/mdig.cpp +++ b/src/generic/mdig.cpp @@ -515,7 +515,7 @@ void wxGenericMDIChildFrame::OnClose(wxCloseEvent& WXUNUSED(event)) delete this; } -bool wxGenericMDIChildFrame::TryParent(wxEvent& event) +bool wxGenericMDIChildFrame::TryAfter(wxEvent& event) { // we shouldn't propagate the event to the parent if we received it from it // in the first place @@ -523,7 +523,7 @@ bool wxGenericMDIChildFrame::TryParent(wxEvent& event) if ( parent && parent->WXIsInsideChildHandler(this) ) return false; - return wxTDIChildFrame::TryParent(event); + return wxTDIChildFrame::TryAfter(event); } // ---------------------------------------------------------------------------- diff --git a/src/msw/mdi.cpp b/src/msw/mdi.cpp index c307027bfa..1386635c51 100644 --- a/src/msw/mdi.cpp +++ b/src/msw/mdi.cpp @@ -669,7 +669,7 @@ void wxMDIParentFrame::OnMDICommand(wxCommandEvent& event) #endif // wxUSE_MENUS -bool wxMDIParentFrame::TryValidator(wxEvent& event) +bool wxMDIParentFrame::TryBefore(wxEvent& event) { // menu (and toolbar) events should be sent to the active child frame // first, if any @@ -680,7 +680,7 @@ bool wxMDIParentFrame::TryValidator(wxEvent& event) return true; } - return wxMDIParentFrameBase::TryValidator(event); + return wxMDIParentFrameBase::TryBefore(event); } WXLRESULT wxMDIParentFrame::MSWDefWindowProc(WXUINT message, -- 2.49.0