Undo: make "move dive computer to front" undoable

Instead of the elegant solution that just modifies the dive,
keep two copies and add either the old or the new copy. This
is primitive, but it trivially keeps the dives in the right order.
The order might change on renumbering the dive computers.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2019-05-17 22:22:55 +02:00 committed by Dirk Hohndel
parent f0307abf50
commit eba6e76b96
7 changed files with 106 additions and 23 deletions

View file

@ -74,6 +74,11 @@ void splitDiveComputer(dive *d, int dc_num)
execute(new SplitDiveComputer(d, dc_num));
}
void moveDiveComputerToFront(dive *d, int dc_num)
{
execute(new MoveDiveComputerToFront(d, dc_num));
}
void mergeDives(const QVector <dive *> &dives)
{
execute(new MergeDives(dives));

View file

@ -36,6 +36,7 @@ void autogroupDives();
void mergeTrips(dive_trip *trip1, dive_trip *trip2);
void splitDives(dive *d, duration_t time);
void splitDiveComputer(dive *d, int dc_num);
void moveDiveComputerToFront(dive *d, int dc_num);
void mergeDives(const QVector <dive *> &dives);
// 3) Dive-site related commands

View file

@ -9,6 +9,7 @@
#include "core/qthelper.h"
#include "core/subsurface-qt/DiveListNotifier.h"
#include "qt-models/filtermodels.h"
#include "../profile-widget/profilewidget2.h"
#include <array>
@ -802,6 +803,57 @@ SplitDiveComputer::SplitDiveComputer(dive *d, int dc_num) : SplitDivesBase(d, sp
setText(tr("split dive computer"));
}
MoveDiveComputerToFront::MoveDiveComputerToFront(dive *d, int dc_num)
{
setText(tr("move dive computer to front"));
dive *new_dive = make_first_dc(d, dc_num);
if (!new_dive)
return;
diveToRemove.dives.push_back(d);
// Currently, the core code selects the dive -> this is not what we want, as
// we manually manage the selection post-command.
// TODO: Reset selection in core.
new_dive->selected = false;
// Reset references to trip and site in the new dive, as the undo command
// will add the dive to the trip and site.
new_dive->divetrip = nullptr;
new_dive->dive_site = nullptr;
diveToAdd.dives.resize(1);
diveToAdd.dives[0].dive.reset(new_dive);
diveToAdd.dives[0].trip = d->divetrip;
diveToAdd.dives[0].site = d->dive_site;
}
bool MoveDiveComputerToFront::workToBeDone()
{
return !diveToRemove.dives.empty() || !diveToAdd.dives.empty();
}
void MoveDiveComputerToFront::redoit()
{
DivesAndSitesToRemove addedDive = addDives(diveToAdd);
diveToAdd = removeDives(diveToRemove);
diveToRemove = std::move(addedDive);
// Select added dive and make it current
restoreSelection(diveToRemove.dives, diveToRemove.dives[0]);
// Update the profile to show the first dive computer
dc_number = 0;
MainWindow::instance()->graphics->replot(current_dive);
}
void MoveDiveComputerToFront::undoit()
{
// Undo and redo do the same
redoit();
}
MergeDives::MergeDives(const QVector <dive *> &dives)
{
setText(tr("merge dive"));

View file

@ -236,6 +236,23 @@ public:
SplitDiveComputer(dive *d, int dc_num);
};
// When moving the dive computer to the front, we go the ineffective,
// but easy way: We keep two full copies of the dive (before and after).
// Removing and readding assures that the dive stays at the correct
// position in the list (the dive computer list is used for sorting dives).
class MoveDiveComputerToFront : public DiveListBase {
public:
MoveDiveComputerToFront(dive *d, int dc_num);
private:
void undoit() override;
void redoit() override;
bool workToBeDone() override;
// For redo and undo
DivesAndTripsToAdd diveToAdd;
DivesAndSitesToRemove diveToRemove;
};
class MergeDives : public DiveListBase {
public:
MergeDives(const QVector<dive *> &dives);