]> git.saurik.com Git - wxWidgets.git/commitdiff
refactor wxDocChildFrame and wxDocMDIChildFrame to use wxDocChildFrameAny intead...
authorVadim Zeitlin <vadim@wxwidgets.org>
Fri, 27 Feb 2009 12:24:03 +0000 (12:24 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Fri, 27 Feb 2009 12:24:03 +0000 (12:24 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@59185 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/docmdi.h
include/wx/docview.h
src/common/docmdi.cpp
src/common/docview.cpp

index e41e4e4e5665041cda6f7cf02e208e8563da9e0e..b389b44d74aeffd7ea1ab52c0d8e076cc4bfb301 100644 (file)
@@ -54,54 +54,39 @@ private:
     wxDECLARE_NO_COPY_CLASS(wxDocMDIParentFrame);
 };
 
-/*
- * Use this instead of wxMDIChildFrame
- */
+// ----------------------------------------------------------------------------
+// An MDI document child frame: we need to define it as a class just for wxRTTI,
+// otherwise we could simply typedef it
+// ----------------------------------------------------------------------------
 
-class WXDLLIMPEXP_CORE wxDocMDIChildFrame: public wxMDIChildFrame
+typedef
+  wxDocChildFrameAny<wxMDIChildFrame, wxMDIParentFrame> wxDocMDIChildFrameBase;
+
+class WXDLLIMPEXP_CORE wxDocMDIChildFrame : public wxDocMDIChildFrameBase
 {
 public:
-    wxDocMDIChildFrame();
-    wxDocMDIChildFrame(wxDocument *doc, wxView *view, wxMDIParentFrame *frame, wxWindowID id,
-        const wxString& title, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
-        long type = wxDEFAULT_FRAME_STYLE, const wxString& name = wxFrameNameStr);
-    virtual ~wxDocMDIChildFrame();
-
-    bool Create(wxDocument *doc,
-                wxView *view,
-                wxMDIParentFrame *frame,
-                wxWindowID id,
-                const wxString& title,
-                const wxPoint& pos = wxDefaultPosition,
-                const wxSize& size = wxDefaultSize,
-                long type = wxDEFAULT_FRAME_STYLE,
-                const wxString& name = wxFrameNameStr);
-
-    void OnActivate(wxActivateEvent& event);
-    void OnCloseWindow(wxCloseEvent& event);
-
-    inline wxDocument *GetDocument() const { return m_childDocument; }
-    inline wxView *GetView(void) const { return m_childView; }
-    inline void SetDocument(wxDocument *doc) { m_childDocument = doc; }
-    inline void SetView(wxView *view) { m_childView = view; }
-    bool Destroy() { m_childView = NULL; return wxMDIChildFrame::Destroy(); }
-
-protected:
-    void Init();
-
-    virtual bool TryBefore(wxEvent& event);
-
-    wxDocument*       m_childDocument;
-    wxView*           m_childView;
+    wxDocMDIChildFrame(wxDocument *doc,
+                       wxView *view,
+                       wxMDIParentFrame *parent,
+                       wxWindowID id,
+                       const wxString& title,
+                       const wxPoint& pos = wxDefaultPosition,
+                       const wxSize& size = wxDefaultSize,
+                       long style = wxDEFAULT_FRAME_STYLE,
+                       const wxString& name = wxFrameNameStr)
+        : wxDocMDIChildFrameBase(doc, view,
+                                 parent, id, title, pos, size, style, name)
+    {
+    }
 
 private:
-    DECLARE_EVENT_TABLE()
     DECLARE_CLASS(wxDocMDIChildFrame)
     wxDECLARE_NO_COPY_CLASS(wxDocMDIChildFrame);
 };
 
-#endif
-    // wxUSE_MDI_ARCHITECTURE
+WXDLLIMPEXP_TEMPLATE_INSTANCE_BASE( wxDocMDIChildFrameBase )
+
+
+#endif // wxUSE_MDI_ARCHITECTURE
 
-#endif
-    // _WX_DOCMDI_H_
+#endif // _WX_DOCMDI_H_
index d6f0e34784438ce133f45ddf348c725d7d5c8f5a..2a08d2c0ff47176504c1d9723faa548c21c0e496 100644 (file)
@@ -34,6 +34,8 @@ class WXDLLIMPEXP_FWD_CORE wxCommandProcessor;
 class WXDLLIMPEXP_FWD_CORE wxFileHistory;
 class WXDLLIMPEXP_FWD_BASE wxConfigBase;
 
+class wxDocChildFrameAnyBase;
+
 #if wxUSE_STD_IOSTREAM
   #include "wx/iosfwrap.h"
 #else
@@ -241,6 +243,16 @@ public:
     virtual wxPrintout *OnCreatePrintout();
 #endif
 
+    // implementation only
+    // -------------------
+
+    // set the associated frame, it is used to reset its view when we're
+    // destroyed
+    void SetDocChildFrame(wxDocChildFrameAnyBase *docChildFrame)
+    {
+        m_docChildFrame = docChildFrame;
+    }
+
 protected:
     // hook the document into event handlers chain here
     virtual bool TryBefore(wxEvent& event);
@@ -249,6 +261,8 @@ protected:
     wxString          m_viewTypeName;
     wxWindow*         m_viewFrame;
 
+    wxDocChildFrameAnyBase *m_docChildFrame;
+
 private:
     DECLARE_ABSTRACT_CLASS(wxView)
     wxDECLARE_NO_COPY_CLASS(wxView);
@@ -500,45 +514,154 @@ inline size_t wxDocManager::GetNoHistoryFiles() const
 #endif // WXWIN_COMPATIBILITY_2_6
 
 // ----------------------------------------------------------------------------
-// A default child frame
+// Base class for child frames -- this is what wxView renders itself into
+//
+// Notice that this is a mix-in class so it doesn't derive from wxWindow, only
+// wxDocChildFrameAny does
 // ----------------------------------------------------------------------------
 
-class WXDLLIMPEXP_CORE wxDocChildFrame : public wxFrame
+class wxDocChildFrameAnyBase
 {
 public:
-    wxDocChildFrame(wxDocument *doc,
-                    wxView *view,
-                    wxFrame *frame,
-                    wxWindowID id,
-                    const wxString& title,
-                    const wxPoint& pos = wxDefaultPosition,
-                    const wxSize& size = wxDefaultSize,
-                    long type = wxDEFAULT_FRAME_STYLE,
-                    const wxString& name = wxFrameNameStr);
-    virtual ~wxDocChildFrame(){}
+    wxDocChildFrameAnyBase(wxDocument *doc, wxView *view)
+    {
+        m_childDocument = doc;
+        m_childView = view;
 
-    void OnActivate(wxActivateEvent& event);
-    void OnCloseWindow(wxCloseEvent& event);
+        if ( view )
+            view->SetDocChildFrame(this);
+    }
 
     wxDocument *GetDocument() const { return m_childDocument; }
     wxView *GetView() const { return m_childView; }
     void SetDocument(wxDocument *doc) { m_childDocument = doc; }
     void SetView(wxView *view) { m_childView = view; }
-    bool Destroy() { m_childView = NULL; return wxFrame::Destroy(); }
 
 protected:
-    // hook the child view into event handlers chain here
-    virtual bool TryBefore(wxEvent& event);
+    // 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->ProcessEventHere(event);
+    }
+
+    // called from EVT_CLOSE handler in the frame: check if we can close and do
+    // cleanup if so; veto the event otherwise
+    bool CloseView(wxCloseEvent& event);
+
 
     wxDocument*       m_childDocument;
     wxView*           m_childView;
 
+    wxDECLARE_NO_COPY_CLASS(wxDocChildFrameAnyBase);
+};
+
+// ----------------------------------------------------------------------------
+// Template implementing child frame concept using the given wxFrame-like class
+//
+// This is used to define wxDocChildFrame and wxDocMDIChildFrame: ChildFrame is
+// a wxFrame or wxMDIChildFrame (although in theory it could be any wxWindow-
+// derived class as long as it provided a ctor with the same signature as
+// wxFrame and OnActivate() method) and ParentFrame is either wxFrame or
+// wxMDIParentFrame.
+// ----------------------------------------------------------------------------
+
+template <class ChildFrame, class ParentFrame>
+class WXDLLIMPEXP_CORE wxDocChildFrameAny : public ChildFrame,
+                                            public wxDocChildFrameAnyBase
+{
+public:
+    typedef ChildFrame BaseClass;
+
+    // ctor for a frame showing the given view of the specified document
+    wxDocChildFrameAny(wxDocument *doc,
+                       wxView *view,
+                       ParentFrame *parent,
+                       wxWindowID id,
+                       const wxString& title,
+                       const wxPoint& pos = wxDefaultPosition,
+                       const wxSize& size = wxDefaultSize,
+                       long style = wxDEFAULT_FRAME_STYLE,
+                       const wxString& name = wxFrameNameStr)
+        : BaseClass(parent, id, title, pos, size, style, name),
+          wxDocChildFrameAnyBase(doc, view)
+    {
+        if ( view )
+            view->SetFrame(this);
+
+        this->Connect(wxEVT_ACTIVATE,
+                      wxActivateEventHandler(wxDocChildFrameAny::OnActivate));
+        this->Connect(wxEVT_CLOSE_WINDOW,
+                      wxCloseEventHandler(wxDocChildFrameAny::OnCloseWindow));
+    }
+
+    virtual bool Destroy()
+    {
+        // FIXME: why exactly do we do this? to avoid activation events during
+        //        destructions maybe?
+        m_childView = NULL;
+        return BaseClass::Destroy();
+    }
+
+protected:
+    // hook the child view into event handlers chain here
+    virtual bool TryBefore(wxEvent& event)
+    {
+        return TryProcessEvent(event) || BaseClass::TryBefore(event);
+    }
+
+private:
+    void OnActivate(wxActivateEvent& event)
+    {
+        BaseClass::OnActivate(event);
+
+        if ( m_childView )
+            m_childView->Activate(event.GetActive());
+    }
+
+    void OnCloseWindow(wxCloseEvent& event)
+    {
+        if ( CloseView(event) )
+            Destroy();
+        //else: vetoed
+    }
+
+    wxDECLARE_NO_COPY_TEMPLATE_CLASS_2(wxDocChildFrameAny,
+                                        ChildFrame, ParentFrame);
+};
+
+// ----------------------------------------------------------------------------
+// A default child frame: we need to define it as a class just for wxRTTI,
+// otherwise we could simply typedef it
+// ----------------------------------------------------------------------------
+
+typedef wxDocChildFrameAny<wxFrame, wxFrame> wxDocChildFrameBase;
+
+class WXDLLIMPEXP_CORE wxDocChildFrame : public wxDocChildFrameBase
+{
+public:
+    wxDocChildFrame(wxDocument *doc,
+                    wxView *view,
+                    wxFrame *parent,
+                    wxWindowID id,
+                    const wxString& title,
+                    const wxPoint& pos = wxDefaultPosition,
+                    const wxSize& size = wxDefaultSize,
+                    long style = wxDEFAULT_FRAME_STYLE,
+                    const wxString& name = wxFrameNameStr)
+        : wxDocChildFrameBase(doc, view,
+                              parent, id, title, pos, size, style, name)
+    {
+    }
+
 private:
     DECLARE_CLASS(wxDocChildFrame)
-    DECLARE_EVENT_TABLE()
     wxDECLARE_NO_COPY_CLASS(wxDocChildFrame);
 };
 
+WXDLLIMPEXP_TEMPLATE_INSTANCE_BASE( wxDocChildFrameBase )
+
 // ----------------------------------------------------------------------------
 // A default parent frame
 // ----------------------------------------------------------------------------
index 95b9627c384bb2c62f73b1466ca2dafb4b5a7d96..c8911d606ade00fac77d21b670060ab02946e503 100644 (file)
@@ -87,97 +87,7 @@ void wxDocMDIParentFrame::OnCloseWindow(wxCloseEvent& event)
 }
 
 
-/*
- * Default document child frame for MDI children
- */
-
 IMPLEMENT_CLASS(wxDocMDIChildFrame, wxMDIChildFrame)
 
-BEGIN_EVENT_TABLE(wxDocMDIChildFrame, wxMDIChildFrame)
-    EVT_ACTIVATE(wxDocMDIChildFrame::OnActivate)
-    EVT_CLOSE(wxDocMDIChildFrame::OnCloseWindow)
-END_EVENT_TABLE()
-
-void wxDocMDIChildFrame::Init()
-{
-    m_childDocument = NULL;
-    m_childView = NULL;
-}
-
-wxDocMDIChildFrame::wxDocMDIChildFrame()
-{
-    Init();
-}
-
-wxDocMDIChildFrame::wxDocMDIChildFrame(wxDocument *doc, wxView *view, wxMDIParentFrame *frame, wxWindowID  id,
-  const wxString& title, const wxPoint& pos, const wxSize& size, long style, const wxString& name)
-{
-    Init();
-    Create(doc, view, frame, id, title, pos, size, style, name);
-}
-
-bool wxDocMDIChildFrame::Create(wxDocument *doc, wxView *view, wxMDIParentFrame *frame, wxWindowID  id,
-  const wxString& title, const wxPoint& pos, const wxSize& size, long style, const wxString& name)
-{
-    m_childDocument = doc;
-    m_childView = view;
-    if (wxMDIChildFrame::Create(frame, id, title, pos, size, style, name))
-    {
-        if (view)
-            view->SetFrame(this);
-        return true;
-    }
-
-    return false;
-}
-
-wxDocMDIChildFrame::~wxDocMDIChildFrame(void)
-{
-    m_childView = NULL;
-}
-
-bool wxDocMDIChildFrame::TryBefore(wxEvent& event)
-{
-    if ( m_childView && m_childView->ProcessEventHere(event) )
-        return true;
-
-    return wxMDIChildFrame::TryBefore(event);
-}
-
-void wxDocMDIChildFrame::OnActivate(wxActivateEvent& event)
-{
-  wxMDIChildFrame::OnActivate(event);
-
-  if (event.GetActive() && m_childView)
-    m_childView->Activate(event.GetActive());
-}
-
-void wxDocMDIChildFrame::OnCloseWindow(wxCloseEvent& event)
-{
-  // Close view but don't delete the frame while doing so!
-  // ...since it will be deleted by wxWidgets if we return true.
-  if (m_childView)
-  {
-    bool ans = event.CanVeto()
-                ? m_childView->Close(false) // false means don't delete associated window
-                : true; // Must delete.
-
-    if (ans)
-    {
-      m_childView->Activate(false);
-      delete m_childView;
-      m_childView = NULL;
-      m_childDocument = NULL;
-
-      this->Destroy();
-    }
-    else
-        event.Veto();
-  }
-  else
-    event.Veto();
-}
-
-#endif
-    // wxUSE_DOC_VIEW_ARCHITECTURE
+#endif // wxUSE_DOC_VIEW_ARCHITECTURE
 
index aca0828ee3e9a8600d423883d33f8c68fe68e772..ca552a25d4fc6dfee5398bd3df8c9a585dd98040 100644 (file)
@@ -642,12 +642,24 @@ wxView::wxView()
     m_viewDocument = NULL;
 
     m_viewFrame = NULL;
+
+    m_docChildFrame = NULL;
 }
 
 wxView::~wxView()
 {
     GetDocumentManager()->ActivateView(this, false);
-    m_viewDocument->RemoveView(this);
+
+    // reset our frame view first, before removing it from the document as
+    // SetView(NULL) is a simple call while RemoveView() may result in user
+    // code being executed and this user code can, for example, show a message
+    // box which would result in an activation event for m_docChildFrame and so
+    // could reactivate the view being destroyed -- unless we reset it first
+    if ( m_docChildFrame && m_docChildFrame->GetView() == this )
+        m_docChildFrame->SetView(NULL);
+
+    if ( m_viewDocument )
+        m_viewDocument->RemoveView(this);
 }
 
 bool wxView::TryBefore(wxEvent& event)
@@ -1776,71 +1788,27 @@ void wxDocManager::ActivateView(wxView *view, bool activate)
 }
 
 // ----------------------------------------------------------------------------
-// Default document child frame
+// wxDocChildFrameAnyBase
 // ----------------------------------------------------------------------------
 
-BEGIN_EVENT_TABLE(wxDocChildFrame, wxFrame)
-    EVT_ACTIVATE(wxDocChildFrame::OnActivate)
-    EVT_CLOSE(wxDocChildFrame::OnCloseWindow)
-END_EVENT_TABLE()
-
-wxDocChildFrame::wxDocChildFrame(wxDocument *doc,
-                                 wxView *view,
-                                 wxFrame *frame,
-                                 wxWindowID id,
-                                 const wxString& title,
-                                 const wxPoint& pos,
-                                 const wxSize& size,
-                                 long style,
-                                 const wxString& name)
-               : wxFrame(frame, id, title, pos, size, style, name)
-{
-    m_childDocument = doc;
-    m_childView = view;
-    if (view)
-        view->SetFrame(this);
-}
-
-bool wxDocChildFrame::TryBefore(wxEvent& event)
+bool wxDocChildFrameAnyBase::CloseView(wxCloseEvent& event)
 {
     if ( m_childView )
     {
-        // FIXME: why is this needed here?
-        m_childView->Activate(true);
-
-        if ( m_childView->ProcessEventHere(event) )
-            return true;
-    }
-
-    return wxFrame::TryBefore(event);
-}
-
-void wxDocChildFrame::OnActivate(wxActivateEvent& event)
-{
-    wxFrame::OnActivate(event);
-
-    if (m_childView)
-        m_childView->Activate(event.GetActive());
-}
-
-void wxDocChildFrame::OnCloseWindow(wxCloseEvent& event)
-{
-    if ( !m_childView )
-        return;
+        if ( event.CanVeto() && !m_childView->Close(false) )
+        {
+            event.Veto();
+            return false;
+        }
 
-    // passing false to Close() means to not delete associated window
-    if ( event.CanVeto() && !m_childView->Close(false) )
-    {
-        event.Veto();
-        return;
+        m_childView->Activate(false);
+        delete m_childView;
+        m_childView = NULL;
     }
 
-    m_childView->Activate(false);
-    delete m_childView;
-    m_childView = NULL;
     m_childDocument = NULL;
 
-    Destroy();
+    return true;
 }
 
 // ----------------------------------------------------------------------------