summaryrefslogtreecommitdiffstats
path: root/desktop-widgets
diff options
context:
space:
mode:
Diffstat (limited to 'desktop-widgets')
-rw-r--r--desktop-widgets/command.cpp5
-rw-r--r--desktop-widgets/command.h1
-rw-r--r--desktop-widgets/command_divelist.cpp86
-rw-r--r--desktop-widgets/command_divelist.h19
4 files changed, 87 insertions, 24 deletions
diff --git a/desktop-widgets/command.cpp b/desktop-widgets/command.cpp
index 84f21265d..638be74d1 100644
--- a/desktop-widgets/command.cpp
+++ b/desktop-widgets/command.cpp
@@ -66,6 +66,11 @@ void splitDives(dive *d, duration_t time)
execute(new SplitDives(d, time));
}
+void splitDiveComputer(dive *d, int dc_num)
+{
+ execute(new SplitDiveComputer(d, dc_num));
+}
+
void mergeDives(const QVector <dive *> &dives)
{
execute(new MergeDives(dives));
diff --git a/desktop-widgets/command.h b/desktop-widgets/command.h
index d527fff3b..4c6240a93 100644
--- a/desktop-widgets/command.h
+++ b/desktop-widgets/command.h
@@ -32,6 +32,7 @@ void createTrip(const QVector<dive *> &divesToAddIn);
void autogroupDives();
void mergeTrips(dive_trip *trip1, dive_trip *trip2);
void splitDives(dive *d, duration_t time);
+void splitDiveComputer(dive *d, int dc_num);
void mergeDives(const QVector <dive *> &dives);
} // namespace Command
diff --git a/desktop-widgets/command_divelist.cpp b/desktop-widgets/command_divelist.cpp
index 845afac75..96c5ead95 100644
--- a/desktop-widgets/command_divelist.cpp
+++ b/desktop-widgets/command_divelist.cpp
@@ -8,6 +8,8 @@
#include "core/subsurface-qt/DiveListNotifier.h"
#include "qt-models/filtermodels.h"
+#include <array>
+
namespace Command {
// Generally, signals are sent in batches per trip. To avoid writing the same loop
@@ -822,42 +824,51 @@ MergeTrips::MergeTrips(dive_trip *trip1, dive_trip *trip2)
divesToMove.divesToMove.push_back( { trip2->dives.dives[i], newTrip } );
}
-SplitDives::SplitDives(dive *d, duration_t time)
+// std::array<dive *, 2> is the same as struct *dive[2], with the fundamental
+// difference that it can be returned from functions. Thus, this constructor
+// can be chained with the result of a function.
+SplitDivesBase::SplitDivesBase(dive *d, std::array<dive *, 2> newDives)
{
- setText(tr("split dive"));
-
- // Split the dive
- dive *new1, *new2;
- int idx = time.seconds < 0 ?
- split_dive(d, &new1, &new2) :
- split_dive_at_time(d, time, &new1, &new2);
-
- // If this didn't work, simply return. Empty arrays indicate that nothing is to be done.
- if (idx < 0)
+ // If either of the new dives is null, simply return. Empty arrays indicate that nothing is to be done.
+ if (!newDives[0] || !newDives[1])
return;
// Currently, the core code selects the dive -> this is not what we want, as
// we manually manage the selection post-command.
// TODO: Reset selection in core.
- new1->selected = false;
- new2->selected = false;
+ newDives[0]->selected = false;
+ newDives[1]->selected = false;
+
+ // Getting the insertion indexes correct is actually not easy, as we don't know
+ // which of the dives will land first when splitting out dive computers!
+ // TODO: We really should think about not storing the insertion index in the undo
+ // command, but calculating it on the fly on execution.
+ int idx_old = get_divenr(d);
+ int idx1 = dive_table_get_insertion_index(&dive_table, newDives[0]);
+ int idx2 = dive_table_get_insertion_index(&dive_table, newDives[1]);
+ if (idx1 > idx_old)
+ --idx1;
+ if (idx2 > idx_old)
+ --idx2;
+ if (idx1 == idx2 && dive_less_than(newDives[0], newDives[1]))
+ ++idx2;
diveToSplit.push_back(d);
splitDives.dives.resize(2);
- splitDives.dives[0].dive.reset(new1);
+ splitDives.dives[0].dive.reset(newDives[0]);
splitDives.dives[0].trip = d->divetrip;
- splitDives.dives[0].idx = idx;
- splitDives.dives[1].dive.reset(new2);
+ splitDives.dives[0].idx = idx1;
+ splitDives.dives[1].dive.reset(newDives[1]);
splitDives.dives[1].trip = d->divetrip;
- splitDives.dives[1].idx = idx + 1;
+ splitDives.dives[1].idx = idx2;
}
-bool SplitDives::workToBeDone()
+bool SplitDivesBase::workToBeDone()
{
return !diveToSplit.empty();
}
-void SplitDives::redoit()
+void SplitDivesBase::redoit()
{
divesToUnsplit = addDives(splitDives);
unsplitDive = removeDives(diveToSplit);
@@ -867,7 +878,7 @@ void SplitDives::redoit()
restoreSelection(divesToUnsplit, divesToUnsplit[0]);
}
-void SplitDives::undoit()
+void SplitDivesBase::undoit()
{
// Note: reverse order with respect to redoit()
diveToSplit = addDives(unsplitDive);
@@ -878,6 +889,41 @@ void SplitDives::undoit()
restoreSelection(diveToSplit, diveToSplit[0] );
}
+static std::array<dive *, 2> doSplitDives(const dive *d, duration_t time)
+{
+ // Split the dive
+ dive *new1, *new2;
+ if (time.seconds < 0)
+ split_dive(d, &new1, &new2);
+ else
+ split_dive_at_time(d, time, &new1, &new2);
+
+ return { new1, new2 };
+}
+
+SplitDives::SplitDives(dive *d, duration_t time) : SplitDivesBase(d, doSplitDives(d, time))
+{
+ setText(tr("split dive"));
+}
+
+static std::array<dive *, 2> splitDiveComputer(const dive *d, int dc_num)
+{
+ // Refuse to do anything if the dive has only one dive computer.
+ // Yes, this should have been checked by the UI, but let's just make sure.
+ if (!d->dc.next)
+ return { nullptr, nullptr};
+
+ dive *new1, *new2;
+ split_divecomputer(d, dc_num, &new1, &new2);
+
+ return { new1, new2 };
+}
+
+SplitDiveComputer::SplitDiveComputer(dive *d, int dc_num) : SplitDivesBase(d, splitDiveComputer(d, dc_num))
+{
+ setText(tr("split dive computer"));
+}
+
MergeDives::MergeDives(const QVector <dive *> &dives)
{
setText(tr("merge dive"));
diff --git a/desktop-widgets/command_divelist.h b/desktop-widgets/command_divelist.h
index 6cf7f48ab..7742cf729 100644
--- a/desktop-widgets/command_divelist.h
+++ b/desktop-widgets/command_divelist.h
@@ -185,10 +185,9 @@ struct MergeTrips : public TripBase {
MergeTrips(dive_trip *trip1, dive_trip *trip2);
};
-class SplitDives : public DiveListBase {
-public:
- // If time is < 0, split at first surface interval
- SplitDives(dive *d, duration_t time);
+class SplitDivesBase : public DiveListBase {
+protected:
+ SplitDivesBase(dive *old, std::array<dive *, 2> newDives);
private:
void undoit() override;
void redoit() override;
@@ -209,6 +208,18 @@ private:
std::vector<dive *> divesToUnsplit;
};
+class SplitDives : public SplitDivesBase {
+public:
+ // If time is < 0, split at first surface interval
+ SplitDives(dive *d, duration_t time);
+};
+
+class SplitDiveComputer : public SplitDivesBase {
+public:
+ // If time is < 0, split at first surface interval
+ SplitDiveComputer(dive *d, int dc_num);
+};
+
class MergeDives : public DiveListBase {
public:
MergeDives(const QVector<dive *> &dives);