// 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)
return NULL;
docNew->SetDocumentName(temp->GetDocumentName());
- docNew->SetDocumentTemplate(temp);
wxTRY
{
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 new and then the
+ // 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.
// already forwarded the event to wxDocManager, check for this:
if ( wxView* const view = m_docManager->GetAnyUsableView() )
{
- wxWindow* win = view->GetFrame();
- if ( win && win != m_frame )
- {
- // Notice that we intentionally don't use wxGetTopLevelParent()
- // here because we want to check both for the case of a child
- // "frame" (e.g. MDI child frame or notebook page) inside this TLW
- // and a separate child TLW frame (as used in the SDI mode) here.
- for ( win = win->GetParent(); win; win = win->GetParent() )
- {
- if ( win == m_frame )
- return false;
- }
- }
- //else: This view is directly associated with the parent frame (which
- // can happen in the so called "single" mode in which only one
- // document can be opened and so is managed by the parent frame
- // itself), there can be no child frame in play so we must forward
- // the event to wxDocManager ourselves.
+ 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 we are the frame's view ourselves.
+ // all or if this event hadn't been sent to the child frame previously.
return m_docManager->ProcessEventLocally(event);
}