diff options
author | Berthold Stoeger <bstoeger@mail.tuwien.ac.at> | 2019-11-03 15:04:48 +0100 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2019-12-05 10:14:25 -0800 |
commit | b3f530bfb9d099414d833e7b0eb8c71cb3780eca (patch) | |
tree | 879112df23e236e93e80cf4a726504fb7dccf09c | |
parent | b3253304a59b85c76f8a70f20ada4139e715a5b3 (diff) | |
download | subsurface-b3f530bfb9d099414d833e7b0eb8c71cb3780eca.tar.gz |
Undo: make weight-deletion an undoable action
This one is a bit more complicated than weight adding, because the
multiple-dive case is not well defined. If multiple dives are selected,
this implementation will search for weights that are identical to the
weight deleted in the currently shown dive. The position of the weight
in the list is ignored.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
-rw-r--r-- | commands/command.cpp | 5 | ||||
-rw-r--r-- | commands/command.h | 1 | ||||
-rw-r--r-- | commands/command_edit.cpp | 71 | ||||
-rw-r--r-- | commands/command_edit.h | 12 | ||||
-rw-r--r-- | core/equipment.c | 16 | ||||
-rw-r--r-- | core/equipment.h | 1 | ||||
-rw-r--r-- | desktop-widgets/tab-widgets/TabDiveEquipment.cpp | 10 | ||||
-rw-r--r-- | qt-models/weightmodel.cpp | 12 | ||||
-rw-r--r-- | qt-models/weightmodel.h | 1 |
9 files changed, 111 insertions, 18 deletions
diff --git a/commands/command.cpp b/commands/command.cpp index 8f3dcc703..9417eec0e 100644 --- a/commands/command.cpp +++ b/commands/command.cpp @@ -273,6 +273,11 @@ int addWeight(bool currentDiveOnly) return execute_edit(new AddWeight(currentDiveOnly)); } +int removeWeight(int index, bool currentDiveOnly) +{ + return execute_edit(new RemoveWeight(index, currentDiveOnly)); +} + // Trip editing related commands void editTripLocation(dive_trip *trip, const QString &s) { diff --git a/commands/command.h b/commands/command.h index 85a37534e..5c60ac316 100644 --- a/commands/command.h +++ b/commands/command.h @@ -82,6 +82,7 @@ void pasteDives(const dive *d, dive_components what); 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); // 5) Trip editing commands diff --git a/commands/command_edit.cpp b/commands/command_edit.cpp index 541eac61a..bfa02a55d 100644 --- a/commands/command_edit.cpp +++ b/commands/command_edit.cpp @@ -985,4 +985,75 @@ void AddWeight::redo() } } +static int find_weightsystem_index(const struct dive *d, weightsystem_t ws) +{ + for (int idx = 0; idx < d->weightsystems.nr; ++idx) { + if (same_weightsystem(d->weightsystems.weightsystems[idx], ws)) + return idx; + } + return -1; +} + +RemoveWeight::RemoveWeight(int index, bool currentDiveOnly) : + EditDivesBase(currentDiveOnly), + ws{ {0}, nullptr } +{ + // Get the old weightsystem, bail if index is invalid + if (!current || index < 0 || index >= current->weightsystems.nr) { + dives.clear(); + return; + } + ws = clone_weightsystem(current->weightsystems.weightsystems[index]); + + // Deleting a weightsystem from multiple dives is semantically ill-defined. + // What we will do is trying to delete the same weightsystem if it exists. + // For that purpose, we will determine the indices of the same weightsystem. + std::vector<dive *> divesNew; + divesNew.reserve(dives.size()); + indexes.reserve(dives.size()); + + for (dive *d: dives) { + if (d == current) { + divesNew.push_back(d); + indexes.push_back(index); + continue; + } + int idx = find_weightsystem_index(d, ws); + if (idx >= 0) { + divesNew.push_back(d); + indexes.push_back(idx); + } + } + dives = std::move(divesNew); + + //: remove the part in parentheses for %n = 1 + setText(tr("Remove weight (%n dive(s))", "", dives.size())); +} + +RemoveWeight::~RemoveWeight() +{ + free((void *)ws.description); +} + +bool RemoveWeight::workToBeDone() +{ + return !dives.empty(); +} + +void RemoveWeight::undo() +{ + for (size_t i = 0; i < dives.size(); ++i) { + add_to_weightsystem_table(&dives[i]->weightsystems, indexes[i], clone_weightsystem(ws)); + emit diveListNotifier.weightAdded(dives[i], indexes[i]); + } +} + +void RemoveWeight::redo() +{ + for (size_t i = 0; i < dives.size(); ++i) { + remove_weightsystem(dives[i], indexes[i]); + emit diveListNotifier.weightRemoved(dives[i], indexes[i]); + } +} + } // namespace Command diff --git a/commands/command_edit.h b/commands/command_edit.h index ecf745070..c23f06094 100644 --- a/commands/command_edit.h +++ b/commands/command_edit.h @@ -339,6 +339,18 @@ private: bool workToBeDone() override; }; +class RemoveWeight : public EditDivesBase { +public: + RemoveWeight(int index, bool currentDiveOnly); + ~RemoveWeight(); +private: + weightsystem_t ws; + std::vector<int> indexes; // An index for each dive in the dives vector. + void undo() override; + void redo() override; + bool workToBeDone() override; +}; + } // namespace Command #endif diff --git a/core/equipment.c b/core/equipment.c index 39505a39d..bd1a0b4e3 100644 --- a/core/equipment.c +++ b/core/equipment.c @@ -111,12 +111,24 @@ void add_weightsystem_description(const weightsystem_t *weightsystem) } } +weightsystem_t clone_weightsystem(weightsystem_t ws) +{ + weightsystem_t res = { ws.weight, copy_string(ws.description) }; + return res; +} + /* Add a clone of a weightsystem to the end of a weightsystem table. * Cloned in means that the description-string is copied. */ void add_cloned_weightsystem(struct weightsystem_table *t, weightsystem_t ws) { - weightsystem_t w_clone = { ws.weight, copy_string(ws.description) }; - add_to_weightsystem_table(t, t->nr, w_clone); + add_to_weightsystem_table(t, t->nr, clone_weightsystem(ws)); +} + +/* Add a clone of a weightsystem to the end of a weightsystem table. + * Cloned in means that the description-string is copied. */ +void add_cloned_weightsystem_at(struct weightsystem_table *t, weightsystem_t ws) +{ + add_to_weightsystem_table(t, t->nr, clone_weightsystem(ws)); } /* Add a clone of a cylinder to the end of a cylinder table. diff --git a/core/equipment.h b/core/equipment.h index 86e23f9f8..687e794a5 100644 --- a/core/equipment.h +++ b/core/equipment.h @@ -67,6 +67,7 @@ struct weightsystem_table { extern int cylinderuse_from_text(const char *text); extern void copy_weights(const struct weightsystem_table *s, struct weightsystem_table *d); +extern weightsystem_t clone_weightsystem(weightsystem_t ws); extern void copy_cylinder_types(const struct dive *s, struct dive *d); extern void add_cloned_weightsystem(struct weightsystem_table *t, weightsystem_t ws); extern cylinder_t *add_empty_cylinder(struct cylinder_table *t); diff --git a/desktop-widgets/tab-widgets/TabDiveEquipment.cpp b/desktop-widgets/tab-widgets/TabDiveEquipment.cpp index cb7182e02..4baca44b2 100644 --- a/desktop-widgets/tab-widgets/TabDiveEquipment.cpp +++ b/desktop-widgets/tab-widgets/TabDiveEquipment.cpp @@ -35,7 +35,6 @@ TabDiveEquipment::TabDiveEquipment(QWidget *parent) : TabBase(parent), connect(&diveListNotifier, &DiveListNotifier::divesChanged, this, &TabDiveEquipment::divesChanged); connect(ui.cylinders, &TableView::itemClicked, cylindersModel, &CylindersModel::remove); connect(ui.cylinders, &TableView::itemClicked, this, &TabDiveEquipment::editCylinderWidget); - connect(ui.weights, &TableView::itemClicked, weightModel, &WeightModel::remove); connect(ui.weights, &TableView::itemClicked, this, &TabDiveEquipment::editWeightWidget); // Current display of things on Gnome3 looks like shit, so @@ -177,10 +176,15 @@ void TabDiveEquipment::editCylinderWidget(const QModelIndex &index) void TabDiveEquipment::editWeightWidget(const QModelIndex &index) { - MainWindow::instance()->mainTab->enableEdition(); + if (!index.isValid()) + return; - if (index.isValid() && index.column() != WeightModel::REMOVE) + if (index.column() == WeightModel::REMOVE) { + divesEdited(Command::removeWeight(index.row(), false)); + } else { + MainWindow::instance()->mainTab->enableEdition(); ui.weights->edit(index); + } } // tricky little macro to edit all the selected dives diff --git a/qt-models/weightmodel.cpp b/qt-models/weightmodel.cpp index ceac7617c..ff0b5c87a 100644 --- a/qt-models/weightmodel.cpp +++ b/qt-models/weightmodel.cpp @@ -29,17 +29,6 @@ weightsystem_t *WeightModel::weightSystemAt(const QModelIndex &index) return &d->weightsystems.weightsystems[index.row()]; } -void WeightModel::remove(QModelIndex index) -{ - if (index.column() != REMOVE || !d) - return; - beginRemoveRows(QModelIndex(), index.row(), index.row()); - rows--; - remove_weightsystem(d, index.row()); - changed = true; - endRemoveRows(); -} - void WeightModel::clear() { updateDive(nullptr); @@ -96,7 +85,6 @@ void WeightModel::passInData(const QModelIndex &index, const QVariant &value) } } - bool WeightModel::setData(const QModelIndex &index, const QVariant &value, int role) { QString vString = value.toString(); diff --git a/qt-models/weightmodel.h b/qt-models/weightmodel.h index bb2c63778..a61217379 100644 --- a/qt-models/weightmodel.h +++ b/qt-models/weightmodel.h @@ -30,7 +30,6 @@ public: public slots: - void remove(QModelIndex index); void weightsystemsReset(const QVector<dive *> &dives); void weightAdded(dive *d, int pos); void weightRemoved(dive *d, int pos); |