aboutsummaryrefslogtreecommitdiffstats
path: root/desktop-widgets/command_divelist.cpp
diff options
context:
space:
mode:
authorGravatar Berthold Stoeger <bstoeger@mail.tuwien.ac.at>2019-03-03 15:12:22 +0100
committerGravatar Dirk Hohndel <dirk@hohndel.org>2019-04-12 18:19:07 +0300
commit82af1b2377cec03a989f86b8009d4ac226c6541e (patch)
treea875f194f7174c8673b2f7bd5cc43aa8ca3c51c6 /desktop-widgets/command_divelist.cpp
parent37146c5742503becf75468fb07aab56011cb9101 (diff)
downloadsubsurface-82af1b2377cec03a989f86b8009d4ac226c6541e.tar.gz
Undo: make undo-system dive site-aware
As opposed to dive trips, dive sites were always directly added to the global table, even on import. Instead, parse the divesites into a distinct table and merge them on import. Currently, this does not do any merging of dive sites, i.e. dive sites are considered as either equal or different. Nevertheless, merging of data should be rather easy to implement and simply follow the code of the dive merging. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Diffstat (limited to 'desktop-widgets/command_divelist.cpp')
-rw-r--r--desktop-widgets/command_divelist.cpp102
1 files changed, 63 insertions, 39 deletions
diff --git a/desktop-widgets/command_divelist.cpp b/desktop-widgets/command_divelist.cpp
index 96c5ead95..9a5a6d398 100644
--- a/desktop-widgets/command_divelist.cpp
+++ b/desktop-widgets/command_divelist.cpp
@@ -106,15 +106,23 @@ dive *DiveListBase::addDive(DiveToAdd &d)
// returns a vector of corresponding DiveToAdd objects, which can later be readded.
// Moreover, a vector of deleted trips is returned, if trips became empty.
// The passed in vector is cleared.
-DivesAndTripsToAdd DiveListBase::removeDives(std::vector<dive *> &divesToDelete)
+DivesAndTripsToAdd DiveListBase::removeDives(DivesAndSitesToRemove &divesAndSitesToDelete)
{
std::vector<DiveToAdd> divesToAdd;
std::vector<OwningTripPtr> tripsToAdd;
- divesToAdd.reserve(divesToDelete.size());
+ std::vector<OwningDiveSitePtr> sitesToAdd;
+ divesToAdd.reserve(divesAndSitesToDelete.dives.size());
+ sitesToAdd.reserve(divesAndSitesToDelete.sites.size());
- for (dive *d: divesToDelete)
+ for (dive *d: divesAndSitesToDelete.dives)
divesToAdd.push_back(removeDive(d, tripsToAdd));
- divesToDelete.clear();
+ divesAndSitesToDelete.dives.clear();
+
+ for (dive_site *ds: divesAndSitesToDelete.sites) {
+ unregister_dive_site(ds);
+ sitesToAdd.emplace_back(ds);
+ }
+ divesAndSitesToDelete.sites.clear();
// We send one dives-deleted signal per trip (see comments in DiveListNotifier.h).
// Therefore, collect all dives in an array and sort by trip.
@@ -131,17 +139,19 @@ DivesAndTripsToAdd DiveListBase::removeDives(std::vector<dive *> &divesToDelete)
{ return ptr.get() == trip; }) != tripsToAdd.end();
emit diveListNotifier.divesDeleted(trip, deleteTrip, divesInTrip);
});
- return { std::move(divesToAdd), std::move(tripsToAdd) };
+ return { std::move(divesToAdd), std::move(tripsToAdd), std::move(sitesToAdd) };
}
// This helper function is the counterpart fo removeDives(): it calls addDive() on a list
// of dives to be (re)added and returns a vector of the added dives. It does this in reverse
// order, so that trips are created appropriately and indexing is correct.
// The passed in vector is cleared.
-std::vector<dive *> DiveListBase::addDives(DivesAndTripsToAdd &toAdd)
+DivesAndSitesToRemove DiveListBase::addDives(DivesAndTripsToAdd &toAdd)
{
std::vector<dive *> res;
+ std::vector<dive_site *> sites;
res.resize(toAdd.dives.size());
+ sites.reserve(toAdd.sites.size());
// Now, add the dives
// Note: the idiomatic STL-way would be std::transform, but let's use a loop since
@@ -161,6 +171,13 @@ std::vector<dive *> DiveListBase::addDives(DivesAndTripsToAdd &toAdd)
}
toAdd.trips.clear();
+ // Finally, add any necessary dive sites
+ for (OwningDiveSitePtr &ds: toAdd.sites) {
+ sites.push_back(ds.get());
+ register_dive_site(ds.release()); // Return ownership to backend
+ }
+ toAdd.sites.clear();
+
// We send one dives-deleted signal per trip (see comments in DiveListNotifier.h).
// Therefore, collect all dives in a array and sort by trip.
std::vector<std::pair<dive_trip *, dive *>> dives;
@@ -175,7 +192,7 @@ std::vector<dive *> DiveListBase::addDives(DivesAndTripsToAdd &toAdd)
// Finally, emit the signal
emit diveListNotifier.divesAdded(trip, createTrip, divesInTrip);
});
- return res;
+ return { res, sites };
}
// This helper function renumbers dives according to an array of id/number pairs.
@@ -520,12 +537,12 @@ void AddDive::redoit()
selection = getDiveSelection();
currentDive = current_dive;
- divesToRemove = addDives(divesToAdd);
+ divesAndSitesToRemove = addDives(divesToAdd);
sort_trip_table(&trip_table); // Though unlikely, adding a dive may reorder trips
mark_divelist_changed(true);
// Select the newly added dive
- restoreSelection(divesToRemove, divesToRemove[0]);
+ restoreSelection(divesAndSitesToRemove.dives, divesAndSitesToRemove.dives[0]);
// Exit from edit mode, but don't recalculate dive list
// TODO: Remove edit mode
@@ -535,7 +552,7 @@ void AddDive::redoit()
void AddDive::undoit()
{
// Simply remove the dive that was previously added...
- divesToAdd = removeDives(divesToRemove);
+ divesToAdd = removeDives(divesAndSitesToRemove);
sort_trip_table(&trip_table); // Though unlikely, removing a dive may reorder trips
// ...and restore the selection
@@ -546,20 +563,26 @@ void AddDive::undoit()
MainWindow::instance()->refreshDisplay(false);
}
-ImportDives::ImportDives(struct dive_table *dives, struct trip_table *trips, int flags, const QString &source)
+ImportDives::ImportDives(struct dive_table *dives, struct trip_table *trips, struct dive_site_table *sites, int flags, const QString &source)
{
setText(tr("import %n dive(s) from %1", "", dives->nr).arg(source));
struct dive_table dives_to_add = { 0 };
struct dive_table dives_to_remove = { 0 };
struct trip_table trips_to_add = { 0 };
- process_imported_dives(dives, trips, flags, &dives_to_add, &dives_to_remove, &trips_to_add);
+ struct dive_site_table sites_to_add = { 0 };
+ process_imported_dives(dives, trips, sites, flags, &dives_to_add, &dives_to_remove, &trips_to_add, &sites_to_add);
// Add trips to the divesToAdd.trips structure
divesToAdd.trips.reserve(trips_to_add.nr);
for (int i = 0; i < trips_to_add.nr; ++i)
divesToAdd.trips.emplace_back(trips_to_add.trips[i]);
+ // Add sites to the divesToAdd.sites structure
+ divesToAdd.sites.reserve(sites_to_add.nr);
+ for (int i = 0; i < sites_to_add.nr; ++i)
+ divesToAdd.sites.emplace_back(sites_to_add.dive_sites[i]);
+
// Add dives to the divesToAdd.dives structure
divesToAdd.dives.reserve(dives_to_add.nr);
for (int i = 0; i < dives_to_add.nr; ++i) {
@@ -577,9 +600,9 @@ ImportDives::ImportDives(struct dive_table *dives, struct trip_table *trips, int
}
// Add dive to be deleted to the divesToRemove structure
- divesToRemove.reserve(dives_to_remove.nr);
+ divesAndSitesToRemove.dives.reserve(dives_to_remove.nr);
for (int i = 0; i < dives_to_remove.nr; ++i)
- divesToRemove.push_back(dives_to_remove.dives[i]);
+ divesAndSitesToRemove.dives.push_back(dives_to_remove.dives[i]);
}
bool ImportDives::workToBeDone()
@@ -592,31 +615,31 @@ void ImportDives::redoit()
// Remember selection so that we can undo it
currentDive = current_dive;
- // Add new dives
- std::vector<dive *> divesToRemoveNew = addDives(divesToAdd);
+ // Add new dives and sites
+ DivesAndSitesToRemove divesAndSitesToRemoveNew = addDives(divesToAdd);
- // Remove old dives
- divesToAdd = removeDives(divesToRemove);
+ // Remove old dives and sites
+ divesToAdd = removeDives(divesAndSitesToRemove);
// Select the newly added dives
- restoreSelection(divesToRemoveNew, divesToRemoveNew.back());
+ restoreSelection(divesAndSitesToRemoveNew.dives, divesAndSitesToRemoveNew.dives.back());
- // Remember dives to remove
- divesToRemove = std::move(divesToRemoveNew);
+ // Remember dives and sites to remove
+ divesAndSitesToRemove = std::move(divesAndSitesToRemoveNew);
mark_divelist_changed(true);
}
void ImportDives::undoit()
{
- // Add new dives
- std::vector<dive *> divesToRemoveNew = addDives(divesToAdd);
+ // Add new dives and sites
+ DivesAndSitesToRemove divesAndSitesToRemoveNew = addDives(divesToAdd);
- // Remove old dives
- divesToAdd = removeDives(divesToRemove);
+ // Remove old dives and sites
+ divesToAdd = removeDives(divesAndSitesToRemove);
- // Remember dives to remove
- divesToRemove = std::move(divesToRemoveNew);
+ // Remember dives and sites to remove
+ divesAndSitesToRemove = std::move(divesAndSitesToRemoveNew);
// ...and restore the selection
restoreSelection(selection, currentDive);
@@ -624,14 +647,15 @@ void ImportDives::undoit()
mark_divelist_changed(true);
}
-DeleteDive::DeleteDive(const QVector<struct dive*> &divesToDeleteIn) : divesToDelete(divesToDeleteIn.toStdVector())
+DeleteDive::DeleteDive(const QVector<struct dive*> &divesToDeleteIn)
{
- setText(tr("delete %n dive(s)", "", divesToDelete.size()));
+ divesToDelete.dives = divesToDeleteIn.toStdVector();
+ setText(tr("delete %n dive(s)", "", divesToDelete.dives.size()));
}
bool DeleteDive::workToBeDone()
{
- return !divesToDelete.empty();
+ return !divesToDelete.dives.empty();
}
void DeleteDive::undoit()
@@ -641,8 +665,8 @@ void DeleteDive::undoit()
mark_divelist_changed(true);
// Select all re-added dives and make the first one current
- dive *currentDive = !divesToDelete.empty() ? divesToDelete[0] : nullptr;
- restoreSelection(divesToDelete, currentDive);
+ dive *currentDive = !divesToDelete.dives.empty() ? divesToDelete.dives[0] : nullptr;
+ restoreSelection(divesToDelete.dives, currentDive);
}
void DeleteDive::redoit()
@@ -853,7 +877,7 @@ SplitDivesBase::SplitDivesBase(dive *d, std::array<dive *, 2> newDives)
if (idx1 == idx2 && dive_less_than(newDives[0], newDives[1]))
++idx2;
- diveToSplit.push_back(d);
+ diveToSplit.dives.push_back(d);
splitDives.dives.resize(2);
splitDives.dives[0].dive.reset(newDives[0]);
splitDives.dives[0].trip = d->divetrip;
@@ -865,7 +889,7 @@ SplitDivesBase::SplitDivesBase(dive *d, std::array<dive *, 2> newDives)
bool SplitDivesBase::workToBeDone()
{
- return !diveToSplit.empty();
+ return !diveToSplit.dives.empty();
}
void SplitDivesBase::redoit()
@@ -875,7 +899,7 @@ void SplitDivesBase::redoit()
mark_divelist_changed(true);
// Select split dives and make first dive current
- restoreSelection(divesToUnsplit, divesToUnsplit[0]);
+ restoreSelection(divesToUnsplit.dives, divesToUnsplit.dives[0]);
}
void SplitDivesBase::undoit()
@@ -886,7 +910,7 @@ void SplitDivesBase::undoit()
mark_divelist_changed(true);
// Select unsplit dive and make it current
- restoreSelection(diveToSplit, diveToSplit[0] );
+ restoreSelection(diveToSplit.dives, diveToSplit.dives[0] );
}
static std::array<dive *, 2> doSplitDives(const dive *d, duration_t time)
@@ -1003,7 +1027,7 @@ MergeDives::MergeDives(const QVector <dive *> &dives)
mergedDive.dives[0].dive = std::move(d);
mergedDive.dives[0].idx = get_divenr(dives[0]);
mergedDive.dives[0].trip = preferred_trip;
- divesToMerge = dives.toStdVector();
+ divesToMerge.dives = dives.toStdVector();
}
bool MergeDives::workToBeDone()
@@ -1018,7 +1042,7 @@ void MergeDives::redoit()
unmergedDives = removeDives(divesToMerge);
// Select merged dive and make it current
- restoreSelection(diveToUnmerge, diveToUnmerge[0]);
+ restoreSelection(diveToUnmerge.dives, diveToUnmerge.dives[0]);
}
void MergeDives::undoit()
@@ -1028,7 +1052,7 @@ void MergeDives::undoit()
renumberDives(divesToRenumber);
// Select unmerged dives and make first one current
- restoreSelection(divesToMerge, divesToMerge[0]);
+ restoreSelection(divesToMerge.dives, divesToMerge.dives[0]);
}
} // namespace Command