diff --git a/core/color.cpp b/core/color.cpp
index b5bbc3269..6ac7fc761 100644
--- a/core/color.cpp
+++ b/core/color.cpp
@@ -32,6 +32,8 @@ void fill_profile_color()
profile_color[CCRSENSOR1] = COLOR(TUNDORA1_MED_TRANS, BLACK1_LOW_TRANS, TUNDORA1_MED_TRANS);
profile_color[CCRSENSOR2] = COLOR(ROYALBLUE2_LOW_TRANS, BLACK1_LOW_TRANS, ROYALBLUE2_LOW_TRANS);
profile_color[CCRSENSOR3] = COLOR(PEANUT, BLACK1_LOW_TRANS, PEANUT);
+ profile_color[SCR_OCPO2] = COLOR(PIRATEGOLD1_MED_TRANS, BLACK1_LOW_TRANS, PIRATEGOLD1_MED_TRANS);
+
profile_color[PP_LINES] = COLOR(BLACK1_HIGH_TRANS, BLACK1_LOW_TRANS, BLACK1_HIGH_TRANS);
profile_color[TEXT_BACKGROUND] = COLOR(CONCRETE1_LOWER_TRANS, WHITE1, CONCRETE1_LOWER_TRANS);
diff --git a/core/color.h b/core/color.h
index 9e2496c8b..bf2f1ddcb 100644
--- a/core/color.h
+++ b/core/color.h
@@ -29,6 +29,7 @@
#define PERSIANRED1 QColor::fromRgbF(0.8, 0.2, 0.2, 1)
#define TUSCANY1 QColor::fromRgbF(0.8, 0.4, 0.2, 1)
#define PIRATEGOLD1 QColor::fromRgbF(0.8, 0.5, 0.0, 1)
+#define PIRATEGOLD1_MED_TRANS QColor::fromRgbF(0.8, 0.5, 0.0, 0.75)
#define HOKEYPOKEY1 QColor::fromRgbF(0.8, 0.6, 0.2, 1)
#define CINNABAR1 QColor::fromRgbF(0.9, 0.3, 0.2, 1)
#define REDORANGE1 QColor::fromRgbF(1.0, 0.2, 0.2, 1)
@@ -102,6 +103,7 @@ typedef enum {
CCRSENSOR1,
CCRSENSOR2,
CCRSENSOR3,
+ SCR_OCPO2,
PP_LINES,
/* Other colors */
diff --git a/core/pref.h b/core/pref.h
index 3ba7c26d3..2628c3677 100644
--- a/core/pref.h
+++ b/core/pref.h
@@ -87,6 +87,7 @@ struct preferences {
bool gf_low_at_maxdepth;
bool show_ccr_setpoint;
bool show_ccr_sensors;
+ bool show_scr_ocpo2;
bool display_invalid_dives;
short unit_system;
struct units units;
diff --git a/core/profile.c b/core/profile.c
index 835e68dcc..c5105c4f5 100644
--- a/core/profile.c
+++ b/core/profile.c
@@ -1214,6 +1214,8 @@ static void calculate_gas_information_new(struct dive *dive, struct divecomputer
fill_pressures(&entry->pressures, amb_pressure, gasmix, entry->o2pressure.mbar / 1000.0, dive->dc.divemode);
fn2 = (int)(1000.0 * entry->pressures.n2 / amb_pressure);
fhe = (int)(1000.0 * entry->pressures.he / amb_pressure);
+ if (dc->divemode == PSCR) // OC pO2 is calulated for PSCR with or without external PO2 monitoring.
+ entry->scr_OC_pO2.mbar = (int) depth_to_mbar(entry->depth, dive) * get_o2(get_gasmix(dive, dc, entry->sec, &ev, gasmix)) / 1000;
/* Calculate MOD, EAD, END and EADD based on partial pressures calculated before
* so there is no difference in calculating between OC and CC
diff --git a/core/profile.h b/core/profile.h
index 0a215d47e..58c44d955 100644
--- a/core/profile.h
+++ b/core/profile.h
@@ -46,6 +46,7 @@ struct plot_data {
pressure_t o2pressure; // for rebreathers, this is consensus measured po2, or setpoint otherwise. 0 for OC.
pressure_t o2sensor[3]; //for rebreathers with up to 3 PO2 sensors
pressure_t o2setpoint;
+ pressure_t scr_OC_pO2;
double mod, ead, end, eadd;
velocity_t velocity;
int speed;
diff --git a/core/subsurface-qt/SettingsObjectWrapper.cpp b/core/subsurface-qt/SettingsObjectWrapper.cpp
index cd1054b97..aaa907759 100644
--- a/core/subsurface-qt/SettingsObjectWrapper.cpp
+++ b/core/subsurface-qt/SettingsObjectWrapper.cpp
@@ -392,6 +392,11 @@ bool TechnicalDetailsSettings::rulerGraph() const
return prefs.rulergraph;
}
+bool TechnicalDetailsSettings::showSCROCpO2() const
+{
+ return prefs.show_scr_ocpo2;
+}
+
bool TechnicalDetailsSettings::showCCRSetpoint() const
{
return prefs.show_ccr_setpoint;
@@ -667,6 +672,18 @@ void TechnicalDetailsSettings::setShowCCRSetpoint(bool value)
emit showCCRSetpointChanged(value);
}
+void TechnicalDetailsSettings::setShowSCROCpO2(bool value)
+{
+ if (value == prefs.show_scr_ocpo2)
+ return;
+
+ QSettings s;
+ s.beginGroup(group);
+ s.setValue("show_scr_ocpo2", value);
+ prefs.show_scr_ocpo2 = value;
+ emit showSCROCpO2Changed(value);
+}
+
void TechnicalDetailsSettings::setShowCCRSensors(bool value)
{
if (value == prefs.show_ccr_sensors)
@@ -2222,6 +2239,7 @@ void SettingsObjectWrapper::load()
GET_BOOL("gf_low_at_maxdepth", gf_low_at_maxdepth);
GET_BOOL("show_ccr_setpoint",show_ccr_setpoint);
GET_BOOL("show_ccr_sensors",show_ccr_sensors);
+ GET_BOOL("show_scr_ocpo2",show_scr_ocpo2);
GET_BOOL("zoomed_plot", zoomed_plot);
set_gf(prefs.gflow, prefs.gfhigh);
set_vpmb_conservatism(prefs.vpmb_conservatism);
diff --git a/core/subsurface-qt/SettingsObjectWrapper.h b/core/subsurface-qt/SettingsObjectWrapper.h
index 94bbcf5fc..f2c6745d8 100644
--- a/core/subsurface-qt/SettingsObjectWrapper.h
+++ b/core/subsurface-qt/SettingsObjectWrapper.h
@@ -135,6 +135,7 @@ class TechnicalDetailsSettings : public QObject {
Q_PROPERTY(bool rulergraph READ rulerGraph WRITE setRulerGraph NOTIFY rulerGraphChanged)
Q_PROPERTY(bool show_ccr_setpoint READ showCCRSetpoint WRITE setShowCCRSetpoint NOTIFY showCCRSetpointChanged)
Q_PROPERTY(bool show_ccr_sensors READ showCCRSensors WRITE setShowCCRSensors NOTIFY showCCRSensorsChanged)
+ Q_PROPERTY(bool show_scr_ocpo2 READ showSCROCpO2 WRITE setShowSCROCpO2 NOTIFY showSCROCpO2Changed)
Q_PROPERTY(bool zoomed_plot READ zoomedPlot WRITE setZoomedPlot NOTIFY zoomedPlotChanged)
Q_PROPERTY(bool show_sac READ showSac WRITE setShowSac NOTIFY showSacChanged)
Q_PROPERTY(bool display_unused_tanks READ displayUnusedTanks WRITE setDisplayUnusedTanks NOTIFY displayUnusedTanksChanged)
@@ -165,6 +166,7 @@ public:
bool rulerGraph() const;
bool showCCRSetpoint() const;
bool showCCRSensors() const;
+ bool showSCROCpO2() const;
bool zoomedPlot() const;
bool showSac() const;
bool displayUnusedTanks() const;
@@ -193,6 +195,7 @@ public slots:
void setRulerGraph(bool value);
void setShowCCRSetpoint(bool value);
void setShowCCRSensors(bool value);
+ void setShowSCROCpO2(bool value);
void setZoomedPlot(bool value);
void setShowSac(bool value);
void setDisplayUnusedTanks(bool value);
@@ -221,6 +224,7 @@ signals:
void rulerGraphChanged(bool value);
void showCCRSetpointChanged(bool value);
void showCCRSensorsChanged(bool value);
+ void showSCROCpO2Changed(bool value);
void zoomedPlotChanged(bool value);
void showSacChanged(bool value);
void displayUnusedTanksChanged(bool value);
diff --git a/core/subsurfacestartup.c b/core/subsurfacestartup.c
index 1f71d2117..9d7d9494b 100644
--- a/core/subsurfacestartup.c
+++ b/core/subsurfacestartup.c
@@ -42,6 +42,7 @@ struct preferences default_prefs = {
.gf_low_at_maxdepth = false,
.show_ccr_setpoint = false,
.show_ccr_sensors = false,
+ .show_scr_ocpo2 = false,
.font_size = -1,
.display_invalid_dives = false,
.show_sac = false,
diff --git a/desktop-widgets/preferences/preferences_graph.cpp b/desktop-widgets/preferences/preferences_graph.cpp
index ccc9aee65..91cd773d8 100644
--- a/desktop-widgets/preferences/preferences_graph.cpp
+++ b/desktop-widgets/preferences/preferences_graph.cpp
@@ -40,6 +40,7 @@ void PreferencesGraph::refreshSettings()
ui->vpmb_conservatism->setValue(prefs.vpmb_conservatism);
ui->show_ccr_setpoint->setChecked(prefs.show_ccr_setpoint);
ui->show_ccr_sensors->setChecked(prefs.show_ccr_sensors);
+ ui->show_scr_ocpo2->setChecked(prefs.show_scr_ocpo2);
ui->defaultSetpoint->setValue((double)prefs.defaultsetpoint / 1000.0);
ui->psro2rate->setValue(prefs.o2consumption / 1000.0);
ui->pscrfactor->setValue(lrint(1000.0 / prefs.pscr_ratio));
@@ -71,6 +72,7 @@ void PreferencesGraph::syncSettings()
tech->setVpmbConservatism(ui->vpmb_conservatism->value());
tech->setShowCCRSetpoint(ui->show_ccr_setpoint->isChecked());
tech->setShowCCRSensors(ui->show_ccr_sensors->isChecked());
+ tech->setShowSCROCpO2(ui->show_scr_ocpo2->isChecked());
tech->setDisplayUnusedTanks(ui->display_unused_tanks->isChecked());
tech->setShowAverageDepth(ui->show_average_depth->isChecked());
tech->setShowIcd(ui->show_icd->isChecked());
diff --git a/desktop-widgets/preferences/preferences_graph.ui b/desktop-widgets/preferences/preferences_graph.ui
index e711ea1c7..020ae498f 100644
--- a/desktop-widgets/preferences/preferences_graph.ui
+++ b/desktop-widgets/preferences/preferences_graph.ui
@@ -158,18 +158,72 @@
-
- Show individual O₂ sensor values when viewing pO₂
+ Show O₂ sensor values when viewing pO₂
-
- Show setpoints when viewing pO₂
+ Show CCR setpoints when viewing pO₂
-
+
+
+ pSCR options:
+
+
+
+ -
+
+
+ pSCR metabolic rate O₂
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ ℓ/min
+
+
+ 3
+
+
+
+ -
+
+
+ Dilution ratio
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+
+
+ 1:
+
+
+
+ -
+
+
+ Show equivalent OC pO₂ with pSCR pO₂
+
+
+
+ -
Show warnings for isobaric counterdiffusion
@@ -195,16 +249,6 @@
- -
-
-
-
-
-
- 1:
-
-
-
-
@@ -225,16 +269,6 @@
- -
-
-
- Dilution ratio
-
-
- Qt::AlignCenter
-
-
-
-
@@ -271,16 +305,6 @@
- -
-
-
- Metabolic rate O₂
-
-
- Qt::AlignCenter
-
-
-
-
@@ -291,16 +315,6 @@
- -
-
-
- ℓ/min
-
-
- 3
-
-
-
-
@@ -321,13 +335,6 @@
- -
-
-
- pSCR options:
-
-
-
-
@@ -386,16 +393,18 @@
pheThreshold
maxpo2
defaultSetpoint
- show_ccr_setpoint
show_ccr_sensors
+ show_ccr_setpoint
+ psro2rate
+ pscrfactor
+ show_scr_ocpo2
+ show_icd
red_ceiling
vpmb
vpmb_conservatism
buehlmann
gflow
gfhigh
- psro2rate
- pscrfactor
display_unused_tanks
show_average_depth
diff --git a/profile-widget/profilewidget2.cpp b/profile-widget/profilewidget2.cpp
index 16d08f119..da3eaad90 100644
--- a/profile-widget/profilewidget2.cpp
+++ b/profile-widget/profilewidget2.cpp
@@ -109,6 +109,7 @@ ProfileWidget2::ProfileWidget2(QWidget *parent) : QGraphicsView(parent),
ccrsensor1GasItem(new PartialPressureGasItem()),
ccrsensor2GasItem(new PartialPressureGasItem()),
ccrsensor3GasItem(new PartialPressureGasItem()),
+ ocpo2GasItem(new PartialPressureGasItem()),
#ifndef SUBSURFACE_MOBILE
diveCeiling(new DiveCalculatedCeiling(this)),
decoModelParameters(new DiveTextItem()),
@@ -198,6 +199,7 @@ void ProfileWidget2::addItemsToScene()
scene()->addItem(ccrsensor1GasItem);
scene()->addItem(ccrsensor2GasItem);
scene()->addItem(ccrsensor3GasItem);
+ scene()->addItem(ocpo2GasItem);
#ifndef SUBSURFACE_MOBILE
scene()->addItem(toolTipItem);
scene()->addItem(diveCeiling);
@@ -315,6 +317,7 @@ void ProfileWidget2::setupItemOnScene()
createPPGas(ccrsensor1GasItem, DivePlotDataModel::CCRSENSOR1, CCRSENSOR1, PO2_ALERT, &prefs.pp_graphs.po2_threshold_min, &prefs.pp_graphs.po2_threshold_max);
createPPGas(ccrsensor2GasItem, DivePlotDataModel::CCRSENSOR2, CCRSENSOR2, PO2_ALERT, &prefs.pp_graphs.po2_threshold_min, &prefs.pp_graphs.po2_threshold_max);
createPPGas(ccrsensor3GasItem, DivePlotDataModel::CCRSENSOR3, CCRSENSOR3, PO2_ALERT, &prefs.pp_graphs.po2_threshold_min, &prefs.pp_graphs.po2_threshold_max);
+ createPPGas(ocpo2GasItem, DivePlotDataModel::SCR_OC_PO2, SCR_OCPO2, PO2_ALERT, &prefs.pp_graphs.po2_threshold_min, &prefs.pp_graphs.po2_threshold_max);
#undef CREATE_PP_GAS
#ifndef SUBSURFACE_MOBILE
@@ -327,6 +330,7 @@ void ProfileWidget2::setupItemOnScene()
//WARNING: The old code was broken, I'm not sure what should trigger the visibility of those graphs, since the old code didn't triggered them
// because it was using a wrong settings.
+ connect(SettingsObjectWrapper::instance()->techDetails, &TechnicalDetailsSettings::showSCROCpO2Changed, ocpo2GasItem, &PartialPressureGasItem::setVisible);
connect(SettingsObjectWrapper::instance()->techDetails, &TechnicalDetailsSettings::showCCRSensorsChanged, ccrsensor1GasItem, &PartialPressureGasItem::setVisible);
connect(SettingsObjectWrapper::instance()->techDetails, &TechnicalDetailsSettings::showCCRSensorsChanged, ccrsensor2GasItem, &PartialPressureGasItem::setVisible);
connect(SettingsObjectWrapper::instance()->techDetails, &TechnicalDetailsSettings::showCCRSensorsChanged, ccrsensor3GasItem, &PartialPressureGasItem::setVisible);
@@ -598,6 +602,7 @@ void ProfileWidget2::plotDive(struct dive *d, bool force)
ccrsensor1GasItem->setVisible(sensorflag);
ccrsensor2GasItem->setVisible(sensorflag && (currentdc->no_o2sensors > 1));
ccrsensor3GasItem->setVisible(sensorflag && (currentdc->no_o2sensors > 2));
+ ocpo2GasItem->setVisible((currentdc->divemode == PSCR) && prefs.show_scr_ocpo2);
/* This struct holds all the data that's about to be plotted.
* I'm not sure this is the best approach ( but since we are
@@ -705,6 +710,7 @@ void ProfileWidget2::plotDive(struct dive *d, bool force)
ccrsensor1GasItem->setVisible(prefs.show_ccr_sensors);
ccrsensor2GasItem->setVisible(prefs.show_ccr_sensors && (currentdc->no_o2sensors > 1));
ccrsensor3GasItem->setVisible(prefs.show_ccr_sensors && (currentdc->no_o2sensors > 1));
+ ocpo2GasItem->setVisible((currentdc->divemode == PSCR) && prefs.show_scr_ocpo2);
temperatureItem->setVisible(false);
} else {
tankItem->setVisible(prefs.tankbar);
@@ -716,6 +722,7 @@ void ProfileWidget2::plotDive(struct dive *d, bool force)
ccrsensor1GasItem->setVisible(false);
ccrsensor2GasItem->setVisible(false);
ccrsensor3GasItem->setVisible(false);
+ ocpo2GasItem->setVisible(false);
}
#endif
tankItem->setData(dataModel, &plotInfo, &displayed_dive);
@@ -1074,6 +1081,7 @@ void ProfileWidget2::setEmptyState()
ccrsensor1GasItem->setVisible(false);
ccrsensor2GasItem->setVisible(false);
ccrsensor3GasItem->setVisible(false);
+ ocpo2GasItem->setVisible(false);
#ifndef SUBSURFACE_MOBILE
toolTipItem->setVisible(false);
diveCeiling->setVisible(false);
@@ -1193,6 +1201,7 @@ void ProfileWidget2::setProfileState()
ccrsensor1GasItem->setVisible(sensorflag);
ccrsensor2GasItem->setVisible(sensorflag && (current_dc->no_o2sensors > 1));
ccrsensor3GasItem->setVisible(sensorflag && (current_dc->no_o2sensors > 2));
+ ocpo2GasItem->setVisible((current_dc->divemode == PSCR) && prefs.show_scr_ocpo2);
heartBeatItem->setVisible(prefs.hrgraph);
diveCeiling->setVisible(prefs.calcceiling);
diff --git a/profile-widget/profilewidget2.h b/profile-widget/profilewidget2.h
index 937e0ee4b..0e44424ee 100644
--- a/profile-widget/profilewidget2.h
+++ b/profile-widget/profilewidget2.h
@@ -202,6 +202,7 @@ private:
PartialPressureGasItem *ccrsensor1GasItem;
PartialPressureGasItem *ccrsensor2GasItem;
PartialPressureGasItem *ccrsensor3GasItem;
+ PartialPressureGasItem *ocpo2GasItem;
#ifndef SUBSURFACE_MOBILE
DiveCalculatedCeiling *diveCeiling;
DiveTextItem *decoModelParameters;
diff --git a/qt-models/diveplotdatamodel.cpp b/qt-models/diveplotdatamodel.cpp
index a2b411bdf..944510167 100644
--- a/qt-models/diveplotdatamodel.cpp
+++ b/qt-models/diveplotdatamodel.cpp
@@ -63,6 +63,8 @@ QVariant DivePlotDataModel::data(const QModelIndex &index, int role) const
return item.o2sensor[1].mbar / 1000.0;
case CCRSENSOR3:
return item.o2sensor[2].mbar / 1000.0;
+ case SCR_OC_PO2:
+ return item.scr_OC_pO2.mbar / 1000.0;
case HEARTBEAT:
return item.heartbeat;
case AMBPRESSURE:
diff --git a/qt-models/diveplotdatamodel.h b/qt-models/diveplotdatamodel.h
index 3316b442c..51dc44176 100644
--- a/qt-models/diveplotdatamodel.h
+++ b/qt-models/diveplotdatamodel.h
@@ -64,6 +64,7 @@ public:
CCRSENSOR1,
CCRSENSOR2,
CCRSENSOR3,
+ SCR_OC_PO2,
HEARTBEAT,
AMBPRESSURE,
GFLINE,