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>
This commit is contained in:
Berthold Stoeger 2019-11-03 15:04:48 +01:00 committed by Dirk Hohndel
parent b3253304a5
commit b3f530bfb9
9 changed files with 111 additions and 18 deletions

View file

@ -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)
{

View file

@ -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

View file

@ -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

View file

@ -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