Undo: implement ReplanDive command

Implement an undo command that overwrites the dive-computers and
cylinders of the current dive with a given dive. This will be used
when replanning a dive.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2019-10-06 20:54:25 +02:00 committed by Dirk Hohndel
parent 6a6b992a77
commit 7b730602c6
4 changed files with 96 additions and 1 deletions

View file

@ -238,6 +238,11 @@ void pasteDives(const dive *d, dive_components what)
execute(new PasteDives(d, what));
}
void replanDive(dive *d)
{
execute(new ReplanDive(d));
}
// Trip editing related commands
void editTripLocation(dive_trip *trip, const QString &s)
{

View file

@ -75,6 +75,7 @@ int editTags(const QStringList &newList, bool currentDiveOnly);
int editBuddies(const QStringList &newList, bool currentDiveOnly);
int editDiveMaster(const QStringList &newList, bool currentDiveOnly);
void pasteDives(const dive *d, dive_components what);
void replanDive(dive *d); // dive computer(s) and cylinder(s) will be reset!
// 5) Trip editing commands

View file

@ -837,4 +837,72 @@ void PasteDives::redo()
undo();
}
// ***** Paste *****
ReplanDive::ReplanDive(dive *source) : d(current_dive),
dc({ 0 }),
notes(nullptr)
{
memset(&cylinders[0], 0, sizeof(cylinders));
if (!d)
return;
when = source->when;
maxdepth = source->maxdepth;
meandepth = source->meandepth;
notes = copy_string(source->notes);
duration = source->duration;
salinity = source->salinity;
surface_pressure = source->surface_pressure;
// This resets the dive computers and cylinders of the source dive, avoiding deep copies.
std::swap(source->cylinder, cylinders);
std::swap(source->dc, dc);
setText(tr("Replan dive"));
}
ReplanDive::~ReplanDive()
{
for (cylinder_t &c: cylinders)
free((void *)c.type.description);
free_dive_dcs(&dc);
free(notes);
}
bool ReplanDive::workToBeDone()
{
return !!d;
}
void ReplanDive::undo()
{
std::swap(d->when, when);
std::swap(d->maxdepth, maxdepth);
std::swap(d->meandepth, meandepth);
std::swap(d->cylinder, cylinders);
std::swap(d->dc, dc);
std::swap(d->notes, notes);
std::swap(d->surface_pressure, surface_pressure);
std::swap(d->duration, duration);
std::swap(d->salinity, salinity);
fixup_dive(d);
QVector<dive *> divesToNotify = { d };
// TODO: Turn field into flags to avoid multiple signals
emit diveListNotifier.divesChanged(divesToNotify, DiveField::DATETIME);
emit diveListNotifier.divesChanged(divesToNotify, DiveField::DURATION);
emit diveListNotifier.divesChanged(divesToNotify, DiveField::DEPTH);
emit diveListNotifier.divesChanged(divesToNotify, DiveField::MODE);
emit diveListNotifier.divesChanged(divesToNotify, DiveField::NOTES);
emit diveListNotifier.divesChanged(divesToNotify, DiveField::SALINITY);
emit diveListNotifier.divesChanged(divesToNotify, DiveField::ATM_PRESS);
emit diveListNotifier.cylindersReset(divesToNotify);
}
// Redo and undo do the same
void ReplanDive::redo()
{
undo();
}
} // namespace Command

View file

@ -267,6 +267,27 @@ private:
bool workToBeDone() override;
};
class ReplanDive : public Base {
dive *d;
// Exchange these data with current dive
timestamp_t when;
depth_t maxdepth, meandepth;
cylinder_t cylinders[MAX_CYLINDERS];
struct divecomputer dc;
char *notes;
pressure_t surface_pressure;
duration_t duration;
int salinity;
public:
ReplanDive(dive *source); // Dive computer(s) and cylinders(s) of the source dive will be reset!
~ReplanDive();
private:
void undo() override;
void redo() override;
bool workToBeDone() override;
};
} // namespace Command
#endif