diff options
author | Berthold Stoeger <bstoeger@mail.tuwien.ac.at> | 2018-07-20 20:26:06 +0200 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2018-10-11 16:22:27 -0700 |
commit | 302f6adb79681da3fe53336f1e4c7525f46fd47d (patch) | |
tree | ce752cf002ec01cd9c26a804e49b2ee5b516d6ac /desktop-widgets | |
parent | 12df9faaa2037b5155ebb84a7f6f6102491a0091 (diff) | |
download | subsurface-302f6adb79681da3fe53336f1e4c7525f46fd47d.tar.gz |
Undo: implement rudimentary support for undo of dive-splitting
For this, the core functionality of the split_dive() and
split_dive_at_time() functions were split out into new
split_dive_dont_insert() and split_dive_at_time_dont_insert(),
which do not add the new dives to the log. Thus, the undo-command
can take ownership of these dives, without having to remove them
first.
The split-dive functionality is temporarily made desktop-only
until mobile also supports "UndoObjects".
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Diffstat (limited to 'desktop-widgets')
-rw-r--r-- | desktop-widgets/divelistview.cpp | 10 | ||||
-rw-r--r-- | desktop-widgets/undocommands.cpp | 56 | ||||
-rw-r--r-- | desktop-widgets/undocommands.h | 19 |
3 files changed, 82 insertions, 3 deletions
diff --git a/desktop-widgets/divelistview.cpp b/desktop-widgets/divelistview.cpp index 945a7381e..938a4e3e5 100644 --- a/desktop-widgets/divelistview.cpp +++ b/desktop-widgets/divelistview.cpp @@ -633,12 +633,16 @@ void DiveListView::splitDives() int i; struct dive *dive; + // Let's collect the dives to be split first, so that we don't catch newly inserted dives! + QVector<struct dive *> dives; for_each_dive (i, dive) { if (dive->selected) - split_dive(dive); + dives.append(dive); + } + for (struct dive *d: dives) { + UndoSplitDives *undoCommand = new UndoSplitDives(d, duration_t{-1}); + MainWindow::instance()->undoStack->push(undoCommand); } - MainWindow::instance()->refreshProfile(); - MainWindow::instance()->refreshDisplay(); } void DiveListView::renumberDives() diff --git a/desktop-widgets/undocommands.cpp b/desktop-widgets/undocommands.cpp index 668a84f9e..45c796af8 100644 --- a/desktop-widgets/undocommands.cpp +++ b/desktop-widgets/undocommands.cpp @@ -180,6 +180,7 @@ void UndoRemoveDivesFromTrip::undo() for (auto &pair: divesToAdd) add_dive_to_trip(pair.first, pair.second); divesToAdd.clear(); + mark_divelist_changed(true); // Finally, do the UI stuff: MainWindow::instance()->refreshDisplay(); @@ -204,3 +205,58 @@ void UndoRemoveDivesFromTrip::redo() // Finally, do the UI stuff: MainWindow::instance()->refreshDisplay(); } + +UndoSplitDives::UndoSplitDives(dive *d, duration_t time) +{ + setText(gettextFromC::tr("split dive")); + + // Split the dive + dive *new1, *new2; + int idx = time.seconds < 0 ? + split_dive_dont_insert(d, &new1, &new2) : + split_dive_at_time_dont_insert(d, time, &new1, &new2); + + // If this didn't work, reset pointers so that redo() and undo() do nothing + if (idx < 0) { + diveToSplit = nullptr; + divesToUnsplit[0] = divesToUnsplit[1]; + return; + } + + diveToSplit = d; + splitDives[0].dive.reset(new1); + splitDives[0].trip = d->divetrip; + splitDives[0].idx = idx; + splitDives[1].dive.reset(new2); + splitDives[1].trip = d->divetrip; + splitDives[1].idx = idx + 1; +} + +void UndoSplitDives::redo() +{ + if (!diveToSplit) + return; + divesToUnsplit[0] = addDive(splitDives[0]); + divesToUnsplit[1] = addDive(splitDives[1]); + unsplitDive = removeDive(diveToSplit); + mark_divelist_changed(true); + + // Finally, do the UI stuff: + MainWindow::instance()->refreshDisplay(); + MainWindow::instance()->refreshProfile(); +} + +void UndoSplitDives::undo() +{ + if (!unsplitDive.dive) + return; + // Note: reverse order with respect to redo() + diveToSplit = addDive(unsplitDive); + splitDives[1] = removeDive(divesToUnsplit[1]); + splitDives[0] = removeDive(divesToUnsplit[0]); + mark_divelist_changed(true); + + // Finally, do the UI stuff: + MainWindow::instance()->refreshDisplay(); + MainWindow::instance()->refreshProfile(); +} diff --git a/desktop-widgets/undocommands.h b/desktop-widgets/undocommands.h index 4c4073454..c30ae5fae 100644 --- a/desktop-widgets/undocommands.h +++ b/desktop-widgets/undocommands.h @@ -227,4 +227,23 @@ private: std::vector<OwningTripPtr> tripsToAdd; }; +class UndoSplitDives : public QUndoCommand { +public: + // If time is < 0, split at first surface interval + UndoSplitDives(dive *d, duration_t time); +private: + void undo() override; + void redo() override; + + // For redo + // For each dive to split, we remove one from and put two dives into the backend + dive *diveToSplit; + DiveToAdd splitDives[2]; + + // For undo + // For each dive to unsplit, we remove two dives from and add one into the backend + DiveToAdd unsplitDive; + dive *divesToUnsplit[2]; +}; + #endif // UNDOCOMMANDS_H |