]> git.saurik.com Git - wxWidgets.git/commitdiff
1. undid the "simplification" of patch 1096066 which resulted in a crash
authorVadim Zeitlin <vadim@wxwidgets.org>
Sat, 19 Feb 2005 13:45:31 +0000 (13:45 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sat, 19 Feb 2005 13:45:31 +0000 (13:45 +0000)
   (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

src/common/docview.cpp

index 64ea2a86273a038b3f8596e0d5d67b1ca567d43e..850a94090d9b2aefe433d4b81aa2d71801b79212 100644 (file)
@@ -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;
 }