mirror of
https://github.com/subsurface/subsurface.git
synced 2025-01-31 20:43:24 +00:00
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>
This commit is contained in:
parent
7c63956ee4
commit
59239cec02
7 changed files with 66 additions and 36 deletions
|
@ -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)
|
struct dive_site *find_or_create_dive_site_with_name(const char *name, struct dive_site_table *ds_table)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -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);
|
void merge_dive_site(struct dive_site *a, struct dive_site *b);
|
||||||
unsigned int get_distance(const location_t *loc1, const location_t *loc2);
|
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);
|
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 purge_empty_dive_sites(struct dive_site_table *ds_table);
|
||||||
void clear_dive_site_table(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);
|
void add_dive_to_dive_site(struct dive *d, struct dive_site *ds);
|
||||||
|
|
|
@ -118,4 +118,9 @@ void addDiveSite(const QString &name)
|
||||||
execute(new AddDiveSite(name));
|
execute(new AddDiveSite(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mergeDiveSites(dive_site *ds, const QVector<dive_site *> &sites)
|
||||||
|
{
|
||||||
|
execute(new MergeDiveSites(ds, sites));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Command
|
} // namespace Command
|
||||||
|
|
|
@ -48,6 +48,7 @@ void editDiveSiteCountry(dive_site *ds, const QString &value);
|
||||||
void editDiveSiteLocation(dive_site *ds, location_t 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 editDiveSiteTaxonomy(dive_site *ds, taxonomy_data &value); // value is consumed (i.e. will be erased after call)!
|
||||||
void addDiveSite(const QString &name);
|
void addDiveSite(const QString &name);
|
||||||
|
void mergeDiveSites(dive_site *ds, const QVector<dive_site *> &sites);
|
||||||
|
|
||||||
} // namespace Command
|
} // namespace Command
|
||||||
|
|
||||||
|
|
|
@ -266,4 +266,45 @@ void EditDiveSiteTaxonomy::undo()
|
||||||
redo();
|
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
|
} // namespace Command
|
||||||
|
|
|
@ -117,6 +117,23 @@ private:
|
||||||
taxonomy_data value; // Value to be set
|
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
|
} // namespace Command
|
||||||
|
|
||||||
#endif // COMMAND_DIVESITE_H
|
#endif // COMMAND_DIVESITE_H
|
||||||
|
|
|
@ -62,24 +62,16 @@ void LocationInformationWidget::mergeSelectedDiveSites()
|
||||||
{
|
{
|
||||||
if (!diveSite)
|
if (!diveSite)
|
||||||
return;
|
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();
|
const QModelIndexList selection = ui.diveSiteListView->selectionModel()->selectedIndexes();
|
||||||
// std::vector guarantees contiguous storage and can therefore be passed to C-code
|
QVector<dive_site *> selected_dive_sites;
|
||||||
std::vector<struct dive_site *> selected_dive_sites;
|
|
||||||
selected_dive_sites.reserve(selection.count());
|
selected_dive_sites.reserve(selection.count());
|
||||||
for (const QModelIndex &idx: selection) {
|
for (const QModelIndex &idx: selection) {
|
||||||
dive_site *ds = idx.data(LocationInformationModel::DIVESITE_ROLE).value<dive_site *>();
|
dive_site *ds = idx.data(LocationInformationModel::DIVESITE_ROLE).value<dive_site *>();
|
||||||
if (ds)
|
if (ds)
|
||||||
selected_dive_sites.push_back(ds);
|
selected_dive_sites.push_back(ds);
|
||||||
}
|
}
|
||||||
merge_dive_sites(diveSite, selected_dive_sites.data(), (int)selected_dive_sites.size());
|
Command::mergeDiveSites(diveSite, selected_dive_sites);
|
||||||
LocationInformationModel::instance()->update();
|
|
||||||
QSortFilterProxyModel *m = (QSortFilterProxyModel *)ui.diveSiteListView->model();
|
|
||||||
m->invalidate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocationInformationWidget::updateLabels()
|
void LocationInformationWidget::updateLabels()
|
||||||
|
|
Loading…
Add table
Reference in a new issue