Index: sources/gui/qml/AlarmItem.qml =================================================================== diff -u -r2aacff00f09521902b4c0e06eb16c69b2cc31eed -rf7d7e8b10c7626f3c6b8450876721a452ebd730f --- sources/gui/qml/AlarmItem.qml (.../AlarmItem.qml) (revision 2aacff00f09521902b4c0e06eb16c69b2cc31eed) +++ sources/gui/qml/AlarmItem.qml (.../AlarmItem.qml) (revision f7d7e8b10c7626f3c6b8450876721a452ebd730f) @@ -116,8 +116,8 @@ titleText : vAlarmStatus.title titlePixelSize : Fonts.fontPixelAlarmTitle description : vAlarmStatus.message - instructions : vAlarmStatus.instructionKeys - images : vAlarmStatus.instructionValues + instructionModel : vAlarmStatus.instructionModel +// images : vAlarmStatus.instructionValues alarmID : vAlarmStatus.alarm_AlarmID isSilenced : vAlarmStatus.alarm_Flag_alarmsSilenced timeout : vAlarmStatus.alarm_MuteTimeout Index: sources/gui/qml/components/AlarmButtonRow.qml =================================================================== diff -u -r5d784780bbec88cd8531bb56fbcc6e6fe2703236 -rf7d7e8b10c7626f3c6b8450876721a452ebd730f --- sources/gui/qml/components/AlarmButtonRow.qml (.../AlarmButtonRow.qml) (revision 5d784780bbec88cd8531bb56fbcc6e6fe2703236) +++ sources/gui/qml/components/AlarmButtonRow.qml (.../AlarmButtonRow.qml) (revision f7d7e8b10c7626f3c6b8450876721a452ebd730f) @@ -15,10 +15,15 @@ readonly property int spacing : Variables.defaultMargin * 4.5 + readonly property color pressedColor : Qt.darker (_root.backgroundColor, 1.15) + signal muteClicked() signal minMaxClicked() signal listClicked() + function buttonBackgroundColor(button) { + return button.isPressed ? Qt.darker (_root.backgroundColor, 1.15) : Colors.transparent + } MuteButton { id: _muteButton anchors{ @@ -27,7 +32,7 @@ verticalCenter : _root.verticalCenter } onClicked : _root.muteClicked() - selectColor : Qt.darker (_root.backgroundColor, 1.15) + backgroundColor : buttonBackgroundColor(_muteButton) } IconButton { id: _alarmsList @@ -38,7 +43,7 @@ } iconSize : Variables.iconsDiameter border.color : Colors.white - backgroundColor : isPressed ? Qt.darker (_root.backgroundColor, 1.15) : Colors.transparent + backgroundColor : buttonBackgroundColor(_alarmsList) iconImageSource : "qrc:/images/iList" onClicked : _root.listClicked() } @@ -51,7 +56,8 @@ upArrow : _root.isMaxButton downArrow : _root.isMinButton - backgroundColor : isPressed ? Qt.darker (_root.backgroundColor, 1.15) : Colors.transparent + backgroundColor : buttonBackgroundColor(_minMaxButton) + isDefault : false borderColor : Colors.white iconSize : Variables.iconsDiameter Index: sources/gui/qml/components/NotificationBar.qml =================================================================== diff -u -r21041955990385205ec1aca17ef51fc1fd9a4b29 -rf7d7e8b10c7626f3c6b8450876721a452ebd730f --- sources/gui/qml/components/NotificationBar.qml (.../NotificationBar.qml) (revision 21041955990385205ec1aca17ef51fc1fd9a4b29) +++ sources/gui/qml/components/NotificationBar.qml (.../NotificationBar.qml) (revision f7d7e8b10c7626f3c6b8450876721a452ebd730f) @@ -30,7 +30,6 @@ property alias isSilenced : _headerButtonGroup.isSilenced property alias timeout : _headerButtonGroup.timeout property bool iconVisible : true - property bool enableMute : true clip : true // the mute button expands so we need to clip the outside unwanted area. visible : _text.text @@ -78,7 +77,7 @@ isMaxButton : true backgroundColor : _root.color - onMuteClicked : _root.enableMute ? _root.muteClicked(): _root.clicked() + onMuteClicked : _root.muteClicked() onMinMaxClicked : _root.maximizeClicked() onListClicked : _root.listClicked() } @@ -93,6 +92,6 @@ } color : Colors.textMain - font.pixelSize : Fonts.fontPixelAlarmTID + font.pixelSize : Fonts.fontPixelAlarmID } } Index: sources/gui/qml/dialogs/AlarmListDialog.qml =================================================================== diff -u -r5d784780bbec88cd8531bb56fbcc6e6fe2703236 -rf7d7e8b10c7626f3c6b8450876721a452ebd730f --- sources/gui/qml/dialogs/AlarmListDialog.qml (.../AlarmListDialog.qml) (revision 5d784780bbec88cd8531bb56fbcc6e6fe2703236) +++ sources/gui/qml/dialogs/AlarmListDialog.qml (.../AlarmListDialog.qml) (revision f7d7e8b10c7626f3c6b8450876721a452ebd730f) @@ -41,8 +41,6 @@ backgroundColor : contentbackgroundColor radius : Variables.alarmDialogRadius - width : Variables.alarmDialogWidth - height : Variables.alarmDialogHeight signal muteClicked() signal minimizeClicked() Index: sources/gui/qml/dialogs/NotificationDialog.qml =================================================================== diff -u -r5d784780bbec88cd8531bb56fbcc6e6fe2703236 -rf7d7e8b10c7626f3c6b8450876721a452ebd730f --- sources/gui/qml/dialogs/NotificationDialog.qml (.../NotificationDialog.qml) (revision 5d784780bbec88cd8531bb56fbcc6e6fe2703236) +++ sources/gui/qml/dialogs/NotificationDialog.qml (.../NotificationDialog.qml) (revision f7d7e8b10c7626f3c6b8450876721a452ebd730f) @@ -31,8 +31,8 @@ property alias titleText : _title.text property alias titlePixelSize : _title.font.pixelSize property string description : "" - property var instructions : [] - property var images : [] + property alias instructionModel : _listView.model +// property var images : [] property alias titleBarForeground : _title.color property alias titleBarBackground : _titleBar.color property alias isSilenced : _headerButtonGroup.isSilenced @@ -60,23 +60,21 @@ // this behaviour does not look nice on the screen and it bounces visible : description && ! isSilenced radius : Variables.alarmDialogRadius - width : Variables.alarmDialogWidth - height : Variables.alarmDialogHeight - onInstructionsChanged: { - _model.clear() +// onInstructionsChanged: { +// _model.clear() - for (var step in instructions) { - _model.append({ text: instructions[step], image: "file:" + images[step] }) - } +// for (var step in instructions) { +// _model.append({ text: instructions[step], image: "file:" + images[step] }) +// } - if ( _model.count > 0) { - _listView.currentIndex = 0 - figureImageSource = _model.get(_listView.currentIndex).image - } - } +// if ( _model.count > 0) { +// _listView.currentIndex = 0 +// figureImageSource = _model.get(_listView.currentIndex).image +// } +// } - ListModel { id: _model } +// ListModel { id: _model } signal muteClicked() signal minimizeClicked() @@ -93,13 +91,6 @@ radius : _root.radius clip : true // the mute button expands so we need to clip the outside unwanted area. - gradient: Gradient { - orientation: Gradient.Horizontal - GradientStop { position: 0.0; color: Qt.darker (_titleBar.color, 1.1) } - GradientStop { position: 0.5; color: Qt.lighter (_titleBar.color, 1.1) } - GradientStop { position: 0.9; color: Qt.darker (_titleBar.color, 1.1) } - } - // TODO: disable doubleClicked later. this is only for diagnostic purpose when alarm dialog covers the entire screen. MouseArea { id: _minimizeArea anchors.fill : parent @@ -187,7 +178,7 @@ width : _descriptionRect.width ListView {id: _listView - model : _model +// model : _model height : _alarmContentRow.height width : parent.width * 0.65 currentIndex: 0 @@ -237,7 +228,7 @@ font.pixelSize : 23 font.weight : _delegateControl.ListView.isCurrentItem ? Font.DemiBold : Font.Normal color : _delegateControl.ListView.isCurrentItem ? "#18559E" : Colors.alarmDialogText - text : model.text + text : model.instruction wrapMode : Text.WordWrap } @@ -423,6 +414,6 @@ bottomMargin: Variables.defaultMargin * 4 } color : Colors.alarmDialogGreyText - font.pixelSize : Fonts.fontPixelAlarmTID + font.pixelSize : Fonts.fontPixelAlarmID } } Index: sources/gui/qml/globals/Fonts.qml =================================================================== diff -u -r21041955990385205ec1aca17ef51fc1fd9a4b29 -rf7d7e8b10c7626f3c6b8450876721a452ebd730f --- sources/gui/qml/globals/Fonts.qml (.../Fonts.qml) (revision 21041955990385205ec1aca17ef51fc1fd9a4b29) +++ sources/gui/qml/globals/Fonts.qml (.../Fonts.qml) (revision f7d7e8b10c7626f3c6b8450876721a452ebd730f) @@ -31,7 +31,7 @@ readonly property int fontPixelAlarmTitle : 48 readonly property int fontPixelAlarmBarTitle : 40 readonly property int fontPixelAlarmMessage : 40 - readonly property int fontPixelAlarmTID : 32 + readonly property int fontPixelAlarmID : 32 readonly property int fontPixelTouchAreaTitle : 16 Index: sources/gui/qml/globals/Variables.qml =================================================================== diff -u -r21041955990385205ec1aca17ef51fc1fd9a4b29 -rf7d7e8b10c7626f3c6b8450876721a452ebd730f --- sources/gui/qml/globals/Variables.qml (.../Variables.qml) (revision 21041955990385205ec1aca17ef51fc1fd9a4b29) +++ sources/gui/qml/globals/Variables.qml (.../Variables.qml) (revision f7d7e8b10c7626f3c6b8450876721a452ebd730f) @@ -74,8 +74,6 @@ readonly property int dialogWidth : applicationWidth - dialogMargin readonly property int dialogHeight : applicationHeight - dialogMargin readonly property int dialogRadius : 10 - readonly property int alarmDialogWidth : applicationWidth * 0.75 - readonly property int alarmDialogHeight : applicationHeight * 0.85 readonly property int alarmDialogRadius : 30 readonly property int rangeRectMargin : 1 Index: sources/model/hd/alarm/MAlarmMapping.cpp =================================================================== diff -u -r8748ddebadd70fe0ae28d5cfdea4df79e9c93353 -rf7d7e8b10c7626f3c6b8450876721a452ebd730f --- sources/model/hd/alarm/MAlarmMapping.cpp (.../MAlarmMapping.cpp) (revision 8748ddebadd70fe0ae28d5cfdea4df79e9c93353) +++ sources/model/hd/alarm/MAlarmMapping.cpp (.../MAlarmMapping.cpp) (revision f7d7e8b10c7626f3c6b8450876721a452ebd730f) @@ -131,8 +131,8 @@ /*0095*/case GuiAlarmID::ALARM_ID_DD_BC_STATE2_FILL_PRESSURE_DROP_OUT_OF_RANGE : { result = QObject::tr("DD balance chamber state2 fill initiated and pressure drop is not in range." ); break; } /* 95*/ /*0096*/case GuiAlarmID::ALARM_ID_TD_TREATMENT_STOPPED_BY_USER : { result = QObject::tr("TD treatment paused by user." ); break; } /* 96*/ /*0097*/case GuiAlarmID::ALARM_ID_DD_D74_COND_SENSOR_FPGA_FAULT : { result = QObject::tr("DD D74 bicarb conductivity sensor freshness/error timeout fault." ); break; } /* 97*/ -/*0098*/case GuiAlarmID::ALARM_ID_AVAILABLE_98 : { result = QObject::tr("Available alarms." ); break; } /* 98*/ -/*0099*/case GuiAlarmID::ALARM_ID_AVAILABLE_99 : { result = QObject::tr("Available alarms." ); break; } /* 99*/ +/*0098*/case GuiAlarmID::ALARM_ID_TD_BLOOD_SITTING_WARNING : { result = QObject::tr("TD blood sitting too long warning." ); break; } /* 98*/ +/*0099*/case GuiAlarmID::ALARM_ID_TD_BLOOD_SITTING_TOO_LONG : { result = QObject::tr("TD blood sitting too long alarm; no resume; no rinseback." ); break; } /* 99*/ /*0100*/case GuiAlarmID::ALARM_ID_TD_COMM_TIMEOUT : { result = QObject::tr("TD communication timeout." ); break; } /* 100*/ /*0101*/case GuiAlarmID::ALARM_ID_UI_POST_FAILURE_OS_VERSION : { result = QObject::tr("UI POST OS version compatibility failure." ); break; } /* 101*/ /*0102*/case GuiAlarmID::ALARM_ID_UI_POST_FAILURE_SHASUM : { result = QObject::tr("UI POST Application Integrity (Sha256Sum) failure." ); break; } /* 102*/ Index: sources/view/hd/alarm/VAlarmInstructionsModel.cpp =================================================================== diff -u --- sources/view/hd/alarm/VAlarmInstructionsModel.cpp (revision 0) +++ sources/view/hd/alarm/VAlarmInstructionsModel.cpp (revision f7d7e8b10c7626f3c6b8450876721a452ebd730f) @@ -0,0 +1,111 @@ +#include "VAlarmInstructionsModel.h" + + +VIEW_DEF_CLASS_EX(VAlarmInstructionsModel, QAbstractListModel) + +void VAlarmInstructionsModel::initConnections() +{ + +} + +/*! + * \brief Retrieve the role names set for this list model. + * \return Role names used for this model. + */ +QHash View::VAlarmInstructionsModel::roleNames() const +{ +// static const QHash roles { +// { eRole_Instruction, "instruction" }, +// { eRole_Image, "image" }, +// }; +// return roles; + + return _dataRoles; +} + +/*! + * \brief Get the number of rows in this list model. + * \return Number of rows in this list model. + */ +int View::VAlarmInstructionsModel::rowCount(const QModelIndex &) const +{ + return _data.size(); +} + +/*! + * \brief Set the role names for the data in this list model. + * \param[in] roleNames New role names for this list model. + * \note This will clear the list model of any data. + */ +QVariant View::VAlarmInstructionsModel::data(const QModelIndex &vIndex, int vRole) const +{ + // check for invalid or out of bounds index + if (vIndex.isValid() == false || vIndex.row() >= rowCount() || vIndex.column() > 0) + { + return QVariant(); + } + else + { + // ensure the role is in the data and return it, otherwise return invalid + return (_data[vIndex.row()].find(vRole) != _data[vIndex.row()].end()) + ? _data[vIndex.row()][vRole] + : QVariant(); + } +} + +/*! + * \brief Clear any data contained in this list model. + */ +void View::VAlarmInstructionsModel::clear() { + beginRemoveRows(QModelIndex(), 0, rowCount()); + _data.clear(); + endRemoveRows(); +} + +/*! + * \brief Get an index for this list model from the given row, column, and parent. + * \param[in] row Index row + * \param[in] column Index column + * \param[in] parent Index parent + * \return An index for the given row, column, and parent, or an invalid index if row, column, + * or parent are not valid. + */ +QModelIndex View::VAlarmInstructionsModel::index(int vRow, int vColumn, const QModelIndex &vParent) const { + return hasIndex(vRow, vColumn, vParent) + ? createIndex(vRow, vColumn) + : QModelIndex(); +} + +/*! + * \brief Sets the value of the data in this list model at the given index and for the given role. + * \param[in] index Location of data to update. + * \param[in] value Value to set. + * \param[in] role The role of the data at the given index to set. + * \return Return true if data was set properly, otherwise false. + */ +bool View::VAlarmInstructionsModel::setData(const QModelIndex &vIndex, const QVariant& vValue, int vRole) { + if (! vIndex.isValid() || vIndex.row() >= _data.count()) { + return false; + } + + if (_data[vIndex.row()][vRole] != vValue) + { + _data[vIndex.row()][vRole] = vValue; + // explicitly emit a dataChanged signal to notify anybody bound to this property (vRole) + Q_EMIT dataChanged(vIndex, vIndex, QVector(1, vRole)); + } + + return true; +} + +/*! + * \brief Appends a row of data to the end of the model. + * \param[in] data The data to append. + */ +void View::VAlarmInstructionsModel::appendData(const QHash &vData) +{ + auto index = std::clamp(rowCount(), 0, rowCount()); + beginInsertRows(QModelIndex(), index, index); + _data.insert(rowCount(), vData); + endInsertRows(); +} Index: sources/view/hd/alarm/VAlarmInstructionsModel.h =================================================================== diff -u --- sources/view/hd/alarm/VAlarmInstructionsModel.h (revision 0) +++ sources/view/hd/alarm/VAlarmInstructionsModel.h (revision f7d7e8b10c7626f3c6b8450876721a452ebd730f) @@ -0,0 +1,46 @@ + +// Qt +#include +#include +#include +#include + +// Project +#include "main.h" // Doxygen : do not remove +#include "VView.h" + +namespace View { + + +class VAlarmInstructionsModel : public QAbstractListModel +{ + Q_OBJECT + + QHash _dataRoles { + { eRole_Instruction , "instruction" }, + { eRole_Image , "image" }, + }; + +public: + + typedef enum { + eRole_Instruction = Qt::UserRole, + eRole_Image, + } DataRole; + + QHash roleNames ( ) const override; + int rowCount (const QModelIndex & = QModelIndex() ) const override; + QVariant data (const QModelIndex &vIndex, int vRole = Qt::DisplayRole ) const override; + bool setData (const QModelIndex &vIndex, const QVariant& vValue, int vRole = Qt::EditRole) override; + QModelIndex index (int vRow, int vColumn, const QModelIndex &vParent = QModelIndex() ) const override; + void clear ( ); + void appendData (const QHash &vData ); + + VIEW_DEC_CLASS_EX(VAlarmInstructionsModel, QAbstractListModel) + +private: + QList> _data; + +}; + +} Index: sources/view/hd/alarm/VAlarmStatus.cpp =================================================================== diff -u -r3c437b45ff53b13c3f567bd8431738941ebce7c3 -rf7d7e8b10c7626f3c6b8450876721a452ebd730f --- sources/view/hd/alarm/VAlarmStatus.cpp (.../VAlarmStatus.cpp) (revision 3c437b45ff53b13c3f567bd8431738941ebce7c3) +++ sources/view/hd/alarm/VAlarmStatus.cpp (.../VAlarmStatus.cpp) (revision f7d7e8b10c7626f3c6b8450876721a452ebd730f) @@ -153,7 +153,17 @@ // alarm is out of silence || ( _alarm_Flag_alarmsSilencedChanged && ! _alarm_Flag_alarmsSilenced ) ){ + + _alarmInstructionsList.clear(); + for (QMap::const_iterator it = _alarms[_alarm_AlarmID].instructions.constBegin(); + it != _alarms[_alarm_AlarmID].instructions.constEnd(); ++it) { + + _alarmInstructionsList.appendData( {{VAlarmInstructionsModel::eRole_Instruction, it.key() }, + {VAlarmInstructionsModel::eRole_Image, it.value()}}); + } + emit didAlarmRaise(); + } } @@ -179,8 +189,8 @@ QString VAlarmStatus::title () { if ( ! _alarm_AlarmID ) return {}; QString s = _alarms[_alarm_AlarmID].title ; if ( ! s.isEmpty()) return s; else return tr("Alarm") ; } QString VAlarmStatus::message () { if ( ! _alarm_AlarmID ) return {}; QString s = _alarms[_alarm_AlarmID].message; if ( ! s.isEmpty()) return s; else return text() ; } -QStringList VAlarmStatus::instructionKeys () { if ( ! _alarm_AlarmID ) return {}; return _alarms[_alarm_AlarmID].instructions.keys () ; } -QStringList VAlarmStatus::instructionValues () { if ( ! _alarm_AlarmID ) return {}; return _alarms[_alarm_AlarmID].instructions.values () ; } +//QStringList VAlarmStatus::instructionKeys () { if ( ! _alarm_AlarmID ) return {}; return _alarms[_alarm_AlarmID].instructions.keys () ; } +//QStringList VAlarmStatus::instructionValues () { if ( ! _alarm_AlarmID ) return {}; return _alarms[_alarm_AlarmID].instructions.values () ; } /*! * \brief View::VAlarmStatus::onActionReceive @@ -198,6 +208,7 @@ AlarmData alarmData; InstructionData instructionData; + for (const QString &key : _Settings.keys(category, group)) { if (Storage::Settings::isKeyTitle ( key ) ) { alarmData.title = _Settings.value(category, group, key).toString(); @@ -211,13 +222,14 @@ instructionData[key] = QFile::exists(imagePath) ? imagePath : QStringLiteral("%1%2").arg(_location) .arg("defaultImage.png"); alarmData.instructions = instructionData; + } } _alarms[id] = alarmData; /// DEBUG: /// TODO: the MSettings model should do the same has been done here and use map instead of separate structure to iterate vertically, while map supports, keys, values. - // qDebug() << "@" << id << _alarms[id].title << _alarms[id].message << _alarms[id].instructions.keys() << _alarms[id].instructions.values(); +// qDebug() << "@" << id << _alarms[id].title << _alarms[id].message << _alarms[id].instructions.keys() << _alarms[id].instructions.values(); // for (const auto &key : _alarms[id].instructions.keys()) { // qDebug() << "-" << key << _alarms[id].instructions.value(key); // } Index: sources/view/hd/alarm/VAlarmStatus.h =================================================================== diff -u -r5d784780bbec88cd8531bb56fbcc6e6fe2703236 -rf7d7e8b10c7626f3c6b8450876721a452ebd730f --- sources/view/hd/alarm/VAlarmStatus.h (.../VAlarmStatus.h) (revision 5d784780bbec88cd8531bb56fbcc6e6fe2703236) +++ sources/view/hd/alarm/VAlarmStatus.h (.../VAlarmStatus.h) (revision f7d7e8b10c7626f3c6b8450876721a452ebd730f) @@ -26,14 +26,12 @@ #include "GuiGlobals.h" #include "MessageGlobals.h" #include "format.h" +#include "VAdjustmentResponseBase.h" +#include "VAlarmInstructionsModel.h" // forward declarations class tst_views; -// Project -#include "main.h" // Doxygen : do not remove -#include "VAdjustmentResponseBase.h" - namespace View { /*! @@ -57,7 +55,7 @@ QString title = ""; QString message = ""; InstructionData instructions; - bool hasInstruction() { return instructions.count(); } +// bool hasInstruction() { return instructions.count(); } }; QMap _alarms; @@ -86,9 +84,10 @@ // ********** STATIC PROPERTIES: The properties which need to be updated by each alarm message received. ********** // Q_PROPERTY(QString title READ title NOTIFY alarm_AlarmIDChanged ) Q_PROPERTY(QString message READ message NOTIFY alarm_AlarmIDChanged ) - Q_PROPERTY(QStringList instructionKeys READ instructionKeys NOTIFY alarm_AlarmIDChanged ) - Q_PROPERTY(QStringList instructionValues READ instructionValues NOTIFY alarm_AlarmIDChanged ) +// Q_PROPERTY(QStringList instructionKeys READ instructionKeys NOTIFY alarm_AlarmIDChanged ) +// Q_PROPERTY(QStringList instructionValues READ instructionValues NOTIFY alarm_AlarmIDChanged ) Q_PROPERTY(QString text READ text NOTIFY alarm_AlarmIDChanged ) + Q_PROPERTY(VAlarmInstructionsModel* instructionModel READ instructionModel NOTIFY alarm_AlarmIDChanged) VIEW_DEC_CLASS ( VAlarmStatus ) VIEW_DEC_SLOT ( AlarmStatusData ) @@ -100,11 +99,12 @@ private: QString title (); QString message (); - QStringList instructionKeys (); - QStringList instructionValues (); QString text (); QString alarmIDText (GuiAlarmID vEnum); + VAlarmInstructionsModel* instructionModel() { return &_alarmInstructionsList; } ; + VAlarmInstructionsModel _alarmInstructionsList; + signals: void didAlarmRaise(); void didAlarmEmpty(); Index: sources/view/td/data/treatment/VTDTreatmentStatesData.cpp =================================================================== diff -u -r43ae56f762e6f3e1416d39e3d16f9103fc597e41 -rf7d7e8b10c7626f3c6b8450876721a452ebd730f --- sources/view/td/data/treatment/VTDTreatmentStatesData.cpp (.../VTDTreatmentStatesData.cpp) (revision 43ae56f762e6f3e1416d39e3d16f9103fc597e41) +++ sources/view/td/data/treatment/VTDTreatmentStatesData.cpp (.../VTDTreatmentStatesData.cpp) (revision f7d7e8b10c7626f3c6b8450876721a452ebd730f) @@ -69,12 +69,10 @@ ENUM_CHECK ( GuiSalineStates, SALINE_BOLUS_STATE_IDLE ) ENUM_CHECK ( GuiSalineStates, SALINE_BOLUS_STATE_WAIT_FOR_PUMPS_STOP ) ENUM_CHECK ( GuiSalineStates, SALINE_BOLUS_STATE_IN_PROGRESS ) - ENUM_CHECK ( GuiSalineStates, SALINE_BOLUS_STATE_MAX_DELIVERED ) ENUM_CHECK_C( GuiSalineStates, NUM_OF_SALINE_BOLUS_STATES ) } ENUM_READ ( GuiSalineStates, SALINE_BOLUS_STATE_IDLE , sbIdle ); ENUM_READ ( GuiSalineStates, SALINE_BOLUS_STATE_WAIT_FOR_PUMPS_STOP , sbWaitPump ); ENUM_READ ( GuiSalineStates, SALINE_BOLUS_STATE_IN_PROGRESS , sbRunning ); - ENUM_READ ( GuiSalineStates, SALINE_BOLUS_STATE_MAX_DELIVERED , sbMaxReached ); // Heparin States _heparin = false;