// Author: Julian Smart
// Modified by: Vadim Zeitlin
// Created: 01/02/97
-// RCS-ID: $Id$
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
bool
wxDocTemplate::InitDocument(wxDocument* doc, const wxString& path, long flags)
{
- wxScopeGuard g = wxMakeObjGuard(*doc, &wxDocument::DeleteAllViews);
-
- doc->SetFilename(path);
- doc->SetDocumentTemplate(this);
- GetDocumentManager()->AddDocument(doc);
- doc->SetCommandProcessor(doc->OnCreateCommandProcessor());
-
- if ( !doc->OnCreate(path, flags) )
- return false;
-
- g.Dismiss(); // no need to call DeleteAllViews() anymore
+ // Normally, if wxDocument::OnCreate() fails, it happens because the view
+ // initialization fails and then the document is destroyed due to the
+ // destruction of its last view. But take into account the (currently
+ // unrealized, AFAICS) possibility of other failures as well and ensure
+ // that the document is always destroyed if it can't be initialized.
+ wxTRY
+ {
+ doc->SetFilename(path);
+ doc->SetDocumentTemplate(this);
+ GetDocumentManager()->AddDocument(doc);
+ doc->SetCommandProcessor(doc->OnCreateCommandProcessor());
- return true;
+ return doc->OnCreate(path, flags);
+ }
+ wxCATCH_ALL(
+ if ( GetDocumentManager()->GetDocuments().Member(doc) )
+ doc->DeleteAllViews();
+ throw;
+ )
}
wxView *wxDocTemplate::CreateView(wxDocument *doc, long flags)
void wxDocManager::OnPrint(wxCommandEvent& WXUNUSED(event))
{
- wxView *view = GetActiveView();
+ wxView *view = GetAnyUsableView();
if (!view)
return;
void wxDocManager::OnPreview(wxCommandEvent& WXUNUSED(event))
{
wxBusyCursor busy;
- wxView *view = GetActiveView();
+ wxView *view = GetAnyUsableView();
if (!view)
return;
cmdproc->SetMenuStrings();
}
-wxView *wxDocManager::GetActiveView() const
+wxView *wxDocManager::GetAnyUsableView() const
{
wxView *view = GetCurrentView();
bool wxDocManager::TryBefore(wxEvent& event)
{
- wxView * const view = GetActiveView();
+ wxView * const view = GetAnyUsableView();
return view && view->ProcessEventLocally(event);
}
win->Raise();
}
+wxDocument* wxDocManager::FindDocumentByPath(const wxString& path) const
+{
+ const wxFileName fileName(path);
+ for ( wxList::const_iterator i = m_docs.begin(); i != m_docs.end(); ++i )
+ {
+ wxDocument * const doc = wxStaticCast(*i, wxDocument);
+
+ if ( fileName == wxFileName(doc->GetFilename()) )
+ return doc;
+ }
+ return NULL;
+}
+
wxDocument *wxDocManager::CreateDocument(const wxString& pathOrig, long flags)
{
// this ought to be const but SelectDocumentType/Path() are not
// check whether the document with this path is already opened
if ( !path.empty() )
{
- const wxFileName fn(path);
- for ( wxList::const_iterator i = m_docs.begin(); i != m_docs.end(); ++i )
+ wxDocument * const doc = FindDocumentByPath(path);
+ if (doc)
{
- wxDocument * const doc = (wxDocument*)*i;
-
- if ( fn == doc->GetFilename() )
- {
- // file already open, just activate it and return
- doc->Activate();
- return doc;
- }
+ // file already open, just activate it and return
+ doc->Activate();
+ return doc;
}
}
-
// no, we need to create a new document
return NULL;
docNew->SetDocumentName(temp->GetDocumentName());
- docNew->SetDocumentTemplate(temp);
wxTRY
{
wxDocument *wxDocManager::GetCurrentDocument() const
{
- wxView * const view = GetActiveView();
+ wxView * const view = GetAnyUsableView();
return view ? view->GetDocument() : NULL;
}
// wxDocChildFrameAnyBase
// ----------------------------------------------------------------------------
+bool wxDocChildFrameAnyBase::TryProcessEvent(wxEvent& event)
+{
+ if ( !m_childView )
+ {
+ // We must be being destroyed, don't forward events anywhere as
+ // m_childDocument could be invalid by now.
+ return false;
+ }
+
+ // Store a (non-owning) pointer to the last processed event here to be able
+ // to recognize this event again if it bubbles up to the parent frame, see
+ // the code in wxDocParentFrameAnyBase::TryProcessEvent().
+ m_lastEvent = &event;
+
+ // Forward the event to the document manager which will, in turn, forward
+ // it to its active view which must be our m_childView.
+ //
+ // Notice that we do things in this roundabout way to guarantee the correct
+ // event handlers call order: first the document, then the view and then the
+ // document manager itself. And if we forwarded the event directly to the
+ // view, then the document manager would do it once again when we forwarded
+ // it to it.
+ return m_childDocument->GetDocumentManager()->ProcessEventLocally(event);
+}
+
bool wxDocChildFrameAnyBase::CloseView(wxCloseEvent& event)
{
if ( m_childView )
// wxDocParentFrameAnyBase
// ----------------------------------------------------------------------------
+bool wxDocParentFrameAnyBase::TryProcessEvent(wxEvent& event)
+{
+ if ( !m_docManager )
+ return false;
+
+ // If we have an active view, its associated child frame may have
+ // already forwarded the event to wxDocManager, check for this:
+ if ( wxView* const view = m_docManager->GetAnyUsableView() )
+ {
+ wxDocChildFrameAnyBase* const childFrame = view->GetDocChildFrame();
+ if ( childFrame && childFrame->HasAlreadyProcessed(event) )
+ return false;
+ }
+
+ // But forward the event to wxDocManager ourselves if there are no views at
+ // all or if this event hadn't been sent to the child frame previously.
+ return m_docManager->ProcessEventLocally(event);
+}
+
+// ----------------------------------------------------------------------------
+// Printing support
+// ----------------------------------------------------------------------------
+
#if wxUSE_PRINTING_ARCHITECTURE
namespace