From bdbcb1b7e38195c3c059dcc5393b6c961c9a5483 Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Fri, 3 Dec 2021 19:04:33 +0100 Subject: [PATCH] profile: access the ProfileScene's plot_info There were two plot_infos of the same dive: one owned by ProfileScene and one owned by DivePlotDataModel. The latter was (or at least should have been) a copy of the former. Simply always access the plot-info which is owned by ProfileScene anyway. That seems much less brittle. Why risk some desyncing? Signed-off-by: Berthold Stoeger --- profile-widget/diveprofileitem.cpp | 78 +++++++++++++++--------------- profile-widget/diveprofileitem.h | 22 ++++----- profile-widget/profilescene.cpp | 10 ++-- 3 files changed, 54 insertions(+), 56 deletions(-) diff --git a/profile-widget/diveprofileitem.cpp b/profile-widget/diveprofileitem.cpp index 73192125f..c5287560b 100644 --- a/profile-widget/diveprofileitem.cpp +++ b/profile-widget/diveprofileitem.cpp @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 #include "profile-widget/diveprofileitem.h" -#include "qt-models/diveplotdatamodel.h" #include "profile-widget/divecartesianaxis.h" #include "profile-widget/divetextitem.h" #include "profile-widget/animationfunctions.h" @@ -12,10 +11,10 @@ #include "libdivecomputer/parser.h" #include "profile-widget/profilewidget2.h" -AbstractProfilePolygonItem::AbstractProfilePolygonItem(const DivePlotDataModel &model, const DiveCartesianAxis &horizontal, +AbstractProfilePolygonItem::AbstractProfilePolygonItem(const plot_info &pInfo, const DiveCartesianAxis &horizontal, const DiveCartesianAxis &vertical, DataAccessor accessor, double dpr) : - hAxis(horizontal), vAxis(vertical), dataModel(model), accessor(accessor), dpr(dpr), from(0), to(0) + hAxis(horizontal), vAxis(vertical), pInfo(pInfo), accessor(accessor), dpr(dpr), from(0), to(0) { setCacheMode(DeviceCoordinateCache); } @@ -47,7 +46,7 @@ void AbstractProfilePolygonItem::clipStop(double &x, double &y, double prev_x, d std::pair AbstractProfilePolygonItem::getPoint(int i) const { - const struct plot_data *data = dataModel.data().entry; + const struct plot_data *data = pInfo.entry; double x = data[i].sec; double y = accessor(data[i]); @@ -97,9 +96,9 @@ void AbstractProfilePolygonItem::makePolygon(int fromIn, int toIn) texts.clear(); } -DiveProfileItem::DiveProfileItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis, +DiveProfileItem::DiveProfileItem(const plot_info &pInfo, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, DataAccessor accessor, double dpr) : - AbstractProfilePolygonItem(model, hAxis, vAxis, accessor, dpr), + AbstractProfilePolygonItem(pInfo, hAxis, vAxis, accessor, dpr), show_reported_ceiling(0), reported_ceiling_in_red(0) { } @@ -121,7 +120,7 @@ void DiveProfileItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *o pen.setCosmetic(true); pen.setWidth(2); QPolygonF poly = polygon(); - const struct plot_data *data = dataModel.data().entry; + const struct plot_data *data = pInfo.entry; // This paints the colors of the velocities. for (int i = from + 1; i < to; i++) { QColor color = getColor((color_index_t)(VELOCITY_COLORS_START_IDX + data[i].velocity)); @@ -146,13 +145,13 @@ void DiveProfileItem::replot(const dive *d, int from, int to, bool in_planner) show_reported_ceiling = prefs.dcceiling; reported_ceiling_in_red = prefs.redceiling; - profileColor = dataModel.data().waypoint_above_ceiling ? QColor(Qt::red) - : getColor(DEPTH_BOTTOM); + profileColor = pInfo.waypoint_above_ceiling ? QColor(Qt::red) + : getColor(DEPTH_BOTTOM); /* Show any ceiling we may have encountered */ if (prefs.dcceiling && !prefs.redceiling) { QPolygonF p = polygon(); - plot_data *entry = dataModel.data().entry + to - 1; + plot_data *entry = pInfo.entry + to - 1; for (int i = to - 1; i >= from; i--, entry--) { if (!entry->in_deco) { /* not in deco implies this is a safety stop, no ceiling */ @@ -178,7 +177,7 @@ void DiveProfileItem::replot(const dive *d, int from, int to, bool in_planner) const int half_interval = vAxis.getMinLabelDistance(hAxis); const int min_depth = 2000; // in mm const int min_prominence = 2000; // in mm (should this adapt to depth range?) - const plot_data *data = dataModel.data().entry; + const plot_data *data = pInfo.entry; const int max_peaks = (data[to - 1].sec - data[from].sec) / half_interval + 1; struct Peak { int range_from; @@ -261,9 +260,9 @@ void DiveProfileItem::plot_depth_sample(const struct plot_data &entry, QFlagsrestore(); } -DiveTemperatureItem::DiveTemperatureItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis, +DiveTemperatureItem::DiveTemperatureItem(const plot_info &pInfo, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, DataAccessor accessor, double dpr) : - AbstractProfilePolygonItem(model, hAxis, vAxis, accessor, dpr) + AbstractProfilePolygonItem(pInfo, hAxis, vAxis, accessor, dpr) { QPen pen; pen.setBrush(QBrush(getColor(::TEMP_PLOT))); @@ -437,9 +436,9 @@ void DiveTemperatureItem::paint(QPainter *painter, const QStyleOptionGraphicsIte static const double diveMeanDepthItemLabelScale = 0.8; -DiveMeanDepthItem::DiveMeanDepthItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis, +DiveMeanDepthItem::DiveMeanDepthItem(const plot_info &pInfo, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, DataAccessor accessor, double dpr) : - AbstractProfilePolygonItem(model, hAxis, vAxis, accessor, dpr), + AbstractProfilePolygonItem(pInfo, hAxis, vAxis, accessor, dpr), labelWidth(DiveTextItem::getLabelSize(dpr, diveMeanDepthItemLabelScale, QStringLiteral("999.9ft")).first) { QPen pen; @@ -453,7 +452,7 @@ DiveMeanDepthItem::DiveMeanDepthItem(const DivePlotDataModel &model, const DiveC std::pair DiveMeanDepthItem::getMeanDepth(int i) const { for ( ; i >= 0; --i) { - const plot_data &entry = dataModel.data().entry[i]; + const plot_data &entry = pInfo.entry[i]; if (entry.running_sum > 0) return { static_cast(entry.sec), static_cast(entry.running_sum) / entry.sec }; @@ -463,9 +462,9 @@ std::pair DiveMeanDepthItem::getMeanDepth(int i) const std::pair DiveMeanDepthItem::getNextMeanDepth(int first) const { - int last = dataModel.data().nr; + int last = pInfo.nr; for (int i = first + 1; i < last; ++i) { - const plot_data &entry = dataModel.data().entry[i]; + const plot_data &entry = pInfo.entry[i]; if (entry.running_sum > 0) return { static_cast(entry.sec), static_cast(entry.running_sum) / entry.sec }; @@ -531,25 +530,24 @@ void DiveGasPressureItem::replot(const dive *d, int fromIn, int toIn, bool in_pl from = fromIn; to = toIn; - const struct plot_info *pInfo = &dataModel.data(); - std::vector plotted_cyl(pInfo->nr_cylinders, false); - std::vector last_plotted(pInfo->nr_cylinders, 0.0); - std::vector act_segments(pInfo->nr_cylinders); + std::vector plotted_cyl(pInfo.nr_cylinders, false); + std::vector last_plotted(pInfo.nr_cylinders, 0.0); + std::vector act_segments(pInfo.nr_cylinders); QPolygonF boundingPoly; segments.clear(); for (int i = from; i < to; i++) { - const struct plot_data *entry = pInfo->entry + i; + const struct plot_data *entry = pInfo.entry + i; - for (int cyl = 0; cyl < pInfo->nr_cylinders; cyl++) { - double mbar = static_cast(get_plot_pressure(pInfo, i, cyl)); + for (int cyl = 0; cyl < pInfo.nr_cylinders; cyl++) { + double mbar = static_cast(get_plot_pressure(&pInfo, i, cyl)); double time = static_cast(entry->sec); if (mbar < 1.0) continue; if (i == from && i < to - 1) { - double mbar2 = static_cast(get_plot_pressure(pInfo, i+1, cyl)); + double mbar2 = static_cast(get_plot_pressure(&pInfo, i+1, cyl)); double time2 = static_cast(entry[1].sec); if (mbar2 < 1.0) continue; @@ -557,7 +555,7 @@ void DiveGasPressureItem::replot(const dive *d, int fromIn, int toIn, bool in_pl } if (i == to - 1 && i > from) { - double mbar2 = static_cast(get_plot_pressure(pInfo, i-1, cyl)); + double mbar2 = static_cast(get_plot_pressure(&pInfo, i-1, cyl)); double time2 = static_cast(entry[-1].sec); if (mbar2 < 1.0) continue; @@ -606,7 +604,7 @@ void DiveGasPressureItem::replot(const dive *d, int fromIn, int toIn, bool in_pl } } - for (int cyl = 0; cyl < pInfo->nr_cylinders; cyl++) { + for (int cyl = 0; cyl < pInfo.nr_cylinders; cyl++) { if (act_segments[cyl].polygon.empty()) continue; act_segments[cyl].cyl = cyl; @@ -626,7 +624,7 @@ void DiveGasPressureItem::replot(const dive *d, int fromIn, int toIn, bool in_pl // pressures. QFlags alignVar = Qt::AlignTop; - std::vector> align(pInfo->nr_cylinders); + std::vector> align(pInfo.nr_cylinders); double labelHeight = DiveTextItem::fontHeight(dpr, 1.0); @@ -685,9 +683,9 @@ void DiveGasPressureItem::paint(QPainter *painter, const QStyleOptionGraphicsIte painter->restore(); } -DiveCalculatedCeiling::DiveCalculatedCeiling(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis, +DiveCalculatedCeiling::DiveCalculatedCeiling(const plot_info &pInfo, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, DataAccessor accessor, double dpr) : - AbstractProfilePolygonItem(model, hAxis, vAxis, accessor, dpr) + AbstractProfilePolygonItem(pInfo, hAxis, vAxis, accessor, dpr) { } @@ -709,21 +707,21 @@ void DiveCalculatedCeiling::paint(QPainter *painter, const QStyleOptionGraphicsI QGraphicsPolygonItem::paint(painter, option, widget); } -DiveCalculatedTissue::DiveCalculatedTissue(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis, +DiveCalculatedTissue::DiveCalculatedTissue(const plot_info &pInfo, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, DataAccessor accessor, double dpr) : - DiveCalculatedCeiling(model, hAxis, vAxis, accessor, dpr) + DiveCalculatedCeiling(pInfo, hAxis, vAxis, accessor, dpr) { } -DiveReportedCeiling::DiveReportedCeiling(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis, +DiveReportedCeiling::DiveReportedCeiling(const plot_info &pInfo, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, DataAccessor accessor, double dpr) : - AbstractProfilePolygonItem(model, hAxis, vAxis, accessor, dpr) + AbstractProfilePolygonItem(pInfo, hAxis, vAxis, accessor, dpr) { } std::pair DiveReportedCeiling::getTimeValue(int i) const { - const plot_data &entry = dataModel.data().entry[i]; + const plot_data &entry = pInfo.entry[i]; int value = entry.in_deco && entry.stopdepth ? std::min(entry.stopdepth, entry.depth) : 0; return { static_cast(entry.sec), static_cast(value) }; } @@ -841,9 +839,9 @@ void PartialPressureGasItem::setThresholdSettingsKey(const double *prefPointerMi thresholdPtrMax = prefPointerMax; } -PartialPressureGasItem::PartialPressureGasItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis, +PartialPressureGasItem::PartialPressureGasItem(const plot_info &pInfo, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, DataAccessor accessor, double dpr) : - AbstractProfilePolygonItem(model, hAxis, vAxis, accessor, dpr), + AbstractProfilePolygonItem(pInfo, hAxis, vAxis, accessor, dpr), thresholdPtrMin(NULL), thresholdPtrMax(NULL) { diff --git a/profile-widget/diveprofileitem.h b/profile-widget/diveprofileitem.h index c6cfe822e..49e947e5c 100644 --- a/profile-widget/diveprofileitem.h +++ b/profile-widget/diveprofileitem.h @@ -15,16 +15,16 @@ This is a generically item and should be used as a base for others, I think... */ -class DivePlotDataModel; class DiveTextItem; class DiveCartesianAxis; struct plot_data; +struct plot_info; struct dive; class AbstractProfilePolygonItem : public QGraphicsPolygonItem { public: using DataAccessor = double (*)(const plot_data &data); // The pointer-to-function syntax is hilarious. - AbstractProfilePolygonItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, + AbstractProfilePolygonItem(const plot_info &pInfo, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, DataAccessor accessor, double dpr); virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) = 0; void clear(); @@ -40,7 +40,7 @@ protected: std::pair getPoint(int i) const; const DiveCartesianAxis &hAxis; const DiveCartesianAxis &vAxis; - const DivePlotDataModel &dataModel; + const plot_info &pInfo; DataAccessor accessor; double dpr; int from, to; @@ -49,7 +49,7 @@ protected: class DiveProfileItem : public AbstractProfilePolygonItem { public: - DiveProfileItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, + DiveProfileItem(const plot_info &pInfo, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, DataAccessor accessor, double dpr); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override; void replot(const dive *d, int from, int to, bool in_planner) override; @@ -64,7 +64,7 @@ private: class DiveMeanDepthItem : public AbstractProfilePolygonItem { public: - DiveMeanDepthItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, + DiveMeanDepthItem(const plot_info &pInfo, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, DataAccessor accessor, double dpr); void replot(const dive *d, int from, int to, bool in_planner) override; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override; @@ -78,7 +78,7 @@ private: class DiveTemperatureItem : public AbstractProfilePolygonItem { public: - DiveTemperatureItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, + DiveTemperatureItem(const plot_info &pInfo, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, DataAccessor accessor, double dpr); void replot(const dive *d, int from, int to, bool in_planner) override; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override; @@ -89,7 +89,7 @@ private: class DiveHeartrateItem : public AbstractProfilePolygonItem { public: - DiveHeartrateItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, + DiveHeartrateItem(const plot_info &pInfo, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, DataAccessor accessor, double dpr); void replot(const dive *d, int from, int to, bool in_planner) override; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; @@ -125,7 +125,7 @@ private: class DiveCalculatedCeiling : public AbstractProfilePolygonItem { public: - DiveCalculatedCeiling(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis, + DiveCalculatedCeiling(const plot_info &pInfo, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, DataAccessor accessor, double dpr); void replot(const dive *d, int from, int to, bool in_planner) override; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override; @@ -133,7 +133,7 @@ public: class DiveReportedCeiling : public AbstractProfilePolygonItem { public: - DiveReportedCeiling(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, DataAccessor accessor, double dpr); + DiveReportedCeiling(const plot_info &pInfo, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, DataAccessor accessor, double dpr); void replot(const dive *d, int from, int to, bool in_planner) override; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override; private: @@ -143,13 +143,13 @@ private: class DiveCalculatedTissue : public DiveCalculatedCeiling { public: - DiveCalculatedTissue(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis, + DiveCalculatedTissue(const plot_info &pInfo, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, DataAccessor accessor, double dpr); }; class PartialPressureGasItem : public AbstractProfilePolygonItem { public: - PartialPressureGasItem(const DivePlotDataModel &model, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, DataAccessor accessor, double dpr); + PartialPressureGasItem(const plot_info &pInfo, const DiveCartesianAxis &hAxis, const DiveCartesianAxis &vAxis, DataAccessor accessor, double dpr); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override; void replot(const dive *d, int from, int to, bool in_planner) override; void setThresholdSettingsKey(const double *prefPointerMin, const double *prefPointerMax); diff --git a/profile-widget/profilescene.cpp b/profile-widget/profilescene.cpp index fb5eac5da..90671bf19 100644 --- a/profile-widget/profilescene.cpp +++ b/profile-widget/profilescene.cpp @@ -50,7 +50,7 @@ public: template T *ProfileScene::createItem(const DiveCartesianAxis &vAxis, DataAccessor accessor, int z, Args&&... args) { - T *res = new T(*dataModel, *timeAxis, vAxis, accessor, std::forward(args)...); + T *res = new T(plotInfo, *timeAxis, vAxis, accessor, std::forward(args)...); res->setZValue(static_cast(z)); profileItems.push_back(res); return res; @@ -518,11 +518,11 @@ void ProfileScene::plotDive(const struct dive *dIn, int dcIn, DivePlannerPointsM tankItem->setData(d, firstSecond, lastSecond); if (ppGraphsEnabled(currentdc, simplified)) { - double max = prefs.pp_graphs.phe ? max_gas(dataModel->data(), &gas_pressures::he) : -1; + double max = prefs.pp_graphs.phe ? max_gas(plotInfo, &gas_pressures::he) : -1; if (prefs.pp_graphs.pn2) - max = std::max(max_gas(dataModel->data(), &gas_pressures::n2), max); + max = std::max(max_gas(plotInfo, &gas_pressures::n2), max); if (prefs.pp_graphs.po2) - max = std::max(max_gas(dataModel->data(), &gas_pressures::o2), max); + max = std::max(max_gas(plotInfo, &gas_pressures::o2), max); gasYAxis->setBounds(0.0, max); gasYAxis->updateTicks(animSpeed); @@ -534,7 +534,7 @@ void ProfileScene::plotDive(const struct dive *dIn, int dcIn, DivePlannerPointsM item->replot(d, from, to, inPlanner); if (prefs.percentagegraph) - percentageItem->replot(d, currentdc, dataModel->data()); + percentageItem->replot(d, currentdc, plotInfo); // The event items are a bit special since we don't know how many events are going to // exist on a dive, so I cant create cache items for that. that's why they are here