From 0212b1b9f7734c2ee4edaf7e27a2c25601b5c4bc Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Thu, 5 Mar 2020 09:00:00 -0800 Subject: [PATCH] undo infrastructure: improve undo command texts For many of the commands it is fairly easy to add information that makes it easier to figure out what actually happened. That's especially true for commands operating on dives. Trip and dive site edits haven't been given these more elaborate undo texts (yet). Signed-off-by: Dirk Hohndel --- commands/command_base.cpp | 32 ++++++++++++++++++++++++++++++++ commands/command_base.h | 5 +++++ commands/command_divelist.cpp | 14 +++++++++----- commands/command_edit.cpp | 32 +++++++++++++++++--------------- 4 files changed, 63 insertions(+), 20 deletions(-) diff --git a/commands/command_base.cpp b/commands/command_base.cpp index d13daf269..8ebbf9be5 100644 --- a/commands/command_base.cpp +++ b/commands/command_base.cpp @@ -3,6 +3,7 @@ #include "command_base.h" #include "core/qthelper.h" // for updateWindowTitle() #include "core/subsurface-qt/divelistnotifier.h" +#include namespace Command { @@ -49,6 +50,37 @@ QAction *redoAction(QObject *parent) return undoStack.createRedoAction(parent, QCoreApplication::translate("Command", "&Redo")); } +QString diveNumberOrDate(struct dive *d) +{ + if (d->number != 0) + return QStringLiteral("#%1").arg(d->number); + else + return QStringLiteral("@%1").arg(get_short_dive_date_string(d->when)); +} + +QString getListOfDives(const std::vector &dives) +{ + QString listOfDives; + if ((int)dives.size() == dive_table.nr) + return Base::tr("all dives"); + int i = 0; + for (dive *d: dives) { + // we show a maximum of five dive numbers, or 4 plus ellipsis + if (++i == 4 && dives.size() >= 5) + return listOfDives + "..."; + listOfDives += diveNumberOrDate(d) + ", "; + } + if (!listOfDives.isEmpty()) + listOfDives.truncate(listOfDives.length() - 2); + return listOfDives; +} + +QString getListOfDives(QVector dives) +{ + return getListOfDives(std::vector(dives.begin(), dives.end())); +} + + // return a string that can be used for the commit message and should list the changes that // were made to the dive list QString changesMade() diff --git a/commands/command_base.h b/commands/command_base.h index 59c3cd412..ffc6c4e91 100644 --- a/commands/command_base.h +++ b/commands/command_base.h @@ -172,7 +172,12 @@ public: // If nothing is to be done, the command will be deleted and false is returned. bool execute(Base *cmd); +// helper function to create more meaningful undo/redo texts (and get the list +// of those texts for the git storage commit message) QUndoStack *getUndoStack(); +QString diveNumberOrDate(struct dive *d); +QString getListOfDives(const std::vector &dives); +QString getListOfDives(QVector dives); } // namespace Command diff --git a/commands/command_divelist.cpp b/commands/command_divelist.cpp index 28857c8fa..93689d44a 100644 --- a/commands/command_divelist.cpp +++ b/commands/command_divelist.cpp @@ -546,7 +546,7 @@ void ImportDives::undoit() DeleteDive::DeleteDive(const QVector &divesToDeleteIn) { divesToDelete.dives = std::vector(divesToDeleteIn.begin(), divesToDeleteIn.end()); - setText(tr("delete %n dive(s)", "", divesToDelete.dives.size())); + setText(QStringLiteral("%1 [%2]").arg(tr("delete %n dive(s)", "", divesToDelete.dives.size())).arg(getListOfDives(divesToDelete.dives))); } bool DeleteDive::workToBeDone() @@ -582,7 +582,7 @@ void DeleteDive::redoit() ShiftTime::ShiftTime(std::vector changedDives, int amount) : diveList(changedDives), timeChanged(amount) { - setText(tr("shift time of %n dives", "", changedDives.size())); + setText(QStringLiteral("%1 [%2]").arg(tr("shift time of %n dives", "", changedDives.size())).arg(getListOfDives(changedDives))); } void ShiftTime::redoit() @@ -626,7 +626,11 @@ void ShiftTime::undoit() RenumberDives::RenumberDives(const QVector> &divesToRenumberIn) : divesToRenumber(divesToRenumberIn) { - setText(tr("renumber %n dive(s)", "", divesToRenumber.count())); + std::vector dives; + dives.reserve(divesToRenumber.length()); + for (QPairdivePlusNumber: divesToRenumber) + dives.push_back(divePlusNumber.first); + setText(QStringLiteral("%1 [%2]").arg(tr("renumber %n dive(s)", "", divesToRenumber.count())).arg(getListOfDives(dives))); } void RenumberDives::undoit() @@ -678,7 +682,7 @@ void TripBase::undoit() RemoveDivesFromTrip::RemoveDivesFromTrip(const QVector &divesToRemove) { - setText(tr("remove %n dive(s) from trip", "", divesToRemove.size())); + setText(QStringLiteral("%1 [%2]").arg(tr("remove %n dive(s) from trip", "", divesToRemove.size())).arg(getListOfDives(divesToRemove))); divesToMove.divesToMove.reserve(divesToRemove.size()); for (dive *d: divesToRemove) { // If a user manually removes a dive from a trip, don't autogroup this dive. @@ -702,7 +706,7 @@ RemoveAutogenTrips::RemoveAutogenTrips() AddDivesToTrip::AddDivesToTrip(const QVector &divesToAddIn, dive_trip *trip) { - setText(tr("add %n dives to trip", "", divesToAddIn.size())); + setText(QStringLiteral("%1 [%2]").arg(tr("add %n dives to trip", "", divesToAddIn.size())).arg(getListOfDives(divesToAddIn))); for (dive *d: divesToAddIn) divesToMove.divesToMove.push_back( {d, trip} ); } diff --git a/commands/command_edit.cpp b/commands/command_edit.cpp index e08f678e7..753c67891 100644 --- a/commands/command_edit.cpp +++ b/commands/command_edit.cpp @@ -91,9 +91,9 @@ bool EditBase::workToBeDone() // Create a text for the menu entry. In the case of multiple dives add the number size_t num_dives = dives.size(); if (num_dives == 1) - setText(tr("Edit %1").arg(fieldName())); + setText(QStringLiteral("%1 [%2]").arg(tr("Edit %1").arg(fieldName())).arg(diveNumberOrDate(dives[0]))); else if (num_dives > 0) - setText(tr("Edit %1 (%n dive(s))", "", num_dives).arg(fieldName())); + setText(QStringLiteral("%1 [%2]").arg(tr("Edit %1 (%n dive(s))", "", num_dives).arg(fieldName())).arg(getListOfDives(dives))); return num_dives > 0; } @@ -656,9 +656,9 @@ bool EditTagsBase::workToBeDone() // Create a text for the menu entry. In the case of multiple dives add the number size_t num_dives = dives.size(); if (num_dives == 1) - setText(tr("Edit %1").arg(fieldName())); + setText(QStringLiteral("%1 [%2]").arg(tr("Edit %1").arg(fieldName())).arg(diveNumberOrDate(dives[0]))); else if (num_dives > 0) - setText(tr("Edit %1 (%n dive(s))", "", num_dives).arg(fieldName())); + setText(QStringLiteral("%1 [%2]").arg(tr("Edit %1 (%n dive(s))", "", num_dives).arg(fieldName())).arg(getListOfDives(dives))); return num_dives != 0; } @@ -865,7 +865,7 @@ PasteDives::PasteDives(const dive *data, dive_components whatIn) : what(whatIn) for (dive *d: selection) dives.emplace_back(d, data, what); - setText(tr("Paste onto %n dive(s)", "", dives.size())); + setText(QStringLiteral("%1 [%2]").arg(tr("Paste onto %n dive(s)", "", dives.size())).arg(getListOfDives(selection))); } bool PasteDives::workToBeDone() @@ -941,7 +941,7 @@ ReplanDive::ReplanDive(dive *source, bool edit_profile) : d(current_dive), std::swap(source->cylinders, cylinders); std::swap(source->dc, dc); - setText(edit_profile ? tr("Replan dive") : tr("Edit profile")); + setText((edit_profile ? tr("Replan dive") : tr("Edit profile")) + diveNumberOrDate(d)); } ReplanDive::~ReplanDive() @@ -988,9 +988,9 @@ AddWeight::AddWeight(bool currentDiveOnly) : EditDivesBase(currentDiveOnly) { if (dives.size() == 1) - setText(tr("Add weight")); + setText(QStringLiteral("%1 [%2]").arg(tr("Add weight")).arg(diveNumberOrDate(dives[0]))); else - setText(tr("Add weight (%n dive(s))", "", dives.size())); + setText(QStringLiteral("%1 [%2]").arg(tr("Add weight (%n dive(s))", "", dives.size())).arg(getListOfDives(dives))); } bool AddWeight::workToBeDone() @@ -1071,10 +1071,11 @@ bool EditWeightBase::workToBeDone() RemoveWeight::RemoveWeight(int index, bool currentDiveOnly) : EditWeightBase(index, currentDiveOnly) { - if (dives.size() == 1) - setText(tr("Remove weight")); + size_t num_dives = dives.size(); + if (num_dives == 1) + setText(QStringLiteral("%1 [%2]").arg(tr("Remove weight")).arg(diveNumberOrDate(dives[0]))); else - setText(tr("Remove weight (%n dive(s))", "", dives.size())); + setText(QStringLiteral("%1 [%2]").arg(tr("Remove weight (%n dive(s))", "", num_dives)).arg(getListOfDives(dives))); } void RemoveWeight::undo() @@ -1100,10 +1101,11 @@ EditWeight::EditWeight(int index, weightsystem_t wsIn, bool currentDiveOnly) : if (dives.empty()) return; - if (dives.size() == 1) - setText(tr("Edit weight")); + size_t num_dives = dives.size(); + if (num_dives == 1) + setText(QStringLiteral("%1 [%2]").arg(tr("Edit weight")).arg(diveNumberOrDate(dives[0]))); else - setText(tr("Edit weight (%n dive(s))", "", dives.size())); + setText(QStringLiteral("%1 [%2]").arg(tr("Edit weight (%n dive(s))", "", num_dives)).arg(getListOfDives(dives))); // Try to untranslate the weightsystem name new_ws = clone_weightsystem(wsIn); @@ -1162,7 +1164,7 @@ EditDive::EditDive(dive *oldDiveIn, dive *newDiveIn, dive_site *createDs, dive_s if (!oldDive || ! newDive) return; - setText(tr("Edit dive")); + setText(tr("Edit dive [%1]").arg(diveNumberOrDate(oldDive))); // Calculate the fields that changed. // Note: Probably not needed, as on mobile we don't have that granularity.