(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
bool wxDocument::DeleteAllViews()
{
wxDocManager* manager = GetDocumentManager();
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() )
- 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;
+ }
+ }