From 03d5e641e1284b9613f605690d04faf48ac40715 Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Thu, 23 May 2019 20:27:19 +0200 Subject: Undo: return number of changed dives from undo commands To enable a "multiple dives edited" message, return the number of edited dives from dive edit undo commands. Since there are two kinds of these commands, viz. normal fields and tag fields, and the former use templates, create a common base class that can return the number of dives. Yes, the class hierarchy is getting scarily deep! At least, this gives a tiny bit of code-reuse. Signed-off-by: Berthold Stoeger --- desktop-widgets/command.cpp | 68 ++++++++++++++++++++++------------------ desktop-widgets/command.h | 30 +++++++++--------- desktop-widgets/command_base.h | 6 ++-- desktop-widgets/command_edit.cpp | 20 ++++++++---- desktop-widgets/command_edit.h | 30 ++++++++++-------- 5 files changed, 87 insertions(+), 67 deletions(-) diff --git a/desktop-widgets/command.cpp b/desktop-widgets/command.cpp index df1ae299d..4bbd5e059 100644 --- a/desktop-widgets/command.cpp +++ b/desktop-widgets/command.cpp @@ -145,80 +145,88 @@ void purgeUnusedDiveSites() execute(new PurgeUnusedDiveSites); } +// Execute an edit-command and return number of edited dives +static int execute_edit(EditDivesBase *cmd) +{ + int res = cmd->numDives(); + execute(cmd); + return res; +} + // Dive editing related commands -void editNotes(const QString &newValue, bool currentDiveOnly) +int editNotes(const QString &newValue, bool currentDiveOnly) { - execute(new EditNotes(newValue, currentDiveOnly)); + return execute_edit(new EditNotes(newValue, currentDiveOnly)); } -void editMode(int index, int newValue, bool currentDiveOnly) +int editMode(int index, int newValue, bool currentDiveOnly) { - execute(new EditMode(index, newValue, currentDiveOnly)); + return execute_edit(new EditMode(index, newValue, currentDiveOnly)); } -void editSuit(const QString &newValue, bool currentDiveOnly) +int editSuit(const QString &newValue, bool currentDiveOnly) { - execute(new EditSuit(newValue, currentDiveOnly)); + return execute_edit(new EditSuit(newValue, currentDiveOnly)); } -void editRating(int newValue, bool currentDiveOnly) +int editRating(int newValue, bool currentDiveOnly) { - execute(new EditRating(newValue, currentDiveOnly)); + return execute_edit(new EditRating(newValue, currentDiveOnly)); } -void editVisibility(int newValue, bool currentDiveOnly) +int editVisibility(int newValue, bool currentDiveOnly) { - execute(new EditVisibility(newValue, currentDiveOnly)); + return execute_edit(new EditVisibility(newValue, currentDiveOnly)); } -void editAirTemp(int newValue, bool currentDiveOnly) +int editAirTemp(int newValue, bool currentDiveOnly) { - execute(new EditAirTemp(newValue, currentDiveOnly)); + return execute_edit(new EditAirTemp(newValue, currentDiveOnly)); } -void editWaterTemp(int newValue, bool currentDiveOnly) +int editWaterTemp(int newValue, bool currentDiveOnly) { - execute(new EditWaterTemp(newValue, currentDiveOnly)); + return execute_edit(new EditWaterTemp(newValue, currentDiveOnly)); } -void editAtmPress(int newValue, bool currentDiveOnly) +int editAtmPress(int newValue, bool currentDiveOnly) { - execute(new EditAtmPress(newValue, currentDiveOnly)); + return execute_edit(new EditAtmPress(newValue, currentDiveOnly)); } -void editDepth(int newValue, bool currentDiveOnly) +int editDepth(int newValue, bool currentDiveOnly) { - execute(new EditDepth(newValue, currentDiveOnly)); + return execute_edit(new EditDepth(newValue, currentDiveOnly)); } -void editDuration(int newValue, bool currentDiveOnly) +int editDuration(int newValue, bool currentDiveOnly) { - execute(new EditDuration(newValue, currentDiveOnly)); + return execute_edit(new EditDuration(newValue, currentDiveOnly)); } -void editDiveSite(struct dive_site *newValue, bool currentDiveOnly) +int editDiveSite(struct dive_site *newValue, bool currentDiveOnly) { - execute(new EditDiveSite(newValue, currentDiveOnly)); + return execute_edit(new EditDiveSite(newValue, currentDiveOnly)); } -void editDiveSiteNew(const QString &newName, bool currentDiveOnly) +int editDiveSiteNew(const QString &newName, bool currentDiveOnly) { - execute(new EditDiveSiteNew(newName, currentDiveOnly)); + return execute_edit(new EditDiveSiteNew(newName, currentDiveOnly)); } -void editTags(const QStringList &newList, bool currentDiveOnly) +int editTags(const QStringList &newList, bool currentDiveOnly) { - execute(new EditTags(newList, currentDiveOnly)); + return execute_edit(new EditTags(newList, currentDiveOnly)); } -void editBuddies(const QStringList &newList, bool currentDiveOnly) +int editBuddies(const QStringList &newList, bool currentDiveOnly) { - execute(new EditBuddies(newList, currentDiveOnly)); + return execute_edit(new EditBuddies(newList, currentDiveOnly)); } -void editDiveMaster(const QStringList &newList, bool currentDiveOnly) +int editDiveMaster(const QStringList &newList, bool currentDiveOnly) { - execute(new EditDiveMaster(newList, currentDiveOnly)); + return execute_edit(new EditDiveMaster(newList, currentDiveOnly)); } void pasteDives(const dive *d, dive_components what) diff --git a/desktop-widgets/command.h b/desktop-widgets/command.h index 497c59a9a..6fbd6bab5 100644 --- a/desktop-widgets/command.h +++ b/desktop-widgets/command.h @@ -56,21 +56,21 @@ void purgeUnusedDiveSites(); // 4) Dive editing related commands -void editNotes(const QString &newValue, bool currentDiveOnly); -void editSuit(const QString &newValue, bool currentDiveOnly); -void editMode(int index, int newValue, bool currentDiveOnly); -void editRating(int newValue, bool currentDiveOnly); -void editVisibility(int newValue, bool currentDiveOnly); -void editAirTemp(int newValue, bool currentDiveOnly); -void editWaterTemp(int newValue, bool currentDiveOnly); -void editAtmPress(int newValue, bool currentDiveOnly); -void editDepth(int newValue, bool currentDiveOnly); -void editDuration(int newValue, bool currentDiveOnly); -void editDiveSite(struct dive_site *newValue, bool currentDiveOnly); -void editDiveSiteNew(const QString &newName, bool currentDiveOnly); -void editTags(const QStringList &newList, bool currentDiveOnly); -void editBuddies(const QStringList &newList, bool currentDiveOnly); -void editDiveMaster(const QStringList &newList, bool currentDiveOnly); +int editNotes(const QString &newValue, bool currentDiveOnly); +int editSuit(const QString &newValue, bool currentDiveOnly); +int editMode(int index, int newValue, bool currentDiveOnly); +int editRating(int newValue, bool currentDiveOnly); +int editVisibility(int newValue, bool currentDiveOnly); +int editAirTemp(int newValue, bool currentDiveOnly); +int editWaterTemp(int newValue, bool currentDiveOnly); +int editAtmPress(int newValue, bool currentDiveOnly); +int editDepth(int newValue, bool currentDiveOnly); +int editDuration(int newValue, bool currentDiveOnly); +int editDiveSite(struct dive_site *newValue, bool currentDiveOnly); +int editDiveSiteNew(const QString &newName, bool currentDiveOnly); +int editTags(const QStringList &newList, bool currentDiveOnly); +int editBuddies(const QStringList &newList, bool currentDiveOnly); +int editDiveMaster(const QStringList &newList, bool currentDiveOnly); void pasteDives(const dive *d, dive_components what); // 4) Trip editing commands diff --git a/desktop-widgets/command_base.h b/desktop-widgets/command_base.h index 26744dc87..cf8f248d2 100644 --- a/desktop-widgets/command_base.h +++ b/desktop-widgets/command_base.h @@ -166,9 +166,9 @@ public: virtual bool workToBeDone() = 0; }; -// Put a command on the undoStack, but test whether there is something to be done -// beforehand by calling the workToBeDone() function. If nothing is to be done, -// the command will be deleted. +// Put a command on the undoStack (and take ownership), but test whether there +// is something to be done beforehand by calling the workToBeDone() function. +// If nothing is to be done, the command will be deleted. void execute(Base *cmd); } // namespace Command diff --git a/desktop-widgets/command_edit.cpp b/desktop-widgets/command_edit.cpp index ff0bd871a..2c9d56ba5 100644 --- a/desktop-widgets/command_edit.cpp +++ b/desktop-widgets/command_edit.cpp @@ -25,15 +25,25 @@ static std::vector getDives(bool currentDiveOnly) return res; } -template -EditBase::EditBase(T newValue, bool currentDiveOnly) : - value(std::move(newValue)), +EditDivesBase::EditDivesBase(bool currentDiveOnly) : dives(getDives(currentDiveOnly)), selectedDives(getDiveSelection()), current(current_dive) { } +int EditDivesBase::numDives() const +{ + return dives.size(); +} + +template +EditBase::EditBase(T newValue, bool currentDiveOnly) : + EditDivesBase(currentDiveOnly), + 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() @@ -439,9 +449,7 @@ DiveField EditMode::fieldId() const // ***** Tag based commands ***** EditTagsBase::EditTagsBase(const QStringList &newListIn, bool currentDiveOnly) : - dives(getDives(currentDiveOnly)), - selectedDives(getDiveSelection()), - current(current_dive), + EditDivesBase(currentDiveOnly), newList(newListIn) { } diff --git a/desktop-widgets/command_edit.h b/desktop-widgets/command_edit.h index a1050d65e..13f1e3bbf 100644 --- a/desktop-widgets/command_edit.h +++ b/desktop-widgets/command_edit.h @@ -23,8 +23,23 @@ // We put everything in a namespace, so that we can shorten names without polluting the global namespace namespace Command { +// Base class for commands that have a list of dives. +// This is used for extracting the number of dives and show a +// warning message when multiple dives are edited. +class EditDivesBase : public Base { +protected: + EditDivesBase(bool currentDiveOnly); + std::vector dives; // Dives to be edited. + + // On undo, we set the selection and current dive at the time of the operation. + std::vector selectedDives; + struct dive *current; +public: + int numDives() const; +}; + template -class EditBase : public Base { +class EditBase : public EditDivesBase { protected: T value; // Value to be set T old; // Previous value @@ -33,10 +48,6 @@ protected: void redo() override; bool workToBeDone() override; - std::vector dives; // Dives to be edited. - // On undo, we set the selection and current dive at the time of the operation. - std::vector selectedDives; - struct dive *current; public: EditBase(T newValue, bool currentDiveOnly); @@ -166,16 +177,9 @@ public: // 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. -class EditTagsBase : public Base { +class EditTagsBase : public EditDivesBase { bool workToBeDone() override; - // Dives to be edited. For historical reasons, the *last* entry was - // the active dive when the user initialized the action. This dive - // will be made the current dive on redo / undo. - std::vector dives; - // On undo, we set the selection and current dive at the time of the operation. - std::vector selectedDives; - struct dive *current; QStringList newList; // Temporary until initialized public: EditTagsBase(const QStringList &newList, bool currentDiveOnly); -- cgit v1.2.3-70-g09d2