aboutsummaryrefslogtreecommitdiffstats
path: root/backend-shared
diff options
context:
space:
mode:
authorGravatar jan Iversen <jan@casacondor.com>2020-01-24 13:31:51 +0100
committerGravatar Dirk Hohndel <dirk@hohndel.org>2020-01-27 14:25:03 -0800
commit6cd46bee063f3cc90934480cba3f8fb7908149bd (patch)
treeb89902837e68a908e897504b730796ed9cb72cd4 /backend-shared
parentbb13065a75fd02d0732575b2c01cb3210ad96f32 (diff)
downloadsubsurface-6cd46bee063f3cc90934480cba3f8fb7908149bd.tar.gz
divesummary: add DiveSummary class to shared and backend
Create DiveSummary class in backend-shared and make the DiveSummary calculation results available to QML. This adds a loop over all dives (could have been done with a model, but the models available to mobile are very limited, so use the basic way). [Dirk Hohndel: renamed the results variable and combined a couple of commits] Signed-off-by: jan Iversen <jan@casacondor.com> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Diffstat (limited to 'backend-shared')
-rw-r--r--backend-shared/CMakeLists.txt1
-rw-r--r--backend-shared/divesummary.cpp169
-rw-r--r--backend-shared/divesummary.h28
3 files changed, 198 insertions, 0 deletions
diff --git a/backend-shared/CMakeLists.txt b/backend-shared/CMakeLists.txt
index fdfdb1e05..4ecd58074 100644
--- a/backend-shared/CMakeLists.txt
+++ b/backend-shared/CMakeLists.txt
@@ -1,6 +1,7 @@
# backend functionality shared between Desktop (UI) and Mobile (QML)
set(BACKEND_SRCS
+ divesummary.cpp
exportfuncs.cpp
exportfuncs.h
plannershared.cpp
diff --git a/backend-shared/divesummary.cpp b/backend-shared/divesummary.cpp
new file mode 100644
index 000000000..43f34a7ff
--- /dev/null
+++ b/backend-shared/divesummary.cpp
@@ -0,0 +1,169 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "divesummary.h"
+#include "core/qthelper.h"
+#include "core/settings/qPrefUnit.h"
+
+#include <QDateTime>
+
+QStringList diveSummary::diveSummaryText;
+
+timestamp_t diveSummary::firstDive, diveSummary::lastDive;
+int diveSummary::dives[2], diveSummary::divesEAN[2], diveSummary::divesDeep[2], diveSummary::diveplans[2];
+long diveSummary::divetime[2], diveSummary::depth[2], diveSummary::sac[2];
+long diveSummary::divetimeMax[2], diveSummary::depthMax[2], diveSummary::sacMin[2];
+
+void diveSummary::summaryCalculation(int primaryPeriod, int secondaryPeriod)
+{
+ QDateTime localTime;
+
+ // Calculate Start of the 2 periods.
+ timestamp_t now, primaryStart, secondaryStart;
+ now = QDateTime::currentMSecsSinceEpoch() / 1000L + gettimezoneoffset();
+ primaryStart = (primaryPeriod == 0) ? 0 : now - primaryPeriod * 30 * 24 * 60 * 60;
+ secondaryStart = (secondaryPeriod == 0) ? 0 : now - secondaryPeriod * 30 * 24 * 60 * 60;
+
+ // Loop over all dives and sum up data
+ loopDives(primaryStart, secondaryStart);
+
+ // prepare stringlist
+ diveSummaryText.clear();
+ diveSummaryText << "??" << "??" << "??" << "??" << "??" <<
+ "??" << "??" << "??" <<
+ "?:??" << "?:??" << "?:??" <<
+ "?:??" << "?:??" << "?:??" <<
+ "??" << "??" << "??" << "??" << "??" <<
+ "??" << "??" << "??" << "??" << "??";
+
+ // set oldest/newest date
+ if (firstDive) {
+ localTime = QDateTime::fromMSecsSinceEpoch(1000 * firstDive, Qt::UTC);
+ localTime.setTimeSpec(Qt::UTC);
+ diveSummaryText[0] = QStringLiteral("%1").arg(localTime.date().toString(prefs.date_format_short));
+ }
+ if (lastDive) {
+ localTime = QDateTime::fromMSecsSinceEpoch(1000 * lastDive, Qt::UTC);
+ localTime.setTimeSpec(Qt::UTC);
+ diveSummaryText[1] = QStringLiteral("%1").arg(localTime.date().toString(prefs.date_format_short));
+ }
+
+ // and add data
+ buildStringList(0);
+ buildStringList(1);
+}
+
+void diveSummary::loopDives(timestamp_t primaryStart, timestamp_t secondaryStart)
+{
+ struct dive *dive;
+ int i;
+
+ // Clear summary data
+ firstDive = lastDive = 0;
+ dives[0] = dives[1] = divesEAN[0] = divesEAN[1] = 0;
+ divesDeep[0] = divesDeep[1] = diveplans[0] = diveplans[1] = 0;
+ divetime[0] = divetime[1] = depth[0] = depth[1] = 0;
+ sac[0] = sac[1] = 0;
+ divetimeMax[0] = divetimeMax[1] = depthMax[0] = depthMax[1] = 0;
+ sacMin[0] = sacMin[1] = 99999;
+
+ for_each_dive (i, dive) {
+ // remember time of oldest and newest dive
+ if (i == 0)
+ firstDive = dive->when;
+ if (dive->when > lastDive)
+ lastDive = dive->when;
+
+ // check if dive is newer than primaryStart (add to first column)
+ if (dive->when > primaryStart) {
+ if (is_dc_planner(&dive->dc))
+ diveplans[0]++;
+ else
+ calculateDive(0, dive);
+ }
+
+ // check if dive is newer than secondaryStart (add to second column)
+ if (dive->when > secondaryStart) {
+ if (is_dc_planner(&dive->dc))
+ diveplans[1]++;
+ else
+ calculateDive(1, dive);
+ }
+ }
+}
+
+void diveSummary::calculateDive(int inx, struct dive *dive)
+{
+ long temp;
+
+ // one more real dive
+ dives[inx]++;
+
+ // sum dive in minutes and check for new max.
+ temp = dive->duration.seconds / 60;
+ divetime[inx] += temp;
+ if (temp > divetimeMax[inx])
+ divetimeMax[inx] = temp;
+
+ // sum depth in meters, check for new max. and if dive is a deep dive
+ temp = dive->maxdepth.mm / 1000;
+ depth[inx] += temp;
+ if (temp > depthMax[inx])
+ depthMax[inx] = temp;
+ if (temp > 39)
+ divesDeep[inx]++;
+
+ // sum SAC in liters, check for new max.
+ temp = dive->sac / 1000;
+ sac[inx] += temp;
+ if (temp < sacMin[inx])
+ sacMin[inx] = temp;
+
+ // EAN dive ?
+ for (int j = 0; j < dive->cylinders.nr; ++j) {
+ if (dive->cylinders.cylinders[j].gasmix.o2.permille > 210)
+ divesEAN[inx]++;
+ }
+}
+
+void diveSummary::buildStringList(int inx)
+{
+ int temp1, temp2;
+ QString tempStr;
+
+ if (!dives[inx])
+ return;
+
+ // dives
+ diveSummaryText[2+inx] = QStringLiteral("%1").arg(dives[inx]);
+ diveSummaryText[4+inx] = QStringLiteral("%1").arg(divesEAN[inx]);
+ diveSummaryText[6+inx] = QStringLiteral("%1").arg(divesDeep[inx]);
+
+ // time
+ temp1 = divetime[inx] / 60;
+ temp2 = divetime[inx] - temp1 * 60;
+ if (temp1 >= 100)
+ diveSummaryText[8+inx] = QStringLiteral("%1h").arg(temp1);
+ else
+ diveSummaryText[8+inx] = QStringLiteral("%1:%2").arg(temp1).arg(temp2);
+ temp1 = divetimeMax[inx] / 60;
+ temp2 = divetimeMax[inx] - temp1 * 60;
+ diveSummaryText[10+inx] = QStringLiteral("%1:%2").arg(temp1).arg(temp2);
+ temp2 = divetime[inx] / dives[inx];
+ temp1 = temp2 / 60;
+ temp2 = temp2 - temp1 * 60;
+ diveSummaryText[12+inx] = QStringLiteral("%1:%2").arg(temp1).arg(temp2);
+
+ // depth
+ tempStr = (qPrefUnits::length() == units::METERS) ? "m" : "ft";
+ diveSummaryText[14+inx] = QStringLiteral("%1%2").arg(depthMax[inx]).arg(tempStr);
+ temp1 = depth[inx] / dives[inx];
+ diveSummaryText[16+inx] = QStringLiteral("%1%2").arg(temp1).arg(tempStr);
+
+ // SAC
+ tempStr = (qPrefUnits::volume() == units::LITER) ? "l/min" : "cuft/min";
+ diveSummaryText[18+inx] = QStringLiteral("%1 %2").arg(sacMin[inx]).arg(tempStr);
+ temp1 = depth[inx] / dives[inx];
+ diveSummaryText[20+inx] = QStringLiteral("%1%2").arg(temp1).arg(tempStr);
+
+ // Diveplan(s)
+ diveSummaryText[22+inx] = QStringLiteral("%1").arg(diveplans[inx]);
+}
diff --git a/backend-shared/divesummary.h b/backend-shared/divesummary.h
new file mode 100644
index 000000000..16f8a09ec
--- /dev/null
+++ b/backend-shared/divesummary.h
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0
+#ifndef DIVESUMMARY_H
+#define DIVESUMMARY_H
+#include <QStringList>
+#include "core/dive.h"
+
+
+class diveSummary {
+
+public:
+ static void summaryCalculation(int primaryPeriod, int secondaryPeriod);
+
+ static QStringList diveSummaryText;
+
+private:
+ diveSummary() {}
+
+ static void loopDives(timestamp_t primaryStart, timestamp_t secondaryStart);
+ static void calculateDive(int inx, struct dive *dive);
+ static void buildStringList(int inx);
+
+ static timestamp_t firstDive, lastDive;
+ static int dives[2], divesEAN[2], divesDeep[2], diveplans[2];
+ static long divetime[2], depth[2], sac[2];
+ static long divetimeMax[2], depthMax[2], sacMin[2];
+ static long divetimeAvg[2], depthAvg[2], sacAvg[2];
+};
+#endif // DIVESUMMARY_H