diff options
-rw-r--r-- | commands/command.cpp | 5 | ||||
-rw-r--r-- | commands/command.h | 4 | ||||
-rw-r--r-- | commands/command_divesite.cpp | 47 | ||||
-rw-r--r-- | commands/command_divesite.h | 26 |
4 files changed, 81 insertions, 1 deletions
diff --git a/commands/command.cpp b/commands/command.cpp index 721f51c64..aa1d18183 100644 --- a/commands/command.cpp +++ b/commands/command.cpp @@ -145,6 +145,11 @@ void purgeUnusedDiveSites() execute(new PurgeUnusedDiveSites); } +void applyGPSFixes(const std::vector<DiveAndLocation> &fixes) +{ + execute(new ApplyGPSFixes(fixes)); +} + // Execute an edit-command and return number of edited dives static int execute_edit(EditDivesBase *cmd) { diff --git a/commands/command.h b/commands/command.h index 7a8ea81b0..281c1635c 100644 --- a/commands/command.h +++ b/commands/command.h @@ -5,6 +5,9 @@ #include "core/dive.h" #include <QVector> #include <QAction> +#include <vector> + +struct DiveAndLocation; // We put everything in a namespace, so that we can shorten names without polluting the global namespace namespace Command { @@ -41,6 +44,7 @@ void splitDiveComputer(dive *d, int dc_num); void moveDiveComputerToFront(dive *d, int dc_num); void deleteDiveComputer(dive *d, int dc_num); void mergeDives(const QVector <dive *> &dives); +void applyGPSFixes(const std::vector<DiveAndLocation> &fixes); // 3) Dive-site related commands diff --git a/commands/command_divesite.cpp b/commands/command_divesite.cpp index 56372ff41..8c61f224b 100644 --- a/commands/command_divesite.cpp +++ b/commands/command_divesite.cpp @@ -391,4 +391,51 @@ void MergeDiveSites::undo() emit diveListNotifier.divesChanged(divesChanged, DiveField::DIVESITE); } +ApplyGPSFixes::ApplyGPSFixes(const std::vector<DiveAndLocation> &fixes) +{ + setText(tr("apply GPS fixes")); + + for (const DiveAndLocation &dl: fixes) { + struct dive_site *ds = dl.d->dive_site; + if (ds) { + // Arbitrary choice: if we find multiple fixes for the same dive, we use the first one. + if (std::find_if(siteLocations.begin(), siteLocations.end(), + [ds] (const SiteAndLocation &sl) { return sl.ds == ds; }) == siteLocations.end()) { + siteLocations.push_back({ ds, dl.location }); + } + } else { + ds = create_dive_site(qPrintable(dl.name), &dive_site_table); + ds->location = dl.location; + add_dive_to_dive_site(dl.d, ds); + dl.d->dive_site = nullptr; // This will be set on redo() + sitesToAdd.emplace_back(ds); + } + } +} + +bool ApplyGPSFixes::workToBeDone() +{ + return !sitesToAdd.empty() || !siteLocations.empty(); +} + +void ApplyGPSFixes::editDiveSites() +{ + for (SiteAndLocation &sl: siteLocations) { + std::swap(sl.location, sl.ds->location); + emit diveListNotifier.diveSiteChanged(sl.ds, LocationInformationModel::LOCATION); // Inform frontend of changed dive site. + } +} + +void ApplyGPSFixes::redo() +{ + sitesToRemove = addDiveSites(sitesToAdd); + editDiveSites(); +} + +void ApplyGPSFixes::undo() +{ + sitesToAdd = removeDiveSites(sitesToRemove); + editDiveSites(); +} + } // namespace Command diff --git a/commands/command_divesite.h b/commands/command_divesite.h index 3fcf085ae..db0c5c73e 100644 --- a/commands/command_divesite.h +++ b/commands/command_divesite.h @@ -5,6 +5,7 @@ #define COMMAND_DIVESITE_H #include "command_base.h" +#include "core/gpslocation.h" #include <QVector> @@ -110,7 +111,6 @@ private: QString value; // Value to be set }; - class EditDiveSiteCountry : public Base { public: EditDiveSiteCountry(dive_site *ds, const QString &country); @@ -165,6 +165,30 @@ private: std::vector<OwningDiveSitePtr> sitesToAdd; }; +class ApplyGPSFixes : public Base { +public: + // Note: the dive site table is consumed after the call it will be empty. + ApplyGPSFixes(const std::vector<DiveAndLocation> &fixes); +private: + bool workToBeDone() override; + void undo() override; + void redo() override; + + // For undo + std::vector<dive_site *> sitesToRemove; + + // For redo + std::vector<OwningDiveSitePtr> sitesToAdd; + + // For redo and undo + struct SiteAndLocation { + dive_site *ds; + location_t location; + }; + std::vector<SiteAndLocation> siteLocations; + void editDiveSites(); +}; + } // namespace Command #endif // COMMAND_DIVESITE_H |