From: Vadim Zeitlin Date: Sat, 19 Feb 2005 13:45:31 +0000 (+0000) Subject: 1. undid the "simplification" of patch 1096066 which resulted in a crash X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/407020995e0e00f847c7eb45d87312217bcdd1ed 1. undid the "simplification" of patch 1096066 which resulted in a crash (see this patch discussion) 2. check that all views agree to close before starting to delete them 3. commented the code so that the next poor soul looking at it will know that deleting a view can delete the document which deletes -- surely wasn't obvious to me... git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@32172 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/src/common/docview.cpp b/src/common/docview.cpp index 64ea2a8627..850a94090d 100644 --- a/src/common/docview.cpp +++ b/src/common/docview.cpp @@ -183,23 +183,43 @@ bool wxDocument::OnCloseDocument() bool wxDocument::DeleteAllViews() { wxDocManager* manager = GetDocumentManager(); - wxList::iterator it, en; - for ( it = m_documentViews.begin(), en = m_documentViews.end(); - it != en; - ++it ) + // first check if all views agree to be closed + const wxList::iterator end = m_documentViews.end(); + for ( wxList::iterator i = m_documentViews.begin(); i != end; ++i ) { - wxView *view = (wxView *)*it; - if (!view->Close()) + wxView *view = (wxView *)*i; + if ( !view->Close() ) return false; + } - delete view; // Deletes node implicitly + // all views agreed to close, now do close them + if ( m_documentViews.empty() ) + { + // normally the document would be implicitly deleted when the last view + // is, but if don't have any views, do it here instead + if ( manager && manager->GetDocuments().Member(this) ) + delete this; } + else // have views + { + // as we delete elements we iterate over, don't use the usual "from + // begin to end" loop + for ( ;; ) + { + wxView *view = (wxView *)*m_documentViews.begin(); - // If we haven't yet deleted the document (for example - // if there were no views) then delete it. - if (manager && manager->GetDocuments().Member(this)) - delete this; + bool isLastOne = m_documentViews.size() == 1; + + // this always deletes the node implicitly and if this is the last + // view also deletes this object itself (also implicitly, great), + // so we can't test for m_documentViews.empty() after calling this! + delete view; + + if ( isLastOne ) + break; + } + } return true; }