diff options
author | Berthold Stoeger <bstoeger@mail.tuwien.ac.at> | 2019-03-15 17:41:31 +0100 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2019-04-12 18:19:07 +0300 |
commit | 59239cec02aedda8c2651a04c65c580a9ff190a9 (patch) | |
tree | 3aa2ce298c132eb6ccacb77d5b2a508e46aa724c | |
parent | 7c63956ee4798a835794eee8189b73e3df07594d (diff) | |
download | subsurface-59239cec02aedda8c2651a04c65c580a9ff190a9.tar.gz |
Undo: make dive site merging undoable
This one was rather trivial, as there is no actual merging
done. Quite simply, a number of dive sites are removed and
their dive added to a different dive site.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
-rw-r--r-- | core/divesite.c | 25 | ||||
-rw-r--r-- | core/divesite.h | 1 | ||||
-rw-r--r-- | desktop-widgets/command.cpp | 5 | ||||
-rw-r--r-- | desktop-widgets/command.h | 1 | ||||
-rw-r--r-- | desktop-widgets/command_divesite.cpp | 41 | ||||
-rw-r--r-- | desktop-widgets/command_divesite.h | 17 | ||||
-rw-r--r-- | desktop-widgets/locationinformation.cpp | 12 |
7 files changed, 66 insertions, 36 deletions
diff --git a/core/divesite.c b/core/divesite.c index 892a2dd78..8757aeed7 100644 --- a/core/divesite.c +++ b/core/divesite.c @@ -310,31 +310,6 @@ void merge_dive_site(struct dive_site *a, struct dive_site *b) } } -void merge_dive_sites(struct dive_site *ref, struct dive_site *dive_sites[], int count) -{ - int curr_dive, i; - struct dive *d; - for(i = 0; i < count; i++){ - if (dive_sites[i] == ref) - continue; - - for_each_dive(curr_dive, d) { - if (d->dive_site != dive_sites[i] ) - continue; - unregister_dive_from_dive_site(d); - add_dive_to_dive_site(d, ref); - invalidate_dive_cache(d); - } - } - - for(i = 0; i < count; i++) { - if (dive_sites[i] == ref) - continue; - delete_dive_site(dive_sites[i], &dive_site_table); - } - mark_divelist_changed(true); -} - struct dive_site *find_or_create_dive_site_with_name(const char *name, struct dive_site_table *ds_table) { int i; diff --git a/core/divesite.h b/core/divesite.h index 50bd0b406..433ad056e 100644 --- a/core/divesite.h +++ b/core/divesite.h @@ -69,7 +69,6 @@ void copy_dive_site(struct dive_site *orig, struct dive_site *copy); void merge_dive_site(struct dive_site *a, struct dive_site *b); unsigned int get_distance(const location_t *loc1, const location_t *loc2); struct dive_site *find_or_create_dive_site_with_name(const char *name, struct dive_site_table *ds_table); -void merge_dive_sites(struct dive_site *ref, struct dive_site *dive_sites[], int count); void purge_empty_dive_sites(struct dive_site_table *ds_table); void clear_dive_site_table(struct dive_site_table *ds_table); void add_dive_to_dive_site(struct dive *d, struct dive_site *ds); diff --git a/desktop-widgets/command.cpp b/desktop-widgets/command.cpp index 785443390..adfd32960 100644 --- a/desktop-widgets/command.cpp +++ b/desktop-widgets/command.cpp @@ -118,4 +118,9 @@ void addDiveSite(const QString &name) execute(new AddDiveSite(name)); } +void mergeDiveSites(dive_site *ds, const QVector<dive_site *> &sites) +{ + execute(new MergeDiveSites(ds, sites)); +} + } // namespace Command diff --git a/desktop-widgets/command.h b/desktop-widgets/command.h index d1a8326ea..1bcc69089 100644 --- a/desktop-widgets/command.h +++ b/desktop-widgets/command.h @@ -48,6 +48,7 @@ void editDiveSiteCountry(dive_site *ds, const QString &value); void editDiveSiteLocation(dive_site *ds, location_t value); void editDiveSiteTaxonomy(dive_site *ds, taxonomy_data &value); // value is consumed (i.e. will be erased after call)! void addDiveSite(const QString &name); +void mergeDiveSites(dive_site *ds, const QVector<dive_site *> &sites); } // namespace Command diff --git a/desktop-widgets/command_divesite.cpp b/desktop-widgets/command_divesite.cpp index 04ee3b212..a5dce00d1 100644 --- a/desktop-widgets/command_divesite.cpp +++ b/desktop-widgets/command_divesite.cpp @@ -266,4 +266,45 @@ void EditDiveSiteTaxonomy::undo() redo(); } +MergeDiveSites::MergeDiveSites(dive_site *dsIn, const QVector<dive_site *> &sites) : ds(dsIn) +{ + setText(tr("merge dive sites")); + sitesToRemove.reserve(sites.size()); + for (dive_site *site: sites) { + if (site != ds) + sitesToRemove.push_back(site); + } +} + +bool MergeDiveSites::workToBeDone() +{ + return !sitesToRemove.empty(); +} + +void MergeDiveSites::redo() +{ + // First, remove all dive sites + sitesToAdd = std::move(removeDiveSites(sitesToRemove)); + + // The dives of the above dive sites were reset to no dive sites. + // Add them to the merged-into dive site. Thankfully, we remember + // the dives in the sitesToAdd vector. + for (const OwningDiveSitePtr &site: sitesToAdd) { + for (int i = 0; i < site->dives.nr; ++i) + add_dive_to_dive_site(site->dives.dives[i], ds); // TODO: send dive changed signal + } +} + +void MergeDiveSites::undo() +{ + // Before readding the dive sites, unregister the corresponding dives so that they can be + // readded to their old dive sites. + for (const OwningDiveSitePtr &site: sitesToAdd) { + for (int i = 0; i < site->dives.nr; ++i) + unregister_dive_from_dive_site(site->dives.dives[i]); + } + + sitesToRemove = std::move(addDiveSites(sitesToAdd)); +} + } // namespace Command diff --git a/desktop-widgets/command_divesite.h b/desktop-widgets/command_divesite.h index b73cc1b5a..58b3aabf5 100644 --- a/desktop-widgets/command_divesite.h +++ b/desktop-widgets/command_divesite.h @@ -117,6 +117,23 @@ private: taxonomy_data value; // Value to be set }; +class MergeDiveSites : public Base { +public: + MergeDiveSites(dive_site *ds, const QVector<dive_site *> &sites); +private: + bool workToBeDone() override; + void undo() override; + void redo() override; + + dive_site *ds; + + // For redo + std::vector<dive_site *> sitesToRemove; + + // For undo + std::vector<OwningDiveSitePtr> sitesToAdd; +}; + } // namespace Command #endif // COMMAND_DIVESITE_H diff --git a/desktop-widgets/locationinformation.cpp b/desktop-widgets/locationinformation.cpp index 244e85f8d..330ccd6f5 100644 --- a/desktop-widgets/locationinformation.cpp +++ b/desktop-widgets/locationinformation.cpp @@ -62,24 +62,16 @@ void LocationInformationWidget::mergeSelectedDiveSites() { if (!diveSite) return; - if (QMessageBox::warning(MainWindow::instance(), tr("Merging dive sites"), - tr("You are about to merge dive sites, you can't undo that action \n Are you sure you want to continue?"), - QMessageBox::Ok, QMessageBox::Cancel) != QMessageBox::Ok) - return; const QModelIndexList selection = ui.diveSiteListView->selectionModel()->selectedIndexes(); - // std::vector guarantees contiguous storage and can therefore be passed to C-code - std::vector<struct dive_site *> selected_dive_sites; + QVector<dive_site *> selected_dive_sites; selected_dive_sites.reserve(selection.count()); for (const QModelIndex &idx: selection) { dive_site *ds = idx.data(LocationInformationModel::DIVESITE_ROLE).value<dive_site *>(); if (ds) selected_dive_sites.push_back(ds); } - merge_dive_sites(diveSite, selected_dive_sites.data(), (int)selected_dive_sites.size()); - LocationInformationModel::instance()->update(); - QSortFilterProxyModel *m = (QSortFilterProxyModel *)ui.diveSiteListView->model(); - m->invalidate(); + Command::mergeDiveSites(diveSite, selected_dive_sites); } void LocationInformationWidget::updateLabels() |