summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--profile.c55
-rw-r--r--qt-ui/profile/animationfunctions.cpp8
-rw-r--r--qt-ui/profile/animationfunctions.h1
-rw-r--r--qt-ui/profile/divecartesianaxis.cpp51
-rw-r--r--qt-ui/profile/divecartesianaxis.h13
-rw-r--r--qt-ui/profile/diveplotdatamodel.cpp20
-rw-r--r--qt-ui/profile/diveplotdatamodel.h4
-rw-r--r--qt-ui/profile/diveprofileitem.cpp30
-rw-r--r--qt-ui/profile/diveprofileitem.h5
-rw-r--r--qt-ui/profile/profilewidget2.cpp62
-rw-r--r--qt-ui/profile/profilewidget2.h3
11 files changed, 196 insertions, 56 deletions
diff --git a/profile.c b/profile.c
index a24cd1682..82aa274f2 100644
--- a/profile.c
+++ b/profile.c
@@ -1249,6 +1249,59 @@ static void calculate_gas_information(struct dive *dive, struct plot_info *pi)
}
}
+
+static void calculate_gas_information_new(struct dive *dive, struct plot_info *pi)
+{
+ int i;
+ double amb_pressure;
+
+ for (i = 1; i < pi->nr; i++) {
+ int fo2, fhe;
+ struct plot_data *entry = pi->entry + i;
+ int cylinderindex = entry->cylinderindex;
+
+ amb_pressure = depth_to_mbar(entry->depth, dive) / 1000.0;
+ fo2 = get_o2(&dive->cylinder[cylinderindex].gasmix);
+ fhe = get_he(&dive->cylinder[cylinderindex].gasmix);
+ double ratio = (double)fhe / (1000.0 - fo2);
+
+ if (entry->po2) {
+ /* we have an O2 partial pressure in the sample - so this
+ * is likely a CC dive... use that instead of the value
+ * from the cylinder info */
+ double po2 = entry->po2 > amb_pressure ? amb_pressure : entry->po2;
+ entry->po2 = po2;
+ entry->phe = (amb_pressure - po2) * ratio;
+ entry->pn2 = amb_pressure - po2 - entry->phe;
+ } else {
+ entry->po2 = fo2 / 1000.0 * amb_pressure;
+ entry->phe = fhe / 1000.0 * amb_pressure;
+ entry->pn2 = (1000 - fo2 - fhe) / 1000.0 * amb_pressure;
+ }
+
+ /* Calculate MOD, EAD, END and EADD based on partial pressures calculated before
+ * so there is no difference in calculating between OC and CC
+ * EAD takes O2 + N2 (air) into account
+ * END just uses N2 */
+ entry->mod = (prefs.mod_ppO2 / fo2 * 1000 - 1) * 10000;
+ entry->ead = (entry->depth + 10000) *
+ (entry->po2 + (amb_pressure - entry->po2) * (1 - ratio)) / amb_pressure - 10000;
+ entry->end = (entry->depth + 10000) *
+ (amb_pressure - entry->po2) * (1 - ratio) / amb_pressure / N2_IN_AIR * 1000 - 10000;
+ entry->eadd = (entry->depth + 10000) *
+ (entry->po2 / amb_pressure * O2_DENSITY + entry->pn2 / amb_pressure *
+ N2_DENSITY + entry->phe / amb_pressure * HE_DENSITY) /
+ (O2_IN_AIR * O2_DENSITY + N2_IN_AIR * N2_DENSITY) * 1000 -10000;
+ if (entry->mod < 0)
+ entry->mod = 0;
+ if (entry->ead < 0)
+ entry->ead = 0;
+ if (entry->end < 0)
+ entry->end = 0;
+ if (entry->eadd < 0)
+ entry->eadd = 0;
+ }
+}
/*
* Create a plot-info with smoothing and ranged min/max
*
@@ -1313,7 +1366,7 @@ void create_plot_info_new(struct dive *dive, struct divecomputer *dc, struct plo
calculate_sac(dive, pi); /* Calculate sac */
if (prefs.profile_calc_ceiling) /* Then, calculate deco information */
calculate_deco_information(dive, dc, pi, false);
- calculate_gas_information(dive, pi); /* And finaly calculate gas partial pressures */
+ calculate_gas_information_new(dive, pi); /* And finaly calculate gas partial pressures */
pi->meandepth = dive->dc.meandepth.mm;
analyze_plot_info(pi);
}
diff --git a/qt-ui/profile/animationfunctions.cpp b/qt-ui/profile/animationfunctions.cpp
index baf180241..d0c7af559 100644
--- a/qt-ui/profile/animationfunctions.cpp
+++ b/qt-ui/profile/animationfunctions.cpp
@@ -7,6 +7,14 @@ namespace Animations {
void hide(QObject* obj)
{
QPropertyAnimation *animation = new QPropertyAnimation(obj, "opacity");
+ animation->setStartValue(1);
+ animation->setEndValue(0);
+ animation->start(QAbstractAnimation::DeleteWhenStopped);
+}
+
+void animDelete(QObject* obj)
+{
+ QPropertyAnimation *animation = new QPropertyAnimation(obj, "opacity");
obj->connect(animation, SIGNAL(finished()), SLOT(deleteLater()));
animation->setStartValue(1);
animation->setEndValue(0);
diff --git a/qt-ui/profile/animationfunctions.h b/qt-ui/profile/animationfunctions.h
index e1a0d4dee..ff2c34d50 100644
--- a/qt-ui/profile/animationfunctions.h
+++ b/qt-ui/profile/animationfunctions.h
@@ -7,6 +7,7 @@ class QObject;
namespace Animations{
void hide(QObject *obj);
void moveTo(QObject *obj, qreal x, qreal y);
+ void animDelete(QObject *obj);
};
#endif \ No newline at end of file
diff --git a/qt-ui/profile/divecartesianaxis.cpp b/qt-ui/profile/divecartesianaxis.cpp
index feeaf12b8..b1586f992 100644
--- a/qt-ui/profile/divecartesianaxis.cpp
+++ b/qt-ui/profile/divecartesianaxis.cpp
@@ -3,6 +3,8 @@
#include "divetextitem.h"
#include "helpers.h"
#include "preferences.h"
+#include "diveplotdatamodel.h"
+#include "animationfunctions.h"
#include <QPen>
#include <QGraphicsScene>
#include <QDebug>
@@ -20,13 +22,12 @@ static QPen gridPen(){
void DiveCartesianAxis::setMaximum(double maximum)
{
max = maximum;
- emit sizeChanged();
+ emit maxChanged();
}
void DiveCartesianAxis::setMinimum(double minimum)
{
min = minimum;
- emit sizeChanged();
}
void DiveCartesianAxis::setTextColor(const QColor& color)
@@ -64,15 +65,16 @@ void DiveCartesianAxis::updateTicks()
double steps = (max - min) / interval;
double currValue = min;
- if(!showText && !labels.empty()){
+ if(!showText && !labels.isEmpty()){
qDeleteAll(labels);
labels.clear();
}
-
+ if (steps < 1)
+ return;
if (!labels.isEmpty() && labels.size() > steps) {
while (labels.size() > steps) {
DiveTextItem *removedText = labels.takeLast();
- removedText->animatedHide();
+ Animations::animDelete(removedText);
}
}
// Move the remaining Ticks / Text to it's corerct position
@@ -290,7 +292,7 @@ QString TemperatureAxis::textForValue(double value)
void DiveCartesianPlane::setLeftAxis(DiveCartesianAxis* axis)
{
leftAxis = axis;
- connect(leftAxis, SIGNAL(sizeChanged()), this, SLOT(setup()));
+ connect(leftAxis, SIGNAL(maxChanged()), this, SLOT(setup()));
if (bottomAxis)
setup();
}
@@ -298,7 +300,7 @@ void DiveCartesianPlane::setLeftAxis(DiveCartesianAxis* axis)
void DiveCartesianPlane::setBottomAxis(DiveCartesianAxis* axis)
{
bottomAxis = axis;
- connect(bottomAxis, SIGNAL(sizeChanged()), this, SLOT(setup()));
+ connect(bottomAxis, SIGNAL(maxChanged()), this, SLOT(setup()));
if (leftAxis)
setup();
}
@@ -371,3 +373,38 @@ void DiveCartesianPlane::setup()
scene()->addItem(line);
}
}
+
+PartialGasPressureAxis::PartialGasPressureAxis()
+{
+ connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), this, SLOT(preferencesChanged()));
+}
+
+void PartialGasPressureAxis::setModel(DivePlotDataModel* m)
+{
+ model = m;
+ connect(model, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(preferencesChanged()));
+ preferencesChanged();
+}
+
+void PartialGasPressureAxis::preferencesChanged()
+{
+ QSettings s;
+ s.beginGroup("TecDetails");
+ bool showPhe = s.value("phegraph").toBool();
+ bool showPn2 = s.value("pn2graph").toBool();
+ bool showPo2 = s.value("po2graph").toBool();
+ setVisible(showPhe || showPn2 || showPo2);
+ if (!model->rowCount())
+ return;
+
+ double max = showPhe ? model->pheMax() : -1;
+ if (showPn2 && model->pn2Max() > max)
+ max = model->pn2Max();
+ if( showPo2 && model->po2Max() > max)
+ max = model->po2Max();
+
+ qreal pp = floor(max * 10.0) / 10.0 + 0.2;
+ setMaximum(pp);
+ setTickInterval( pp > 4 ? 0.5 : 0.25 );
+ updateTicks();
+}
diff --git a/qt-ui/profile/divecartesianaxis.h b/qt-ui/profile/divecartesianaxis.h
index 507d0349c..e4366eaf4 100644
--- a/qt-ui/profile/divecartesianaxis.h
+++ b/qt-ui/profile/divecartesianaxis.h
@@ -7,6 +7,7 @@
class QPropertyAnimation;
class DiveTextItem;
class DiveLineItem;
+class DivePlotDataModel;
class DiveCartesianAxis : public QObject, public QGraphicsLineItem{
Q_OBJECT
@@ -38,6 +39,7 @@ public slots:
void updateTicks();
signals:
void sizeChanged();
+ void maxChanged();
protected:
virtual QString textForValue(double value);
virtual QColor colorForValue(double value);
@@ -75,6 +77,17 @@ protected:
QString textForValue(double value);
};
+class PartialGasPressureAxis : public DiveCartesianAxis{
+ Q_OBJECT
+public:
+ PartialGasPressureAxis();
+ void setModel(DivePlotDataModel *model);
+public slots:
+ void preferencesChanged();
+private:
+ DivePlotDataModel *model;
+};
+
// This is a try. Maybe the CartesianPlane should have the X and Y
// axis and handle things internally?
class DiveCartesianPlane :public QObject, public QGraphicsRectItem{
diff --git a/qt-ui/profile/diveplotdatamodel.cpp b/qt-ui/profile/diveplotdatamodel.cpp
index bf4425abc..362eb018b 100644
--- a/qt-ui/profile/diveplotdatamodel.cpp
+++ b/qt-ui/profile/diveplotdatamodel.cpp
@@ -122,3 +122,23 @@ int DivePlotDataModel::id() const
{
return diveId;
}
+
+#define MAX_PPGAS_FUNC( GAS, GASFUNC ) \
+double DivePlotDataModel::GASFUNC() \
+{ \
+ double ret = -1; \
+ for(int i = 0, count = rowCount(); i < count; i++){ \
+ if (plotData[i].GAS > ret) \
+ ret = plotData[i].GAS; \
+ } \
+ return ret; \
+}
+
+MAX_PPGAS_FUNC(phe, pheMax);
+MAX_PPGAS_FUNC(pn2, pn2Max);
+MAX_PPGAS_FUNC(po2, po2Max);
+
+void DivePlotDataModel::emitDataChanged()
+{
+ emit dataChanged(QModelIndex(), QModelIndex());
+}
diff --git a/qt-ui/profile/diveplotdatamodel.h b/qt-ui/profile/diveplotdatamodel.h
index c5ed17581..6f4929bb2 100644
--- a/qt-ui/profile/diveplotdatamodel.h
+++ b/qt-ui/profile/diveplotdatamodel.h
@@ -22,6 +22,10 @@ public:
void setDive(struct dive *d, const plot_info& pInfo);
plot_data* data();
int id() const;
+ double pheMax();
+ double pn2Max();
+ double po2Max();
+ void emitDataChanged();
private:
int sampleCount;
plot_data *plotData;
diff --git a/qt-ui/profile/diveprofileitem.cpp b/qt-ui/profile/diveprofileitem.cpp
index 15944e990..b7682f9df 100644
--- a/qt-ui/profile/diveprofileitem.cpp
+++ b/qt-ui/profile/diveprofileitem.cpp
@@ -30,6 +30,7 @@ void AbstractProfilePolygonItem::preferencesChanged()
void AbstractProfilePolygonItem::setHorizontalAxis(DiveCartesianAxis* horizontal)
{
hAxis = horizontal;
+ connect(hAxis, SIGNAL(sizeChanged()), this, SLOT(modelDataChanged()));
modelDataChanged();
}
@@ -43,13 +44,14 @@ void AbstractProfilePolygonItem::setModel(DivePlotDataModel* model)
{
dataModel = model;
connect(dataModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelDataChanged()));
- connect(dataModel, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(modelDataChanged()));
modelDataChanged();
}
void AbstractProfilePolygonItem::setVerticalAxis(DiveCartesianAxis* vertical)
{
vAxis = vertical;
+ connect(vAxis, SIGNAL(sizeChanged()), this, SLOT(modelDataChanged()));
+ connect(vAxis, SIGNAL(maxChanged()), this, SLOT(modelDataChanged()));
modelDataChanged();
}
@@ -258,7 +260,6 @@ void DiveTemperatureItem::paint(QPainter* painter, const QStyleOptionGraphicsIte
painter->drawPolyline(polygon());
}
-
void DiveGasPressureItem::modelDataChanged()
{
// We don't have enougth data to calculate things, quit.
@@ -484,7 +485,6 @@ void PartialPressureGasItem::modelDataChanged()
QSettings s;
s.beginGroup("TecDetails");
double threshould = s.value(threshouldKey).toDouble();
-
for(int i = 0; i < dataModel->rowCount(); i++, entry++){
double value = dataModel->index(i, vDataColumn).data().toDouble();
int time = dataModel->index(i, hDataColumn).data().toInt();
@@ -493,17 +493,17 @@ void PartialPressureGasItem::modelDataChanged()
if (value >= threshould)
alertPoly.push_back(point);
}
-
setPolygon(poly);
/*
createPPLegend(trUtf8("pN" UTF8_SUBSCRIPT_2),getColor(PN2), legendPos);
*/
}
+
void PartialPressureGasItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
-{//TODO: fix the colors.
- painter->setPen(getColor(PN2));
+{
+ painter->setPen(normalColor);
painter->drawPolyline(polygon());
- painter->setPen(getColor(PN2_ALERT));
+ painter->setPen(alertColor);
painter->drawPolyline(alertPoly);
}
@@ -514,10 +514,22 @@ void PartialPressureGasItem::setThreshouldSettingsKey(const QString& threshouldS
PartialPressureGasItem::PartialPressureGasItem()
{
-
}
void PartialPressureGasItem::preferencesChanged()
{
- AbstractProfilePolygonItem::preferencesChanged();
+ QSettings s;
+ s.beginGroup("TecDetails");
+ setVisible( s.value(visibilityKey).toBool() );
+}
+
+void PartialPressureGasItem::setVisibilitySettingsKey(const QString& key)
+{
+ visibilityKey = key;
+}
+
+void PartialPressureGasItem::setColors(const QColor& normal, const QColor& alert)
+{
+ normalColor = normal;
+ alertColor = alert;
}
diff --git a/qt-ui/profile/diveprofileitem.h b/qt-ui/profile/diveprofileitem.h
index 8da9acee1..5c35bf7a2 100644
--- a/qt-ui/profile/diveprofileitem.h
+++ b/qt-ui/profile/diveprofileitem.h
@@ -130,8 +130,13 @@ public:
virtual void modelDataChanged();
virtual void preferencesChanged();
void setThreshouldSettingsKey(const QString& threshouldSettingsKey);
+ void setVisibilitySettingsKey(const QString& setVisibilitySettingsKey);
+ void setColors(const QColor& normalColor, const QColor& alertColor);
private:
QPolygonF alertPoly;
QString threshouldKey;
+ QString visibilityKey;
+ QColor normalColor;
+ QColor alertColor;
};
#endif
diff --git a/qt-ui/profile/profilewidget2.cpp b/qt-ui/profile/profilewidget2.cpp
index a39dbadd7..007ca8a68 100644
--- a/qt-ui/profile/profilewidget2.cpp
+++ b/qt-ui/profile/profilewidget2.cpp
@@ -27,7 +27,7 @@ ProfileWidget2::ProfileWidget2(QWidget *parent) :
stateMachine(new QStateMachine(this)),
background (new DivePixmapItem()),
profileYAxis(new DepthAxis()),
- gasYAxis(new DiveCartesianAxis()),
+ gasYAxis(new PartialGasPressureAxis()),
temperatureAxis(new TemperatureAxis()),
timeAxis(new TimeAxis()),
depthController(new DiveRectItem()),
@@ -72,6 +72,8 @@ ProfileWidget2::ProfileWidget2(QWidget *parent) :
gasYAxis->setTickInterval(1);
gasYAxis->setTickSize(2);
gasYAxis->setY(70);
+ gasYAxis->setMinimum(0);
+ gasYAxis->setModel(dataModel);
scene()->addItem(gasYAxis);
temperatureAxis->setOrientation(DiveCartesianAxis::BottomToTop);
@@ -89,6 +91,7 @@ ProfileWidget2::ProfileWidget2(QWidget *parent) :
timeAxis->setLine(0,0,96,0);
timeAxis->setX(3);
timeAxis->setTickSize(1);
+
depthController->setRect(0, 0, 10, 5);
timeController->setRect(0, 0, 10, 5);
timeController->setX(sceneRect().width() - timeController->boundingRect().width()); // Position it on the right spot.
@@ -170,35 +173,24 @@ ProfileWidget2::ProfileWidget2(QWidget *parent) :
diveProfileItem->setZValue(0);
scene()->addItem(diveProfileItem);
- pn2GasItem = new PartialPressureGasItem();
- pn2GasItem->setHorizontalAxis(timeAxis);
- pn2GasItem->setVerticalAxis(gasYAxis);
- pn2GasItem->setModel(dataModel);
- pn2GasItem->setVerticalDataColumn(DivePlotDataModel::PN2);
- pn2GasItem->setHorizontalDataColumn(DivePlotDataModel::TIME);
- pn2GasItem->setZValue(0);
- pn2GasItem->setThreshouldSettingsKey("pn2threshold");
- scene()->addItem(pn2GasItem);
-
- pheGasItem = new PartialPressureGasItem();
- pheGasItem->setHorizontalAxis(timeAxis);
- pheGasItem->setVerticalAxis(gasYAxis);
- pheGasItem->setModel(dataModel);
- pheGasItem->setVerticalDataColumn(DivePlotDataModel::PHE);
- pheGasItem->setHorizontalDataColumn(DivePlotDataModel::TIME);
- pheGasItem->setZValue(0);
- pheGasItem->setThreshouldSettingsKey("phethreshold");
- scene()->addItem(pheGasItem);
-
- pheGasItem = new PartialPressureGasItem();
- pheGasItem->setHorizontalAxis(timeAxis);
- pheGasItem->setVerticalAxis(gasYAxis);
- pheGasItem->setModel(dataModel);
- pheGasItem->setVerticalDataColumn(DivePlotDataModel::PO2);
- pheGasItem->setHorizontalDataColumn(DivePlotDataModel::TIME);
- pheGasItem->setZValue(0);
- pheGasItem->setThreshouldSettingsKey("po2threshold");
- scene()->addItem(pheGasItem);
+#define CREATE_PP_GAS( ITEM, VERTICAL_COLUMN, COLOR, COLOR_ALERT, THRESHOULD_SETTINGS, VISIBILITY_SETTINGS ) \
+ ITEM = new PartialPressureGasItem(); \
+ ITEM->setHorizontalAxis(timeAxis); \
+ ITEM->setVerticalAxis(gasYAxis); \
+ ITEM->setModel(dataModel); \
+ ITEM->setVerticalDataColumn(DivePlotDataModel::VERTICAL_COLUMN); \
+ ITEM->setHorizontalDataColumn(DivePlotDataModel::TIME); \
+ ITEM->setZValue(0); \
+ ITEM->setThreshouldSettingsKey(THRESHOULD_SETTINGS); \
+ ITEM->setVisibilitySettingsKey(VISIBILITY_SETTINGS); \
+ ITEM->setColors(getColor(COLOR), getColor(COLOR_ALERT)); \
+ ITEM->preferencesChanged(); \
+ scene()->addItem(ITEM);
+
+ CREATE_PP_GAS( pn2GasItem, PN2, PN2, PN2_ALERT, "pn2threshold", "pn2graph");
+ CREATE_PP_GAS( pheGasItem, PHE, PHE, PHE_ALERT, "phethreshold", "phegraph");
+ CREATE_PP_GAS( po2GasItem, PO2, PO2, PO2_ALERT, "po2threshold", "po2graph");
+#undef CREATE_PP_GAS
background->setFlag(QGraphicsItem::ItemIgnoresTransformations);
@@ -387,6 +379,7 @@ void ProfileWidget2::plotDives(QList<dive*> dives)
int maxtime = get_maxtime(&pInfo);
int maxdepth = get_maxdepth(&pInfo);
+ dataModel->setDive(current_dive, pInfo);
// It seems that I'll have a lot of boilerplate setting the model / axis for
// each item, I'll mostly like to fix this in the future, but I'll keep at this for now.
profileYAxis->setMaximum(maxdepth);
@@ -400,14 +393,7 @@ void ProfileWidget2::plotDives(QList<dive*> dives)
meanDepth->setMeanDepth(pInfo.meandepth);
meanDepth->animateMoveTo(3, profileYAxis->posAtValue(pInfo.meandepth));
- qreal pp = floor(pInfo.maxpp * 10.0) / 10.0 + 0.2;
- gasYAxis->setMaximum(pp);
- gasYAxis->setMinimum(0);
- gasYAxis->setTickInterval(pp > 4 ? 0.5 : 0.25);
- gasYAxis->updateTicks();
-
- dataModel->setDive(current_dive, pInfo);
-
+ dataModel->emitDataChanged();
// 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
// while all other items are up there on the constructor.
diff --git a/qt-ui/profile/profilewidget2.h b/qt-ui/profile/profilewidget2.h
index 41819017f..df4a844bd 100644
--- a/qt-ui/profile/profilewidget2.h
+++ b/qt-ui/profile/profilewidget2.h
@@ -38,6 +38,7 @@ struct DiveCalculatedCeiling;
struct DiveReportedCeiling;
struct DiveCalculatedTissue;
struct PartialPressureGasItem;
+struct PartialGasPressureAxis;
class ProfileWidget2 : public QGraphicsView {
Q_OBJECT
@@ -76,7 +77,7 @@ private:
// In the meantime, keep it here.
struct plot_info *plotInfo;
DepthAxis *profileYAxis ;
- DiveCartesianAxis *gasYAxis;
+ PartialGasPressureAxis *gasYAxis;
TemperatureAxis *temperatureAxis;
TimeAxis *timeAxis;
DiveRectItem *depthController;