diff options
author | Berthold Stoeger <bstoeger@mail.tuwien.ac.at> | 2019-02-14 23:07:12 +0100 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2019-04-12 18:19:07 +0300 |
commit | 5436f9b8590e6022ce2dabefb23ffb037020784a (patch) | |
tree | 7de4df5ccae63f2bf57e95138d06a4f33680c362 | |
parent | cddd5942f8accaa612d8e107b45c1bf3d47a5c95 (diff) | |
download | subsurface-5436f9b8590e6022ce2dabefb23ffb037020784a.tar.gz |
Undo: move dive-list logic into edit commands
The edit-commands were called with a list of selected dives and
the original value. Move the creation of the list and extraction
of the original value into the edit-commmands.
This removes the "current is last" rule and allows for more
flexibility.
Since the depth- and duration editing applies only to the current
dive and not all selected dives, add a parameter to the edit-commands
controlling whether only the current or all selected dives are edited.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
-rw-r--r-- | desktop-widgets/command.cpp | 56 | ||||
-rw-r--r-- | desktop-widgets/command.h | 28 | ||||
-rw-r--r-- | desktop-widgets/command_edit.cpp | 71 | ||||
-rw-r--r-- | desktop-widgets/command_edit.h | 16 | ||||
-rw-r--r-- | desktop-widgets/tab-widgets/maintab.cpp | 39 |
5 files changed, 112 insertions, 98 deletions
diff --git a/desktop-widgets/command.cpp b/desktop-widgets/command.cpp index 2f73477fe..0486b2bce 100644 --- a/desktop-widgets/command.cpp +++ b/desktop-widgets/command.cpp @@ -130,74 +130,74 @@ void purgeUnusedDiveSites() } // Dive editing related commands -void editNotes(const QVector<dive *> dives, const QString &newValue, const QString &oldValue) +void editNotes(const QString &newValue, bool currentDiveOnly) { - execute(new EditNotes(dives, newValue, oldValue)); + execute(new EditNotes(newValue, currentDiveOnly)); } -void editMode(const QVector<dive *> dives, int index, int newValue, int oldValue) +void editMode(int index, int newValue, bool currentDiveOnly) { - execute(new EditMode(dives, index, newValue, oldValue)); + execute(new EditMode(index, newValue, currentDiveOnly)); } -void editSuit(const QVector<dive *> dives, const QString &newValue, const QString &oldValue) +void editSuit(const QString &newValue, bool currentDiveOnly) { - execute(new EditSuit(dives, newValue, oldValue)); + execute(new EditSuit(newValue, currentDiveOnly)); } -void editRating(const QVector<dive *> dives, int newValue, int oldValue) +void editRating(int newValue, bool currentDiveOnly) { - execute(new EditRating(dives, newValue, oldValue)); + execute(new EditRating(newValue, currentDiveOnly)); } -void editVisibility(const QVector<dive *> dives, int newValue, int oldValue) +void editVisibility(int newValue, bool currentDiveOnly) { - execute(new EditVisibility(dives, newValue, oldValue)); + execute(new EditVisibility(newValue, currentDiveOnly)); } -void editAirTemp(const QVector<dive *> dives, int newValue, int oldValue) +void editAirTemp(int newValue, bool currentDiveOnly) { - execute(new EditAirTemp(dives, newValue, oldValue)); + execute(new EditAirTemp(newValue, currentDiveOnly)); } -void editWaterTemp(const QVector<dive *> dives, int newValue, int oldValue) +void editWaterTemp(int newValue, bool currentDiveOnly) { - execute(new EditWaterTemp(dives, newValue, oldValue)); + execute(new EditWaterTemp(newValue, currentDiveOnly)); } -void editDepth(const QVector<dive *> dives, int newValue, int oldValue) +void editDepth(int newValue, bool currentDiveOnly) { - execute(new EditDepth(dives, newValue, oldValue)); + execute(new EditDepth(newValue, currentDiveOnly)); } -void editDuration(const QVector<dive *> dives, int newValue, int oldValue) +void editDuration(int newValue, bool currentDiveOnly) { - execute(new EditDuration(dives, newValue, oldValue)); + execute(new EditDuration(newValue, currentDiveOnly)); } -void editDiveSite(const QVector<dive *> dives, struct dive_site *newValue, struct dive_site *oldValue) +void editDiveSite(struct dive_site *newValue, bool currentDiveOnly) { - execute(new EditDiveSite(dives, newValue, oldValue)); + execute(new EditDiveSite(newValue, currentDiveOnly)); } -void editDiveSiteNew(const QVector<dive *> dives, const QString &newName, struct dive_site *oldValue) +void editDiveSiteNew(const QString &newName, bool currentDiveOnly) { - execute(new EditDiveSiteNew(dives, newName, oldValue)); + execute(new EditDiveSiteNew(newName, currentDiveOnly)); } -void editTags(const QVector<dive *> &dives, const QStringList &newList, struct dive *d) +void editTags(const QStringList &newList, bool currentDiveOnly) { - execute(new EditTags(dives, newList, d)); + execute(new EditTags(newList, currentDiveOnly)); } -void editBuddies(const QVector<dive *> &dives, const QStringList &newList, struct dive *d) +void editBuddies(const QStringList &newList, bool currentDiveOnly) { - execute(new EditBuddies(dives, newList, d)); + execute(new EditBuddies(newList, currentDiveOnly)); } -void editDiveMaster(const QVector<dive *> &dives, const QStringList &newList, struct dive *d) +void editDiveMaster(const QStringList &newList, bool currentDiveOnly) { - execute(new EditDiveMaster(dives, newList, d)); + execute(new EditDiveMaster(newList, currentDiveOnly)); } } // namespace Command diff --git a/desktop-widgets/command.h b/desktop-widgets/command.h index 4754a6937..7667f3482 100644 --- a/desktop-widgets/command.h +++ b/desktop-widgets/command.h @@ -52,20 +52,20 @@ void purgeUnusedDiveSites(); // 4) Dive editing related commands -void editNotes(const QVector<dive *> dives, const QString &newValue, const QString &oldValue); -void editSuit(const QVector<dive *> dives, const QString &newValue, const QString &oldValue); -void editMode(const QVector<dive *> dives, int index, int newValue, int oldValue); -void editRating(const QVector<dive *> dives, int newValue, int oldValue); -void editVisibility(const QVector<dive *> dives, int newValue, int oldValue); -void editAirTemp(const QVector<dive *> dives, int newValue, int oldValue); -void editWaterTemp(const QVector<dive *> dives, int newValue, int oldValue); -void editDepth(const QVector<dive *> dives, int newValue, int oldValue); -void editDuration(const QVector<dive *> dives, int newValue, int oldValue); -void editDiveSite(const QVector<dive *> dives, struct dive_site *newValue, struct dive_site *oldValue); -void editDiveSiteNew(const QVector<dive *> dives, const QString &newName, struct dive_site *oldValue); -void editTags(const QVector<dive *> &dives, const QStringList &newList, struct dive *d); -void editBuddies(const QVector<dive *> &dives, const QStringList &newList, struct dive *d); -void editDiveMaster(const QVector<dive *> &dives, const QStringList &newList, struct dive *d); +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 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); } // namespace Command diff --git a/desktop-widgets/command_edit.cpp b/desktop-widgets/command_edit.cpp index dd681e1d8..b8727bfb6 100644 --- a/desktop-widgets/command_edit.cpp +++ b/desktop-widgets/command_edit.cpp @@ -8,16 +8,28 @@ namespace Command { +static std::vector<dive *> getSelectedDives(bool currentDiveOnly) +{ + if (currentDiveOnly) + return current_dive ? std::vector<dive *> { current_dive } + : std::vector<dive *> { }; + + std::vector<dive *> res; + struct dive *d; + int i; + for_each_dive (i, d) { + if (d->selected) + res.push_back(d); + } + return res; +} + template<typename T> -EditBase<T>::EditBase(const QVector<dive *> &divesIn, T newValue, T oldValue) : +EditBase<T>::EditBase(T newValue, bool currentDiveOnly) : value(std::move(newValue)), - old(std::move(oldValue)), - dives(divesIn.toStdVector()) + dives(getSelectedDives(currentDiveOnly)), + current(current_dive) { - // If there is nothing to do, clear the dives vector. - // This signals that no action has to be taken. - if (old == value) - dives.clear(); } // This is quite hackish: we can't use virtual functions in the constructor and @@ -28,6 +40,16 @@ EditBase<T>::EditBase(const QVector<dive *> &divesIn, T newValue, T oldValue) : template<typename T> bool EditBase<T>::workToBeDone() { + // First, let's fetch the old value, i.e. the value of the current dive. + // If no current dive exists, bail. + if (!current) + return false; + old = data(current); + + // If there is no change - do nothing. + if (old == value) + return false; + std::vector<dive *> divesNew; divesNew.reserve(dives.size()); for (dive *d: dives) { @@ -42,7 +64,7 @@ bool EditBase<T>::workToBeDone() //: remove the part in parantheses for %n = 1 setText(tr("Edit %1 (%n dive(s))", "", num_dives).arg(fieldName())); - return num_dives; + return num_dives > 0; } template<typename T> @@ -74,11 +96,11 @@ void EditBase<T>::undo() // don't have their own constructor. They simply delegate to the base // class by virtue of a "using" declaration. template -EditBase<QString>::EditBase(const QVector<dive *> &dives, QString oldValue, QString newValue); +EditBase<QString>::EditBase(QString newValue, bool currentDiveOnly); template -EditBase<int>::EditBase(const QVector<dive *> &dives, int oldValue, int newValue); +EditBase<int>::EditBase(int newValue, bool currentDiveOnly); template -EditBase<struct dive_site *>::EditBase(const QVector<dive *> &dives, struct dive_site *oldValue, struct dive_site *newValue); +EditBase<struct dive_site *>::EditBase(struct dive_site *newValue, bool currentDiveOnly); // Undo and redo do the same as just the stored value is exchanged template<typename T> @@ -305,9 +327,10 @@ void EditDiveSite::redo() EditDiveSite::undo(); // Undo and redo do the same } -static struct dive_site *createDiveSite(const QString &name, struct dive_site *old) +static struct dive_site *createDiveSite(const QString &name) { struct dive_site *ds = alloc_dive_site(); + struct dive_site *old = current_dive ? current_dive->dive_site : nullptr; if (old) { copy_dive_site(old, ds); free(ds->name); // Free name, as we will overwrite it with our own version @@ -316,8 +339,8 @@ static struct dive_site *createDiveSite(const QString &name, struct dive_site *o return ds; } -EditDiveSiteNew::EditDiveSiteNew(const QVector<dive *> &dives, const QString &newName, struct dive_site *oldValue) : - EditDiveSite(dives, createDiveSite(newName, oldValue), oldValue), +EditDiveSiteNew::EditDiveSiteNew(const QString &newName, bool currentDiveOnly) : + EditDiveSite(createDiveSite(newName), currentDiveOnly), diveSiteToAdd(value), diveSiteToRemove(nullptr) { @@ -353,8 +376,8 @@ void EditDiveSiteNew::redo() // - Not derive EditMode from EditBase. // - Change the semantics of the mode-editing. // The future will tell. -EditMode::EditMode(const QVector<dive *> &dives, int indexIn, int newValue, int oldValue) - : EditBase(dives, newValue, oldValue), index(indexIn) +EditMode::EditMode(int indexIn, int newValue, bool currentDiveOnly) + : EditBase(newValue, currentDiveOnly), index(indexIn) { } @@ -380,10 +403,10 @@ DiveField EditMode::fieldId() const } // ***** Tag based commands ***** -EditTagsBase::EditTagsBase(const QVector<dive *> &divesIn, const QStringList &newListIn, struct dive *d): - dives(divesIn.toStdVector()), - newList(newListIn), - oldDive(d) +EditTagsBase::EditTagsBase(const QStringList &newListIn, bool currentDiveOnly) : + dives(getSelectedDives(currentDiveOnly)), + current(current_dive), + newList(newListIn) { } @@ -412,8 +435,12 @@ bool EditTagsBase::workToBeDone() // here's what I think... add the tags that were added to the displayed dive and remove the tags // that were removed from it + // If there is no current dive, bail. + if (!current) + return false; + // Calculate tags to add and tags to remove - QStringList oldList = data(oldDive); + QStringList oldList = data(current); for (const QString &s: newList) { if (!oldList.contains(s)) tagsToAdd.push_back(s); @@ -441,7 +468,7 @@ bool EditTagsBase::workToBeDone() //: remove the part in parantheses for %n = 1 setText(tr("Edit %1 (%n dive(s))", "", num_dives).arg(fieldName())); - return num_dives; + return num_dives != 0; } void EditTagsBase::undo() diff --git a/desktop-widgets/command_edit.h b/desktop-widgets/command_edit.h index 081ea11bb..4363cb9bd 100644 --- a/desktop-widgets/command_edit.h +++ b/desktop-widgets/command_edit.h @@ -33,12 +33,10 @@ protected: void redo() override; 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<dive *> dives; + std::vector<dive *> dives; // Dives to be edited. + struct dive *current; // On undo, we set the current dive at the time of the operation. public: - EditBase(const QVector<dive *> &dives, T newValue, T oldValue); + EditBase(T newValue, bool currentDiveOnly); protected: // Get and set functions to be overriden by sub-classes. @@ -139,7 +137,7 @@ class EditDiveSiteNew : public EditDiveSite { public: OwningDiveSitePtr diveSiteToAdd; struct dive_site *diveSiteToRemove; - EditDiveSiteNew(const QVector<dive *> &dives, const QString &newName, struct dive_site *oldValue); + EditDiveSiteNew(const QString &newName, bool currentDiveOnly); void undo() override; void redo() override; }; @@ -147,7 +145,7 @@ public: class EditMode : public EditBase<int> { int index; public: - EditMode(const QVector<dive *> &dives, int indexIn, int newValue, int oldValue); + EditMode(int indexIn, int newValue, bool currentDiveOnly); void set(struct dive *d, int i) const override; int data(struct dive *d) const override; QString fieldName() const override; @@ -164,10 +162,10 @@ class EditTagsBase : public Base { // the active dive when the user initialized the action. This dive // will be made the current dive on redo / undo. std::vector<dive *> dives; + struct dive *current; QStringList newList; // Temporary until initialized - struct dive *oldDive; // Temporary until initialized public: - EditTagsBase(const QVector<dive *> &dives, const QStringList &newList, struct dive *d); + EditTagsBase(const QStringList &newList, bool currentDiveOnly); protected: QStringList tagsToAdd; diff --git a/desktop-widgets/tab-widgets/maintab.cpp b/desktop-widgets/tab-widgets/maintab.cpp index 31fe4d130..19b096f0f 100644 --- a/desktop-widgets/tab-widgets/maintab.cpp +++ b/desktop-widgets/tab-widgets/maintab.cpp @@ -737,13 +737,6 @@ static QVector<dive *> getSelectedDivesCurrentLast() return res; } -// When editing depth and duration, we only edit a single dive. Therefore, return the current dive as a list -static QVector<dive *> getCurrentAsList() -{ - return current_dive ? QVector<dive *> { current_dive } - : QVector<dive *> { }; -} - void MainTab::acceptChanges() { int i, addedId = -1; @@ -1016,7 +1009,7 @@ void MainTab::on_buddy_editingFinished() if (editMode == IGNORE || !current_dive) return; - Command::editBuddies(getSelectedDivesCurrentLast(), stringToList(ui.buddy->toPlainText()), current_dive); + Command::editBuddies(stringToList(ui.buddy->toPlainText()), false); } void MainTab::on_divemaster_editingFinished() @@ -1024,7 +1017,7 @@ void MainTab::on_divemaster_editingFinished() if (editMode == IGNORE || !current_dive) return; - Command::editDiveMaster(getSelectedDivesCurrentLast(), stringToList(ui.divemaster->toPlainText()), current_dive); + Command::editDiveMaster(stringToList(ui.divemaster->toPlainText()), false); } void MainTab::on_duration_editingFinished() @@ -1033,7 +1026,7 @@ void MainTab::on_duration_editingFinished() return; // Duration editing is special: we only edit the current dive. - Command::editDuration(getCurrentAsList(), parseDurationToSeconds(ui.duration->text()), displayed_dive.dc.duration.seconds); + Command::editDuration(parseDurationToSeconds(ui.duration->text()), true); } void MainTab::on_depth_editingFinished() @@ -1042,32 +1035,28 @@ void MainTab::on_depth_editingFinished() return; // Depth editing is special: we only edit the current dive. - Command::editDepth(getCurrentAsList(), parseLengthToMm(ui.depth->text()), current_dive->dc.maxdepth.mm); + Command::editDepth(parseLengthToMm(ui.depth->text()), true); } void MainTab::on_airtemp_editingFinished() { if (editMode == IGNORE || !current_dive) return; - Command::editAirTemp(getSelectedDivesCurrentLast(), - parseTemperatureToMkelvin(ui.airtemp->text()), current_dive->airtemp.mkelvin); + Command::editAirTemp(parseTemperatureToMkelvin(ui.airtemp->text()), false); } void MainTab::divetype_Changed(int index) { if (editMode == IGNORE || !current_dive) return; - Command::editMode(getSelectedDivesCurrentLast(), dc_number, (enum divemode_t)index, - get_dive_dc(current_dive, dc_number)->divemode); + Command::editMode(dc_number, (enum divemode_t)index, false); } void MainTab::on_watertemp_editingFinished() { if (editMode == IGNORE || !current_dive) return; - Command::editWaterTemp(getSelectedDivesCurrentLast(), - parseTemperatureToMkelvin(ui.watertemp->text()), - current_dive->watertemp.mkelvin); + Command::editWaterTemp(parseTemperatureToMkelvin(ui.watertemp->text()), false); } // Editing of the dive time is different. If multiple dives are edited, @@ -1182,7 +1171,7 @@ void MainTab::on_tagWidget_editingFinished() if (editMode == IGNORE || !current_dive) return; - Command::editTags(getSelectedDivesCurrentLast(), ui.tagWidget->getBlockStringList(), current_dive); + Command::editTags(ui.tagWidget->getBlockStringList(), false); } void MainTab::on_location_diveSiteSelected() @@ -1192,9 +1181,9 @@ void MainTab::on_location_diveSiteSelected() struct dive_site *newDs = ui.location->currDiveSite(); if (newDs == RECENTLY_ADDED_DIVESITE) - Command::editDiveSiteNew(getSelectedDivesCurrentLast(), ui.location->text(), current_dive->dive_site); + Command::editDiveSiteNew(ui.location->text(), false); else - Command::editDiveSite(getSelectedDivesCurrentLast(), newDs, current_dive->dive_site); + Command::editDiveSite(newDs, false); } void MainTab::on_diveTripLocation_textEdited(const QString& text) @@ -1211,7 +1200,7 @@ void MainTab::on_suit_editingFinished() if (editMode == IGNORE || !current_dive) return; - Command::editSuit(getSelectedDivesCurrentLast(), ui.suit->text(), QString(current_dive->suit)); + Command::editSuit(ui.suit->text(), false); } void MainTab::on_notes_textChanged() @@ -1235,7 +1224,7 @@ void MainTab::on_notes_editingFinished() QString notes = ui.notes->toHtml().indexOf("<div") != -1 ? ui.notes->toHtml() : ui.notes->toPlainText(); - Command::editNotes(getSelectedDivesCurrentLast(), notes, QString(current_dive->notes)); + Command::editNotes(notes, false); } void MainTab::on_rating_valueChanged(int value) @@ -1243,7 +1232,7 @@ void MainTab::on_rating_valueChanged(int value) if (editMode == IGNORE || !current_dive) return; - Command::editRating(getSelectedDivesCurrentLast(), value, current_dive->rating); + Command::editRating(value, false); } void MainTab::on_visibility_valueChanged(int value) @@ -1251,7 +1240,7 @@ void MainTab::on_visibility_valueChanged(int value) if (editMode == IGNORE || !current_dive) return; - Command::editVisibility(getSelectedDivesCurrentLast(), value, current_dive->visibility); + Command::editVisibility(value, false); } #undef MODIFY_DIVES |