summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--desktop-widgets/CMakeLists.txt2
-rw-r--r--desktop-widgets/command.cpp7
-rw-r--r--desktop-widgets/command.h4
-rw-r--r--desktop-widgets/command_divesite.cpp83
-rw-r--r--desktop-widgets/command_divesite.h31
-rw-r--r--qt-models/divelocationmodel.cpp25
-rw-r--r--qt-models/divelocationmodel.h2
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;