From 1afd295c413dad73293aac580ee854ea90f8fbd3 Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Fri, 10 Aug 2018 08:02:02 -0400 Subject: Undo: use vectors for MergeDives and SplitDive The MergeDives and SplitDive commands used addDive() and removeDive() calls to manage their dives. Unfortunately, these calls don't send the proper signals and thus the dive-list was not updated. Instead, use one- and two-element vectors, which are passed to addDives() and removeDives() [note the plural]. Signed-off-by: Berthold Stoeger --- desktop-widgets/command_divelist.cpp | 55 ++++++++++++++++++++---------------- desktop-widgets/command_divelist.h | 24 ++++++++++------ 2 files changed, 46 insertions(+), 33 deletions(-) diff --git a/desktop-widgets/command_divelist.cpp b/desktop-widgets/command_divelist.cpp index 9cf61eff9..1cd1b4e25 100644 --- a/desktop-widgets/command_divelist.cpp +++ b/desktop-widgets/command_divelist.cpp @@ -717,14 +717,18 @@ SplitDives::SplitDives(dive *d, duration_t time) split_dive_dont_insert(d, &new1, &new2) : split_dive_at_time_dont_insert(d, time, &new1, &new2); - // If this didn't work, reset pointers as a mark that nothing is to be done. - if (idx < 0) { - diveToSplit = nullptr; - divesToUnsplit[0] = divesToUnsplit[1]; + // If this didn't work, simply return. Empty arrays indicate that nothing is to be done. + if (idx < 0) return; - } - diveToSplit = 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. + new1->selected = false; + new2->selected = false; + + diveToSplit.push_back(d); + splitDives.resize(2); splitDives[0].dive.reset(new1); splitDives[0].trip = d->divetrip; splitDives[0].idx = idx; @@ -735,39 +739,34 @@ SplitDives::SplitDives(dive *d, duration_t time) bool SplitDives::workToBeDone() { - return !!diveToSplit; + return !diveToSplit.empty(); } void SplitDives::redoit() { - divesToUnsplit[0] = addDive(splitDives[0]); - divesToUnsplit[1] = addDive(splitDives[1]); - unsplitDive = removeDive(diveToSplit); + divesToUnsplit = addDives(splitDives); + unsplitDive = removeDives(diveToSplit); mark_divelist_changed(true); // Select split dives and make first dive current - restoreSelection(std::vector{ divesToUnsplit[0], divesToUnsplit[1] }, divesToUnsplit[0]); + restoreSelection(divesToUnsplit, divesToUnsplit[0]); } void SplitDives::undoit() { // Note: reverse order with respect to redoit() - diveToSplit = addDive(unsplitDive); - splitDives[1] = removeDive(divesToUnsplit[1]); - splitDives[0] = removeDive(divesToUnsplit[0]); + diveToSplit = addDives(unsplitDive); + splitDives = removeDives(divesToUnsplit); mark_divelist_changed(true); // Select unsplit dive and make it current - restoreSelection(std::vector{ diveToSplit }, diveToSplit); + restoreSelection(diveToSplit, diveToSplit[0] ); } MergeDives::MergeDives(const QVector &dives) { setText(tr("merge dive")); - // We start in redo mode - diveToUnmerge = nullptr; - // Just a safety check - if there's not two or more dives - do nothing // The caller should have made sure that this doesn't happen. if (dives.count() < 2) { @@ -778,6 +777,11 @@ MergeDives::MergeDives(const QVector &dives) dive_trip *preferred_trip; OwningDivePtr d(merge_dives(dives[0], dives[1], dives[1]->when - dives[0]->when, false, &preferred_trip)); + // Currently, the core code selects the dive -> this is not what we want, as + // we manually manage the selection post-command. + // TODO: Remove selection code from core. + d->selected = false; + // Set the preferred dive trip, so that for subsequent merges the better trip can be selected d->divetrip = preferred_trip; for (int i = 2; i < dives.count(); ++i) { @@ -834,31 +838,32 @@ MergeDives::MergeDives(const QVector &dives) } } - mergedDive.dive = std::move(d); - mergedDive.idx = get_divenr(dives[0]); - mergedDive.trip = preferred_trip; + mergedDive.resize(1); + mergedDive[0].dive = std::move(d); + mergedDive[0].idx = get_divenr(dives[0]); + mergedDive[0].trip = preferred_trip; divesToMerge = dives.toStdVector(); } bool MergeDives::workToBeDone() { - return !!mergedDive.dive; + return !mergedDive.empty(); } void MergeDives::redoit() { renumberDives(divesToRenumber); - diveToUnmerge = addDive(mergedDive); + diveToUnmerge = addDives(mergedDive); unmergedDives = removeDives(divesToMerge); // Select merged dive and make it current - restoreSelection(std::vector{ diveToUnmerge }, diveToUnmerge); + restoreSelection(diveToUnmerge, diveToUnmerge[0]); } void MergeDives::undoit() { divesToMerge = addDives(unmergedDives); - mergedDive = removeDive(diveToUnmerge); + mergedDive = removeDives(diveToUnmerge); renumberDives(divesToRenumber); // Select unmerged dives and make first one current diff --git a/desktop-widgets/command_divelist.h b/desktop-widgets/command_divelist.h index 01dd4db77..650a64ba4 100644 --- a/desktop-widgets/command_divelist.h +++ b/desktop-widgets/command_divelist.h @@ -182,13 +182,17 @@ private: // For redo // For each dive to split, we remove one from and put two dives into the backend - dive *diveToSplit; - DiveToAdd splitDives[2]; + // Note: we use a vector even though we split only a single dive, so + // that we can reuse the multi-dive functions of the other commands. + std::vector diveToSplit; + std::vector splitDives; // For undo // For each dive to unsplit, we remove two dives from and add one into the backend - DiveToAdd unsplitDive; - dive *divesToUnsplit[2]; + // Note: we use a vector even though we unsplit only a single dive, so + // that we can reuse the multi-dive functions of the other commands. + std::vector unsplitDive; + std::vector divesToUnsplit; }; class MergeDives : public DiveListBase { @@ -201,13 +205,17 @@ private: // For redo // Add one and remove a batch of dives - DiveToAdd mergedDive; - std::vector divesToMerge; + // Note: we use a vector even though we add only a single dive, so + // that we can reuse the multi-dive functions of the other commands. + std::vector mergedDive; + std::vector divesToMerge; // For undo // Remove one and add a batch of dives - dive *diveToUnmerge; - std::vector unmergedDives; + // Note: we use a vector even though we remove only a single dive, so + // that we can reuse the multi-dive functions of the other commands. + std::vector diveToUnmerge; + std::vector unmergedDives; // For undo and redo QVector> divesToRenumber; -- cgit v1.2.3-70-g09d2