diff options
-rw-r--r-- | desktop-widgets/CMakeLists.txt | 2 | ||||
-rw-r--r-- | desktop-widgets/command.cpp | 7 | ||||
-rw-r--r-- | desktop-widgets/command.h | 4 | ||||
-rw-r--r-- | desktop-widgets/command_divesite.cpp | 83 | ||||
-rw-r--r-- | desktop-widgets/command_divesite.h | 31 | ||||
-rw-r--r-- | qt-models/divelocationmodel.cpp | 25 | ||||
-rw-r--r-- | qt-models/divelocationmodel.h | 2 |
7 files changed, 153 insertions, 1 deletions
diff --git a/desktop-widgets/CMakeLists.txt b/desktop-widgets/CMakeLists.txt index efccfcc26..c494f1a8b 100644 --- a/desktop-widgets/CMakeLists.txt +++ b/desktop-widgets/CMakeLists.txt @@ -62,6 +62,8 @@ set(SUBSURFACE_INTERFACE command_base.h command_divelist.cpp command_divelist.h + command_divesite.cpp + command_divesite.h configuredivecomputerdialog.cpp configuredivecomputerdialog.h divecomputermanagementdialog.cpp diff --git a/desktop-widgets/command.cpp b/desktop-widgets/command.cpp index 2e2982860..80a233404 100644 --- a/desktop-widgets/command.cpp +++ b/desktop-widgets/command.cpp @@ -2,6 +2,7 @@ #include "command.h" #include "command_divelist.h" +#include "command_divesite.h" namespace Command { @@ -76,4 +77,10 @@ void mergeDives(const QVector <dive *> &dives) execute(new MergeDives(dives)); } +// Dive site related commands +void deleteDiveSites(const QVector <dive_site *> &sites) +{ + execute(new DeleteDiveSites(sites)); +} + } // namespace Command diff --git a/desktop-widgets/command.h b/desktop-widgets/command.h index dfc79a9e6..77920a81c 100644 --- a/desktop-widgets/command.h +++ b/desktop-widgets/command.h @@ -38,6 +38,10 @@ void splitDives(dive *d, duration_t time); void splitDiveComputer(dive *d, int dc_num); void mergeDives(const QVector <dive *> &dives); +// 3) Dive-site related commands + +void deleteDiveSites(const QVector <dive_site *> &sites); + } // namespace Command #endif // COMMAND_H diff --git a/desktop-widgets/command_divesite.cpp b/desktop-widgets/command_divesite.cpp new file mode 100644 index 000000000..d4c5d87b8 --- /dev/null +++ b/desktop-widgets/command_divesite.cpp @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include "command_divesite.h" +#include "core/divesite.h" +#include "core/subsurface-qt/DiveListNotifier.h" + +namespace Command { + +// Helper functions to add / remove a set of dive sites + +// Add a set of dive sites to the core. The dives that were associated with +// that dive site will be restored to that dive site. +static std::vector<dive_site *> addDiveSites(std::vector<OwningDiveSitePtr> &sites) +{ + std::vector<dive_site *> res; + res.reserve(sites.size()); + + for (OwningDiveSitePtr &ds: sites) { + // Readd the dives that belonged to this site + for (int i = 0; i < ds->dives.nr; ++i) { + // TODO: send dive site changed signal + ds->dives.dives[i]->dive_site = ds.get(); + } + + // Add dive site to core, but remember a non-owning pointer first. + res.push_back(ds.get()); + int idx = register_dive_site(ds.release()); // Return ownership to backend. + emit diveListNotifier.diveSiteAdded(res.back(), idx); // Inform frontend of new dive site. + } + + // Clear vector of unused owning pointers + sites.clear(); + + return res; +} + +// Remove a set of dive sites. Get owning pointers to them. The dives are set to +// being at no dive site, but the dive site will retain a list of dives, so +// that the dives can be readded to the site on undo. +static std::vector<OwningDiveSitePtr> removeDiveSites(std::vector<dive_site *> &sites) +{ + std::vector<OwningDiveSitePtr> res; + res.reserve(sites.size()); + + for (dive_site *ds: sites) { + // Reset the dive_site field of the affected dives + for (int i = 0; i < ds->dives.nr; ++i) { + // TODO: send dive site changed signal + ds->dives.dives[i]->dive_site = nullptr; + } + + // Remove dive site from core and take ownership. + int idx = unregister_dive_site(ds); + res.emplace_back(ds); + emit diveListNotifier.diveSiteDeleted(ds, idx); // Inform frontend of removed dive site. + } + + sites.clear(); + + return res; +} + +DeleteDiveSites::DeleteDiveSites(const QVector<dive_site *> &sites) : sitesToRemove(sites.toStdVector()) +{ + setText(tr("delete %n dive site(s)", "", sites.size())); +} + +bool DeleteDiveSites::workToBeDone() +{ + return !sitesToRemove.empty(); +} + +void DeleteDiveSites::redo() +{ + sitesToAdd = std::move(removeDiveSites(sitesToRemove)); +} + +void DeleteDiveSites::undo() +{ + sitesToRemove = std::move(addDiveSites(sitesToAdd)); +} + +} // namespace Command diff --git a/desktop-widgets/command_divesite.h b/desktop-widgets/command_divesite.h new file mode 100644 index 000000000..9c4f93058 --- /dev/null +++ b/desktop-widgets/command_divesite.h @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0 +// Note: this header file is used by the undo-machinery and should not be included elsewhere. + +#ifndef COMMAND_DIVESITE_H +#define COMMAND_DIVESITE_H + +#include "command_base.h" + +#include <QVector> + +// We put everything in a namespace, so that we can shorten names without polluting the global namespace +namespace Command { + +class DeleteDiveSites : public Base { +public: + DeleteDiveSites(const QVector<dive_site *> &sites); +private: + bool workToBeDone() override; + + // For redo + std::vector<dive_site *> sitesToRemove; + + // For undo + std::vector<OwningDiveSitePtr> sitesToAdd; + void undo() override; + void redo() override; +}; + +} // namespace Command + +#endif // COMMAND_DIVESITE_H diff --git a/qt-models/divelocationmodel.cpp b/qt-models/divelocationmodel.cpp index 383de43ca..ebdffc185 100644 --- a/qt-models/divelocationmodel.cpp +++ b/qt-models/divelocationmodel.cpp @@ -5,8 +5,12 @@ #include "core/qthelper.h" #include "core/divesite.h" #include "core/metrics.h" +#ifndef SUBSURFACE_MOBILE #include "cleanertablemodel.h" // for trashIcon(); -#include <QDebug> +#include "desktop-widgets/mainwindow.h" // to place message box +#include "desktop-widgets/command.h" +#include <QMessageBox> +#endif #include <QLineEdit> #include <QIcon> #include <core/gettextfromc.h> @@ -219,6 +223,25 @@ QStringList DiveSiteSortedModel::allSiteNames() const return locationNames; } +#ifndef SUBSURFACE_MOBILE +// TODO: Remove from model. It doesn't make sense to call the model here, which calls the undo command, +// which in turn calls the model. +void DiveSiteSortedModel::remove(const QModelIndex &index) +{ + if (index.column() != LocationInformationModel::REMOVE) + return; + struct dive_site *ds = get_dive_site(mapToSource(index).row(), &dive_site_table); + if (!ds) + return; + if (ds->dives.nr > 0 && + QMessageBox::warning(MainWindow::instance(), tr("Delete dive site?"), + tr("This dive site has %n dive(s). Do you really want to delete it?\n", "", ds->dives.nr), + QMessageBox::Yes|QMessageBox::No) == QMessageBox::No) + return; + Command::deleteDiveSites(QVector<dive_site *>{ds}); +} +#endif + GeoReferencingOptionsModel *GeoReferencingOptionsModel::instance() { static GeoReferencingOptionsModel *self = new GeoReferencingOptionsModel(); diff --git a/qt-models/divelocationmodel.h b/qt-models/divelocationmodel.h index f2bcc7cf7..34ac34c04 100644 --- a/qt-models/divelocationmodel.h +++ b/qt-models/divelocationmodel.h @@ -42,6 +42,8 @@ class DiveSiteSortedModel : public QSortFilterProxyModel { private: bool filterAcceptsRow(int sourceRow, const QModelIndex &source_parent) const override; bool lessThan(const QModelIndex &i1, const QModelIndex &i2) const override; +public slots: + void remove(const QModelIndex &index); public: DiveSiteSortedModel(); QStringList allSiteNames() const; |