diff options
author | Berthold Stoeger <bstoeger@mail.tuwien.ac.at> | 2019-03-30 18:39:27 +0100 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2019-04-12 18:19:07 +0300 |
commit | 58f2e5f77c2faaf4c2f75767ee8fde67cc0931ac (patch) | |
tree | 9f76fbf3ccb1cb17c516f077af08810f11fcb40d /desktop-widgets | |
parent | 837ab6c90b7952095c0dadf2de18db883b0f5ecf (diff) | |
download | subsurface-58f2e5f77c2faaf4c2f75767ee8fde67cc0931ac.tar.gz |
Undo: use QUndoStack::isClean() to determine unsaved changes
Properly implement the unsaved-changes flag(s). Since we currently have
two kinds of changes, there are two flags:
1) dive_list_changed in divelist.c marks non-undoable changes. This flag
is only cleared on save or load.
2) QUndoStack::isClean() is used to determine the state of undoable
changes. Every time the user returns to the state where they saved,
this flag is cleared.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Diffstat (limited to 'desktop-widgets')
-rw-r--r-- | desktop-widgets/command.h | 3 | ||||
-rw-r--r-- | desktop-widgets/command_base.cpp | 16 | ||||
-rw-r--r-- | desktop-widgets/command_divelist.cpp | 14 | ||||
-rw-r--r-- | desktop-widgets/command_edit.cpp | 4 | ||||
-rw-r--r-- | desktop-widgets/command_edit_trip.cpp | 2 | ||||
-rw-r--r-- | desktop-widgets/mainwindow.cpp | 33 | ||||
-rw-r--r-- | desktop-widgets/mainwindow.h | 1 |
7 files changed, 44 insertions, 29 deletions
diff --git a/desktop-widgets/command.h b/desktop-widgets/command.h index 82cb06f31..9e08b9a5e 100644 --- a/desktop-widgets/command.h +++ b/desktop-widgets/command.h @@ -10,7 +10,10 @@ namespace Command { // 1) General commands +void init(); // Setup signals to inform frontend of clean status. void clear(); // Reset the undo stack. Delete all commands. +void setClean(); // Call after save - this marks a state where no changes need to be saved. +bool isClean(); // Any changes need to be saved? QAction *undoAction(QObject *parent); // Create an undo action. QAction *redoAction(QObject *parent); // Create an redo action. diff --git a/desktop-widgets/command_base.cpp b/desktop-widgets/command_base.cpp index 24ce81225..26a587f7c 100644 --- a/desktop-widgets/command_base.cpp +++ b/desktop-widgets/command_base.cpp @@ -1,17 +1,33 @@ // SPDX-License-Identifier: GPL-2.0 #include "command_base.h" +#include "core/qthelper.h" // for updateWindowTitle() namespace Command { static QUndoStack undoStack; // General commands +void init() +{ + QObject::connect(&undoStack, &QUndoStack::cleanChanged, &updateWindowTitle); +} + void clear() { undoStack.clear(); } +void setClean() +{ + undoStack.setClean(); +} + +bool isClean() +{ + return undoStack.isClean(); +} + QAction *undoAction(QObject *parent) { return undoStack.createUndoAction(parent, QCoreApplication::translate("Command", "&Undo")); diff --git a/desktop-widgets/command_divelist.cpp b/desktop-widgets/command_divelist.cpp index 4e1359ea7..31696f2ff 100644 --- a/desktop-widgets/command_divelist.cpp +++ b/desktop-widgets/command_divelist.cpp @@ -411,7 +411,6 @@ void AddDive::redoit() divesAndSitesToRemove = addDives(divesToAdd); sort_trip_table(&trip_table); // Though unlikely, adding a dive may reorder trips - mark_divelist_changed(true); // Select the newly added dive restoreSelection(divesAndSitesToRemove.dives, divesAndSitesToRemove.dives[0]); @@ -500,8 +499,6 @@ void ImportDives::redoit() // Remember dives and sites to remove divesAndSitesToRemove = std::move(divesAndSitesToRemoveNew); - - mark_divelist_changed(true); } void ImportDives::undoit() @@ -517,8 +514,6 @@ void ImportDives::undoit() // ...and restore the selection restoreSelection(selection, currentDive); - - mark_divelist_changed(true); } DeleteDive::DeleteDive(const QVector<struct dive*> &divesToDeleteIn) @@ -536,7 +531,6 @@ void DeleteDive::undoit() { divesToDelete = addDives(divesToAdd); sort_trip_table(&trip_table); // Though unlikely, removing a dive may reorder trips - mark_divelist_changed(true); // Select all re-added dives and make the first one current dive *currentDive = !divesToDelete.dives.empty() ? divesToDelete.dives[0] : nullptr; @@ -547,7 +541,6 @@ void DeleteDive::redoit() { divesToAdd = removeDives(divesToDelete); sort_trip_table(&trip_table); // Though unlikely, adding a dive may reorder trips - mark_divelist_changed(true); // Deselect all dives and select dive that was close to the first deleted dive dive *newCurrent = nullptr; @@ -587,8 +580,6 @@ void ShiftTime::redoit() // Negate the time-shift so that the next call does the reverse timeChanged = -timeChanged; - - mark_divelist_changed(true); } bool ShiftTime::workToBeDone() @@ -611,7 +602,6 @@ RenumberDives::RenumberDives(const QVector<QPair<dive *, int>> &divesToRenumberI void RenumberDives::undoit() { renumberDives(divesToRenumber); - mark_divelist_changed(true); } bool RenumberDives::workToBeDone() @@ -634,8 +624,6 @@ void TripBase::redoit() { moveDivesBetweenTrips(divesToMove); sort_trip_table(&trip_table); // Though unlikely, moving dives may reorder trips - - mark_divelist_changed(true); } void TripBase::undoit() @@ -764,7 +752,6 @@ void SplitDivesBase::redoit() { divesToUnsplit = addDives(splitDives); unsplitDive = removeDives(diveToSplit); - mark_divelist_changed(true); // Select split dives and make first dive current restoreSelection(divesToUnsplit.dives, divesToUnsplit.dives[0]); @@ -775,7 +762,6 @@ void SplitDivesBase::undoit() // Note: reverse order with respect to redoit() diveToSplit = addDives(unsplitDive); splitDives = removeDives(divesToUnsplit); - mark_divelist_changed(true); // Select unsplit dive and make it current restoreSelection(diveToSplit.dives, diveToSplit.dives[0] ); diff --git a/desktop-widgets/command_edit.cpp b/desktop-widgets/command_edit.cpp index 7ff714e8f..31d34a89b 100644 --- a/desktop-widgets/command_edit.cpp +++ b/desktop-widgets/command_edit.cpp @@ -92,8 +92,6 @@ void EditBase<T>::undo() if (setSelection(selectedDives, current)) emit diveListNotifier.selectionChanged(); // If the selection changed -> tell the frontend - - mark_divelist_changed(true); } // We have to manually instantiate the constructors of the EditBase class, @@ -509,8 +507,6 @@ void EditTagsBase::undo() if (setSelection(selectedDives, current)) emit diveListNotifier.selectionChanged(); // If the selection changed -> tell the frontend - - mark_divelist_changed(true); } // Undo and redo do the same as just the stored value is exchanged diff --git a/desktop-widgets/command_edit_trip.cpp b/desktop-widgets/command_edit_trip.cpp index 4dc680e2d..b25e3fcc5 100644 --- a/desktop-widgets/command_edit_trip.cpp +++ b/desktop-widgets/command_edit_trip.cpp @@ -2,7 +2,6 @@ #include "command_edit_trip.h" #include "command_private.h" -#include "core/divelist.h" // for mark_divelist_changed(). TODO: remove #include "core/qthelper.h" namespace Command { @@ -27,7 +26,6 @@ void EditTripBase::undo() value = old; emit diveListNotifier.tripChanged(trip, fieldId()); - mark_divelist_changed(true); } // Undo and redo do the same as just the stored value is exchanged diff --git a/desktop-widgets/mainwindow.cpp b/desktop-widgets/mainwindow.cpp index cc1adc3b2..09af6414f 100644 --- a/desktop-widgets/mainwindow.cpp +++ b/desktop-widgets/mainwindow.cpp @@ -128,6 +128,7 @@ MainWindow::MainWindow() : QMainWindow(), m_Instance = this; ui.setupUi(this); read_hashes(); + Command::init(); // Define the States of the Application Here, Currently the states are situations where the different // widgets will change on the mainwindow. @@ -589,7 +590,15 @@ void MainWindow::on_actionCloudstoragesave_triggered() return; setCurrentFile(qPrintable(filename)); - mark_divelist_changed(false); + setFileClean(); +} + +// Currently we have two markers for unsaved changes: +// 1) unsaved_changes() returns true for non-undoable changes. +// 2) Command::isClean() returns false for undoable changes. +static bool unsavedChanges() +{ + return unsaved_changes() || !Command::isClean(); } void MainWindow::on_actionCloudOnline_triggered() @@ -611,7 +620,7 @@ void MainWindow::on_actionCloudOnline_triggered() git_local_only = isOffline; if (!isOffline) { // User requests to go online. Try to sync cloud storage - if (unsaved_changes()) { + if (unsavedChanges()) { // If there are unsaved changes, ask the user if they want to save them. // If they don't, they have to sync manually. if (QMessageBox::warning(this, tr("Save changes?"), @@ -653,12 +662,18 @@ bool MainWindow::okToClose(QString message) QMessageBox::warning(this, tr("Warning"), message); return false; } - if (unsaved_changes() && askSaveChanges() == false) + if (unsavedChanges() && askSaveChanges() == false) return false; return true; } +void MainWindow::setFileClean() +{ + mark_divelist_changed(false); + Command::setClean(); +} + void MainWindow::closeCurrentFile() { graphics->setEmptyState(); @@ -667,7 +682,7 @@ void MainWindow::closeCurrentFile() clear_dive_file_data(); setCurrentFile(nullptr); cleanUpEmpty(); - mark_divelist_changed(false); + setFileClean(); clear_events(); @@ -763,7 +778,7 @@ void MainWindow::on_actionQuit_triggered() return; } - if (unsaved_changes() && (askSaveChanges() == false)) + if (unsavedChanges() && (askSaveChanges() == false)) return; writeSettings(); QApplication::quit(); @@ -1421,7 +1436,7 @@ void MainWindow::closeEvent(QCloseEvent *event) return; } - if (unsaved_changes() && (askSaveChanges() == false)) { + if (unsavedChanges() && (askSaveChanges() == false)) { event->ignore(); return; } @@ -1555,7 +1570,7 @@ int MainWindow::file_save_as(void) return -1; setCurrentFile(qPrintable(filename)); - mark_divelist_changed(false); + setFileClean(); addRecentFile(filename, true); return 0; } @@ -1592,7 +1607,7 @@ int MainWindow::file_save(void) } if (is_cloud) hideProgressBar(); - mark_divelist_changed(false); + setFileClean(); addRecentFile(QString(existing_filename), true); return 0; } @@ -1631,7 +1646,7 @@ void MainWindow::setTitle() return; } - QString unsaved = (unsaved_changes() ? " *" : ""); + QString unsaved = (unsavedChanges() ? " *" : ""); QString shown = QString(" (%1)").arg(filterWidget2.shownText()); setWindowTitle("Subsurface: " + displayedFilename(existing_filename) + unsaved + shown); } diff --git a/desktop-widgets/mainwindow.h b/desktop-widgets/mainwindow.h index 196ceb4dc..efac8610e 100644 --- a/desktop-widgets/mainwindow.h +++ b/desktop-widgets/mainwindow.h @@ -203,6 +203,7 @@ private: void writeSettings(); int file_save(); int file_save_as(); + void setFileClean(); void beginChangeState(CurrentState s); void saveSplitterSizes(); void toggleCollapsible(bool toggle); |