Don't call wxDocument::OnCloseDocument() twice when closing
When closing the document using wxDocManager::CloseDocument(), which is what happens when using the standard wxID_CLOSE menu command handler, OnCloseDocument() was called twice: first when wxDocument::Close() was called directly from CloseDocument() itself and once again later when it was implicitly called from DeleteAllViews(). This was unexpected and also resulted in calling DeleteContents() twice, which is even more so for a function supposed to perform cleanup. Fix this by not calling Close() itself but instead a new CanClose() function from CloseDocument() to check whether we can close and then relying on DeleteAllViews() to actually close the document.
This commit is contained in:
parent
3e195db27e
commit
ee6d58abe2
3 changed files with 25 additions and 5 deletions
|
|
@ -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
|
||||
-----------------------------------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue