diff --git a/docs/changes.txt b/docs/changes.txt index 969bb9ee95..898516b8f5 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -11,6 +11,12 @@ INCOMPATIBLE CHANGES SINCE 3.2.x: Changes in behaviour not resulting in compilation errors -------------------------------------------------------- +- wxDocument::OnCloseDocument() was called twice in previous versions when + closing the document from the menu. Now it is only called once and after + destroying all the existing document views. If you overrode this function, + please check that you don't rely on any views existing when it's called. + + Changes in behaviour which may result in build errors ----------------------------------------------------- diff --git a/include/wx/docview.h b/include/wx/docview.h index c969da7fe3..1d7d329a3c 100644 --- a/include/wx/docview.h +++ b/include/wx/docview.h @@ -188,6 +188,12 @@ public: // part of the parent document and not a disk file as usual. bool IsChildDocument() const { return m_documentParent != NULL; } + // Ask the user if the document should be saved if it's modified and save + // it if necessary. + // + // Returns false if the user cancelled closing or if saving failed. + bool CanClose(); + protected: wxList m_documentViews; wxString m_documentFile; diff --git a/src/common/docview.cpp b/src/common/docview.cpp index d6a7349cde..fc6ecd445a 100644 --- a/src/common/docview.cpp +++ b/src/common/docview.cpp @@ -144,15 +144,14 @@ wxDocument::~wxDocument() //DeleteAllViews(); } -bool wxDocument::Close() +bool wxDocument::CanClose() { if ( !OnSaveModified() ) return false; // When the parent document closes, its children must be closed as well as - // they can't exist without the parent. + // they can't exist without the parent, so ask them too. - // As usual, first check if all children can be closed. DocsList::const_iterator it = m_childDocuments.begin(); for ( DocsList::const_iterator end = m_childDocuments.end(); it != end; ++it ) { @@ -163,6 +162,15 @@ bool wxDocument::Close() } } + return true; +} + +bool wxDocument::Close() +{ + // First check if this document itself and all its children can be closed. + if ( !CanClose() ) + return false; + // Now that they all did, do close them: as m_childDocuments is modified as // we iterate over it, don't use the usual for-style iteration here. while ( !m_childDocuments.empty() ) @@ -996,12 +1004,12 @@ wxDocManager::~wxDocManager() // closes the specified document bool wxDocManager::CloseDocument(wxDocument* doc, bool force) { - if ( !doc->Close() && !force ) + if ( !doc->CanClose() && !force ) return false; // To really force the document to close, we must ensure that it isn't // modified, otherwise it would ask the user about whether it should be - // destroyed (again, it had been already done by Close() above) and might + // destroyed (again, it had been already done by CanClose() above) and might // not destroy it at all, while we must do it here. doc->Modify(false);