From a94c84d5982a10cd9adfd421aed41cf159dd3303 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Fri, 2 Oct 2015 14:50:12 -0400 Subject: Undo/redo of dive deletion needs to handle trips as well If we delete dives that were part of a trip, that trip may get deleted as well. So if we undo that operation we need to bring back the trip, too. This also deals with a bug in the original code that did the delete both in calling code (in divelistview.cpp) and in the redo function. Because of the nature of the delete this didn't really matter but it is of course wrong and with the new code it would in fact cause an issue. Signed-off-by: Dirk Hohndel --- qt-ui/divelistview.cpp | 11 ++--------- qt-ui/undocommands.cpp | 42 ++++++++++++++++++++++++++++++++++++++---- qt-ui/undocommands.h | 1 + 3 files changed, 41 insertions(+), 13 deletions(-) (limited to 'qt-ui') diff --git a/qt-ui/divelistview.cpp b/qt-ui/divelistview.cpp index 51720a317..d2386ecf1 100644 --- a/qt-ui/divelistview.cpp +++ b/qt-ui/divelistview.cpp @@ -776,23 +776,16 @@ void DiveListView::deleteDive() if (!d) return; - //TODO: port this to C-code. int i; - // after a dive is deleted the ones following it move forward in the dive_table - // so instead of using the for_each_dive macro I'm using an explicit for loop - // to make this easier to understand int lastDiveNr = -1; QList deletedDives; //a list of all deleted dives to be stored in the undo command for_each_dive (i, d) { if (!d->selected) continue; - struct dive* undo_entry = alloc_dive(); - copy_dive(get_dive(i), undo_entry); - deletedDives.append(undo_entry); - delete_single_dive(i); - i--; // so the next dive isn't skipped... it's now #i + deletedDives.append(d); lastDiveNr = i; } + // the actual dive deletion is happening in the redo command that is implicitly triggered UndoDeleteDive *undoEntry = new UndoDeleteDive(deletedDives); MainWindow::instance()->undoStack->push(undoEntry); if (amount_selected == 0) { diff --git a/qt-ui/undocommands.cpp b/qt-ui/undocommands.cpp index d7bae75a9..dbfc77472 100644 --- a/qt-ui/undocommands.cpp +++ b/qt-ui/undocommands.cpp @@ -2,8 +2,7 @@ #include "mainwindow.h" #include "divelist.h" -UndoDeleteDive::UndoDeleteDive(QList deletedDives) - : diveList(deletedDives) +UndoDeleteDive::UndoDeleteDive(QList deletedDives) : diveList(deletedDives) { setText("delete dive"); if (diveList.count() > 1) @@ -12,8 +11,25 @@ UndoDeleteDive::UndoDeleteDive(QList deletedDives) void UndoDeleteDive::undo() { - for (int i = 0; i < diveList.count(); i++) + // first bring back the trip(s) + Q_FOREACH(struct dive_trip *trip, tripList) + insert_trip(&trip); + + // now walk the list of deleted dives + for (int i = 0; i < diveList.count(); i++) { + struct dive *d = diveList.at(i); + // we adjusted the divetrip to point to the "new" divetrip + if (d->divetrip) { + struct dive_trip *trip = d->divetrip; + tripflag_t tripflag = d->tripflag; // this gets overwritten in add_dive_to_trip() + d->divetrip = NULL; + d->next = NULL; + d->pprev = NULL; + add_dive_to_trip(d, trip); + d->tripflag = tripflag; + } record_dive(diveList.at(i)); + } mark_divelist_changed(true); MainWindow::instance()->refreshDisplay(); } @@ -22,10 +38,28 @@ void UndoDeleteDive::redo() { QList newList; for (int i = 0; i < diveList.count(); i++) { - //make a copy of the dive before deleting it + // make a copy of the dive before deleting it struct dive* d = alloc_dive(); copy_dive(diveList.at(i), d); newList.append(d); + // check for trip - if this is the last dive in the trip + // the trip will get deleted, so we need to remember it as well + if (d->divetrip && d->divetrip->nrdives == 1) { + struct dive_trip *undo_trip = (struct dive_trip *)calloc(1, sizeof(struct dive_trip)); + *undo_trip = *d->divetrip; + undo_trip->location = strdup(d->divetrip->location); + undo_trip->notes = strdup(d->divetrip->notes); + undo_trip->nrdives = 0; + undo_trip->next = NULL; + undo_trip->dives = NULL; + // update all the dives who were in this trip to point to the copy of the + // trip that we are about to delete implicitly when deleting its last dive below + Q_FOREACH(struct dive *inner_dive, newList) + if (inner_dive->divetrip == d->divetrip) + inner_dive->divetrip = undo_trip; + d->divetrip = undo_trip; + tripList.append(undo_trip); + } //delete the dive delete_single_dive(get_divenr(diveList.at(i))); } diff --git a/qt-ui/undocommands.h b/qt-ui/undocommands.h index 62fb2d22b..8e359db51 100644 --- a/qt-ui/undocommands.h +++ b/qt-ui/undocommands.h @@ -13,6 +13,7 @@ public: private: QList diveList; + QList tripList; }; class UndoShiftTime : public QUndoCommand { -- cgit v1.2.3-70-g09d2