Index: AlarmMapping.csv =================================================================== diff -u -r465a935949a85d3d1bebd11979737ff38ef96122 -r35db01154f90ebfdb6174033a66f5c20af82e14d --- AlarmMapping.csv (.../AlarmMapping.csv) (revision 465a935949a85d3d1bebd11979737ff38ef96122) +++ AlarmMapping.csv (.../AlarmMapping.csv) (revision 35db01154f90ebfdb6174033a66f5c20af82e14d) @@ -12,8 +12,8 @@ 11,"HD dialysate temperature below target temperature." 12,"HD firmware image integrity POST test failed." 13,"DG firmware image integrity POST test failed." - 14,"Not used." - 15,"Not used." + 14,"DG invalid usage record CRC." + 15,"HD invalid usage record CRC." 16,"HD alarm audio failed POST." 17,"HD UI POST failed." 18,"DG load cells invalid calibration record." @@ -101,9 +101,9 @@ 100,"HD no cartridge self-test timeout." 101,"HD dry self-test timeout." 102,"DG heat disinfect temperature gradient out of range." - 103,"HD non-volatile calibration group invalid record CRC." + 103,"HD invalid calibration CRC." 104,"Air trap level sensors reporting illegal combination of air/fluid." - 105,"DG non-volatile system group invalid record CRC." + 105,"DG invalid calibration CRC." 106,"DG dialysate flow sensor invalid calibration record." 107,"HD reports DG restarted fault." 108,"HD syringe pump ADC error." Index: denali.pro.user =================================================================== diff -u -r153bcdb67dca6c40022318b80d5c7079d48bb37f -r35db01154f90ebfdb6174033a66f5c20af82e14d --- denali.pro.user (.../denali.pro.user) (revision 153bcdb67dca6c40022318b80d5c7079d48bb37f) +++ denali.pro.user (.../denali.pro.user) (revision 35db01154f90ebfdb6174033a66f5c20af82e14d) @@ -1,6 +1,6 @@ - + EnvironmentId Index: sources/canbus/MessageInterpreter.cpp =================================================================== diff -u -rcb7d9e125fe619ab0713f9146e9774940e26a096 -r35db01154f90ebfdb6174033a66f5c20af82e14d --- sources/canbus/MessageInterpreter.cpp (.../MessageInterpreter.cpp) (revision cb7d9e125fe619ab0713f9146e9774940e26a096) +++ sources/canbus/MessageInterpreter.cpp (.../MessageInterpreter.cpp) (revision 35db01154f90ebfdb6174033a66f5c20af82e14d) @@ -688,11 +688,11 @@ { // DEBUG: qDebug() << _Settings.groups(Storage::Settings_Category_MessagesUnhandled); for(const auto group: _Settings.groups(Storage::Settings_Category_MessagesUnhandled)) { - // DEBUG: qDebug() << _Settings.keys(group); bool ok; quint16 id = QString(group).toUInt(&ok,16); if (!ok) continue; _messageList[ id ] = _Settings.keys(group); + // DEBUG: qDebug() << _Settings.keys(group); } } Index: sources/gui/qml/pages/disinfect/DisinfectStack.qml =================================================================== diff -u -r153bcdb67dca6c40022318b80d5c7079d48bb37f -r35db01154f90ebfdb6174033a66f5c20af82e14d --- sources/gui/qml/pages/disinfect/DisinfectStack.qml (.../DisinfectStack.qml) (revision 153bcdb67dca6c40022318b80d5c7079d48bb37f) +++ sources/gui/qml/pages/disinfect/DisinfectStack.qml (.../DisinfectStack.qml) (revision 35db01154f90ebfdb6174033a66f5c20af82e14d) @@ -49,7 +49,7 @@ ] instructionBased : true header.confirmVisible : vDisinfectAdjustDisinfect .canCancel // if initiated by User from setting can be canceled. - header.confirmText : qsTr("Cancel") + header.confirmText.text : qsTr("Cancel") onConfirmClicked : { vDisinfectAdjustDisinfect .doCancel () } } Index: sources/model/hd/alarm/MAlarmMapping.cpp =================================================================== diff -u -r153bcdb67dca6c40022318b80d5c7079d48bb37f -r35db01154f90ebfdb6174033a66f5c20af82e14d --- sources/model/hd/alarm/MAlarmMapping.cpp (.../MAlarmMapping.cpp) (revision 153bcdb67dca6c40022318b80d5c7079d48bb37f) +++ sources/model/hd/alarm/MAlarmMapping.cpp (.../MAlarmMapping.cpp) (revision 35db01154f90ebfdb6174033a66f5c20af82e14d) @@ -7,7 +7,7 @@ * * \file MAlarmMapping.cpp * \author (last) Behrouz NematiPour - * \date (last) 14-Aug-2022 + * \date (last) 15-Aug-2022 * \author (original) Behrouz NematiPour * \date (original) 03-May-2021 * @@ -47,8 +47,8 @@ /*0011*/case GuiAlarmID::ALARM_ID_HD_DIALYSATE_TEMP_BELOW_TARGET_TEMP : { result = QObject::tr("HD dialysate temperature below target temperature." ); break; } /* 11*/ /*0012*/case GuiAlarmID::ALARM_ID_HD_INTEGRITY_POST_TEST_FAILED : { result = QObject::tr("HD firmware image integrity POST test failed." ); break; } /* 12*/ /*0013*/case GuiAlarmID::ALARM_ID_DG_INTEGRITY_POST_TEST_FAILED : { result = QObject::tr("DG firmware image integrity POST test failed." ); break; } /* 13*/ -/*0014*/case GuiAlarmID::ALARM_ID___AVAILABLE_1 : { result = QObject::tr("Not used." ); break; } /* 14*/ -/*0015*/case GuiAlarmID::ALARM_ID___AVAILABLE_2 : { result = QObject::tr("Not used." ); break; } /* 15*/ +/*0014*/case GuiAlarmID::ALARM_ID_DG_INVALID_USAGE_RECORD : { result = QObject::tr("DG invalid usage record CRC." ); break; } /* 14*/ +/*0015*/case GuiAlarmID::ALARM_ID_HD_INVALID_USAGE_RECORD : { result = QObject::tr("HD invalid usage record CRC." ); break; } /* 15*/ /*0016*/case GuiAlarmID::ALARM_ID_HD_ALARM_AUDIO_SELF_TEST_FAILURE : { result = QObject::tr("HD alarm audio failed POST." ); break; } /* 16*/ /*0017*/case GuiAlarmID::ALARM_ID_HD_UI_POST_FAILED : { result = QObject::tr("HD UI POST failed." ); break; } /* 17*/ /*0018*/case GuiAlarmID::ALARM_ID_DG_PRESSURE_SENSORS_INVALID_CAL_RECORD : { result = QObject::tr("DG load cells invalid calibration record." ); break; } /* 18*/ @@ -136,9 +136,9 @@ /*0100*/case GuiAlarmID::ALARM_ID_HD_NO_CART_SELF_TEST_TIMEOUT : { result = QObject::tr("HD no cartridge self-test timeout." ); break; } /* 100*/ /*0101*/case GuiAlarmID::ALARM_ID_HD_DRY_SELF_TEST_TIMEOUT : { result = QObject::tr("HD dry self-test timeout." ); break; } /* 101*/ /*0102*/case GuiAlarmID::ALARM_ID_DG_HEAT_DISINFECT_TEMP_GRAD_OUT_OF_RANAGE : { result = QObject::tr("DG heat disinfect temperature gradient out of range." ); break; } /* 102*/ -/*0103*/case GuiAlarmID::ALARM_ID_HD_NVDATAMGMT_CAL_GROUP_RECORD_CRC_INVALID : { result = QObject::tr("HD non-volatile calibration group invalid record CRC." ); break; } /* 103*/ +/*0103*/case GuiAlarmID::ALARM_ID_HD_NVDATAMGMT_CAL_GROUP_RECORD_CRC_INVALID : { result = QObject::tr("HD invalid calibration CRC." ); break; } /* 103*/ /*0104*/case GuiAlarmID::ALARM_ID_AIR_TRAP_ILLEGAL_LEVELS : { result = QObject::tr("Air trap level sensors reporting illegal combination of air/fluid." ); break; } /* 104*/ -/*0105*/case GuiAlarmID::ALARM_ID_DG_NVDATAMGMT_CAL_GROUP_RECORD_CRC_INVALID : { result = QObject::tr("DG non-volatile system group invalid record CRC." ); break; } /* 105*/ +/*0105*/case GuiAlarmID::ALARM_ID_DG_NVDATAMGMT_CAL_GROUP_RECORD_CRC_INVALID : { result = QObject::tr("DG invalid calibration CRC." ); break; } /* 105*/ /*0106*/case GuiAlarmID::ALARM_ID_DG_DIALYSATE_FLOW_SENSOR_INVALID_CAL_RECORD : { result = QObject::tr("DG dialysate flow sensor invalid calibration record." ); break; } /* 106*/ /*0107*/case GuiAlarmID::ALARM_ID_DG_RESTARTED_FAULT : { result = QObject::tr("HD reports DG restarted fault." ); break; } /* 107*/ /*0108*/case GuiAlarmID::ALARM_ID_HD_SYRINGE_PUMP_ADC_ERROR : { result = QObject::tr("HD syringe pump ADC error." ); break; } /* 108*/ Index: sources/model/settings/MSettings.cpp =================================================================== diff -u -r6f2622be80fcaee8d71baf78404627381157970c -r35db01154f90ebfdb6174033a66f5c20af82e14d --- sources/model/settings/MSettings.cpp (.../MSettings.cpp) (revision 6f2622be80fcaee8d71baf78404627381157970c) +++ sources/model/settings/MSettings.cpp (.../MSettings.cpp) (revision 35db01154f90ebfdb6174033a66f5c20af82e14d) @@ -136,21 +136,26 @@ * \param vLocation - the location of the setting data if is different will be set. * \param vLocation - the category of the setting data which by default is the base location if has extra folder + filename. */ -void MSettings::add(const QString &vGroup, const QString &vKey, const QVariant &vValue, const QString &vLocation, const QString &vCategory) +void MSettings::add(const QString &vGroup, const QString &vKey, const QVariant &vValue, const QString &vLocation, const QString &vCategory, bool vEnableDuplicateKeys) { QMutexLocker locker(&_mutex); if ( ! _category[vCategory].contains(vGroup) ) _category[vCategory] += vGroup; KeyValue mGroup = _settings[vGroup]; if ( mGroup.location != vLocation ) mGroup.location = vLocation; if ( mGroup.category != vCategory ) mGroup.category = vCategory; - if ( mGroup.keys.contains(vKey)) { - int index = mGroup.keys.indexOf(vKey); - mGroup.values[index] = vValue; - } - else { + if ( vEnableDuplicateKeys ) { mGroup.keys += vKey ; mGroup.values += vValue ; + } else { + if ( mGroup.keys.contains(vKey)) { + int index = mGroup.keys.indexOf(vKey); + mGroup.values[index] = vValue; + } + else { + mGroup.keys += vKey ; + mGroup.values += vValue ; + } } _settings[vGroup] = mGroup; } Index: sources/model/settings/MSettings.h =================================================================== diff -u -ra82ee4f326b26c4369f1306f867edc1bca6dabbe -r35db01154f90ebfdb6174033a66f5c20af82e14d --- sources/model/settings/MSettings.h (.../MSettings.h) (revision a82ee4f326b26c4369f1306f867edc1bca6dabbe) +++ sources/model/settings/MSettings.h (.../MSettings.h) (revision 35db01154f90ebfdb6174033a66f5c20af82e14d) @@ -63,7 +63,7 @@ QVariant value (const QString &vGroup , const QString &vKey); QString location (const QString &vGroup ); - void add (const QString &vGroup, const QString &vKey, const QVariant &vValue, const QString &vLocation, const QString &vCategory); + void add (const QString &vGroup, const QString &vKey, const QVariant &vValue, const QString &vLocation, const QString &vCategory, bool vEnableDuplicateKeys); // the utility static functions private : QString _datetimeFormat = "MM/dd/yyyy HH:mm:ss"; Index: sources/storage/Settings.cpp =================================================================== diff -u -r465a935949a85d3d1bebd11979737ff38ef96122 -r35db01154f90ebfdb6174033a66f5c20af82e14d --- sources/storage/Settings.cpp (.../Settings.cpp) (revision 465a935949a85d3d1bebd11979737ff38ef96122) +++ sources/storage/Settings.cpp (.../Settings.cpp) (revision 35db01154f90ebfdb6174033a66f5c20af82e14d) @@ -88,28 +88,54 @@ } for (const auto &detail : details) { + bool enableDuplicateKey = false; + QString attribute = QString("%1%2").arg(_config_attribute_tag); QString group = ""; QStringList lines = detail.content.split('\n'); for (QString line : lines) { - // ignore empty lines - if ( line.trimmed().isEmpty() ) continue; + // ----- trim the line + line = line.trimmed(); - // remove comments + // ----- ignore empty lines + if ( line.isEmpty() ) continue; + + // ----- find comments int commentPosition = line.indexOf('#'); - if ( commentPosition == 0 ) continue; // comment line - if ( commentPosition > 0 ) // inline comment - line.truncate(commentPosition); + + // ----- ignore comment line or find attributes + if ( commentPosition == 0 ) { + + // ----- find the configuration file attribute + int attributeTagPosition = line.indexOf(_config_attribute_tag); + if ( attributeTagPosition == 0 ) { + + // ----- find the attribute : duplicate_key_... + if ( line == attribute.arg( _duplicate_key_on ) ) { enableDuplicateKey = true ;} + else if ( line == attribute.arg(_duplicate_key_off ) ) { enableDuplicateKey = false ;} + + else { + LOG_EVENT_UI(( "Unknown '" + line + "' attribute in %1").arg(detail.category)); + } + } + + // next line + continue; + } + + // ----- remove inline comment + if ( commentPosition > 0 ) line.truncate(commentPosition); + + // ----- find group if (line.contains("[") && line.contains("]")) { line.replace("[","").replace("]", ""); - group = line.trimmed(); + group = line; } else { if ( group.isEmpty() ) { continue; } else { - line = line.trimmed(); if ( ! line.isEmpty() ) { QString key = ""; QString value = ""; @@ -121,7 +147,7 @@ else { key = line; } - _Settings.add(group, key, QVariant(value), detail.location, detail.category); + _Settings.add(group, key, QVariant(value), detail.location, detail.category, enableDuplicateKey); // DEBUG: qDebug() << group << key << value << location << category; } } @@ -145,7 +171,11 @@ // << vValue; QString mFileName = fileName(vCategory); QString mContent; - _Settings.add(vGroup, vKey, vValue,"", vCategory); + // -------------------------------------------------------------------------------------------------------------- + //Note: the configuration files which can be saved, are like settings and should not have duplicate values. + // as an example the Alarm volume can't have two separate duplicate entry in the settings. + // -------------------------------------------------------------------------------------------------------------- + _Settings.add(vGroup, vKey, vValue,"", vCategory, false); QString mPath = QFileInfo(mFileName).absolutePath(); if ( mPath.trimmed().isEmpty() ) { LOG_DEBUG("The settings path is empty."); Index: sources/storage/Settings.h =================================================================== diff -u -r6f2622be80fcaee8d71baf78404627381157970c -r35db01154f90ebfdb6174033a66f5c20af82e14d --- sources/storage/Settings.h (.../Settings.h) (revision 6f2622be80fcaee8d71baf78404627381157970c) +++ sources/storage/Settings.h (.../Settings.h) (revision 35db01154f90ebfdb6174033a66f5c20af82e14d) @@ -40,8 +40,11 @@ class Settings { // Settings - const char *_settingsExt = "conf"; - const char *_settingsFormat = "%1/%2.%3"; + const char *_config_attribute_tag = "#--"; + const char *_duplicate_key_on = "duplicate_key_on"; + const char *_duplicate_key_off = "duplicate_key_off"; + const char *_settingsExt = "conf"; + const char *_settingsFormat = "%1/%2.%3"; struct Detail { QString category; QString location; Index: sources/view/hd/adjustment/disinfect/VDisinfectAdjustDisinfect.h =================================================================== diff -u -r79a6cfcb10472261f3ec26eaf0baf6f1245cd311 -r35db01154f90ebfdb6174033a66f5c20af82e14d --- sources/view/hd/adjustment/disinfect/VDisinfectAdjustDisinfect.h (.../VDisinfectAdjustDisinfect.h) (revision 79a6cfcb10472261f3ec26eaf0baf6f1245cd311) +++ sources/view/hd/adjustment/disinfect/VDisinfectAdjustDisinfect.h (.../VDisinfectAdjustDisinfect.h) (revision 35db01154f90ebfdb6174033a66f5c20af82e14d) @@ -51,6 +51,8 @@ PROPERTY( bool , heat , 0) PROPERTY( bool , chemical , 0) + PROPERTY( bool , canCancel , 0) + VIEW_DEC_CLASS_ADJUSTMENT(VDisinfectAdjustDisinfect, AdjustDisinfectResponseData) public slots: