Merge pull request #1235 from Technius/issue-1233

Fix document close handling logic
presentation
Bryan Tan 7 years ago committed by GitHub
commit 1c0f9915e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 131
      src/control/Control.cpp
  2. 34
      src/control/Control.h
  3. 10
      src/control/jobs/SaveJob.cpp

@ -2232,7 +2232,7 @@ bool Control::newFile(string pageTemplate)
{
XOJ_CHECK_TYPE(Control);
if (!this->close())
if (!this->close(true))
{
return false;
}
@ -2292,7 +2292,7 @@ bool Control::openFile(Path filename, int scrollToPage, bool forceOpen)
return false;
}
if (!this->close())
if (!this->close(false))
{
return false;
}
@ -2316,6 +2316,8 @@ bool Control::openFile(Path filename, int scrollToPage, bool forceOpen)
}
}
this->closeDocument();
// Read template file
if (filename.hasExtension(".xopt"))
{
@ -2535,7 +2537,7 @@ bool Control::annotatePdf(Path filename, bool attachPdf, bool attachToDocument)
{
XOJ_CHECK_TYPE(Control);
if (!this->close())
if (!this->close(false))
{
return false;
}
@ -2550,6 +2552,8 @@ bool Control::annotatePdf(Path filename, bool attachPdf, bool attachToDocument)
}
}
this->closeDocument();
getCursor()->setCursorBusy(true);
this->doc->setFilename("");
@ -2675,6 +2679,7 @@ bool Control::save(bool synchron)
{
result = job->save();
unblock();
this->resetSavedStatus();
}
else
{
@ -2843,11 +2848,22 @@ bool Control::saveAs()
return save();
}
void Control::resetSavedStatus()
{
this->doc->lock();
Path filename = this->doc->getFilename();
this->doc->unlock();
this->undoRedo->documentSaved();
this->recent->addRecentFileFilename(filename);
this->updateWindowTitle();
}
void Control::quit(bool allowCancel)
{
XOJ_CHECK_TYPE(Control);
if (!this->close(true, allowCancel))
if (!this->close(false, allowCancel))
{
if (!allowCancel)
{
@ -2860,6 +2876,8 @@ void Control::quit(bool allowCancel)
return;
}
this->closeDocument();
this->scheduler->lock();
audioController->stopRecording();
@ -2870,100 +2888,81 @@ void Control::quit(bool allowCancel)
gtk_main_quit();
}
bool Control::close(bool destroy, bool allowCancel)
bool Control::close(const bool allowDestroy, const bool allowCancel)
{
XOJ_CHECK_TYPE(Control);
clearSelectionEndText();
metadata->documentChanged();
bool discard = false;
const bool fileRemoved = !doc->getFilename().isEmpty() && !this->doc->getFilename().exists();
if (undoRedo->isChanged())
{
GtkWidget* dialog = gtk_message_dialog_new(getGtkWindow(),
GTK_DIALOG_MODAL,
GTK_MESSAGE_WARNING,
GTK_BUTTONS_NONE,
"%s",
_("This document is not saved yet."));
const auto message = fileRemoved ? _("Document file was removed.") : _("This document is not saved yet.");
const auto saveLabel = fileRemoved ? _("Save As...") : _("Save");
GtkWidget* dialog = gtk_message_dialog_new(getGtkWindow(), GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING,
GTK_BUTTONS_NONE, "%s", message);
gtk_dialog_add_button(GTK_DIALOG(dialog), _("Save"), 1);
gtk_dialog_add_button(GTK_DIALOG(dialog), _("Discard"), 2);
gtk_dialog_add_button(GTK_DIALOG(dialog), saveLabel, GTK_RESPONSE_ACCEPT);
gtk_dialog_add_button(GTK_DIALOG(dialog), _("Discard"), GTK_RESPONSE_REJECT);
if (allowCancel)
{
gtk_dialog_add_button(GTK_DIALOG(dialog), _("Cancel"), 3);
gtk_dialog_add_button(GTK_DIALOG(dialog), _("Cancel"), GTK_RESPONSE_CANCEL);
}
gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(this->getWindow()->getWindow()));
int resNotSaved = gtk_dialog_run(GTK_DIALOG(dialog));
const guint dialogResponse = gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
// save
if (resNotSaved == 1)
{
return this->save(true);
}
// cancel or closed
if (resNotSaved != 2) // 2 = discard
{
return false;
}
else
{
destroy = true;
}
}
if (!doc->getFilename().isEmpty())
{
if (!this->doc->getFilename().exists())
switch (dialogResponse)
{
GtkWidget* dialog = gtk_message_dialog_new(getGtkWindow(),
GTK_DIALOG_MODAL,
GTK_MESSAGE_WARNING,
GTK_BUTTONS_NONE,
"%s",
_("Document file was removed."));
gtk_dialog_add_button(GTK_DIALOG(dialog), _("Save As..."), 1);
gtk_dialog_add_button(GTK_DIALOG(dialog), _("Discard"), 2);
gtk_dialog_add_button(GTK_DIALOG(dialog), _("Cancel"), 3);
gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(this->getWindow()->getWindow()));
int resDocRemoved = gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
if (resDocRemoved == 1)
case GTK_RESPONSE_ACCEPT:
if (fileRemoved)
{
return this->saveAs();
}
// cancel or closed
if (resDocRemoved != 2) // 2 = discard
{
return false;
}
else
{
destroy = true;
return this->save(true);
}
break;
case GTK_RESPONSE_REJECT:
discard = true;
break;
default:
return false;
break;
}
}
if (destroy)
if (allowDestroy && discard)
{
undoRedo->clearContents();
this->doc->lock();
this->doc->clearDocument(destroy);
this->doc->unlock();
// updateWindowTitle();
undoRedoChanged();
this->closeDocument();
}
return true;
}
bool Control::closeAndDestroy(bool allowCancel)
{
// We don't want to "double close", so disallow it first.
auto retval = this->close(false, allowCancel);
this->closeDocument();
return retval;
}
void Control::closeDocument()
{
this->undoRedo->clearContents();
this->doc->lock();
this->doc->clearDocument(true);
this->doc->unlock();
this->undoRedoChanged();
}
bool Control::checkExistingFile(Path& folder, Path& filename)
{
XOJ_CHECK_TYPE(Control);

@ -75,10 +75,35 @@ public:
void exportAsPdf();
void exportAs();
void exportBase(BaseExportJob* job);
void quit(bool allowCancel = true);
/**
* Save the current document.
*
* @param synchron Whether the save should be run synchronously or asynchronously.
*/
bool save(bool synchron = false);
bool saveAs();
void quit(bool allowCancel = true);
bool close(bool destroy = false, bool allowCancel = true);
/**
* Marks the current document as saved if it is currently marked as unsaved.
*/
void resetSavedStatus();
/**
* Close the current document, prompting to save unsaved changes.
*
* @param allowDestroy Whether clicking "Discard" should destroy the current document.
* @param allowCancel Whether the user should be able to cancel closing the document.
* @return true if the user closed the document, otherwise false.
*/
bool close(bool allowDestroy = false, bool allowCancel = true);
/**
* Calls close, always forcing the document to be destroyed.
* @return The value returned by close
*/
bool closeAndDestroy(bool allowCancel = false);
// Asks user to replace an existing file when saving / exporting, since we add the extension
// after the OK, we need to check manually
@ -297,6 +322,11 @@ protected:
private:
XOJ_TYPE_ATTRIB;
/**
* "Closes" the document, preparing the editor for a new document.
*/
void closeDocument();
RecentManager* recent;
UndoRedoHandler* undoRedo;
ZoomControl* zoom;

@ -42,15 +42,7 @@ void SaveJob::afterRun()
}
else
{
Document* doc = this->control->getDocument();
doc->lock();
Path filename = doc->getFilename();
doc->unlock();
control->getUndoRedoHandler()->documentSaved();
control->getRecentManager()->addRecentFileFilename(filename);
control->updateWindowTitle();
this->control->resetSavedStatus();
}
}

Loading…
Cancel
Save