diff options
-rw-r--r-- | profile.c | 55 | ||||
-rw-r--r-- | qt-ui/profile/animationfunctions.cpp | 8 | ||||
-rw-r--r-- | qt-ui/profile/animationfunctions.h | 1 | ||||
-rw-r--r-- | qt-ui/profile/divecartesianaxis.cpp | 51 | ||||
-rw-r--r-- | qt-ui/profile/divecartesianaxis.h | 13 | ||||
-rw-r--r-- | qt-ui/profile/diveplotdatamodel.cpp | 20 | ||||
-rw-r--r-- | qt-ui/profile/diveplotdatamodel.h | 4 | ||||
-rw-r--r-- | qt-ui/profile/diveprofileitem.cpp | 30 | ||||
-rw-r--r-- | qt-ui/profile/diveprofileitem.h | 5 | ||||
-rw-r--r-- | qt-ui/profile/profilewidget2.cpp | 62 | ||||
-rw-r--r-- | qt-ui/profile/profilewidget2.h | 3 |
11 files changed, 196 insertions, 56 deletions
@@ -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; |