summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Robert C. Helling <helling@atdotde.de>2014-09-15 14:09:00 +0200
committerGravatar Dirk Hohndel <dirk@hohndel.org>2014-09-19 21:46:30 -0700
commit3fc9c1e0053a0ca1d4af7c1e5fb8e118afe0badf (patch)
tree7b9f8d5124e7beb267d099bf85c0495042781700
parent7cdf55ffcc8d0525657dd0780f7436284e9b72aa (diff)
downloadsubsurface-3fc9c1e0053a0ca1d4af7c1e5fb8e118afe0badf.tar.gz
Tissue saturation plot a la Sherwater Pretel
This adds a toolbox icon to turn on a tissue plot inspired by the bar graph of the Sherwater Petrel, It shows the inert gas partial pressures for individual compartments. If they are below the ambient pressure (grey line) they are shown in units of the ambient pressure, if they are above, the excess is shown as a percentage of the allowed overpressure for plain Buehlmann. So it has the same units as a gradient factor. Thus also the a gradient factor line (for the current depth) is shown. The different tissues get different colors, greener for the faster ones and bluer for the slower ones. Positioning and on/off icon action still need some tender loving care. Signed-off-by: Robert C. Helling <helling@atdotde.de> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r--deco.c4
-rw-r--r--deco.h4
-rw-r--r--display.h2
-rw-r--r--icons/petrel.pngbin0 -> 3732 bytes
-rw-r--r--pref.h1
-rw-r--r--profile.c11
-rw-r--r--profile.h3
-rw-r--r--qt-ui/graphicsview-common.cpp3
-rw-r--r--qt-ui/graphicsview-common.h5
-rw-r--r--qt-ui/mainwindow.cpp4
-rw-r--r--qt-ui/mainwindow.h1
-rw-r--r--qt-ui/mainwindow.ui17
-rw-r--r--qt-ui/preferences.cpp1
-rw-r--r--qt-ui/profile/diveplotdatamodel.cpp13
-rw-r--r--qt-ui/profile/diveplotdatamodel.h18
-rw-r--r--qt-ui/profile/diveprofileitem.cpp149
-rw-r--r--qt-ui/profile/diveprofileitem.h33
-rw-r--r--qt-ui/profile/profilewidget2.cpp50
-rw-r--r--qt-ui/profile/profilewidget2.h6
-rw-r--r--subsurface.qrc1
-rw-r--r--subsurfacestartup.c1
21 files changed, 319 insertions, 8 deletions
diff --git a/deco.c b/deco.c
index 2a0ae940c..ec281b1fe 100644
--- a/deco.c
+++ b/deco.c
@@ -85,12 +85,12 @@ double gf_low_pressure_this_dive;
#define TISSUE_ARRAY_SZ sizeof(tissue_n2_sat)
double tolerated_by_tissue[16];
-
+double tissue_inertgas_saturation[16];
+double buehlmann_inertgas_a[16], buehlmann_inertgas_b[16];
static double tissue_tolerance_calc(const struct dive *dive)
{
int ci = -1;
- double tissue_inertgas_saturation[16], buehlmann_inertgas_a[16], buehlmann_inertgas_b[16];
double ret_tolerance_limit_ambient_pressure = 0.0;
double gf_high = buehlmann_config.gf_high;
double gf_low = buehlmann_config.gf_low;
diff --git a/deco.h b/deco.h
index aa6d299dd..08ff93422 100644
--- a/deco.h
+++ b/deco.h
@@ -7,6 +7,10 @@ extern "C" {
extern double tolerated_by_tissue[];
extern double buehlmann_N2_t_halflife[];
+extern double tissue_inertgas_saturation[16];
+extern double buehlmann_inertgas_a[16], buehlmann_inertgas_b[16];
+extern double gf_low_pressure_this_dive;
+
#ifdef __cplusplus
}
diff --git a/display.h b/display.h
index 7775dcf7a..96a83c5ee 100644
--- a/display.h
+++ b/display.h
@@ -66,6 +66,8 @@ extern const char *default_dive_computer_vendor;
extern const char *default_dive_computer_product;
extern const char *default_dive_computer_device;
+#define AMB_PERCENTAGE 50.0
+
#ifdef __cplusplus
}
#endif
diff --git a/icons/petrel.png b/icons/petrel.png
new file mode 100644
index 000000000..d597326f8
--- /dev/null
+++ b/icons/petrel.png
Binary files differ
diff --git a/pref.h b/pref.h
index 7febf408c..bd2c38469 100644
--- a/pref.h
+++ b/pref.h
@@ -45,6 +45,7 @@ struct preferences {
short show_average_depth;
short zoomed_plot;
short hrgraph;
+ short percentagegraph;
short rulergraph;
short tankbar;
short save_userid_local;
diff --git a/profile.c b/profile.c
index 8656429d5..6caeab0a8 100644
--- a/profile.c
+++ b/profile.c
@@ -759,6 +759,10 @@ void calculate_deco_information(struct dive *dive, struct divecomputer *dc, stru
struct plot_data *entry = pi->entry + i;
int j, t0 = (entry - 1)->sec, t1 = entry->sec;
int time_stepsize = 20;
+
+ entry->ambpressure = (double) depth_to_mbar(entry->depth, dive) / 1000.0;
+ entry->gfline = MAX((double) prefs.gflow, (entry->ambpressure - surface_pressure) / (gf_low_pressure_this_dive - surface_pressure) *
+ (prefs.gflow - prefs.gfhigh) + prefs.gfhigh) * (100.0 - AMB_PERCENTAGE) / 100.0 + AMB_PERCENTAGE;
if (t0 != t1 && t1 - t0 < time_stepsize)
time_stepsize = t1 - t0;
for (j = t0 + time_stepsize; j <= t1; j += time_stepsize) {
@@ -773,8 +777,13 @@ void calculate_deco_information(struct dive *dive, struct divecomputer *dc, stru
entry->ceiling = (entry - 1)->ceiling;
else
entry->ceiling = deco_allowed_depth(tissue_tolerance, surface_pressure, dive, !prefs.calcceiling3m);
- for (j = 0; j < 16; j++)
+ for (j = 0; j < 16; j++) {
+ double m_value = buehlmann_inertgas_a[j] + entry->ambpressure / buehlmann_inertgas_b[j];
entry->ceilings[j] = deco_allowed_depth(tolerated_by_tissue[j], surface_pressure, dive, 1);
+ entry->percentages[j] = tissue_inertgas_saturation[j] < entry->ambpressure ?
+ tissue_inertgas_saturation[j] / entry->ambpressure * AMB_PERCENTAGE:
+ AMB_PERCENTAGE + (tissue_inertgas_saturation[j] - entry->ambpressure) / (m_value - entry->ambpressure) * (100.0 - AMB_PERCENTAGE);
+ }
/* should we do more calculations?
* We don't for print-mode because this info doesn't show up there */
diff --git a/profile.h b/profile.h
index 384a17bf3..05fe1359d 100644
--- a/profile.h
+++ b/profile.h
@@ -31,6 +31,7 @@ struct plot_data {
int depth;
int ceiling;
int ceilings[16];
+ int percentages[16];
int ndl;
int tts;
int stoptime;
@@ -55,6 +56,8 @@ struct plot_data {
int pressure_time;
int heartbeat;
int bearing;
+ double ambpressure;
+ double gfline;
};
struct ev_select {
diff --git a/qt-ui/graphicsview-common.cpp b/qt-ui/graphicsview-common.cpp
index 35c7b2e03..4beab9d3a 100644
--- a/qt-ui/graphicsview-common.cpp
+++ b/qt-ui/graphicsview-common.cpp
@@ -57,6 +57,9 @@ void fill_profile_color()
profile_color[CEILING_DEEP] = COLOR(RED1_MED_TRANS, BLACK1_HIGH_TRANS, RED1_MED_TRANS);
profile_color[CALC_CEILING_SHALLOW] = COLOR(FUNGREEN1_HIGH_TRANS, BLACK1_HIGH_TRANS, FUNGREEN1_HIGH_TRANS);
profile_color[CALC_CEILING_DEEP] = COLOR(APPLE1_HIGH_TRANS, BLACK1_HIGH_TRANS, APPLE1_HIGH_TRANS);
+ profile_color[TISSUE_PERCENTAGE] = COLOR(GOVERNORBAY2, BLACK1_LOW_TRANS, GOVERNORBAY2);
+ profile_color[GF_LINE] = COLOR(BLACK1, BLACK1_LOW_TRANS, BLACK1);
+ profile_color[AMB_PRESSURE_LINE] = COLOR(TUNDORA1_MED_TRANS, BLACK1_LOW_TRANS, ATLANTIS1);
#undef COLOR
}
diff --git a/qt-ui/graphicsview-common.h b/qt-ui/graphicsview-common.h
index f79f635f0..c223c30c7 100644
--- a/qt-ui/graphicsview-common.h
+++ b/qt-ui/graphicsview-common.h
@@ -67,7 +67,10 @@ typedef enum {
CEILING_SHALLOW,
CEILING_DEEP,
CALC_CEILING_SHALLOW,
- CALC_CEILING_DEEP
+ CALC_CEILING_DEEP,
+ TISSUE_PERCENTAGE,
+ GF_LINE,
+ AMB_PRESSURE_LINE
} color_indice_t;
diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp
index 3f004b79c..30227a478 100644
--- a/qt-ui/mainwindow.cpp
+++ b/qt-ui/mainwindow.cpp
@@ -73,7 +73,7 @@ MainWindow::MainWindow() : QMainWindow(),
profileToolbarActions << ui.profCalcAllTissues << ui.profCalcCeiling << ui.profDcCeiling << ui.profEad <<
ui.profHR << ui.profIncrement3m << ui.profMod << ui.profNdl_tts << ui.profNdl_tts <<
ui.profPhe << ui.profPn2 << ui.profPO2 << ui.profRuler << ui.profSAC << ui.profScaled <<
- ui.profTogglePicture << ui.profTankbar;
+ ui.profTogglePicture << ui.profTankbar << ui.profTissues;
setWindowIcon(QIcon(":subsurface-icon"));
if (!QIcon::hasThemeIcon("window-close")) {
QIcon::setThemeName("subsurface");
@@ -815,6 +815,7 @@ void MainWindow::readSettings()
TOOLBOX_PREF_BUTTON(show_sac, show_sac, profSAC);
TOOLBOX_PREF_BUTTON(show_pictures_in_profile, show_pictures_in_profile, profTogglePicture);
TOOLBOX_PREF_BUTTON(tankbar, tankbar, profTankbar);
+ TOOLBOX_PREF_BUTTON(percentagegraph, precentagegraph, profTissues);
s.endGroup();
s.beginGroup("DiveComputer");
default_dive_computer_vendor = getSetting(s, "dive_computer_vendor");
@@ -1286,6 +1287,7 @@ TOOLBOX_PREF_PROFILE(profSAC, show_sac, show_sac);
TOOLBOX_PREF_PROFILE(profScaled, zoomed_plot, zoomed_plot);
TOOLBOX_PREF_PROFILE(profTogglePicture, show_pictures_in_profile, show_pictures_in_profile);
TOOLBOX_PREF_PROFILE(profTankbar, tankbar, tankbar);
+TOOLBOX_PREF_PROFILE(profTissues, percentagegraph, percentagegraph);
void MainWindow::turnOffNdlTts()
{
diff --git a/qt-ui/mainwindow.h b/qt-ui/mainwindow.h
index ab1c4f7b4..edf33a500 100644
--- a/qt-ui/mainwindow.h
+++ b/qt-ui/mainwindow.h
@@ -143,6 +143,7 @@ slots:
void on_profScaled_triggered(bool triggered);
void on_profTogglePicture_triggered(bool triggered);
void on_profTankbar_triggered(bool triggered);
+ void on_profTissues_triggered(bool triggered);
void on_actionExport_triggered();
void on_copy_triggered();
void on_paste_triggered();
diff --git a/qt-ui/mainwindow.ui b/qt-ui/mainwindow.ui
index 1387be577..88921538a 100644
--- a/qt-ui/mainwindow.ui
+++ b/qt-ui/mainwindow.ui
@@ -256,7 +256,7 @@ p, li { white-space: pre-wrap; }
<x>0</x>
<y>0</y>
<width>1682</width>
- <height>25</height>
+ <height>22</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
@@ -844,6 +844,21 @@ p, li { white-space: pre-wrap; }
<string>Filter by Tags</string>
</property>
</action>
+ <action name="profTissues">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="icon">
+ <iconset resource="../subsurface.qrc">
+ <normaloff>:/icon_tissue</normaloff>:/icon_tissue</iconset>
+ </property>
+ <property name="text">
+ <string>Toggle Tissue Graph</string>
+ </property>
+ <property name="toolTip">
+ <string>Toggle Tissue Graph</string>
+ </property>
+ </action>
</widget>
<customwidgets>
<customwidget>
diff --git a/qt-ui/preferences.cpp b/qt-ui/preferences.cpp
index 9d23c104e..71a62d7bd 100644
--- a/qt-ui/preferences.cpp
+++ b/qt-ui/preferences.cpp
@@ -330,6 +330,7 @@ void PreferencesDialog::loadSettings()
GET_BOOL("calcalltissues", calcalltissues);
GET_BOOL("hrgraph", hrgraph);
GET_BOOL("tankbar", tankbar);
+ GET_BOOL("percentagegraph", percentagegraph);
GET_INT("gflow", gflow);
GET_INT("gfhigh", gfhigh);
GET_BOOL("gf_low_at_maxdepth", gf_low_at_maxdepth);
diff --git a/qt-ui/profile/diveplotdatamodel.cpp b/qt-ui/profile/diveplotdatamodel.cpp
index 993c09045..51aea1b59 100644
--- a/qt-ui/profile/diveplotdatamodel.cpp
+++ b/qt-ui/profile/diveplotdatamodel.cpp
@@ -54,6 +54,10 @@ QVariant DivePlotDataModel::data(const QModelIndex &index, int role) const
return item.pressures.o2;
case HEARTBEAT:
return item.heartbeat;
+ case AMBPRESSURE:
+ return AMB_PERCENTAGE;
+ case GFLINE:
+ return item.gfline;
}
}
@@ -61,6 +65,10 @@ QVariant DivePlotDataModel::data(const QModelIndex &index, int role) const
return item.ceilings[index.column() - TISSUE_1];
}
+ if (role == Qt::DisplayRole && index.column() >= PERCENTAGE_1 && index.column() <= PERCENTAGE_16) {
+ return item.percentages[index.column() - PERCENTAGE_1];
+ }
+
if (role == Qt::BackgroundRole) {
switch (index.column()) {
case COLOR:
@@ -117,10 +125,15 @@ QVariant DivePlotDataModel::headerData(int section, Qt::Orientation orientation,
return tr("pHe");
case PO2:
return tr("pO₂");
+ case AMBPRESSURE:
+ return tr("Ambient pressure");
}
if (role == Qt::DisplayRole && section >= TISSUE_1 && section <= TISSUE_16) {
return QString("Ceiling: %1").arg(section - TISSUE_1);
}
+ if (role == Qt::DisplayRole && section >= PERCENTAGE_1 && section <= PERCENTAGE_16) {
+ return QString("Tissue: %1").arg(section - PERCENTAGE_1);
+ }
return QVariant();
}
diff --git a/qt-ui/profile/diveplotdatamodel.h b/qt-ui/profile/diveplotdatamodel.h
index 9db4a078d..416ae6905 100644
--- a/qt-ui/profile/diveplotdatamodel.h
+++ b/qt-ui/profile/diveplotdatamodel.h
@@ -40,10 +40,28 @@ public:
TISSUE_14,
TISSUE_15,
TISSUE_16,
+ PERCENTAGE_1,
+ PERCENTAGE_2,
+ PERCENTAGE_3,
+ PERCENTAGE_4,
+ PERCENTAGE_5,
+ PERCENTAGE_6,
+ PERCENTAGE_7,
+ PERCENTAGE_8,
+ PERCENTAGE_9,
+ PERCENTAGE_10,
+ PERCENTAGE_11,
+ PERCENTAGE_12,
+ PERCENTAGE_13,
+ PERCENTAGE_14,
+ PERCENTAGE_15,
+ PERCENTAGE_16,
PN2,
PHE,
PO2,
HEARTBEAT,
+ AMBPRESSURE,
+ GFLINE,
COLUMNS
};
explicit DivePlotDataModel(QObject *parent = 0);
diff --git a/qt-ui/profile/diveprofileitem.cpp b/qt-ui/profile/diveprofileitem.cpp
index 9ff30ff32..ef75f2fad 100644
--- a/qt-ui/profile/diveprofileitem.cpp
+++ b/qt-ui/profile/diveprofileitem.cpp
@@ -338,6 +338,155 @@ void DiveHeartrateItem::settingsChanged()
setVisible(prefs.hrgraph);
}
+DivePercentageItem::DivePercentageItem(int i)
+{
+ QPen pen;
+ QColor color;
+ color.setHsl(100 + 10 * i, 200, 100);
+ pen.setBrush(QBrush(color));
+ pen.setCosmetic(true);
+ pen.setWidth(1);
+ setPen(pen);
+ settingsChanged();
+}
+
+void DivePercentageItem::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
+{
+ int last = -300, last_printed_hr = 0, sec = 0;
+
+ // We don't have enougth data to calculate things, quit.
+ if (!shouldCalculateStuff(topLeft, bottomRight))
+ return;
+
+ // Ignore empty values. a heartrate of 0 would be a bad sign.
+ QPolygonF poly;
+ for (int i = 0, modelDataCount = dataModel->rowCount(); i < modelDataCount; i++) {
+ int hr = dataModel->index(i, vDataColumn).data().toInt();
+ if (!hr)
+ continue;
+ sec = dataModel->index(i, hDataColumn).data().toInt();
+ QPointF point(hAxis->posAtValue(sec), vAxis->posAtValue(hr));
+ poly.append(point);
+ }
+ setPolygon(poly);
+
+ if (texts.count())
+ texts.last()->setAlignment(Qt::AlignLeft | Qt::AlignBottom);
+}
+
+void DivePercentageItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ if (polygon().isEmpty())
+ return;
+ painter->save();
+ painter->setPen(pen());
+ painter->drawPolyline(polygon());
+ painter->restore();
+}
+
+void DivePercentageItem::settingsChanged()
+{
+ setVisible(prefs.percentagegraph);
+}
+
+DiveAmbPressureItem::DiveAmbPressureItem()
+{
+ QPen pen;
+ pen.setBrush(QBrush(getColor(::AMB_PRESSURE_LINE)));
+ pen.setCosmetic(true);
+ pen.setWidth(2);
+ setPen(pen);
+ settingsChanged();
+}
+
+void DiveAmbPressureItem::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
+{
+ int last = -300, last_printed_hr = 0, sec = 0;
+
+ // We don't have enougth data to calculate things, quit.
+ if (!shouldCalculateStuff(topLeft, bottomRight))
+ return;
+
+ // Ignore empty values. a heartrate of 0 would be a bad sign.
+ QPolygonF poly;
+ for (int i = 0, modelDataCount = dataModel->rowCount(); i < modelDataCount; i++) {
+ int hr = dataModel->index(i, vDataColumn).data().toInt();
+ if (!hr)
+ continue;
+ sec = dataModel->index(i, hDataColumn).data().toInt();
+ QPointF point(hAxis->posAtValue(sec), vAxis->posAtValue(hr));
+ poly.append(point);
+ }
+ setPolygon(poly);
+
+ if (texts.count())
+ texts.last()->setAlignment(Qt::AlignLeft | Qt::AlignBottom);
+}
+
+void DiveAmbPressureItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ if (polygon().isEmpty())
+ return;
+ painter->save();
+ painter->setPen(pen());
+ painter->drawPolyline(polygon());
+ painter->restore();
+}
+
+void DiveAmbPressureItem::settingsChanged()
+{
+ setVisible(prefs.percentagegraph);
+}
+
+DiveGFLineItem::DiveGFLineItem()
+{
+ QPen pen;
+ pen.setBrush(QBrush(getColor(::GF_LINE)));
+ pen.setCosmetic(true);
+ pen.setWidth(2);
+ setPen(pen);
+ settingsChanged();
+}
+
+void DiveGFLineItem::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
+{
+ int last = -300, last_printed_hr = 0, sec = 0;
+
+ // We don't have enougth data to calculate things, quit.
+ if (!shouldCalculateStuff(topLeft, bottomRight))
+ return;
+
+ // Ignore empty values. a heartrate of 0 would be a bad sign.
+ QPolygonF poly;
+ for (int i = 0, modelDataCount = dataModel->rowCount(); i < modelDataCount; i++) {
+ int hr = dataModel->index(i, vDataColumn).data().toInt();
+ if (!hr)
+ continue;
+ sec = dataModel->index(i, hDataColumn).data().toInt();
+ QPointF point(hAxis->posAtValue(sec), vAxis->posAtValue(hr));
+ poly.append(point);
+ }
+ setPolygon(poly);
+
+ if (texts.count())
+ texts.last()->setAlignment(Qt::AlignLeft | Qt::AlignBottom);
+}
+
+void DiveGFLineItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ if (polygon().isEmpty())
+ return;
+ painter->save();
+ painter->setPen(pen());
+ painter->drawPolyline(polygon());
+ painter->restore();
+}
+
+void DiveGFLineItem::settingsChanged()
+{
+ setVisible(prefs.percentagegraph);
+}
+
DiveTemperatureItem::DiveTemperatureItem()
{
QPen pen;
diff --git a/qt-ui/profile/diveprofileitem.h b/qt-ui/profile/diveprofileitem.h
index f98af5184..300e4b265 100644
--- a/qt-ui/profile/diveprofileitem.h
+++ b/qt-ui/profile/diveprofileitem.h
@@ -107,6 +107,39 @@ private:
QString visibilityKey;
};
+class DivePercentageItem : public AbstractProfilePolygonItem {
+ Q_OBJECT
+public:
+ DivePercentageItem(int i);
+ virtual void modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+ virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+ virtual void settingsChanged();
+private:
+ QString visibilityKey;
+};
+
+class DiveAmbPressureItem : public AbstractProfilePolygonItem {
+ Q_OBJECT
+public:
+ DiveAmbPressureItem();
+ virtual void modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+ virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+ virtual void settingsChanged();
+private:
+ QString visibilityKey;
+};
+
+class DiveGFLineItem : public AbstractProfilePolygonItem {
+ Q_OBJECT
+public:
+ DiveGFLineItem();
+ virtual void modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+ virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+ virtual void settingsChanged();
+private:
+ QString visibilityKey;
+};
+
class DiveGasPressureItem : public AbstractProfilePolygonItem {
Q_OBJECT
diff --git a/qt-ui/profile/profilewidget2.cpp b/qt-ui/profile/profilewidget2.cpp
index fcad3197f..16339c1de 100644
--- a/qt-ui/profile/profilewidget2.cpp
+++ b/qt-ui/profile/profilewidget2.cpp
@@ -57,6 +57,7 @@ static struct _ItemPos {
_Axis depth;
_Axis partialPressure;
_Axis partialPressureWithTankBar;
+ _Axis percentage;
_Axis time;
_Axis cylinder;
_Axis temperature;
@@ -89,6 +90,9 @@ ProfileWidget2::ProfileWidget2(QWidget *parent) : QGraphicsView(parent),
po2GasItem(new PartialPressureGasItem()),
heartBeatAxis(new DiveCartesianAxis()),
heartBeatItem(new DiveHeartrateItem()),
+ percentageAxis(new DiveCartesianAxis()),
+ ambPressureItem(new DiveAmbPressureItem()),
+ gflineItem(new DiveGFLineItem()),
mouseFollowerVertical(new DiveLineItem()),
mouseFollowerHorizontal(new DiveLineItem()),
rulerItem(new RulerItem2()),
@@ -159,6 +163,7 @@ void ProfileWidget2::addItemsToScene()
scene()->addItem(pn2GasItem);
scene()->addItem(pheGasItem);
scene()->addItem(po2GasItem);
+ scene()->addItem(percentageAxis);
scene()->addItem(heartBeatAxis);
scene()->addItem(heartBeatItem);
scene()->addItem(rulerItem);
@@ -174,6 +179,11 @@ void ProfileWidget2::addItemsToScene()
Q_FOREACH (DiveCalculatedTissue *tissue, allTissues) {
scene()->addItem(tissue);
}
+ Q_FOREACH (DivePercentageItem *percentage, allPercentages) {
+ scene()->addItem(percentage);
+ }
+ scene()->addItem(ambPressureItem);
+ scene()->addItem(gflineItem);
}
void ProfileWidget2::setupItemOnScene()
@@ -207,6 +217,12 @@ void ProfileWidget2::setupItemOnScene()
heartBeatAxis->setFontLabelScale(0.7);
heartBeatAxis->setLineSize(96);
+ percentageAxis->setOrientation(DiveCartesianAxis::BottomToTop);
+ percentageAxis->setTickSize(0.2);
+ percentageAxis->setTickInterval(10);
+ percentageAxis->setFontLabelScale(0.7);
+ percentageAxis->setLineSize(96);
+
temperatureAxis->setOrientation(DiveCartesianAxis::BottomToTop);
temperatureAxis->setTickSize(2);
temperatureAxis->setTickInterval(300);
@@ -233,10 +249,15 @@ void ProfileWidget2::setupItemOnScene()
DiveCalculatedTissue *tissueItem = new DiveCalculatedTissue();
setupItem(tissueItem, timeAxis, profileYAxis, dataModel, DivePlotDataModel::TISSUE_1 + i, DivePlotDataModel::TIME, 1 + i);
allTissues.append(tissueItem);
+ DivePercentageItem *percentageItem = new DivePercentageItem(i);
+ setupItem(percentageItem, timeAxis, percentageAxis, dataModel, DivePlotDataModel::PERCENTAGE_1 + i, DivePlotDataModel::TIME, 1 + i);
+ allPercentages.append(percentageItem);
}
setupItem(gasPressureItem, timeAxis, cylinderPressureAxis, dataModel, DivePlotDataModel::TEMPERATURE, DivePlotDataModel::TIME, 1);
setupItem(temperatureItem, timeAxis, temperatureAxis, dataModel, DivePlotDataModel::TEMPERATURE, DivePlotDataModel::TIME, 1);
setupItem(heartBeatItem, timeAxis, heartBeatAxis, dataModel, DivePlotDataModel::HEARTBEAT, DivePlotDataModel::TIME, 1);
+ setupItem(ambPressureItem, timeAxis, percentageAxis, dataModel, DivePlotDataModel::AMBPRESSURE, DivePlotDataModel::TIME, 1);
+ setupItem(gflineItem, timeAxis, percentageAxis, dataModel, DivePlotDataModel::GFLINE, DivePlotDataModel::TIME, 1);
setupItem(diveProfileItem, timeAxis, profileYAxis, dataModel, DivePlotDataModel::DEPTH, DivePlotDataModel::TIME, 0);
#define CREATE_PP_GAS(ITEM, VERTICAL_COLUMN, COLOR, COLOR_ALERT, THRESHOULD_SETTINGS, VISIBILITY_SETTINGS) \
@@ -261,6 +282,8 @@ void ProfileWidget2::setupItemOnScene()
gasYAxis->setZValue(timeAxis->zValue() + 1);
heartBeatAxis->setTextVisible(true);
heartBeatAxis->setLinesVisible(true);
+ percentageAxis->setTextVisible(true);
+ percentageAxis->setLinesVisible(true);
}
void ProfileWidget2::replot()
@@ -307,7 +330,7 @@ void ProfileWidget2::setupItemSizes()
itemPos.partialPressure.pos.off.setX(110);
itemPos.partialPressure.pos.off.setY(63);
itemPos.partialPressure.expanded.setP1(QPointF(0, 0));
- itemPos.partialPressure.expanded.setP2(QPointF(0, 30));
+ itemPos.partialPressure.expanded.setP2(QPointF(0, 20));
itemPos.partialPressureWithTankBar = itemPos.partialPressure;
itemPos.partialPressureWithTankBar.expanded.setP2(QPointF(0, 27));
@@ -334,7 +357,12 @@ void ProfileWidget2::setupItemSizes()
itemPos.heartBeat.pos.on.setX(3);
itemPos.heartBeat.pos.on.setY(60);
itemPos.heartBeat.expanded.setP1(QPointF(0, 0));
- itemPos.heartBeat.expanded.setP2(QPointF(0, 20));
+ itemPos.heartBeat.expanded.setP2(QPointF(0, 15));
+
+ itemPos.percentage.pos.on.setX(3);
+ itemPos.percentage.pos.on.setY(85); // was 80
+ itemPos.percentage.expanded.setP1(QPointF(0, 0));
+ itemPos.percentage.expanded.setP2(QPointF(0, 15)); // was 20
itemPos.dcLabel.on.setX(3);
itemPos.dcLabel.on.setY(100);
@@ -485,6 +513,11 @@ void ProfileWidget2::plotDive(struct dive *d, bool force)
}
heartBeatAxis->setVisible(prefs.hrgraph && pInfo.maxhr);
+ percentageAxis->setMinimum(0);
+ percentageAxis->setMaximum(100);
+ percentageAxis->setVisible(false);
+ percentageAxis->updateTicks(HR_AXIS);
+
timeAxis->setMaximum(maxtime);
int i, incr;
static int increments[8] = { 10, 20, 30, 60, 5 * 60, 10 * 60, 15 * 60, 30 * 60 };
@@ -760,12 +793,15 @@ void ProfileWidget2::setEmptyState()
pn2GasItem->setVisible(false);
po2GasItem->setVisible(false);
pheGasItem->setVisible(false);
+ ambPressureItem->setVisible(false);
+ gflineItem->setVisible(false);
mouseFollowerHorizontal->setVisible(false);
mouseFollowerVertical->setVisible(false);
#define HIDE_ALL(TYPE, CONTAINER) \
Q_FOREACH (TYPE *item, CONTAINER) item->setVisible(false);
HIDE_ALL(DiveCalculatedTissue, allTissues);
+ HIDE_ALL(DivePercentageItem, allPercentages);
HIDE_ALL(DiveEventItem, eventItems);
HIDE_ALL(DiveHandler, handles);
HIDE_ALL(QGraphicsSimpleTextItem, gases);
@@ -842,6 +878,16 @@ void ProfileWidget2::setProfileState()
tissue->setVisible(true);
}
}
+ percentageAxis->setPos(itemPos.percentage.pos.on);
+ percentageAxis->setLine(itemPos.percentage.expanded);
+ if (prefs.percentagegraph) {
+ Q_FOREACH (DivePercentageItem *percentage, allPercentages) {
+ percentage->setVisible(true);
+ }
+
+ ambPressureItem->setVisible(true);
+ } gflineItem->setVisible(true);
+
rulerItem->setVisible(prefs.rulergraph);
tankItem->setVisible(prefs.tankbar);
tankItem->setPos(itemPos.tankBar.on);
diff --git a/qt-ui/profile/profilewidget2.h b/qt-ui/profile/profilewidget2.h
index af52b41bb..79d5938c1 100644
--- a/qt-ui/profile/profilewidget2.h
+++ b/qt-ui/profile/profilewidget2.h
@@ -15,6 +15,7 @@
// */
#include "graphicsview-common.h"
#include "divelineitem.h"
+#include "diveprofileitem.h"
class RulerItem2;
struct dive;
@@ -34,6 +35,7 @@ class DiveProfileItem;
class TimeAxis;
class DiveTemperatureItem;
class DiveHeartrateItem;
+class PercentageItem;
class DiveGasPressureItem;
class DiveCalculatedCeiling;
class DiveCalculatedTissue;
@@ -163,6 +165,10 @@ private:
PartialPressureGasItem *po2GasItem;
DiveCartesianAxis *heartBeatAxis;
DiveHeartrateItem *heartBeatItem;
+ DiveCartesianAxis *percentageAxis;
+ QList<DivePercentageItem *> allPercentages;
+ DiveAmbPressureItem *ambPressureItem;
+ DiveGFLineItem *gflineItem;
DiveLineItem *mouseFollowerVertical;
DiveLineItem *mouseFollowerHorizontal;
RulerItem2 *rulerItem;
diff --git a/subsurface.qrc b/subsurface.qrc
index 1951bb424..eab95d2ef 100644
--- a/subsurface.qrc
+++ b/subsurface.qrc
@@ -58,6 +58,7 @@
<file alias="icon_ceiling_dc">icons/pc.png</file>
<file alias="icon_ead">icons/ead.png</file>
<file alias="icon_HR">icons/icon-HR.png</file>
+ <file alias="icon_tissue">icons/petrel.png</file>
<file alias="calendar">icons/calendarbg.png</file>
<file alias="pictures">icons/pictures.png</file>
<file>icons/subsurface/index.theme</file>
diff --git a/subsurfacestartup.c b/subsurfacestartup.c
index 10dacfcba..4bdd7012d 100644
--- a/subsurfacestartup.c
+++ b/subsurfacestartup.c
@@ -19,6 +19,7 @@ struct preferences default_prefs = {
.modpO2 = 1.6,
.ead = false,
.hrgraph = true,
+ .percentagegraph = true,
.dcceiling = true,
.redceiling = false,
.calcceiling = false,