Improve behaviour of "force closing" wxDocuments
When the document was forced to close, OnSaveModified() was still called and allowed the user to cancel closing the document -- but it was still closed after OnSaveModified() returned. Be more upfront about it and tell the user that the document will be closed anyhow, but still propose them to save it if necessary. An alternative solution might be to just deprecate "force closing" entirely, as this seems very user-unfriendly.
This commit is contained in:
parent
ee6d58abe2
commit
dcee1cd025
5 changed files with 85 additions and 7 deletions
|
|
@ -117,6 +117,10 @@ public:
|
|||
// modified to false)
|
||||
virtual bool OnSaveModified();
|
||||
|
||||
// Similar to OnSaveModified() but doesn't allow the user to prevent the
|
||||
// document from closing as it will be closed unconditionally.
|
||||
virtual void OnSaveBeforeForceClose();
|
||||
|
||||
// if you override, remember to call the default
|
||||
// implementation (wxDocument::OnChangeFilename)
|
||||
virtual void OnChangeFilename(bool notifyViews);
|
||||
|
|
|
|||
|
|
@ -1544,6 +1544,19 @@ public:
|
|||
*/
|
||||
virtual bool OnSaveModified();
|
||||
|
||||
/**
|
||||
This function is called when a document is forced to close.
|
||||
|
||||
The default implementation asks the user whether to save the changes
|
||||
but, unlike OnSaveModified(), does not allow to cancel closing.
|
||||
|
||||
The document is force closed when wxDocManager::CloseDocument() is
|
||||
called with its @c force argument set to @true.
|
||||
|
||||
@since 3.3.0
|
||||
*/
|
||||
virtual void OnSaveBeforeForceClose();
|
||||
|
||||
/**
|
||||
Removes the view from the document's list of views.
|
||||
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ wxIMPLEMENT_APP(MyApp);
|
|||
|
||||
wxBEGIN_EVENT_TABLE(MyApp, wxApp)
|
||||
EVT_MENU(wxID_ABOUT, MyApp::OnAbout)
|
||||
EVT_MENU(wxID_CLEAR, MyApp::OnForceCloseAll)
|
||||
wxEND_EVENT_TABLE()
|
||||
|
||||
MyApp::MyApp()
|
||||
|
|
@ -315,6 +316,7 @@ void MyApp::AppendDocumentFileCommands(wxMenu *menu, bool supportsPrinting)
|
|||
menu->Append(wxID_SAVE);
|
||||
menu->Append(wxID_SAVEAS);
|
||||
menu->Append(wxID_REVERT, _("Re&vert..."));
|
||||
menu->Append(wxID_CLEAR, "&Force close all");
|
||||
|
||||
if ( supportsPrinting )
|
||||
{
|
||||
|
|
@ -437,6 +439,13 @@ wxFrame *MyApp::CreateChildFrame(wxView *view, bool isCanvas)
|
|||
return subframe;
|
||||
}
|
||||
|
||||
void MyApp::OnForceCloseAll(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
// Pass "true" here to force closing just for testing this functionality,
|
||||
// there is no real reason to force the issue here.
|
||||
wxDocManager::GetDocumentManager()->CloseDocuments(true);
|
||||
}
|
||||
|
||||
void MyApp::OnAbout(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
wxString modeName;
|
||||
|
|
|
|||
|
|
@ -71,6 +71,9 @@ private:
|
|||
void CreateMenuBarForFrame(wxFrame *frame, wxMenu *file, wxMenu *edit);
|
||||
|
||||
|
||||
// force close all windows
|
||||
void OnForceCloseAll(wxCommandEvent& event);
|
||||
|
||||
// show the about box: as we can have different frames it's more
|
||||
// convenient, even if somewhat less usual, to handle this in the
|
||||
// application object itself
|
||||
|
|
|
|||
|
|
@ -554,6 +554,50 @@ bool wxDocument::OnSaveModified()
|
|||
return true;
|
||||
}
|
||||
|
||||
void wxDocument::OnSaveBeforeForceClose()
|
||||
{
|
||||
if ( !IsModified() )
|
||||
return;
|
||||
|
||||
wxMessageDialog dialogSave
|
||||
(
|
||||
GetDocumentWindow(),
|
||||
wxString::Format
|
||||
(
|
||||
_("Do you want to save changes to %s before closing it?"),
|
||||
GetUserReadableName()
|
||||
),
|
||||
wxTheApp->GetAppDisplayName(),
|
||||
wxYES_NO | wxICON_QUESTION | wxCENTRE
|
||||
);
|
||||
dialogSave.SetExtendedMessage(_("The document must be closed."));
|
||||
dialogSave.SetYesNoLabels(_("&Save"), _("&Discard changes"));
|
||||
|
||||
if ( dialogSave.ShowModal() == wxID_YES )
|
||||
{
|
||||
while ( !Save() )
|
||||
{
|
||||
wxMessageDialog dialogRetry
|
||||
(
|
||||
GetDocumentWindow(),
|
||||
wxString::Format
|
||||
(
|
||||
_("Saving %s failed, would you like to retry?"),
|
||||
GetUserReadableName()
|
||||
),
|
||||
wxTheApp->GetAppDisplayName(),
|
||||
wxYES_NO | wxICON_ERROR | wxCENTRE
|
||||
);
|
||||
dialogRetry.SetYesNoLabels(_("Retry"), _("Discard changes"));
|
||||
|
||||
if ( dialogRetry.ShowModal() != wxID_YES )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Modify(false);
|
||||
}
|
||||
|
||||
bool wxDocument::Draw(wxDC& WXUNUSED(context))
|
||||
{
|
||||
return true;
|
||||
|
|
@ -1004,14 +1048,19 @@ wxDocManager::~wxDocManager()
|
|||
// closes the specified document
|
||||
bool wxDocManager::CloseDocument(wxDocument* doc, bool force)
|
||||
{
|
||||
if ( !doc->CanClose() && !force )
|
||||
return false;
|
||||
if ( force )
|
||||
{
|
||||
// We need to close, but at least ask the user if the document should
|
||||
// be saved before doing it.
|
||||
doc->OnSaveBeforeForceClose();
|
||||
}
|
||||
else // Allow the user to cancel closing too.
|
||||
{
|
||||
if ( !doc->CanClose() )
|
||||
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 CanClose() above) and might
|
||||
// not destroy it at all, while we must do it here.
|
||||
doc->Modify(false);
|
||||
// Note that by now the document is certain not to be modified any longer.
|
||||
|
||||
// Implicitly deletes the document when
|
||||
// the last view is deleted
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue