This patch implements the visualisation of the oxygen sensor data for CCR dives. The partial pressure measurements of each of the sensors are graphed using the existing partial pressure axis in the dive profile widget. There are now four separate sets of data that can be plotted using the partial pressure axis system: po2, pn2, phe, and this additional one: sensor data. The sensor data can be visualised individually or in combination with any of the other three partial pressure graphs, mentioned above. The display of the sensor data is activated by the button at the bottom of the toolbar, allowing the evaluation of data from individual oxygen sensors with respect to drift or fluctuation and with respect to the setpoint setting, these being important criteria for evaluating the reliability of these sensors for a particular set of CCR equipment. It is a feature that many implementations of proprietary CCR dive logs have.
I need critical evaluation of this Qt code, please!! Signed-off-by: willem ferguson <[email protected]> ---
>From fd53dc4095982e0af8df0873193b1d861061aaf7 Mon Sep 17 00:00:00 2001 From: willem ferguson <[email protected]> Date: Fri, 9 Jan 2015 10:29:49 +0200 Subject: [PATCH] Create display of oxygen sensor data This patch implements the visualisation of the oxygen sensor data for CCR dives. The partial pressure measurements of each of the sensors are graphed using the existing partial pressure axis in the dive profile widget. There are now four separate sets of data that can be plotted using the partial pressure axis system: po2, pn2, phe, and this additional one: sensor data. The sensor data can be visualised individually or in combination with any of the other three partial pressure graphs, mentioned above. The display of the sensor data is activated by the button at the bottom of the toolbar, allowing the evaluation of data from individual oxygen sensors with respect to drift or fluctuation and with respect to the setpoint setting, these being important criteria for evaluating the reliabilty of these sensors for a particular set of CCR equipment. It is a feature that many implementations of proprietary CCR dive logs have. I need critical evaluation of this Qt code, please!! Signed-off-by: willem ferguson <[email protected]> --- icons/icon_CCR.png | Bin 0 -> 1332 bytes pref.h | 3 ++- qt-ui/graphicsview-common.cpp | 3 +++ qt-ui/graphicsview-common.h | 3 +++ qt-ui/mainwindow.cpp | 4 +++- qt-ui/mainwindow.h | 1 + qt-ui/mainwindow.ui | 12 ++++++++++++ qt-ui/profile/divecartesianaxis.cpp | 5 ++++- qt-ui/profile/diveplotdatamodel.cpp | 29 ++++++++++++++++++++++++++++- qt-ui/profile/diveplotdatamodel.h | 4 ++++ qt-ui/profile/profilewidget2.cpp | 18 ++++++++++++++++++ qt-ui/profile/profilewidget2.h | 3 +++ subsurface.qrc | 1 + subsurfacestartup.c | 1 + 14 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 icons/icon_CCR.png diff --git a/icons/icon_CCR.png b/icons/icon_CCR.png new file mode 100644 index 0000000000000000000000000000000000000000..1b4ea4a5ec081b74ef4a8d21240414fd8289624c GIT binary patch literal 1332 zcmV-41<U%0P)<h;3K|Lk000e1NJLTq000*N000*V1^@s6;40Lh00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru-V7fT3?@mks_y^*02y>e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00f*#L_t(Y$BmVHNY!T;$3O4; z`<;t=yrid6=dEo@w@EauWo1Jo`=cOZA#B~FF%}UO21Y?e;VR}IAw#0<CX4zbY_%KM zvWqPet+diOHZP4%7Fv4j=()YW{ULdBTK4?^e!kE5;d#EVa5x+Wqm&d9vozD=?ZMga z1OpU`gs=o6O_6w%2W2SUSNdpBx8F@oXALJECuwuFp$QEDAp}0<!)~>+I(0R<@wr5p zBi<<@{@;1k(<+MZ7Gsj8L3OF43mqvW%24<XKR)F{FetS3v#l&nT#SM7et1!B5%pd5 z2n1%$%>G&XnG!w)DdZ4bp}603pY6A{Bas*wq(`SynpH}_zkeiLmpc3I?Bj~_3f_R1 zt?7f^ym>sLBLoV?#eXkS+E@y}+=+83&MamiFc2IuK+~%xE<e4DU-{Yn`EHgaFGC<k z1p^ou2n6|w`D{zyM!*Pg_1RU<{c{cgo5{wpN5_!5)Y<a)7Br!;Vd@5Q;&SjQA7hnA zdFb)>ke{5-%CwbeLgQ4+DJt75$-b0Ld}uuS?dP`{Py>XU!YN28AYcRlc<y?^?%#gk zfwPH}=p=S7DkOEnCvRDnY`nP<M~?%OG!deQ(C6!;tf>r(W+5*j5B*;EJtUGflh+^+ z0Nie?qp)%pCs&qXx5eQ0_OrI)d%n(C&NrFM0We7ur@uVSfqMt2dRjGXWGAvu3@(AA z*MSg%rHM-i?fShGR_@}=+GC`|Bw@3JF(KT}g>Qf6NX>Cv1Fj*EG8BdBg_O)L8QPS@ zutdgL#tpjb?C->8vZ0H?dur`!!>pOGhuMc;o2D}<CYft3H%H8W`nc&_%DY6AIf|q6 zkG^$~2!sf3#(>X*CN-p#BOsyX5PAlBN8KKq$wt|{GP*onL3o%RhRYkY8et8`8}JcO z{t=L_*Dv`fGLEX|YVu0+DJWkvG^P%B2Md2+$g1j9L3mnZ8p=>ydwvaokL@W)A*g@S zFbv$@{e)+|oh(S5$Ly30e);Y!uRU&RJMIARp!)$)<|ype;5hXeF*CT(eu0vP60&l# z064R@oUe|qV$sxG=1iK!LuWH*>(BF3K?wliRvUjkx=L)sM7~JL#Hv}TY_G(?ATJ>= z*m>53EZlxKecnDAUo|2SjJMgT-ux@m<EHS?+01yGoj*37XIk830B$_K#r{8kWapwn z0xCeo;|f}PThWBZy0mq{m}qHfF={$%*jv9Bf#CRp<HUx<zV|w7+v}<8xQl^7YT_gg zH6Oq*43;D>Vbj!2!-Gp8*nDd<&99m<FgQ5-Aek|lc$N2^0%mEZy0e-+b$gIVl59zo zXO|C)j-klah0glx>uGhh;!{3y5^`Aa=?bPrPQ$PKC_^EIM3Wi~FB_<6so;k51}14D zHYAoK^N(Pb=6C0Ls2)mDZ4uX>T}KFkC*UE%62VOSOya}hak`z<y{N<GabeLcc$Jq7 zdj^MQ9UA+yc$3wA{yuip?x3Tu19!m9uy+Einw4lvG>7LLCej@F;osb7*VowHh=D;s q1;`wqIh34Z)tK-%Zr&FA(E1MvrT!fbJRyhx0000<MNUMnLSTZw5pz-i literal 0 HcmV?d00001 diff --git a/pref.h b/pref.h index 49e1afa..a122057 100644 --- a/pref.h +++ b/pref.h @@ -13,6 +13,7 @@ typedef struct short po2; short pn2; short phe; + short ccrsensors; double po2_threshold; double pn2_threshold; double phe_threshold; @@ -88,7 +89,7 @@ enum unit_system_values { extern struct preferences prefs, default_prefs; -#define PP_GRAPHS_ENABLED (prefs.pp_graphs.po2 || prefs.pp_graphs.pn2 || prefs.pp_graphs.phe) +#define PP_GRAPHS_ENABLED (prefs.pp_graphs.po2 || prefs.pp_graphs.pn2 || prefs.pp_graphs.phe || prefs.pp_graphs.ccrsensors) extern const char *system_divelist_default_font; extern double system_divelist_default_font_size; diff --git a/qt-ui/graphicsview-common.cpp b/qt-ui/graphicsview-common.cpp index 4402a23..a1813ce 100644 --- a/qt-ui/graphicsview-common.cpp +++ b/qt-ui/graphicsview-common.cpp @@ -28,6 +28,9 @@ void fill_profile_color() profile_color[PHE] = COLOR(PEANUT, BLACK1_LOW_TRANS, PEANUT); profile_color[PHE_ALERT] = COLOR(RED1, BLACK1_LOW_TRANS, RED1); profile_color[O2SETPOINT] = COLOR(RED1, BLACK1_LOW_TRANS, RED1); + 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[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/qt-ui/graphicsview-common.h b/qt-ui/graphicsview-common.h index 294109d..3c1cb75 100644 --- a/qt-ui/graphicsview-common.h +++ b/qt-ui/graphicsview-common.h @@ -38,6 +38,9 @@ typedef enum { PHE, PHE_ALERT, O2SETPOINT, + CCRSENSOR1, + CCRSENSOR2, + CCRSENSOR3, PP_LINES, /* Other colors */ diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp index 9186b7a..ad701d7 100644 --- a/qt-ui/mainwindow.cpp +++ b/qt-ui/mainwindow.cpp @@ -81,7 +81,7 @@ MainWindow::MainWindow() : QMainWindow(), ui.profMod << ui.profNdl_tts << // various values that a user is either interested in or not ui.profEad << ui.profSAC << ui.profHR << // very few dive computers support this - ui.profTissues; // maybe less frequently used + ui.profTissues << ui.profCCR; // maybe less frequently used setWindowIcon(QIcon(":subsurface-icon")); if (!QIcon::hasThemeIcon("window-close")) { QIcon::setThemeName("subsurface"); @@ -917,6 +917,7 @@ void MainWindow::readSettings() TOOLBOX_PREF_BUTTON(pp_graphs.phe, phegraph, profPhe); TOOLBOX_PREF_BUTTON(pp_graphs.pn2, pn2graph, profPn2); TOOLBOX_PREF_BUTTON(pp_graphs.po2, po2graph, profPO2); + TOOLBOX_PREF_BUTTON(pp_graphs.ccrsensors, ccrsensorgraph, profCCR); TOOLBOX_PREF_BUTTON(hrgraph, hrgraph, profHR); TOOLBOX_PREF_BUTTON(rulergraph, rulergraph, profRuler); TOOLBOX_PREF_BUTTON(show_sac, show_sac, profSAC); @@ -1425,6 +1426,7 @@ TOOLBOX_PREF_PROFILE(profNdl_tts, calcndltts, calcndltts); TOOLBOX_PREF_PROFILE(profPhe, pp_graphs.phe, phegraph); TOOLBOX_PREF_PROFILE(profPn2, pp_graphs.pn2, pn2graph); TOOLBOX_PREF_PROFILE(profPO2, pp_graphs.po2, po2graph); +TOOLBOX_PREF_PROFILE(profCCR, pp_graphs.ccrsensors, ccrsensorgraph); TOOLBOX_PREF_PROFILE(profHR, hrgraph, hrgraph); TOOLBOX_PREF_PROFILE(profRuler, rulergraph, rulergraph); TOOLBOX_PREF_PROFILE(profSAC, show_sac, show_sac); diff --git a/qt-ui/mainwindow.h b/qt-ui/mainwindow.h index 8a9d6f3..38d8384 100644 --- a/qt-ui/mainwindow.h +++ b/qt-ui/mainwindow.h @@ -139,6 +139,7 @@ slots: void on_profPO2_triggered(bool triggered); void on_profPhe_triggered(bool triggered); void on_profPn2_triggered(bool triggered); + void on_profCCR_triggered(bool triggered); void on_profHR_triggered(bool triggered); void on_profRuler_triggered(bool triggered); void on_profSAC_triggered(bool triggered); diff --git a/qt-ui/mainwindow.ui b/qt-ui/mainwindow.ui index a416b43..e0a6538 100644 --- a/qt-ui/mainwindow.ui +++ b/qt-ui/mainwindow.ui @@ -629,6 +629,18 @@ p, li { white-space: pre-wrap; } <string>Toggle pHe graph</string> </property> </action> + <action name="profCCR"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="icon"> + <iconset resource="../subsurface.qrc"> + <normaloff>:/icon_CCR</normaloff>:/icon_CCR</iconset> + </property> + <property name="text"> + <string>Toggle CCR Oâââ analysis</string> + </property> + </action> <action name="profDcCeiling"> <property name="checkable"> <bool>true</bool> diff --git a/qt-ui/profile/divecartesianaxis.cpp b/qt-ui/profile/divecartesianaxis.cpp index aaa85c6..53e4647 100644 --- a/qt-ui/profile/divecartesianaxis.cpp +++ b/qt-ui/profile/divecartesianaxis.cpp @@ -429,7 +429,8 @@ void PartialGasPressureAxis::settingsChanged() bool showPhe = prefs.pp_graphs.phe; bool showPn2 = prefs.pp_graphs.pn2; bool showPo2 = prefs.pp_graphs.po2; - setVisible(showPhe || showPn2 || showPo2); + bool showccrsensors = prefs.pp_graphs.ccrsensors; + setVisible(showPhe || showPn2 || showPo2 || showccrsensors); if (!model->rowCount()) return; @@ -438,6 +439,8 @@ void PartialGasPressureAxis::settingsChanged() max = model->pn2Max(); if (showPo2 && model->po2Max() > max) max = model->po2Max(); + if (showccrsensors && model->CCRMax() > max) + max = model->CCRMax(); qreal pp = floor(max * 10.0) / 10.0 + 0.2; if (IS_FP_SAME(maximum(), pp)) diff --git a/qt-ui/profile/diveplotdatamodel.cpp b/qt-ui/profile/diveplotdatamodel.cpp index e60dd9d..6bd9503 100644 --- a/qt-ui/profile/diveplotdatamodel.cpp +++ b/qt-ui/profile/diveplotdatamodel.cpp @@ -53,7 +53,14 @@ QVariant DivePlotDataModel::data(const QModelIndex &index, int role) const case PO2: return item.pressures.o2; case O2SETPOINT: - return item.o2setpoint.mbar / 1000.0; + if (item.o2setpoint.mbar > 5000) return 0; + else return item.o2setpoint.mbar / 1000.0; + case CCRSENSOR1: + return item.o2sensor[0].mbar / 1000.0; + case CCRSENSOR2: + return item.o2sensor[1].mbar / 1000.0; + case CCRSENSOR3: + return item.o2sensor[2].mbar / 1000.0; case HEARTBEAT: return item.heartbeat; case AMBPRESSURE: @@ -131,6 +138,12 @@ QVariant DivePlotDataModel::headerData(int section, Qt::Orientation orientation, return tr("pOâ"); case O2SETPOINT: return tr("Setpoint"); + case CCRSENSOR1: + return tr("Sensor1"); + case CCRSENSOR2: + return tr("Sensor2"); + case CCRSENSOR3: + return tr("Sensor3"); case AMBPRESSURE: return tr("Ambient pressure"); case HEARTBEAT: @@ -187,9 +200,23 @@ unsigned int DivePlotDataModel::dcShown() const return ret; \ } +#define MAX_PP2GAS_FUNC(GASFUNC) \ + double DivePlotDataModel::GASFUNC() /* CCR: This function finds the largest measured po2 value */ \ + { /* by scanning the readings from the three individual o2 sensors. */ \ + double ret = -1; /* This is used for scaling the Y-axis for partial pressures */ \ + for (int s = 0; s < 3; s++) { /* when displaying the graphs for individual o2 sensors */ \ + for (int i = 0, count = rowCount(); i < count; i++) { /* POTENTIAL PROBLEM: the '3' is hard-coded here */\ + if (pInfo.entry[i].o2sensor[s].mbar > ret) \ + ret = pInfo.entry[i].o2sensor[s].mbar; \ + } \ + } \ + return (ret / 1000.0); \ + } + MAX_PPGAS_FUNC(he, pheMax); MAX_PPGAS_FUNC(n2, pn2Max); MAX_PPGAS_FUNC(o2, po2Max); +MAX_PP2GAS_FUNC(CCRMax); void DivePlotDataModel::emitDataChanged() { diff --git a/qt-ui/profile/diveplotdatamodel.h b/qt-ui/profile/diveplotdatamodel.h index 6fdb5fc..6a1f9bd 100644 --- a/qt-ui/profile/diveplotdatamodel.h +++ b/qt-ui/profile/diveplotdatamodel.h @@ -60,6 +60,9 @@ public: PHE, PO2, O2SETPOINT, + CCRSENSOR1, + CCRSENSOR2, + CCRSENSOR3, HEARTBEAT, AMBPRESSURE, GFLINE, @@ -78,6 +81,7 @@ public: double pheMax(); double pn2Max(); double po2Max(); + double CCRMax(); void emitDataChanged(); void calculateDecompression(); diff --git a/qt-ui/profile/profilewidget2.cpp b/qt-ui/profile/profilewidget2.cpp index a3e08d8..c9f4b84 100644 --- a/qt-ui/profile/profilewidget2.cpp +++ b/qt-ui/profile/profilewidget2.cpp @@ -94,6 +94,9 @@ ProfileWidget2::ProfileWidget2(QWidget *parent) : QGraphicsView(parent), pheGasItem(new PartialPressureGasItem()), po2GasItem(new PartialPressureGasItem()), o2SetpointGasItem(new PartialPressureGasItem()), + ccrsensor1GasItem(new PartialPressureGasItem()), + ccrsensor2GasItem(new PartialPressureGasItem()), + ccrsensor3GasItem(new PartialPressureGasItem()), heartBeatAxis(new DiveCartesianAxis()), heartBeatItem(new DiveHeartrateItem()), percentageAxis(new DiveCartesianAxis()), @@ -164,6 +167,9 @@ ProfileWidget2::~ProfileWidget2() delete pheGasItem; delete po2GasItem; delete o2SetpointGasItem; + delete ccrsensor1GasItem; + delete ccrsensor2GasItem; + delete ccrsensor3GasItem; delete heartBeatAxis; delete heartBeatItem; delete percentageAxis; @@ -204,6 +210,9 @@ void ProfileWidget2::addItemsToScene() scene()->addItem(pheGasItem); scene()->addItem(po2GasItem); scene()->addItem(o2SetpointGasItem); + scene()->addItem(ccrsensor1GasItem); + scene()->addItem(ccrsensor2GasItem); + scene()->addItem(ccrsensor3GasItem); scene()->addItem(percentageAxis); scene()->addItem(heartBeatAxis); scene()->addItem(heartBeatItem); @@ -317,6 +326,9 @@ void ProfileWidget2::setupItemOnScene() CREATE_PP_GAS(pheGasItem, PHE, PHE, PHE_ALERT, &prefs.pp_graphs.phe_threshold, "phegraph"); CREATE_PP_GAS(po2GasItem, PO2, PO2, PO2_ALERT, &prefs.pp_graphs.po2_threshold, "po2graph"); CREATE_PP_GAS(o2SetpointGasItem, O2SETPOINT, PO2_ALERT, PO2_ALERT, &prefs.pp_graphs.po2_threshold, "po2graph"); + CREATE_PP_GAS(ccrsensor1GasItem, CCRSENSOR1, CCRSENSOR1, PO2_ALERT, &prefs.pp_graphs.po2_threshold, "ccrsensorgraph"); + CREATE_PP_GAS(ccrsensor2GasItem, CCRSENSOR2, CCRSENSOR2, PO2_ALERT, &prefs.pp_graphs.po2_threshold, "ccrsensorgraph"); + CREATE_PP_GAS(ccrsensor3GasItem, CCRSENSOR3, CCRSENSOR3, PO2_ALERT, &prefs.pp_graphs.po2_threshold, "ccrsensorgraph"); #undef CREATE_PP_GAS temperatureAxis->setTextVisible(false); @@ -893,6 +905,9 @@ void ProfileWidget2::setEmptyState() pn2GasItem->setVisible(false); po2GasItem->setVisible(false); o2SetpointGasItem->setVisible(false); + ccrsensor1GasItem->setVisible(false); + ccrsensor2GasItem->setVisible(false); + ccrsensor3GasItem->setVisible(false); pheGasItem->setVisible(false); ambPressureItem->setVisible(false); gflineItem->setVisible(false); @@ -992,6 +1007,9 @@ void ProfileWidget2::setProfileState() pn2GasItem->setVisible(prefs.pp_graphs.pn2); po2GasItem->setVisible(prefs.pp_graphs.po2); o2SetpointGasItem->setVisible(current_dive && (current_dc->dctype == CCR) && (prefs.show_ccr_setpoint)); + ccrsensor1GasItem->setVisible(prefs.pp_graphs.ccrsensors); + ccrsensor2GasItem->setVisible(prefs.pp_graphs.ccrsensors); + ccrsensor3GasItem->setVisible(prefs.pp_graphs.ccrsensors); pheGasItem->setVisible(prefs.pp_graphs.phe); timeAxis->setPos(itemPos.time.pos.on); diff --git a/qt-ui/profile/profilewidget2.h b/qt-ui/profile/profilewidget2.h index ffeecb3..6e8b9c4 100644 --- a/qt-ui/profile/profilewidget2.h +++ b/qt-ui/profile/profilewidget2.h @@ -175,6 +175,9 @@ private: PartialPressureGasItem *pheGasItem; PartialPressureGasItem *po2GasItem; PartialPressureGasItem *o2SetpointGasItem; + PartialPressureGasItem *ccrsensor1GasItem; + PartialPressureGasItem *ccrsensor2GasItem; + PartialPressureGasItem *ccrsensor3GasItem; DiveCartesianAxis *heartBeatAxis; DiveHeartrateItem *heartBeatItem; DiveCartesianAxis *percentageAxis; diff --git a/subsurface.qrc b/subsurface.qrc index 13e2229..41511ff 100644 --- a/subsurface.qrc +++ b/subsurface.qrc @@ -53,6 +53,7 @@ <file alias="icon_he">icons/he.png</file> <file alias="icon_n2">icons/n2.png</file> <file alias="icon_o2">icons/o2.png</file> + <file alias="icon_CCR">icons/icon_CCR.png</file> <file alias="icon_ceiling_calculated">icons/ss.png</file> <file alias="icon_ceiling_alltissues">icons/icon-ceiling-alltissues.png</file> <file alias="icon_NDLTTS">icons/limit.png</file> diff --git a/subsurfacestartup.c b/subsurfacestartup.c index 1e3a2c1..6474517 100644 --- a/subsurfacestartup.c +++ b/subsurfacestartup.c @@ -11,6 +11,7 @@ struct preferences default_prefs = { .po2 = false, .pn2 = false, .phe = false, + .ccrsensors = false, .po2_threshold = 1.6, .pn2_threshold = 4.0, .phe_threshold = 13.0, -- 1.9.1
_______________________________________________ subsurface mailing list [email protected] http://lists.subsurface-divelog.org/cgi-bin/mailman/listinfo/subsurface
