From 726d08c2f71920acd8e5cc9b2d6850d1249466aa Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Wed, 17 Jul 2019 15:49:45 +0200 Subject: [PATCH] Undo: make editing of dive number undoable When pressing F2 in the dive list, the number can be edited. Make this action undoable by implementing a EditNumber command. This command is differs from the other undo commands, as not the currently selected dives are changed. This means that the EditCommand needs an alternative constructor taking a single dive. This constructor was implemented in the base class so that all edit commands can now be called with a single dive. Signed-off-by: Berthold Stoeger --- desktop-widgets/command.cpp | 5 +++++ desktop-widgets/command.h | 1 + desktop-widgets/command_edit.cpp | 36 ++++++++++++++++++++++++++++++++ desktop-widgets/command_edit.h | 11 ++++++++++ qt-models/divetripmodel.cpp | 4 ++-- 5 files changed, 55 insertions(+), 2 deletions(-) diff --git a/desktop-widgets/command.cpp b/desktop-widgets/command.cpp index 78f849651..cf8aeb7f9 100644 --- a/desktop-widgets/command.cpp +++ b/desktop-widgets/command.cpp @@ -163,6 +163,11 @@ int editMode(int index, int newValue, bool currentDiveOnly) return execute_edit(new EditMode(index, newValue, currentDiveOnly)); } +int editNumber(int newValue, bool currentDiveOnly) +{ + return execute_edit(new EditNumber(newValue, currentDiveOnly)); +} + int editSuit(const QString &newValue, bool currentDiveOnly) { return execute_edit(new EditSuit(newValue, currentDiveOnly)); diff --git a/desktop-widgets/command.h b/desktop-widgets/command.h index fec5d76a9..fa4ce2a45 100644 --- a/desktop-widgets/command.h +++ b/desktop-widgets/command.h @@ -60,6 +60,7 @@ void purgeUnusedDiveSites(); int editNotes(const QString &newValue, bool currentDiveOnly); int editSuit(const QString &newValue, bool currentDiveOnly); int editMode(int index, int newValue, bool currentDiveOnly); +int editNumber(int newValue, bool currentDiveOnly); int editRating(int newValue, bool currentDiveOnly); int editVisibility(int newValue, bool currentDiveOnly); int editAirTemp(int newValue, bool currentDiveOnly); diff --git a/desktop-widgets/command_edit.cpp b/desktop-widgets/command_edit.cpp index 6f69f8d8a..16fc4034e 100644 --- a/desktop-widgets/command_edit.cpp +++ b/desktop-widgets/command_edit.cpp @@ -33,6 +33,13 @@ EditDivesBase::EditDivesBase(bool currentDiveOnly) : { } +EditDivesBase::EditDivesBase(dive *d) : + dives({ d }), + selectedDives(getDiveSelection()), + current(current_dive) +{ +} + int EditDivesBase::numDives() const { return dives.size(); @@ -45,6 +52,13 @@ EditBase::EditBase(T newValue, bool currentDiveOnly) : { } +template +EditBase::EditBase(T newValue, dive *d) : + EditDivesBase(d), + value(std::move(newValue)) +{ +} + // This is quite hackish: we can't use virtual functions in the constructor and // therefore can't initialize the list of dives [the values of the dives are // accessed by virtual functions]. Therefore, we (mis)use the fact that workToBeDone() @@ -445,6 +459,28 @@ DiveField EditMode::fieldId() const return DiveField::MODE; } +// ***** Number ***** +void EditNumber::set(struct dive *d, int number) const +{ + d->number = number; +} + +int EditNumber::data(struct dive *d) const +{ + return d->number; +} + +QString EditNumber::fieldName() const +{ + return tr("number"); +} + +DiveField EditNumber::fieldId() const +{ + return DiveField::NR; +} + + // ***** Tag based commands ***** EditTagsBase::EditTagsBase(const QStringList &newListIn, bool currentDiveOnly) : EditDivesBase(currentDiveOnly), diff --git a/desktop-widgets/command_edit.h b/desktop-widgets/command_edit.h index d23860283..0ba3d1a14 100644 --- a/desktop-widgets/command_edit.h +++ b/desktop-widgets/command_edit.h @@ -29,6 +29,7 @@ namespace Command { class EditDivesBase : public Base { protected: EditDivesBase(bool currentDiveOnly); + EditDivesBase(dive *d); std::vector dives; // Dives to be edited. // On undo, we set the selection and current dive at the time of the operation. @@ -50,6 +51,7 @@ protected: public: EditBase(T newValue, bool currentDiveOnly); + EditBase(T newValue, dive *d); protected: // Get and set functions to be overriden by sub-classes. @@ -174,6 +176,15 @@ public: DiveField fieldId() const override; }; +class EditNumber : public EditBase { +public: + using EditBase::EditBase; // Use constructor of base class. + void set(struct dive *d, int number) const override; + int data(struct dive *d) const override; + QString fieldName() const override; + DiveField fieldId() const override; +}; + // Fields that work with tag-lists (tags, buddies, divemasters) work differently and therefore // have their own base class. In this case, it's not a template, as all these lists are base // on strings. diff --git a/qt-models/divetripmodel.cpp b/qt-models/divetripmodel.cpp index 3956ab6e2..09c5c308d 100644 --- a/qt-models/divetripmodel.cpp +++ b/qt-models/divetripmodel.cpp @@ -7,6 +7,7 @@ #include "core/qthelper.h" #include "core/subsurface-string.h" #include "core/tag.h" +#include "desktop-widgets/command.h" #include #include #include @@ -412,8 +413,7 @@ bool DiveTripModelBase::setData(const QModelIndex &index, const QVariant &value, if (dive->number == v) return false; } - d->number = v; - mark_divelist_changed(true); + Command::editNumber(v, d); return true; }