From 72c6b838662f1fb79a806ac2264c7215efa0aa67 Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Fri, 8 Nov 2019 22:47:38 +0100 Subject: Undo: make weight editing undoable Implement the EditWeight undo command. Since there is common code (storage of the old weight), this creates a common base class for RemoveWeight and EditWeight. The model calls directly into the undo command, which is somewhat unfortunate as it feels like a layering violation. It's the easy thing to do for now. Signed-off-by: Berthold Stoeger --- commands/command.cpp | 5 ++++ commands/command.h | 1 + commands/command_edit.cpp | 70 +++++++++++++++++++++++++++++++++++++++++++---- commands/command_edit.h | 26 ++++++++++++++---- 4 files changed, 91 insertions(+), 11 deletions(-) (limited to 'commands') diff --git a/commands/command.cpp b/commands/command.cpp index 9417eec0e..9ea0e860f 100644 --- a/commands/command.cpp +++ b/commands/command.cpp @@ -278,6 +278,11 @@ int removeWeight(int index, bool currentDiveOnly) return execute_edit(new RemoveWeight(index, currentDiveOnly)); } +int editWeight(int index, weightsystem_t ws, bool currentDiveOnly) +{ + return execute_edit(new EditWeight(index, ws, currentDiveOnly)); +} + // Trip editing related commands void editTripLocation(dive_trip *trip, const QString &s) { diff --git a/commands/command.h b/commands/command.h index 5c60ac316..0f93a3e85 100644 --- a/commands/command.h +++ b/commands/command.h @@ -83,6 +83,7 @@ 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); +int editWeight(int index, weightsystem_t ws, bool currentDiveOnly); // 5) Trip editing commands diff --git a/commands/command_edit.cpp b/commands/command_edit.cpp index 61b2f0d7a..2ca13199d 100644 --- a/commands/command_edit.cpp +++ b/commands/command_edit.cpp @@ -6,6 +6,7 @@ #include "core/selection.h" #include "core/subsurface-string.h" #include "core/tag.h" +#include "qt-models/weightsysteminfomodel.h" namespace Command { @@ -993,7 +994,7 @@ static int find_weightsystem_index(const struct dive *d, weightsystem_t ws) return -1; } -RemoveWeight::RemoveWeight(int index, bool currentDiveOnly) : +EditWeightBase::EditWeightBase(int index, bool currentDiveOnly) : EditDivesBase(currentDiveOnly), ws(empty_weightsystem) { @@ -1024,21 +1025,25 @@ RemoveWeight::RemoveWeight(int index, bool currentDiveOnly) : } } dives = std::move(divesNew); - - //: remove the part in parentheses for %n = 1 - setText(tr("Remove weight (%n dive(s))", "", dives.size())); } -RemoveWeight::~RemoveWeight() +EditWeightBase::~EditWeightBase() { free_weightsystem(ws); } -bool RemoveWeight::workToBeDone() +bool EditWeightBase::workToBeDone() { return !dives.empty(); } +RemoveWeight::RemoveWeight(int index, bool currentDiveOnly) : + EditWeightBase(index, currentDiveOnly) +{ + //: remove the part in parentheses for %n = 1 + setText(tr("Remove weight (%n dive(s))", "", dives.size())); +} + void RemoveWeight::undo() { for (size_t i = 0; i < dives.size(); ++i) { @@ -1055,4 +1060,57 @@ void RemoveWeight::redo() } } +EditWeight::EditWeight(int index, weightsystem_t wsIn, bool currentDiveOnly) : + EditWeightBase(index, currentDiveOnly), + new_ws(empty_weightsystem) +{ + if (dives.empty()) + return; + + //: remove the part in parentheses for %n = 1 + setText(tr("Edit weight (%n dive(s))", "", dives.size())); + + // Try to untranslate the weightsystem name + new_ws = clone_weightsystem(wsIn); + QString vString(new_ws.description); + for (int i = 0; i < MAX_WS_INFO && ws_info[i].name; ++i) { + if (gettextFromC::tr(ws_info[i].name) == vString) { + free_weightsystem(new_ws); + new_ws.description = copy_string(ws_info[i].name); + break; + } + } + + // If that doesn't change anything, do nothing + if (same_weightsystem(ws, new_ws)) { + dives.clear(); + return; + } + + WSInfoModel *wsim = WSInfoModel::instance(); + QModelIndexList matches = wsim->match(wsim->index(0, 0), Qt::DisplayRole, gettextFromC::tr(new_ws.description)); + if (!matches.isEmpty()) + wsim->setData(wsim->index(matches.first().row(), WSInfoModel::GR), new_ws.weight.grams); +} + +EditWeight::~EditWeight() +{ + free_weightsystem(new_ws); +} + +void EditWeight::redo() +{ + for (size_t i = 0; i < dives.size(); ++i) { + set_weightsystem(dives[i], indexes[i], new_ws); + emit diveListNotifier.weightEdited(dives[i], indexes[i]); + } + std::swap(ws, new_ws); +} + +// Undo and redo do the same as just the stored value is exchanged +void EditWeight::undo() +{ + redo(); +} + } // namespace Command diff --git a/commands/command_edit.h b/commands/command_edit.h index c23f06094..76b538b4d 100644 --- a/commands/command_edit.h +++ b/commands/command_edit.h @@ -339,16 +339,32 @@ private: bool workToBeDone() override; }; -class RemoveWeight : public EditDivesBase { +class EditWeightBase : public EditDivesBase { +protected: + EditWeightBase(int index, bool currentDiveOnly); + ~EditWeightBase(); + + weightsystem_t ws; + std::vector indexes; // An index for each dive in the dives vector. + bool workToBeDone() override; +}; + +class RemoveWeight : public EditWeightBase { 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; +}; + +class EditWeight : public EditWeightBase { +public: + EditWeight(int index, weightsystem_t ws, bool currentDiveOnly); // Clones ws + ~EditWeight(); +private: + weightsystem_t new_ws; + void undo() override; + void redo() override; }; } // namespace Command -- cgit v1.2.3-70-g09d2