From b3f530bfb9d099414d833e7b0eb8c71cb3780eca Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Sun, 3 Nov 2019 15:04:48 +0100 Subject: Undo: make weight-deletion an undoable action This one is a bit more complicated than weight adding, because the multiple-dive case is not well defined. If multiple dives are selected, this implementation will search for weights that are identical to the weight deleted in the currently shown dive. The position of the weight in the list is ignored. Signed-off-by: Berthold Stoeger --- commands/command.cpp | 5 ++++ commands/command.h | 1 + commands/command_edit.cpp | 71 +++++++++++++++++++++++++++++++++++++++++++++++ commands/command_edit.h | 12 ++++++++ 4 files changed, 89 insertions(+) (limited to 'commands') diff --git a/commands/command.cpp b/commands/command.cpp index 8f3dcc703..9417eec0e 100644 --- a/commands/command.cpp +++ b/commands/command.cpp @@ -273,6 +273,11 @@ int addWeight(bool currentDiveOnly) return execute_edit(new AddWeight(currentDiveOnly)); } +int removeWeight(int index, bool currentDiveOnly) +{ + return execute_edit(new RemoveWeight(index, currentDiveOnly)); +} + // Trip editing related commands void editTripLocation(dive_trip *trip, const QString &s) { diff --git a/commands/command.h b/commands/command.h index 85a37534e..5c60ac316 100644 --- a/commands/command.h +++ b/commands/command.h @@ -82,6 +82,7 @@ void pasteDives(const dive *d, dive_components what); void replanDive(dive *d); // dive computer(s) and cylinder(s) will be reset! void editProfile(dive *d); // dive computer(s) and cylinder(s) will be reset! int addWeight(bool currentDiveOnly); +int removeWeight(int index, bool currentDiveOnly); // 5) Trip editing commands diff --git a/commands/command_edit.cpp b/commands/command_edit.cpp index 541eac61a..bfa02a55d 100644 --- a/commands/command_edit.cpp +++ b/commands/command_edit.cpp @@ -985,4 +985,75 @@ void AddWeight::redo() } } +static int find_weightsystem_index(const struct dive *d, weightsystem_t ws) +{ + for (int idx = 0; idx < d->weightsystems.nr; ++idx) { + if (same_weightsystem(d->weightsystems.weightsystems[idx], ws)) + return idx; + } + return -1; +} + +RemoveWeight::RemoveWeight(int index, bool currentDiveOnly) : + EditDivesBase(currentDiveOnly), + ws{ {0}, nullptr } +{ + // Get the old weightsystem, bail if index is invalid + if (!current || index < 0 || index >= current->weightsystems.nr) { + dives.clear(); + return; + } + ws = clone_weightsystem(current->weightsystems.weightsystems[index]); + + // Deleting a weightsystem from multiple dives is semantically ill-defined. + // What we will do is trying to delete the same weightsystem if it exists. + // For that purpose, we will determine the indices of the same weightsystem. + std::vector divesNew; + divesNew.reserve(dives.size()); + indexes.reserve(dives.size()); + + for (dive *d: dives) { + if (d == current) { + divesNew.push_back(d); + indexes.push_back(index); + continue; + } + int idx = find_weightsystem_index(d, ws); + if (idx >= 0) { + divesNew.push_back(d); + indexes.push_back(idx); + } + } + dives = std::move(divesNew); + + //: remove the part in parentheses for %n = 1 + setText(tr("Remove weight (%n dive(s))", "", dives.size())); +} + +RemoveWeight::~RemoveWeight() +{ + free((void *)ws.description); +} + +bool RemoveWeight::workToBeDone() +{ + return !dives.empty(); +} + +void RemoveWeight::undo() +{ + for (size_t i = 0; i < dives.size(); ++i) { + add_to_weightsystem_table(&dives[i]->weightsystems, indexes[i], clone_weightsystem(ws)); + emit diveListNotifier.weightAdded(dives[i], indexes[i]); + } +} + +void RemoveWeight::redo() +{ + for (size_t i = 0; i < dives.size(); ++i) { + remove_weightsystem(dives[i], indexes[i]); + emit diveListNotifier.weightRemoved(dives[i], indexes[i]); + } +} + } // namespace Command diff --git a/commands/command_edit.h b/commands/command_edit.h index ecf745070..c23f06094 100644 --- a/commands/command_edit.h +++ b/commands/command_edit.h @@ -339,6 +339,18 @@ private: bool workToBeDone() override; }; +class RemoveWeight : public EditDivesBase { +public: + RemoveWeight(int index, bool currentDiveOnly); + ~RemoveWeight(); +private: + weightsystem_t ws; + std::vector indexes; // An index for each dive in the dives vector. + void undo() override; + void redo() override; + bool workToBeDone() override; +}; + } // namespace Command #endif -- cgit v1.2.3-70-g09d2