Undo: make "delete dive computer" undoable

Simply reuse the code for "move dive computer" by creating
a DiveComputerBase base class.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2019-05-19 14:27:10 +02:00 committed by Dirk Hohndel
parent eba6e76b96
commit 0bc96905bf
7 changed files with 60 additions and 25 deletions

View file

@ -4234,10 +4234,22 @@ static void delete_divecomputer(struct dive *d, int num)
invalidate_dive_cache(d); invalidate_dive_cache(d);
} }
/* always acts on the current dive */ /* Clone a dive and delete goven dive computer */
void delete_current_divecomputer(void) struct dive *clone_delete_divecomputer(const struct dive *d, int dc_number)
{ {
delete_divecomputer(current_dive, dc_number); struct dive *res;
/* copy the dive */
res = alloc_dive();
copy_dive(d, res);
/* make a new unique id, since we still can't handle two equal ids */
res->id = dive_getUniqID();
invalidate_dive_cache(res);
delete_divecomputer(res, dc_number);
return res;
} }
/* /*

View file

@ -436,7 +436,7 @@ extern timestamp_t dive_endtime(const struct dive *dive);
extern struct dive *make_first_dc(const struct dive *d, int dc_number); extern struct dive *make_first_dc(const struct dive *d, int dc_number);
extern unsigned int count_divecomputers(void); extern unsigned int count_divecomputers(void);
extern void delete_current_divecomputer(void); extern struct dive *clone_delete_divecomputer(const struct dive *d, int dc_number);
void split_divecomputer(const struct dive *src, int num, struct dive **out1, struct dive **out2); void split_divecomputer(const struct dive *src, int num, struct dive **out1, struct dive **out2);
/* /*

View file

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

View file

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

View file

@ -803,15 +803,12 @@ SplitDiveComputer::SplitDiveComputer(dive *d, int dc_num) : SplitDivesBase(d, sp
setText(tr("split dive computer")); setText(tr("split dive computer"));
} }
MoveDiveComputerToFront::MoveDiveComputerToFront(dive *d, int dc_num) DiveComputerBase::DiveComputerBase(dive *old_dive, dive *new_dive)
{ {
setText(tr("move dive computer to front"));
dive *new_dive = make_first_dc(d, dc_num);
if (!new_dive) if (!new_dive)
return; return;
diveToRemove.dives.push_back(d); diveToRemove.dives.push_back(old_dive);
// Currently, the core code selects the dive -> this is not what we want, as // Currently, the core code selects the dive -> this is not what we want, as
// we manually manage the selection post-command. // we manually manage the selection post-command.
@ -825,16 +822,16 @@ MoveDiveComputerToFront::MoveDiveComputerToFront(dive *d, int dc_num)
diveToAdd.dives.resize(1); diveToAdd.dives.resize(1);
diveToAdd.dives[0].dive.reset(new_dive); diveToAdd.dives[0].dive.reset(new_dive);
diveToAdd.dives[0].trip = d->divetrip; diveToAdd.dives[0].trip = old_dive->divetrip;
diveToAdd.dives[0].site = d->dive_site; diveToAdd.dives[0].site = old_dive->dive_site;
} }
bool MoveDiveComputerToFront::workToBeDone() bool DiveComputerBase::workToBeDone()
{ {
return !diveToRemove.dives.empty() || !diveToAdd.dives.empty(); return !diveToRemove.dives.empty() || !diveToAdd.dives.empty();
} }
void MoveDiveComputerToFront::redoit() void DiveComputerBase::redoit()
{ {
DivesAndSitesToRemove addedDive = addDives(diveToAdd); DivesAndSitesToRemove addedDive = addDives(diveToAdd);
diveToAdd = removeDives(diveToRemove); diveToAdd = removeDives(diveToRemove);
@ -848,12 +845,24 @@ void MoveDiveComputerToFront::redoit()
MainWindow::instance()->graphics->replot(current_dive); MainWindow::instance()->graphics->replot(current_dive);
} }
void MoveDiveComputerToFront::undoit() void DiveComputerBase::undoit()
{ {
// Undo and redo do the same // Undo and redo do the same
redoit(); redoit();
} }
MoveDiveComputerToFront::MoveDiveComputerToFront(dive *d, int dc_num)
: DiveComputerBase(d, make_first_dc(d, dc_num))
{
setText(tr("move dive computer to front"));
}
DeleteDiveComputer::DeleteDiveComputer(dive *d, int dc_num)
: DiveComputerBase(d, clone_delete_divecomputer(d, dc_num))
{
setText(tr("delete dive computer"));
}
MergeDives::MergeDives(const QVector <dive *> &dives) MergeDives::MergeDives(const QVector <dive *> &dives)
{ {
setText(tr("merge dive")); setText(tr("merge dive"));

View file

@ -236,23 +236,36 @@ public:
SplitDiveComputer(dive *d, int dc_num); SplitDiveComputer(dive *d, int dc_num);
}; };
// When moving the dive computer to the front, we go the ineffective, // When manipulating dive computers (moving, deleting) we go the ineffective,
// but easy way: We keep two full copies of the dive (before and after). // but simple and robust way: We keep two full copies of the dive (before and after).
// Removing and readding assures that the dive stays at the correct // Removing and readding assures that the dive stays at the correct
// position in the list (the dive computer list is used for sorting dives). // position in the list (the dive computer list is used for sorting dives).
class MoveDiveComputerToFront : public DiveListBase { class DiveComputerBase : public DiveListBase {
public: protected:
MoveDiveComputerToFront(dive *d, int dc_num); // old_dive must be a dive known to the core.
// new_dive must be new dive whose ownership is taken.
DiveComputerBase(dive *old_dive, dive *new_dive);
private: private:
void undoit() override; void undoit() override;
void redoit() override; void redoit() override;
bool workToBeDone() override; bool workToBeDone() override;
protected:
// For redo and undo // For redo and undo
DivesAndTripsToAdd diveToAdd; DivesAndTripsToAdd diveToAdd;
DivesAndSitesToRemove diveToRemove; DivesAndSitesToRemove diveToRemove;
}; };
class MoveDiveComputerToFront : public DiveComputerBase {
public:
MoveDiveComputerToFront(dive *d, int dc_num);
};
class DeleteDiveComputer : public DiveComputerBase {
public:
DeleteDiveComputer(dive *d, int dc_num);
};
class MergeDives : public DiveListBase { class MergeDives : public DiveListBase {
public: public:
MergeDives(const QVector<dive *> &dives); MergeDives(const QVector<dive *> &dives);

View file

@ -1575,12 +1575,7 @@ void ProfileWidget2::contextMenuEvent(QContextMenuEvent *event)
void ProfileWidget2::deleteCurrentDC() void ProfileWidget2::deleteCurrentDC()
{ {
delete_current_divecomputer(); Command::deleteDiveComputer(current_dive, dc_number);
mark_divelist_changed(true);
// we need to force it since it's likely the same dive and same dc_number - but that's a different dive computer now
plotDive(0, true, false);
emit refreshDisplay(true);
} }
void ProfileWidget2::splitCurrentDC() void ProfileWidget2::splitCurrentDC()