X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/838dd956a4049c7c95f015ee6b79d3bcf2ec9d6e..af58844636f51ca9c9350c66de3baf427d3e8646:/src/common/docview.cpp diff --git a/src/common/docview.cpp b/src/common/docview.cpp index db67b46123..51c55bcaf3 100644 --- a/src/common/docview.cpp +++ b/src/common/docview.cpp @@ -56,7 +56,11 @@ #include "wx/cmdproc.h" #include "wx/tokenzr.h" #include "wx/filename.h" +#include "wx/stdpaths.h" #include "wx/vector.h" +#include "wx/scopedarray.h" +#include "wx/scopedptr.h" +#include "wx/except.h" #if wxUSE_STD_IOSTREAM #include "wx/ioswrap.h" @@ -101,17 +105,10 @@ IMPLEMENT_DYNAMIC_CLASS(wxFileHistory, wxObject) namespace { -wxWindow *wxFindSuitableParent() -{ - wxWindow * const win = wxGetTopLevelParent(wxWindow::FindFocus()); - - return win ? win : wxTheApp->GetTopWindow(); -} - wxString FindExtension(const wxString& path) { wxString ext; - wxSplitPath(path, NULL, NULL, &ext); + wxFileName::SplitPath(path, NULL, NULL, &ext); // VZ: extensions are considered not case sensitive - is this really a good // idea? @@ -154,8 +151,7 @@ wxDocument::~wxDocument() { DeleteContents(); - if (m_commandProcessor) - delete m_commandProcessor; + delete m_commandProcessor; if (GetDocumentManager()) GetDocumentManager()->RemoveDocument(this); @@ -168,10 +164,10 @@ wxDocument::~wxDocument() bool wxDocument::Close() { - if (OnSaveModified()) - return OnCloseDocument(); - else + if ( !OnSaveModified() ) return false; + + return OnCloseDocument(); } bool wxDocument::OnCloseDocument() @@ -231,9 +227,10 @@ bool wxDocument::DeleteAllViews() wxView *wxDocument::GetFirstView() const { - if (m_documentViews.GetCount() == 0) + if ( m_documentViews.empty() ) return NULL; - return (wxView *)m_documentViews.GetFirst()->GetData(); + + return static_cast(m_documentViews.GetFirst()->GetData()); } wxDocManager *wxDocument::GetDocumentManager() const @@ -243,11 +240,13 @@ wxDocManager *wxDocument::GetDocumentManager() const bool wxDocument::OnNewDocument() { - if ( !OnSaveModified() ) - return false; + // notice that there is no need to neither reset nor even check the + // modified flag here as the document itself is a new object (this is only + // called from CreateDocument()) and so it shouldn't be saved anyhow even + // if it is modified -- this could happen if the user code creates + // documents pre-filled with some user-entered (and which hence must not be + // lost) information - DeleteContents(); - Modify(false); SetDocumentSaved(false); const wxString name = GetDocumentManager()->MakeNewDocumentName(); @@ -259,7 +258,7 @@ bool wxDocument::OnNewDocument() bool wxDocument::Save() { - if (!IsModified() && m_savedYet) + if ( AlreadySaved() ) return true; if ( m_documentFile.empty() || !m_savedYet ) @@ -274,15 +273,17 @@ bool wxDocument::SaveAs() if (!docTemplate) return false; -#if defined(__WXMSW__) || defined(__WXGTK__) || defined(__WXMAC__) - wxString filter = docTemplate->GetDescription() + wxT(" (") + docTemplate->GetFileFilter() + wxT(")|") + docTemplate->GetFileFilter(); +#ifdef wxHAS_MULTIPLE_FILEDLG_FILTERS + wxString filter = docTemplate->GetDescription() + wxT(" (") + + docTemplate->GetFileFilter() + wxT(")|") + + docTemplate->GetFileFilter(); // Now see if there are some other template with identical view and document // classes, whose filters may also be used. - if (docTemplate->GetViewClassInfo() && docTemplate->GetDocClassInfo()) { - wxList::compatibility_iterator node = docTemplate->GetDocumentManager()->GetTemplates().GetFirst(); + wxList::compatibility_iterator + node = docTemplate->GetDocumentManager()->GetTemplates().GetFirst(); while (node) { wxDocTemplate *t = (wxDocTemplate*) node->GetData(); @@ -295,7 +296,8 @@ bool wxDocument::SaveAs() if ( !filter.empty() ) filter << wxT('|'); - filter << t->GetDescription() << wxT(" (") << t->GetFileFilter() << wxT(") |") + filter << t->GetDescription() + << wxT(" (") << t->GetFileFilter() << wxT(") |") << t->GetFileFilter(); } @@ -305,11 +307,16 @@ bool wxDocument::SaveAs() #else wxString filter = docTemplate->GetFileFilter() ; #endif + wxString defaultDir = docTemplate->GetDirectory(); - if (defaultDir.IsEmpty()) + if ( defaultDir.empty() ) + { defaultDir = wxPathOnly(GetFilename()); + if ( defaultDir.empty() ) + defaultDir = GetDocumentManager()->GetLastDirectory(); + } - wxString tmp = wxFileSelector(_("Save As"), + wxString fileName = wxFileSelector(_("Save As"), defaultDir, wxFileNameFromPath(GetFilename()), docTemplate->GetDefaultExtension(), @@ -317,12 +324,11 @@ bool wxDocument::SaveAs() wxFD_SAVE | wxFD_OVERWRITE_PROMPT, GetDocumentWindow()); - if (tmp.empty()) - return false; + if (fileName.empty()) + return false; // cancelled by user - wxString fileName(tmp); - wxString path, name, ext; - wxSplitPath(fileName, & path, & name, & ext); + wxString ext; + wxFileName::SplitPath(fileName, NULL, NULL, &ext); if (ext.empty()) { @@ -330,33 +336,22 @@ bool wxDocument::SaveAs() fileName += docTemplate->GetDefaultExtension(); } - SetFilename(fileName); - SetTitle(wxFileNameFromPath(fileName)); - - // Notify the views that the filename has changed - wxList::compatibility_iterator node = m_documentViews.GetFirst(); - while (node) - { - wxView *view = (wxView *)node->GetData(); - view->OnChangeFilename(); - node = node->GetNext(); - } - // Files that were not saved correctly are not added to the FileHistory. - if (!OnSaveDocument(m_documentFile)) + if (!OnSaveDocument(fileName)) return false; - // A file that doesn't use the default extension of its document template cannot be opened - // via the FileHistory, so we do not add it. + SetTitle(wxFileNameFromPath(fileName)); + SetFilename(fileName, true); // will call OnChangeFileName automatically + + // A file that doesn't use the default extension of its document template + // cannot be opened via the FileHistory, so we do not add it. if (docTemplate->FileMatchesTemplate(fileName)) { GetDocumentManager()->AddFileToHistory(fileName); } - else - { - // The user will probably not be able to open the file again, so - // we could warn about the wrong file-extension here. - } + //else: the user will probably not be able to open the file again, so we + // could warn about the wrong file-extension here + return true; } @@ -380,15 +375,20 @@ bool wxDocument::OnSaveDocument(const wxString& file) bool wxDocument::OnOpenDocument(const wxString& file) { - if ( !OnSaveModified() ) - return false; + // notice that there is no need to check the modified flag here for the + // reasons explained in OnNewDocument() if ( !DoOpenDocument(file) ) return false; SetFilename(file, true); - Modify(false); - m_savedYet = true; + + // stretching the logic a little this does make sense because the document + // had been saved into the file we just loaded it from, it just could have + // happened during a previous program execution, it's just that the name of + // this method is a bit unfortunate, it should probably have been called + // HasAssociatedFileName() + SetDocumentSaved(true); UpdateAllViews(); @@ -459,11 +459,9 @@ wxString wxDocument::DoGetUserReadableName() const wxWindow *wxDocument::GetDocumentWindow() const { - wxView *view = GetFirstView(); - if (view) - return view->GetFrame(); - else - return wxTheApp->GetTopWindow(); + wxView * const view = GetFirstView(); + + return view ? view->GetFrame() : wxTheApp->GetTopWindow(); } wxCommandProcessor *wxDocument::OnCreateCommandProcessor() @@ -480,12 +478,11 @@ bool wxDocument::OnSaveModified() ( wxString::Format ( - _("Do you want to save changes to document %s?"), + _("Do you want to save changes to %s?"), GetUserReadableName() ), wxTheApp->GetAppDisplayName(), - wxYES_NO | wxCANCEL | wxICON_QUESTION, - GetDocumentWindow() + wxYES_NO | wxCANCEL | wxICON_QUESTION | wxCENTRE ) ) { case wxNO: @@ -565,6 +562,11 @@ void wxDocument::NotifyClosing() void wxDocument::SetFilename(const wxString& filename, bool notifyViews) { m_documentFile = filename; + OnChangeFilename(notifyViews); +} + +void wxDocument::OnChangeFilename(bool notifyViews) +{ if ( notifyViews ) { // Notify the views that the filename has changed @@ -608,7 +610,7 @@ bool wxDocument::DoOpenDocument(const wxString& file) if ( !store ) #else wxFileInputStream store(file); - if (store.GetLastError() != wxSTREAM_NO_ERROR) + if (store.GetLastError() != wxSTREAM_NO_ERROR || !store.IsOk()) #endif { wxLogError(_("File \"%s\" could not be opened for reading."), file); @@ -640,21 +642,54 @@ 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 ) + { + // prevent it from doing anything with us + m_docChildFrame->SetView(NULL); + + // it doesn't make sense to leave the frame alive if its associated + // view doesn't exist any more so unconditionally close it as well + // + // notice that we only get here if m_docChildFrame is non-NULL in the + // first place and it will be always NULL if we're deleted because our + // frame was closed, so this only catches the case of directly deleting + // the view, as it happens if its creation fails in wxDocTemplate:: + // CreateView() for example + m_docChildFrame->GetWindow()->Destroy(); + } + + if ( m_viewDocument ) + m_viewDocument->RemoveView(this); } -bool wxView::TryValidator(wxEvent& event) +void wxView::SetDocChildFrame(wxDocChildFrameAnyBase *docChildFrame) +{ + SetFrame(docChildFrame ? docChildFrame->GetWindow() : NULL); + m_docChildFrame = docChildFrame; +} + +bool wxView::TryBefore(wxEvent& event) { wxDocument * const doc = GetDocument(); return doc && doc->ProcessEventHere(event); } -void wxView::OnActivateView(bool WXUNUSED(activate), wxView *WXUNUSED(activeView), wxView *WXUNUSED(deactiveView)) +void wxView::OnActivateView(bool WXUNUSED(activate), + wxView *WXUNUSED(activeView), + wxView *WXUNUSED(deactiveView)) { } @@ -751,11 +786,15 @@ wxDocTemplate::~wxDocTemplate() // Tries to dynamically construct an object of the right class. wxDocument *wxDocTemplate::CreateDocument(const wxString& path, long flags) { + // InitDocument() is supposed to delete the document object if its + // initialization fails so don't use wxScopedPtr<> here: this is fragile + // but unavoidable because the default implementation uses CreateView() + // which may -- or not -- create a wxView and if it does create it and its + // initialization fails then the view destructor will delete the document + // (via RemoveView()) and as we can't distinguish between the two cases we + // just have to assume that it always deletes it in case of failure wxDocument * const doc = DoCreateDocument(); - // VZ: this code doesn't delete doc if InitDocument() (i.e. doc->OnCreate()) - // fails, is this intentional? - return doc && InitDocument(doc, path, flags) ? doc : NULL; } @@ -769,30 +808,23 @@ wxDocTemplate::InitDocument(wxDocument* doc, const wxString& path, long flags) if (doc->OnCreate(path, flags)) return true; - else - { - if (GetDocumentManager()->GetDocuments().Member(doc)) - doc->DeleteAllViews(); - return false; - } + + if (GetDocumentManager()->GetDocuments().Member(doc)) + doc->DeleteAllViews(); + return false; } wxView *wxDocTemplate::CreateView(wxDocument *doc, long flags) { - wxView *view = DoCreateView(); - if ( view == NULL ) + wxScopedPtr view(DoCreateView()); + if ( !view ) return NULL; view->SetDocument(doc); - if (view->OnCreate(doc, flags)) - { - return view; - } - else - { - delete view; + if ( !view->OnCreate(doc, flags) ) return NULL; - } + + return view.release(); } // The default (very primitive) format detection: check is the extension is @@ -818,7 +850,7 @@ wxDocument *wxDocTemplate::DoCreateDocument() if (!m_docClassInfo) return NULL; - return (wxDocument *)m_docClassInfo->CreateObject(); + return static_cast(m_docClassInfo->CreateObject()); } wxView *wxDocTemplate::DoCreateView() @@ -826,7 +858,7 @@ wxView *wxDocTemplate::DoCreateView() if (!m_viewClassInfo) return NULL; - return (wxView *)m_viewClassInfo->CreateObject(); + return static_cast(m_viewClassInfo->CreateObject()); } // ---------------------------------------------------------------------------- @@ -889,19 +921,18 @@ wxDocManager::~wxDocManager() // closes the specified document bool wxDocManager::CloseDocument(wxDocument* doc, bool force) { - if (doc->Close() || force) - { - // Implicitly deletes the document when - // the last view is deleted - doc->DeleteAllViews(); + if ( !doc->Close() && !force ) + return false; - // Check we're really deleted - if (m_docs.Member(doc)) - delete doc; + // Implicitly deletes the document when + // the last view is deleted + doc->DeleteAllViews(); - return true; - } - return false; + // Check we're really deleted + if (m_docs.Member(doc)) + delete doc; + + return true; } bool wxDocManager::CloseDocuments(bool force) @@ -947,6 +978,41 @@ bool wxDocManager::Initialize() return true; } +wxString wxDocManager::GetLastDirectory() const +{ + // if we haven't determined the last used directory yet, do it now + if ( m_lastDirectory.empty() ) + { + // we're going to modify m_lastDirectory in this const method, so do it + // via non-const self pointer instead of const this one + wxDocManager * const self = const_cast(this); + + // first try to reuse the directory of the most recently opened file: + // this ensures that if the user opens a file, closes the program and + // runs it again the "Open file" dialog will open in the directory of + // the last file he used + wxString lastOpened = GetHistoryFile(0); + if ( !lastOpened.empty() ) + { + const wxFileName fn(lastOpened); + if ( fn.DirExists() ) + { + self->m_lastDirectory = fn.GetPath(); + } + //else: should we try the next one? + } + + // if we don't have any files in the history (yet?), use the + // system-dependent default location for the document files + if ( m_lastDirectory.empty() ) + { + self->m_lastDirectory = wxStandardPaths::Get().GetAppDocumentsDir(); + } + } + + return m_lastDirectory; +} + wxFileHistory *wxDocManager::OnCreateFileHistory() { return new wxFileHistory; @@ -977,7 +1043,7 @@ void wxDocManager::OnFileNew(wxCommandEvent& WXUNUSED(event)) void wxDocManager::OnFileOpen(wxCommandEvent& WXUNUSED(event)) { - if ( !CreateDocument( wxEmptyString, 0) ) + if ( !CreateDocument("") ) { OnOpenFileFailure(); } @@ -1010,7 +1076,7 @@ void wxDocManager::OnFileSaveAs(wxCommandEvent& WXUNUSED(event)) void wxDocManager::OnPrint(wxCommandEvent& WXUNUSED(event)) { #if wxUSE_PRINTING_ARCHITECTURE - wxView *view = GetCurrentView(); + wxView *view = GetActiveView(); if (!view) return; @@ -1028,7 +1094,7 @@ void wxDocManager::OnPrint(wxCommandEvent& WXUNUSED(event)) void wxDocManager::OnPreview(wxCommandEvent& WXUNUSED(event)) { #if wxUSE_PRINTING_ARCHITECTURE - wxView *view = GetCurrentView(); + wxView *view = GetActiveView(); if (!view) return; @@ -1036,16 +1102,18 @@ void wxDocManager::OnPreview(wxCommandEvent& WXUNUSED(event)) if (printout) { // Pass two printout objects: for preview, and possible printing. - wxPrintPreviewBase *preview = new wxPrintPreview(printout, view->OnCreatePrintout()); + wxPrintPreviewBase * + preview = new wxPrintPreview(printout, view->OnCreatePrintout()); if ( !preview->Ok() ) { delete preview; - wxMessageBox( _("Sorry, print preview needs a printer to be installed.") ); + wxLogError(_("Print preview creation failed.")); return; } - wxPreviewFrame *frame = new wxPreviewFrame(preview, (wxFrame *)wxTheApp->GetTopWindow(), _("Print Preview"), - wxPoint(100, 100), wxSize(600, 650)); + wxPreviewFrame * + frame = new wxPreviewFrame(preview, wxTheApp->GetTopWindow(), + _("Print Preview")); frame->Centre(wxBOTH); frame->Initialize(); frame->Show(true); @@ -1055,31 +1123,35 @@ void wxDocManager::OnPreview(wxCommandEvent& WXUNUSED(event)) void wxDocManager::OnUndo(wxCommandEvent& event) { - wxDocument *doc = GetCurrentDocument(); - if (!doc) - return; - if (doc->GetCommandProcessor()) - doc->GetCommandProcessor()->Undo(); - else + wxCommandProcessor * const cmdproc = GetCurrentCommandProcessor(); + if ( !cmdproc ) + { event.Skip(); + return; + } + + cmdproc->Undo(); } void wxDocManager::OnRedo(wxCommandEvent& event) { - wxDocument *doc = GetCurrentDocument(); - if (!doc) - return; - if (doc->GetCommandProcessor()) - doc->GetCommandProcessor()->Redo(); - else + wxCommandProcessor * const cmdproc = GetCurrentCommandProcessor(); + if ( !cmdproc ) + { event.Skip(); + return; + } + + cmdproc->Redo(); } // Handlers for UI update commands void wxDocManager::OnUpdateFileOpen(wxUpdateUIEvent& event) { - event.Enable( true ); + // CreateDocument() (which is called from OnFileOpen) may succeed + // only when there is at least a template: + event.Enable( GetTemplates().GetCount()>0 ); } void wxDocManager::OnUpdateDisableIfNoDoc(wxUpdateUIEvent& event) @@ -1089,58 +1161,70 @@ void wxDocManager::OnUpdateDisableIfNoDoc(wxUpdateUIEvent& event) void wxDocManager::OnUpdateFileNew(wxUpdateUIEvent& event) { - event.Enable( true ); + // CreateDocument() (which is called from OnFileNew) may succeed + // only when there is at least a template: + event.Enable( GetTemplates().GetCount()>0 ); } void wxDocManager::OnUpdateFileSave(wxUpdateUIEvent& event) { - wxDocument *doc = GetCurrentDocument(); - event.Enable( doc && doc->IsModified() ); + wxDocument * const doc = GetCurrentDocument(); + event.Enable( doc && !doc->AlreadySaved() ); } void wxDocManager::OnUpdateUndo(wxUpdateUIEvent& event) { - wxDocument *doc = GetCurrentDocument(); - if (!doc) - event.Enable(false); - else if (!doc->GetCommandProcessor()) - event.Skip(); - else + wxCommandProcessor * const cmdproc = GetCurrentCommandProcessor(); + if ( !cmdproc ) { - event.Enable( doc->GetCommandProcessor()->CanUndo() ); - doc->GetCommandProcessor()->SetMenuStrings(); + event.Enable(false); + return; } + + event.Enable(cmdproc->CanUndo()); + cmdproc->SetMenuStrings(); } void wxDocManager::OnUpdateRedo(wxUpdateUIEvent& event) { - wxDocument *doc = GetCurrentDocument(); - if (!doc) - event.Enable(false); - else if (!doc->GetCommandProcessor()) - event.Skip(); - else + wxCommandProcessor * const cmdproc = GetCurrentCommandProcessor(); + if ( !cmdproc ) { - event.Enable( doc->GetCommandProcessor()->CanRedo() ); - doc->GetCommandProcessor()->SetMenuStrings(); + event.Enable(false); + return; } + + event.Enable(cmdproc->CanRedo()); + cmdproc->SetMenuStrings(); } -wxView *wxDocManager::GetCurrentView() const +wxView *wxDocManager::GetActiveView() const { - if (m_currentView) - return m_currentView; - if (m_docs.GetCount() == 1) + wxView *view = GetCurrentView(); + + if ( !view && !m_docs.empty() ) { - wxDocument* doc = (wxDocument*) m_docs.GetFirst()->GetData(); - return doc->GetFirstView(); + // if we have exactly one document, consider its view to be the current + // one + // + // VZ: I'm not exactly sure why is this needed but this is how this + // code used to behave before the bug #9518 was fixed and it seems + // safer to preserve the old logic + wxList::compatibility_iterator node = m_docs.GetFirst(); + if ( !node->GetNext() ) + { + wxDocument *doc = static_cast(node->GetData()); + view = doc->GetFirstView(); + } + //else: we have more than one document } - return NULL; + + return view; } -bool wxDocManager::TryValidator(wxEvent& event) +bool wxDocManager::TryBefore(wxEvent& event) { - wxView * const view = GetCurrentView(); + wxView * const view = GetActiveView(); return view && view->ProcessEventHere(event); } @@ -1261,15 +1345,18 @@ wxDocument *wxDocManager::CreateDocument(const wxString& pathOrig, long flags) docNew->SetDocumentName(temp->GetDocumentName()); docNew->SetDocumentTemplate(temp); - // call the appropriate function depending on whether we're creating a new - // file or opening an existing one - if ( !(flags & wxDOC_NEW ? docNew->OnNewDocument() - : docNew->OnOpenDocument(path)) ) + wxTRY { - // Document is implicitly deleted by DeleteAllViews - docNew->DeleteAllViews(); - return NULL; + // call the appropriate function depending on whether we're creating a + // new file or opening an existing one + if ( !(flags & wxDOC_NEW ? docNew->OnNewDocument() + : docNew->OnOpenDocument(path)) ) + { + docNew->DeleteAllViews(); + return NULL; + } } + wxCATCH_ALL( docNew->DeleteAllViews(); throw; ) // add the successfully opened file to MRU, but only if we're going to be // able to reopen it successfully later which requires the template for @@ -1315,11 +1402,14 @@ bool wxDocManager::FlushDoc(wxDocument *WXUNUSED(doc)) wxDocument *wxDocManager::GetCurrentDocument() const { - wxView *view = GetCurrentView(); - if (view) - return view->GetDocument(); - else - return NULL; + wxView * const view = GetActiveView(); + return view ? view->GetDocument() : NULL; +} + +wxCommandProcessor *wxDocManager::GetCurrentCommandProcessor() const +{ + wxDocument * const doc = GetCurrentDocument(); + return doc ? doc->GetCommandProcessor() : NULL; } // Make a default name for a new document @@ -1467,12 +1557,10 @@ wxDocTemplate *wxDocManager::SelectDocumentPath(wxDocTemplate **templates, long WXUNUSED(flags), bool WXUNUSED(save)) { - // We can only have multiple filters in Windows and GTK -#if defined(__WXMSW__) || defined(__WXGTK__) || defined(__WXMAC__) +#ifdef wxHAS_MULTIPLE_FILEDLG_FILTERS wxString descrBuf; - int i; - for (i = 0; i < noTemplates; i++) + for (int i = 0; i < noTemplates; i++) { if (templates[i]->IsVisible()) { @@ -1492,15 +1580,11 @@ wxDocTemplate *wxDocManager::SelectDocumentPath(wxDocTemplate **templates, int FilterIndex = -1; - wxWindow* parent = wxFindSuitableParent(); - wxString pathTmp = wxFileSelectorEx(_("Open File"), - m_lastDirectory, + GetLastDirectory(), wxEmptyString, &FilterIndex, - descrBuf, - 0, - parent); + descrBuf); wxDocTemplate *theTemplate = NULL; if (!pathTmp.empty()) @@ -1513,13 +1597,15 @@ wxDocTemplate *wxDocManager::SelectDocumentPath(wxDocTemplate **templates, else msgTitle = wxString(_("File error")); - (void)wxMessageBox(_("Sorry, could not open this file."), msgTitle, wxOK | wxICON_EXCLAMATION, - parent); + wxMessageBox(_("Sorry, could not open this file."), + msgTitle, + wxOK | wxICON_EXCLAMATION | wxCENTRE); path = wxEmptyString; return NULL; } - m_lastDirectory = wxPathOnly(pathTmp); + + SetLastDirectory(wxPathOnly(pathTmp)); path = pathTmp; @@ -1531,16 +1617,17 @@ wxDocTemplate *wxDocManager::SelectDocumentPath(wxDocTemplate **templates, theTemplate = FindTemplateForPath(path); if ( !theTemplate ) { - // Since we do not add files with non-default extensions to the FileHistory this - // can only happen if the application changes the allowed templates in runtime. - (void)wxMessageBox(_("Sorry, the format for this file is unknown."), - _("Open File"), - wxOK | wxICON_EXCLAMATION, wxFindSuitableParent()); + // Since we do not add files with non-default extensions to the + // file history this can only happen if the application changes the + // allowed templates in runtime. + wxMessageBox(_("Sorry, the format for this file is unknown."), + _("Open File"), + wxOK | wxICON_EXCLAMATION | wxCENTRE); } } else { - path = wxEmptyString; + path.clear(); } return theTemplate; @@ -1550,7 +1637,7 @@ wxDocTemplate *wxDocManager::SelectDocumentType(wxDocTemplate **templates, int noTemplates, bool sort) { wxArrayString strings; - wxDocTemplate **data = new wxDocTemplate *[noTemplates]; + wxScopedArray data(new wxDocTemplate *[noTemplates]); int i; int n = 0; @@ -1617,13 +1704,10 @@ wxDocTemplate *wxDocManager::SelectDocumentType(wxDocTemplate **templates, _("Select a document template"), _("Templates"), strings, - (void **)data, - wxFindSuitableParent() + (void **)data.get() ); } - delete[] data; - return theTemplate; } @@ -1631,7 +1715,7 @@ wxDocTemplate *wxDocManager::SelectViewType(wxDocTemplate **templates, int noTemplates, bool sort) { wxArrayString strings; - wxDocTemplate **data = new wxDocTemplate *[noTemplates]; + wxScopedArray data(new wxDocTemplate *[noTemplates]); int i; int n = 0; @@ -1694,13 +1778,11 @@ wxDocTemplate *wxDocManager::SelectViewType(wxDocTemplate **templates, _("Select a document view"), _("Views"), strings, - (void **)data, - wxFindSuitableParent() + (void **)data.get() ); } - delete[] data; return theTemplate; } @@ -1746,72 +1828,34 @@ 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::TryValidator(wxEvent& event) -{ - if ( !m_childView ) - return false; - - // FIXME: why is this needed here? - m_childView->Activate(true); - - return m_childView->ProcessEventHere(event); -} - -void wxDocChildFrame::OnActivate(wxActivateEvent& event) +bool wxDocChildFrameAnyBase::CloseView(wxCloseEvent& event) { - wxFrame::OnActivate(event); - - if (m_childView) - m_childView->Activate(event.GetActive()); -} - -void wxDocChildFrame::OnCloseWindow(wxCloseEvent& event) -{ - if (m_childView) + if ( m_childView ) { - bool ans = event.CanVeto() - ? m_childView->Close(false) // false means don't delete associated window - : true; // Must delete. - - if (ans) + if ( event.CanVeto() && !m_childView->Close(false) ) { - m_childView->Activate(false); - delete m_childView; - m_childView = NULL; - m_childDocument = NULL; - - this->Destroy(); - } - else event.Veto(); + return false; + } + + m_childView->Activate(false); + + // it is important to reset m_childView frame pointer to NULL before + // deleting it because while normally it is the frame which deletes the + // view when it's closed, the view also closes the frame if it is + // deleted directly not by us as indicated by its doc child frame + // pointer still being set + m_childView->SetDocChildFrame(NULL); + delete m_childView; + m_childView = NULL; } - else - event.Veto(); + + m_childDocument = NULL; + + return true; } // ---------------------------------------------------------------------------- @@ -1894,9 +1938,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 @@ -1905,7 +1952,7 @@ void wxDocParentFrame::OnCloseWindow(wxCloseEvent& event) { if (m_docManager->Clear(!event.CanVeto())) { - this->Destroy(); + Destroy(); } else event.Veto(); @@ -1971,7 +2018,8 @@ bool wxDocPrintout::OnBeginDocument(int startPage, int endPage) return true; } -void wxDocPrintout::GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int *selPageTo) +void wxDocPrintout::GetPageInfo(int *minPage, int *maxPage, + int *selPageFrom, int *selPageTo) { *minPage = 1; *maxPage = 1;