The DiveCalculatedCeiling profile-item has a recalc()
function, which calls "dataModel->calculateDecompression()".
This is a questionable reversal of control-flow: The
profile-item should paint the model-data not change it.
The code was supposed to be called under two conditions:
1) The value of the calcceiling3m preferences flag changed.
This code was buggy for two reasons: Firstly, the cached
value was always initialized to false, which means that
sometimes the first call was missed. Secondly, the
settingsChanged() functions was only called when closing
the preferences window, not when changing the flag in the
profile widgets.
2) The datetime of the dive changed. The whole control-flow is
pretty absurd (due to "bit rot"):
- The replan-dive command sends a date-time changed signal.
- The main tab changes the date-time and informs the profile.
- The profile sends a signal to the item.
- The item instructs the model to recalculate the
decompression.
- The model causes the profile to be redrawn.
In any case, the whole thing is moot, because the decompression
is recalculated for *every* profile plot in create_plot_info_new().
Let's remove the code from the DiveCalculatedCeiling profile-item
and the calculateDecompression() function, which is now not
used anymore.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
221 lines
7.6 KiB
C++
221 lines
7.6 KiB
C++
// SPDX-License-Identifier: GPL-2.0
|
|
#ifndef DIVEPROFILEITEM_H
|
|
#define DIVEPROFILEITEM_H
|
|
|
|
#include <QObject>
|
|
#include <QGraphicsPolygonItem>
|
|
#include <QModelIndex>
|
|
|
|
#include "divelineitem.h"
|
|
|
|
/* This is the Profile Item, it should be used for quite a lot of things
|
|
on the profile view. The usage should be pretty simple:
|
|
|
|
DiveProfileItem *profile = new DiveProfileItem();
|
|
profile->setVerticalAxis( profileYAxis );
|
|
profile->setHorizontalAxis( timeAxis );
|
|
profile->setModel( DiveDataModel );
|
|
profile->setHorizontalDataColumn( DiveDataModel::TIME );
|
|
profile->setVerticalDataColumn( DiveDataModel::DEPTH );
|
|
scene()->addItem(profile);
|
|
|
|
This is a generically item and should be used as a base for others, I think...
|
|
*/
|
|
|
|
class ProfileWidget2;
|
|
class DivePlotDataModel;
|
|
class DiveTextItem;
|
|
class DiveCartesianAxis;
|
|
class QAbstractTableModel;
|
|
struct plot_data;
|
|
|
|
class AbstractProfilePolygonItem : public QObject, public QGraphicsPolygonItem {
|
|
Q_OBJECT
|
|
Q_PROPERTY(QPointF pos WRITE setPos READ pos)
|
|
Q_PROPERTY(qreal x WRITE setX READ x)
|
|
Q_PROPERTY(qreal y WRITE setY READ y)
|
|
public:
|
|
AbstractProfilePolygonItem();
|
|
void setVerticalAxis(DiveCartesianAxis *vertical);
|
|
void setHorizontalAxis(DiveCartesianAxis *horizontal);
|
|
void setModel(DivePlotDataModel *model);
|
|
void setHorizontalDataColumn(int column);
|
|
void setVerticalDataColumn(int column);
|
|
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) = 0;
|
|
public
|
|
slots:
|
|
virtual void settingsChanged();
|
|
virtual void modelDataChanged(const QModelIndex &topLeft = QModelIndex(), const QModelIndex &bottomRight = QModelIndex());
|
|
virtual void modelDataRemoved(const QModelIndex &parent, int from, int to);
|
|
void setVisible(bool visible);
|
|
|
|
protected:
|
|
/* when the model emits a 'datachanged' signal, this method below should be used to check if the
|
|
* modified data affects this particular item ( for example, when setting the '3m increment'
|
|
* the data for Ceiling and tissues will be changed, and only those. so, the topLeft will be the CEILING
|
|
* column and the bottomRight will have the TISSUE_16 column. this method takes the vDataColumn and hDataColumn
|
|
* into consideration when returning 'true' for "yes, continue the calculation', and 'false' for
|
|
* 'do not recalculate, we already have the right data.
|
|
*/
|
|
bool shouldCalculateStuff(const QModelIndex &topLeft, const QModelIndex &bottomRight);
|
|
|
|
DiveCartesianAxis *hAxis;
|
|
DiveCartesianAxis *vAxis;
|
|
DivePlotDataModel *dataModel;
|
|
int hDataColumn;
|
|
int vDataColumn;
|
|
QList<DiveTextItem *> texts;
|
|
};
|
|
|
|
class DiveProfileItem : public AbstractProfilePolygonItem {
|
|
Q_OBJECT
|
|
|
|
public:
|
|
DiveProfileItem();
|
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override;
|
|
void modelDataChanged(const QModelIndex &topLeft = QModelIndex(), const QModelIndex &bottomRight = QModelIndex()) override;
|
|
void settingsToggled(bool toggled);
|
|
void settingsChanged() override;
|
|
void plot_depth_sample(struct plot_data *entry, QFlags<Qt::AlignmentFlag> flags, const QColor &color);
|
|
int maxCeiling(int row);
|
|
|
|
private:
|
|
unsigned int show_reported_ceiling;
|
|
unsigned int reported_ceiling_in_red;
|
|
QColor profileColor;
|
|
};
|
|
|
|
class DiveMeanDepthItem : public AbstractProfilePolygonItem {
|
|
Q_OBJECT
|
|
public:
|
|
DiveMeanDepthItem();
|
|
void modelDataChanged(const QModelIndex &topLeft = QModelIndex(), const QModelIndex &bottomRight = QModelIndex()) override;
|
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override;
|
|
|
|
private:
|
|
void createTextItem();
|
|
double lastRunningSum;
|
|
QString visibilityKey;
|
|
};
|
|
|
|
class DiveTemperatureItem : public AbstractProfilePolygonItem {
|
|
Q_OBJECT
|
|
public:
|
|
DiveTemperatureItem();
|
|
void modelDataChanged(const QModelIndex &topLeft = QModelIndex(), const QModelIndex &bottomRight = QModelIndex()) override;
|
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override;
|
|
|
|
private:
|
|
void createTextItem(int seconds, int mkelvin);
|
|
};
|
|
|
|
class DiveHeartrateItem : public AbstractProfilePolygonItem {
|
|
Q_OBJECT
|
|
public:
|
|
DiveHeartrateItem();
|
|
void modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) override;
|
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
|
|
|
private:
|
|
void createTextItem(int seconds, int hr);
|
|
QString visibilityKey;
|
|
};
|
|
|
|
class DivePercentageItem : public AbstractProfilePolygonItem {
|
|
Q_OBJECT
|
|
public:
|
|
DivePercentageItem(int i);
|
|
void modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) override;
|
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
|
|
|
private:
|
|
QString visibilityKey;
|
|
int tissueIndex;
|
|
QColor ColorScale(double value, int inert);
|
|
|
|
};
|
|
|
|
class DiveAmbPressureItem : public AbstractProfilePolygonItem {
|
|
Q_OBJECT
|
|
public:
|
|
DiveAmbPressureItem();
|
|
void modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) override;
|
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
|
|
|
private:
|
|
QString visibilityKey;
|
|
};
|
|
|
|
class DiveGFLineItem : public AbstractProfilePolygonItem {
|
|
Q_OBJECT
|
|
public:
|
|
DiveGFLineItem();
|
|
void modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) override;
|
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
|
|
|
private:
|
|
QString visibilityKey;
|
|
};
|
|
|
|
class DiveGasPressureItem : public AbstractProfilePolygonItem {
|
|
Q_OBJECT
|
|
|
|
public:
|
|
void modelDataChanged(const QModelIndex &topLeft = QModelIndex(), const QModelIndex &bottomRight = QModelIndex()) override;
|
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override;
|
|
|
|
private:
|
|
void plotPressureValue(int mbar, int sec, QFlags<Qt::AlignmentFlag> align, double offset);
|
|
void plotGasValue(int mbar, int sec, struct gasmix gasmix, QFlags<Qt::AlignmentFlag> align, double offset);
|
|
QVector<QPolygonF> polygons;
|
|
};
|
|
|
|
class DiveCalculatedCeiling : public AbstractProfilePolygonItem {
|
|
Q_OBJECT
|
|
|
|
public:
|
|
DiveCalculatedCeiling(ProfileWidget2 *profileWidget);
|
|
void modelDataChanged(const QModelIndex &topLeft = QModelIndex(), const QModelIndex &bottomRight = QModelIndex()) override;
|
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override;
|
|
|
|
private:
|
|
ProfileWidget2 *profileWidget;
|
|
};
|
|
|
|
class DiveReportedCeiling : public AbstractProfilePolygonItem {
|
|
Q_OBJECT
|
|
|
|
public:
|
|
DiveReportedCeiling();
|
|
void modelDataChanged(const QModelIndex &topLeft = QModelIndex(), const QModelIndex &bottomRight = QModelIndex()) override;
|
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override;
|
|
};
|
|
|
|
class DiveCalculatedTissue : public DiveCalculatedCeiling {
|
|
Q_OBJECT
|
|
public:
|
|
DiveCalculatedTissue(ProfileWidget2 *profileWidget);
|
|
void setVisible(bool visible);
|
|
void settingsChanged() override;
|
|
};
|
|
|
|
class PartialPressureGasItem : public AbstractProfilePolygonItem {
|
|
Q_OBJECT
|
|
public:
|
|
PartialPressureGasItem();
|
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override;
|
|
void modelDataChanged(const QModelIndex &topLeft = QModelIndex(), const QModelIndex &bottomRight = QModelIndex()) override;
|
|
void setThresholdSettingsKey(const double *prefPointerMin, const double *prefPointerMax);
|
|
void setVisibilitySettingsKey(const QString &setVisibilitySettingsKey);
|
|
void setColors(const QColor &normalColor, const QColor &alertColor);
|
|
|
|
private:
|
|
QVector<QPolygonF> alertPolygons;
|
|
const double *thresholdPtrMin;
|
|
const double *thresholdPtrMax;
|
|
QString visibilityKey;
|
|
QColor normalColor;
|
|
QColor alertColor;
|
|
};
|
|
#endif // DIVEPROFILEITEM_H
|