diff options
author | jan Iversen <jan@casacondor.com> | 2020-01-24 13:31:51 +0100 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2020-01-27 14:25:03 -0800 |
commit | 6cd46bee063f3cc90934480cba3f8fb7908149bd (patch) | |
tree | b89902837e68a908e897504b730796ed9cb72cd4 /backend-shared | |
parent | bb13065a75fd02d0732575b2c01cb3210ad96f32 (diff) | |
download | subsurface-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.txt | 1 | ||||
-rw-r--r-- | backend-shared/divesummary.cpp | 169 | ||||
-rw-r--r-- | backend-shared/divesummary.h | 28 |
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 |