diff --git a/companion/src/datamodels/compounditemmodels.cpp b/companion/src/datamodels/compounditemmodels.cpp index ab0ba83ba..2f04a34fb 100644 --- a/companion/src/datamodels/compounditemmodels.cpp +++ b/companion/src/datamodels/compounditemmodels.cpp @@ -444,7 +444,7 @@ CustomFuncResetParamItemModel::CustomFuncResetParamItemModel(const GeneralSettin AbstractDynamicItemModel(generalSettings, modelData, firmware, board, boardType) { setId(IMID_CustomFuncResetParam); - setUpdateMask(IMUE_TeleSensors); + setUpdateMask(IMUE_TeleSensors | IMUE_Timers); for (int i = 0; i < CustomFunctionData::resetParamCount(); i++) { QStandardItem * modelItem = new QStandardItem(); @@ -717,6 +717,16 @@ AbstractItemModel * CompoundItemModelFactory::getItemModel(const int id) const return nullptr; } +AbstractItemModel * CompoundItemModelFactory::getItemModel(const QString name) const +{ + foreach (AbstractItemModel * itemModel, registeredItemModels) { + if (itemModel->getName() == name) + return itemModel; + } + + return nullptr; +} + bool CompoundItemModelFactory::isItemModelRegistered(const int id) const { foreach (AbstractItemModel * itemModel, registeredItemModels) { diff --git a/companion/src/datamodels/compounditemmodels.h b/companion/src/datamodels/compounditemmodels.h index 7acfcbdc9..d5a7c5f27 100644 --- a/companion/src/datamodels/compounditemmodels.h +++ b/companion/src/datamodels/compounditemmodels.h @@ -363,6 +363,7 @@ class CompoundItemModelFactory void unregisterItemModel(const int id); bool isItemModelRegistered(const int id) const; AbstractItemModel * getItemModel(const int id) const; + AbstractItemModel * getItemModel(const QString name) const; void update(const int event = AbstractItemModel::IMUE_SystemRefresh); void dumpAllItemModelContents() const; diff --git a/companion/src/dialogs/filesyncdialog.cpp b/companion/src/dialogs/filesyncdialog.cpp index 3927a3ffd..30026c931 100644 --- a/companion/src/dialogs/filesyncdialog.cpp +++ b/companion/src/dialogs/filesyncdialog.cpp @@ -39,6 +39,8 @@ #include #include #include +#include +#include FileSyncDialog::FileSyncDialog(QWidget * parent, const SyncProcess::SyncOptions & syncOptions) : QDialog(parent), diff --git a/companion/src/firmwares/CMakeLists.txt b/companion/src/firmwares/CMakeLists.txt index 3bc2ca275..b79d8fd42 100644 --- a/companion/src/firmwares/CMakeLists.txt +++ b/companion/src/firmwares/CMakeLists.txt @@ -23,11 +23,13 @@ set(firmwares_SRCS rawswitch.cpp sensordata.cpp telem_data.cpp + timerdata.cpp afhds3.cpp ersky9x/ersky9xeeprom.cpp ersky9x/ersky9xinterface.cpp opentx/opentxeeprom.cpp opentx/opentxinterface.cpp + datahelpers.cpp ) string(REPLACE ".cpp" ".h" firmwares_HDRS "${firmwares_SRCS}") @@ -35,7 +37,6 @@ string(REPLACE ".cpp" ".h" firmwares_HDRS "${firmwares_SRCS}") list(APPEND firmwares_HDRS eepromimportexport.h moduledata.h - helpersdata.h ) set(firmwares_QT diff --git a/companion/src/firmwares/datahelpers.cpp b/companion/src/firmwares/datahelpers.cpp new file mode 100644 index 000000000..8ae759a1b --- /dev/null +++ b/companion/src/firmwares/datahelpers.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "datahelpers.h" + +QString DataHelpers::boolToString(const bool value, const BoolFormat format) +{ + static const char *strings[] = { + QT_TRANSLATE_NOOP("DataHelpers", "Disabled"), + QT_TRANSLATE_NOOP("DataHelpers", "Enabled"), + QT_TRANSLATE_NOOP("DataHelpers", "OFF"), + QT_TRANSLATE_NOOP("DataHelpers", "ON"), + QT_TRANSLATE_NOOP("DataHelpers", "False"), + QT_TRANSLATE_NOOP("DataHelpers", "True"), + QT_TRANSLATE_NOOP("DataHelpers", "N"), + QT_TRANSLATE_NOOP("DataHelpers", "Y"), + QT_TRANSLATE_NOOP("DataHelpers", "No"), + QT_TRANSLATE_NOOP("DataHelpers", "Yes") + }; + + return QCoreApplication::translate("DataHelpers", strings[format * 2 + value]); +} + +QString DataHelpers::getElementName(const QString & prefix, const unsigned int index, const char * name, const bool padding) +{ + QString result = prefix; + result.append(padding ? QString("%1").arg(index, 2, 10, QChar('0')) : QString("%1").arg(index)); + if (name && QString(name).trimmed().length() > 0) + result.append(":" + QString(name).trimmed()); + + return result; +} + +QString DataHelpers::timeToString(const int value, const unsigned int mask) +{ + bool negative = value < 0 ? true : false; + int val = abs(value); + + QString result = QString("%1").arg(negative ? "-" : ((mask & TIMESTR_MASK_PADSIGN) ? " " : "")); + + if (mask & TIMESTR_MASK_HRSMINS) { + int hours = val / 3600; + if (hours > 0 || (mask & TIMESTR_MASK_ZEROHRS)) { + val -= hours * 3600; + result.append(QString("%1:").arg(hours, 2, 10, QLatin1Char('0'))); + } + } + + int minutes = val / 60; + int seconds = val % 60; + result.append(QString("%1:%2").arg(minutes, 2, 10, QLatin1Char('0')).arg(seconds, 2, 10, QLatin1Char('0'))); + return result; +} diff --git a/companion/src/firmwares/helpersdata.h b/companion/src/firmwares/datahelpers.h similarity index 64% rename from companion/src/firmwares/helpersdata.h rename to companion/src/firmwares/datahelpers.h index 29273e5f0..ccd3b0f64 100644 --- a/companion/src/firmwares/helpersdata.h +++ b/companion/src/firmwares/datahelpers.h @@ -24,8 +24,6 @@ class FieldRange { - Q_DECLARE_TR_FUNCTIONS(FieldRange) - public: FieldRange(): decimals(0), @@ -48,3 +46,24 @@ class FieldRange QString prefix; QString unit; }; + + +constexpr unsigned int TIMESTR_MASK_HRSMINS { 1 << 1 }; +constexpr unsigned int TIMESTR_MASK_ZEROHRS { 1 << 2 }; +constexpr unsigned int TIMESTR_MASK_PADSIGN { 1 << 3 }; + +namespace DataHelpers +{ + enum BoolFormat { + BOOL_FMT_ENABLEDISABLE, + BOOL_FMT_ONOFF, + BOOL_FMT_TRUEFALSE, + BOOL_FMT_YN, + BOOL_FMT_YESNO + }; + + QString boolToString(const bool value, const BoolFormat format); + QString getElementName(const QString & prefix, const unsigned int index, const char * name = 0, const bool padding = false); + QString timeToString(const int value, const unsigned int mask); + +} diff --git a/companion/src/firmwares/modeldata.cpp b/companion/src/firmwares/modeldata.cpp index 1e5d4d59c..85a7f0473 100644 --- a/companion/src/firmwares/modeldata.cpp +++ b/companion/src/firmwares/modeldata.cpp @@ -27,31 +27,6 @@ #include "helpers.h" #include "adjustmentreference.h" -/* - * TimerData - */ - -void TimerData::convert(RadioDataConversionState & cstate) -{ - cstate.setComponent(tr("TMR"), 1); - cstate.setSubComp(tr("Timer %1").arg(cstate.subCompIdx + 1)); - mode.convert(cstate); -} - -bool TimerData::isEmpty() -{ - return (mode == RawSwitch(SWITCH_TYPE_TIMER_MODE, 0) && name[0] == '\0' && minuteBeep == 0 && countdownBeep == COUNTDOWN_SILENT && val == 0 && persistent == 0 /*&& pvalue == 0*/); -} - -QString TimerData::nameToString(int index) const -{ - return RadioData::getElementName(tr("TMR", "as in Timer"), index + 1, name); -} - -/* - * ModelData - */ - ModelData::ModelData() { clear(); @@ -1381,7 +1356,6 @@ void ModelData::sortMixes() void ModelData::updateResetParam(CustomFunctionData * cfd) { - if (cfd->func != FuncReset) return; @@ -1392,6 +1366,11 @@ void ModelData::updateResetParam(CustomFunctionData * cfd) switch (updRefInfo.type) { + case REF_UPD_TYPE_TIMER: + if (cfd->param < 0 || cfd->param > 2) + return; + idxAdj = -2; // reverse earlier offset required for rawsource + break; case REF_UPD_TYPE_SENSOR: idxAdj = 5/*3 Timers + Flight + Telemetery*/ + firmware->getCapability(RotaryEncoders); if (cfd->param < idxAdj || cfd->param > (idxAdj + firmware->getCapability(Sensors))) diff --git a/companion/src/firmwares/modeldata.h b/companion/src/firmwares/modeldata.h index 4794ff232..f834a0779 100644 --- a/companion/src/firmwares/modeldata.h +++ b/companion/src/firmwares/modeldata.h @@ -33,6 +33,7 @@ #include "output_data.h" #include "sensordata.h" #include "telem_data.h" +#include "timerdata.h" #include @@ -55,35 +56,6 @@ class RSSIAlarmData { } }; -#define TIMER_NAME_LEN 8 - -class TimerData { - Q_DECLARE_TR_FUNCTIONS(TimerData) - - public: - enum CountDownMode { - COUNTDOWN_SILENT, - COUNTDOWN_BEEPS, - COUNTDOWN_VOICE, - COUNTDOWN_HAPTIC - }; - TimerData() { clear(); } - RawSwitch mode; - char name[TIMER_NAME_LEN+1]; - bool minuteBeep; - unsigned int countdownBeep; - unsigned int val; - unsigned int persistent; - int countdownStart; - unsigned int direction; - int pvalue; - void clear() { memset(reinterpret_cast(this), 0, sizeof(TimerData)); mode = RawSwitch(SWITCH_TYPE_TIMER_MODE, 0); } - void convert(RadioDataConversionState & cstate); - bool isEmpty(); - bool isModeOff() { return mode == RawSwitch(SWITCH_TYPE_TIMER_MODE, 0); } - QString nameToString(int index) const; -}; - #define CPN_MAX_SCRIPTS 9 #define CPN_MAX_SCRIPT_INPUTS 10 class ScriptData { diff --git a/companion/src/firmwares/radiodata.cpp b/companion/src/firmwares/radiodata.cpp index 8054e5b1a..c833281fd 100644 --- a/companion/src/firmwares/radiodata.cpp +++ b/companion/src/firmwares/radiodata.cpp @@ -22,23 +22,6 @@ #include "radiodataconversionstate.h" #include "eeprominterface.h" -// static -QString RadioData::getElementName(const QString & prefix, unsigned int index, const char * name, bool padding) -{ - QString result = prefix; - if (padding) - result += QString("%1").arg(index, 2, 10, QChar('0')); - else - result += QString("%1").arg(index); - if (name) { - QString trimmed = QString(name).trimmed(); - if (trimmed.length() > 0) { - result += ":" + QString(name).trimmed(); - } - } - return result; -} - RadioData::RadioData() { models.resize(getCurrentFirmware()->getCapability(Models)); diff --git a/companion/src/firmwares/radiodata.h b/companion/src/firmwares/radiodata.h index 29d29e4eb..d289f1846 100644 --- a/companion/src/firmwares/radiodata.h +++ b/companion/src/firmwares/radiodata.h @@ -1,9 +1,10 @@ -#ifndef _RADIODATA_H_ -#define _RADIODATA_H_ +#pragma once #include "generalsettings.h" #include "modeldata.h" +#include "datahelpers.h" // required for getElementName + #include class RadioDataConversionState; @@ -32,10 +33,10 @@ class RadioData { void fixModelFilenames(); QString getNextModelFilename(); - static QString getElementName(const QString & prefix, unsigned int index, const char * name = 0, bool padding = false); + // leave here until all calls repointed + static QString getElementName(const QString & prefix, unsigned int index, const char * name = 0, bool padding = false) + { return DataHelpers::getElementName(prefix, index, name, padding); } protected: void fixModelFilename(unsigned int index); }; - -#endif // _RADIODATA_H_ diff --git a/companion/src/firmwares/sensordata.cpp b/companion/src/firmwares/sensordata.cpp index 2c0866e66..ae602bd0d 100644 --- a/companion/src/firmwares/sensordata.cpp +++ b/companion/src/firmwares/sensordata.cpp @@ -19,8 +19,6 @@ */ #include "sensordata.h" - -#include "radiodata.h" #include "modeldata.h" #include "eeprominterface.h" #include "compounditemmodels.h" @@ -35,7 +33,7 @@ void SensorData::updateUnit() QString SensorData::nameToString(int index) const { - return RadioData::getElementName(tr("TELE"), index + 1, label); + return DataHelpers::getElementName(tr("TELE"), index + 1, label); } QString SensorData::getOrigin(const ModelData * model) const @@ -171,7 +169,7 @@ QString SensorData::paramsToString(const ModelData * model) const int precsn = prec == 0 ? 1 : pow(10, prec); str.append(QString(FMT_LABEL_VALUE).arg(tr("Ratio")).arg((float)ratio / 10)); str.append(QString(FMT_LABEL_VALUE).arg(tr("Offset")).arg(QString::number((float)offset / precsn, 'f', prec))); - str.append(QString(FMT_LABEL_VALUE).arg(tr("Auto Offset")).arg(boolToString(autoOffset))); + str.append(QString(FMT_LABEL_VALUE).arg(tr("Auto Offset")).arg(DataHelpers::boolToString(autoOffset, DataHelpers::BOOL_FMT_YN))); } else { str.append(QString(FMT_LABEL_VALUE).arg(tr("Blades")).arg(ratio)); // TODO refactor to dedicated RPMS field @@ -180,15 +178,15 @@ QString SensorData::paramsToString(const ModelData * model) const } if (mask & SENSOR_ISCONFIGURABLE) - str.append(QString(FMT_LABEL_VALUE).arg(tr("Filter")).arg(boolToString(filter))); + str.append(QString(FMT_LABEL_VALUE).arg(tr("Filter")).arg(DataHelpers::boolToString(filter, DataHelpers::BOOL_FMT_YN))); if (type == TELEM_TYPE_CALCULATED) - str.append(QString(FMT_LABEL_VALUE).arg(tr("Persist")).arg(boolToString(persistent))); + str.append(QString(FMT_LABEL_VALUE).arg(tr("Persist")).arg(DataHelpers::boolToString(persistent, DataHelpers::BOOL_FMT_YN))); if (mask & SENSOR_HAS_POSITIVE) - str.append(QString(FMT_LABEL_VALUE).arg(tr("Positive")).arg(boolToString(onlyPositive))); + str.append(QString(FMT_LABEL_VALUE).arg(tr("Positive")).arg(DataHelpers::boolToString(onlyPositive, DataHelpers::BOOL_FMT_YN))); - str.append(QString(FMT_LABEL_VALUE).arg(tr("Log")).arg(boolToString(logs))); + str.append(QString(FMT_LABEL_VALUE).arg(tr("Log")).arg(DataHelpers::boolToString(logs, DataHelpers::BOOL_FMT_YN))); return str; } diff --git a/companion/src/firmwares/sensordata.h b/companion/src/firmwares/sensordata.h index 2353a0ebf..8a032cec5 100644 --- a/companion/src/firmwares/sensordata.h +++ b/companion/src/firmwares/sensordata.h @@ -20,7 +20,7 @@ #pragma once -#include "helpersdata.h" +#include "datahelpers.h" #include @@ -205,7 +205,6 @@ class SensorData { static QString cellIndexToString(const int value); static QString unitToString(const int value); static QString precToString(const int value); - static QString boolToString(const bool value) { return value ? tr("Y") : tr("N"); } static bool isRssiSensorAvailable(const ModelData * model, const int value); static QString rssiSensorToString(const ModelData * model, const int value); diff --git a/companion/src/firmwares/timerdata.cpp b/companion/src/firmwares/timerdata.cpp new file mode 100644 index 000000000..9034ed7e0 --- /dev/null +++ b/companion/src/firmwares/timerdata.cpp @@ -0,0 +1,188 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "timerdata.h" +#include "radiodataconversionstate.h" +#include "compounditemmodels.h" + +void TimerData::convert(RadioDataConversionState & cstate) +{ + cstate.setComponent(tr("TMR"), 1); + cstate.setSubComp(tr("Timer %1").arg(cstate.subCompIdx + 1)); + mode.convert(cstate); +} + +void TimerData::clear() +{ + memset(reinterpret_cast(this), 0, sizeof(TimerData)); + mode = RawSwitch(SWITCH_TYPE_TIMER_MODE, 0); +} + +bool TimerData::isEmpty() +{ + return (mode == RawSwitch(SWITCH_TYPE_TIMER_MODE, 0) && name[0] == '\0' && minuteBeep == 0 && countdownBeep == COUNTDOWNBEEP_SILENT && val == 0 && persistent == 0 /*&& pvalue == 0*/); +} + +bool TimerData::isModeOff() +{ + return mode == RawSwitch(SWITCH_TYPE_TIMER_MODE, 0); +} + +QString TimerData::nameToString(int index) const +{ + return DataHelpers::getElementName(tr("TMR", "as in Timer"), index + 1, name); +} + +QString TimerData::countdownBeepToString() const +{ + return countdownBeepToString(countdownBeep); +} + +QString TimerData::countdownStartToString() const +{ + if (countdownBeep == COUNTDOWNBEEP_SILENT) + return ""; + else + return countdownStartToString(countdownStart); +} + +QString TimerData::persistentToString(const bool verbose) const +{ + return persistentToString(persistent, verbose); +} + +QString TimerData::pvalueToString() const +{ + return pvalueToString(pvalue); +} + +QString TimerData::valToString() const +{ + return valToString(val); +} + +void TimerData::countdownBeepChanged() +{ + if (countdownBeep == COUNTDOWNBEEP_SILENT) + countdownStart = 0; +} + +// static +QString TimerData::countdownBeepToString(const int value) +{ + switch(value) { + case COUNTDOWNBEEP_SILENT: + return tr("Silent"); + case COUNTDOWNBEEP_BEEPS: + return tr("Beeps"); + case COUNTDOWNBEEP_VOICE: + return tr("Voice"); + case COUNTDOWNBEEP_HAPTIC: + return tr("Haptic"); + default: + return CPN_STR_UNKNOWN_ITEM; + } +} + +// static +QString TimerData::countdownStartToString(const int value) +{ + switch(value) { + case COUNTDOWNSTART_5: + return tr("5s"); + case COUNTDOWNSTART_10: + return tr("10s"); + case COUNTDOWNSTART_20: + return tr("20s"); + case COUNTDOWNSTART_30: + return tr("30s"); + default: + return CPN_STR_UNKNOWN_ITEM; + } +} + +// static +QString TimerData::persistentToString(const int value, const bool verbose) +{ + switch(value) { + case PERSISTENT_NOT: + return verbose ? tr("Not persistent") : tr("NOT"); + case PERSISTENT_FLIGHT: + return verbose ? tr("Persistent (flight)") : tr("Flight"); + case PERSISTENT_MANUALRESET: + return verbose ? tr("Persistent (manual reset)") : tr("Manual reset"); + default: + return CPN_STR_UNKNOWN_ITEM; + } +} + +// static +QString TimerData::pvalueToString(const int value) +{ + return DataHelpers::timeToString(value, TIMESTR_MASK_HRSMINS | TIMESTR_MASK_ZEROHRS); +} + +// static +QString TimerData::valToString(const int value) +{ + return DataHelpers::timeToString(value, TIMESTR_MASK_HRSMINS | TIMESTR_MASK_ZEROHRS); +} + +// static +AbstractStaticItemModel * TimerData::countdownBeepItemModel() +{ + AbstractStaticItemModel * mdl = new AbstractStaticItemModel(); + mdl->setName(AIM_TIMER_COUNTDOWNBEEP); + + for (int i = 0; i < COUNTDOWNBEEP_COUNT; i++) { + mdl->appendToItemList(countdownBeepToString(i), i); + } + + mdl->loadItemList(); + return mdl; +} + +// static +AbstractStaticItemModel * TimerData::countdownStartItemModel() +{ + AbstractStaticItemModel * mdl = new AbstractStaticItemModel(); + mdl->setName(AIM_TIMER_COUNTDOWNSTART); + + for (int i = COUNTDOWNSTART_LAST; i >= COUNTDOWNSTART_FIRST; i--) { + mdl->appendToItemList(countdownStartToString(i), i); + } + + mdl->loadItemList(); + return mdl; +} + +// static +AbstractStaticItemModel * TimerData::persistentItemModel() +{ + AbstractStaticItemModel * mdl = new AbstractStaticItemModel(); + mdl->setName(AIM_TIMER_PERSISTENT); + + for (int i = 0; i < PERSISTENT_COUNT; i++) { + mdl->appendToItemList(persistentToString(i), i); + } + + mdl->loadItemList(); + return mdl; +} diff --git a/companion/src/firmwares/timerdata.h b/companion/src/firmwares/timerdata.h new file mode 100644 index 000000000..07cc1eedd --- /dev/null +++ b/companion/src/firmwares/timerdata.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#pragma once + +#include "rawswitch.h" +#include "datahelpers.h" + +#include + +class RadioDataConversionState; +class AbstractStaticItemModel; + +constexpr char AIM_TIMER_COUNTDOWNBEEP[] {"timerdata.countdownBeep"}; +constexpr char AIM_TIMER_COUNTDOWNSTART[] {"timerdata.countdownStart"}; +constexpr char AIM_TIMER_PERSISTENT[] {"timerdata.persistent"}; + +constexpr int TIMER_NAME_LEN {8}; + +class TimerData { + Q_DECLARE_TR_FUNCTIONS(TimerData) + + public: + enum CountDownBeepType { + COUNTDOWNBEEP_SILENT, + COUNTDOWNBEEP_BEEPS, + COUNTDOWNBEEP_VOICE, + COUNTDOWNBEEP_HAPTIC, + COUNTDOWNBEEP_COUNT + }; + + enum CountDownStart { + COUNTDOWNSTART_30 = -2, + COUNTDOWNSTART_FIRST = COUNTDOWNSTART_30, + COUNTDOWNSTART_20, + COUNTDOWNSTART_10, + COUNTDOWNSTART_5, + COUNTDOWNSTART_LAST = COUNTDOWNSTART_5 + }; + + enum PersistentType { + PERSISTENT_NOT, + PERSISTENT_FLIGHT, + PERSISTENT_MANUALRESET, + PERSISTENT_COUNT + }; + + TimerData() { clear(); } + + RawSwitch mode; + char name[TIMER_NAME_LEN + 1]; + bool minuteBeep; + unsigned int countdownBeep; + unsigned int val; + unsigned int persistent; + int countdownStart; + unsigned int direction; + int pvalue; + + void convert(RadioDataConversionState & cstate); + void clear(); + bool isEmpty(); + bool isModeOff(); + QString nameToString(int index) const; + QString countdownBeepToString() const; + QString countdownStartToString() const; + QString persistentToString(const bool verbose = true) const; + QString pvalueToString() const; + QString valToString() const; + void countdownBeepChanged(); + + static QString countdownBeepToString(const int value); + static QString countdownStartToString(const int value); + static QString persistentToString(const int value, const bool verbose = true); + static QString pvalueToString(const int value); + static QString valToString(const int value); + static AbstractStaticItemModel * countdownBeepItemModel(); + static AbstractStaticItemModel * countdownStartItemModel(); + static AbstractStaticItemModel * persistentItemModel(); + +}; diff --git a/companion/src/modeledit/setup.cpp b/companion/src/modeledit/setup.cpp index b695b03ff..3a3a7e910 100644 --- a/companion/src/modeledit/setup.cpp +++ b/companion/src/modeledit/setup.cpp @@ -22,7 +22,6 @@ #include "ui_setup.h" #include "ui_setup_timer.h" #include "ui_setup_module.h" -#include "filtereditemmodels.h" #include "appdata.h" #include "modelprinter.h" #include "multiprotocols.h" @@ -31,54 +30,53 @@ #include -TimerPanel::TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware, - QWidget * prevFocus, FilteredItemModel * rawSwitchFilteredModel): +constexpr char FIM_TIMERSWITCH[] {"Timer Switch"}; +constexpr char FIM_THRSOURCE[] {"Throttle Source"}; + +TimerPanel::TimerPanel(QWidget * parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware, + QWidget * prevFocus, FilteredItemModelFactory * panelFilteredModels, CompoundItemModelFactory * panelItemModels): ModelPanel(parent, model, generalSettings, firmware), timer(timer), - ui(new Ui::Timer) + ui(new Ui::Timer), + modelsUpdateCnt(0) { ui->setupUi(this); - connectItemModelEvents(rawSwitchFilteredModel); + connectItemModelEvents(panelFilteredModels->getItemModel(FIM_TIMERSWITCH)); lock = true; // Name int length = firmware->getCapability(TimersName); - if (length == 0) { + if (length == 0) ui->name->hide(); + else { + ui->name->setField(timer.name, length, this); + connect(ui->name, SIGNAL(currentDataChanged()), this, SLOT(onNameChanged())); + } + + ui->value->setField(timer.val, this); + ui->value->setMaximumTime(firmware->getMaxTimerStart()); + + ui->mode->setModel(panelFilteredModels->getItemModel(FIM_TIMERSWITCH)); + ui->mode->setField(timer.mode, this); + + ui->countdownBeep->setModel(panelItemModels->getItemModel(AIM_TIMER_COUNTDOWNBEEP)); + ui->countdownBeep->setField(timer.countdownBeep, this); + connect(ui->countdownBeep, SIGNAL(currentDataChanged(int)), this, SLOT(onCountdownBeepChanged(int))); + + ui->minuteBeep->setField(timer.minuteBeep, this); + + if (firmware->getCapability(PermTimers)) { + ui->persistent->setModel(panelItemModels->getItemModel(AIM_TIMER_PERSISTENT)); + ui->persistent->setField(timer.persistent, this); } else { - ui->name->setMaxLength(length); - } - - // Mode - ui->mode->setModel(rawSwitchFilteredModel); - ui->mode->setCurrentIndex(ui->mode->findData(timer.mode.toValue())); - connect(ui->mode, SIGNAL(activated(int)), this, SLOT(onModeChanged(int))); - - if (!firmware->getCapability(PermTimers)) { ui->persistent->hide(); ui->persistentValue->hide(); } - ui->countdownBeep->setField(timer.countdownBeep, this); - ui->countdownBeep->addItem(tr("Silent"), TimerData::COUNTDOWN_SILENT); - ui->countdownBeep->addItem(tr("Beeps"), TimerData::COUNTDOWN_BEEPS); - ui->countdownBeep->addItem(tr("Voice"), TimerData::COUNTDOWN_VOICE); - ui->countdownBeep->addItem(tr("Haptic"), TimerData::COUNTDOWN_HAPTIC); - - ui->value->setMaximumTime(firmware->getMaxTimerStart()); - - ui->persistent->setField(timer.persistent, this); - ui->persistent->addItem(tr("Not persistent"), 0); - ui->persistent->addItem(tr("Persistent (flight)"), 1); - ui->persistent->addItem(tr("Persistent (manual reset)"), 2); - + ui->countdownStart->setModel(panelItemModels->getItemModel(AIM_TIMER_COUNTDOWNSTART)); ui->countdownStart->setField(timer.countdownStart, this); - ui->countdownStart->addItem("5s", 1); - ui->countdownStart->addItem("10s", 0); - ui->countdownStart->addItem("20s", -1); - ui->countdownStart->addItem("30s", -2); disableMouseScrolling(); QWidget::setTabOrder(prevFocus, ui->name); @@ -102,33 +100,27 @@ void TimerPanel::update() { lock = true; - ui->name->setText(timer.name); + ui->name->updateValue(); + ui->mode->updateValue(); + ui->value->updateValue(); + ui->countdownBeep->updateValue(); + ui->minuteBeep->updateValue(); + ui->countdownStart->updateValue(); - int hour = timer.val / 3600; - int min = (timer.val - (hour * 3600)) / 60; - int sec = (timer.val - (hour * 3600)) % 60; + if (timer.countdownBeep == TimerData::COUNTDOWNBEEP_SILENT) { + ui->countdownStartLabel->setEnabled(false); + ui->countdownStart->setEnabled(false); + } + else { + ui->countdownStartLabel->setEnabled(true); + ui->countdownStart->setEnabled(true); + } - ui->mode->setCurrentIndex(ui->mode->findData(timer.mode.toValue())); - ui->value->setTime(QTime(hour, min, sec)); - if (firmware->getCapability(PermTimers)) { - int sign = 1; - int pvalue = timer.pvalue; - if (pvalue < 0) { - pvalue = -pvalue; - sign = -1; - } - int hours = pvalue / 3600; - pvalue -= hours * 3600; - int minutes = pvalue / 60; - int seconds = pvalue % 60; - ui->persistentValue->setText(QString(" %1(%2:%3:%4)").arg(sign < 0 ? "-" :" ").arg(hours, 2, 10, QLatin1Char('0')).arg(minutes, 2, 10, QLatin1Char('0')).arg(seconds, 2, 10, QLatin1Char('0'))); + ui->persistent->updateValue(); + ui->persistentValue->setText(timer.pvalueToString()); } - ui->countdownBeep->updateValue(); - ui->minuteBeep->setChecked(timer.minuteBeep); - ui->persistent->updateValue(); - ui->countdownStart->updateValue(); lock = false; } @@ -137,57 +129,6 @@ QWidget * TimerPanel::getLastFocus() return ui->persistent; } -void TimerPanel::on_countdownBeep_currentIndexChanged(int index) -{ - if(index == TimerData::COUNTDOWN_SILENT) - ui->countdownStart->hide(); - else - ui->countdownStart->show(); -} - -void TimerPanel::on_value_editingFinished() -{ - if (!lock) { - unsigned val = ui->value->time().hour() * 3600 + ui->value->time().minute() * 60 + ui->value->time().second(); - if (timer.val != val) { - timer.val = val; - emit modified(); - } - } -} - -void TimerPanel::onModeChanged(int index) -{ - if (!lock) { - bool ok; - const RawSwitch rs(ui->mode->itemData(index).toInt(&ok)); - if (ok && timer.mode.toValue() != rs.toValue()) { - timer.mode = rs; - emit modified(); - } - } -} - -void TimerPanel::on_minuteBeep_toggled(bool checked) -{ - if (!lock) { - timer.minuteBeep = checked; - emit modified(); - } -} - -void TimerPanel::on_name_editingFinished() -{ - if (!lock) { - if (QString(timer.name) != ui->name->text()) { - int length = ui->name->maxLength(); - strncpy(timer.name, ui->name->text().toLatin1(), length); - emit nameChanged(); - emit modified(); - } - } -} - void TimerPanel::connectItemModelEvents(const FilteredItemModel * itemModel) { connect(itemModel, &FilteredItemModel::aboutToBeUpdated, this, &TimerPanel::onItemModelAboutToBeUpdated); @@ -197,12 +138,27 @@ void TimerPanel::connectItemModelEvents(const FilteredItemModel * itemModel) void TimerPanel::onItemModelAboutToBeUpdated() { lock = true; + modelsUpdateCnt++; } void TimerPanel::onItemModelUpdateComplete() { + modelsUpdateCnt--; + if (modelsUpdateCnt < 1) { + update(); + lock = false; + } +} + +void TimerPanel::onNameChanged() +{ + emit nameChanged(); +} + +void TimerPanel::onCountdownBeepChanged(int index) +{ + timer.countdownBeepChanged(); update(); - lock = false; } /******************************************************************************/ @@ -1023,16 +979,26 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge { ui->setupUi(this); - rawSwitchFilteredModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSwitch), RawSwitch::TimersContext); - connectItemModelEvents(rawSwitchFilteredModel); + lock = true; - thrSourceFilteredModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_ThrSource)); - connectItemModelEvents(thrSourceFilteredModel); + panelFilteredModels = new FilteredItemModelFactory(); + + panelFilteredModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSwitch), + RawSwitch::TimersContext), + FIM_TIMERSWITCH); + connectItemModelEvents(panelFilteredModels->getItemModel(FIM_TIMERSWITCH)); + + panelFilteredModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_ThrSource)), + FIM_THRSOURCE); + connectItemModelEvents(panelFilteredModels->getItemModel(FIM_THRSOURCE)); + + panelItemModels = new CompoundItemModelFactory(&generalSettings, &model); + panelItemModels->registerItemModel(TimerData::countdownBeepItemModel()); + panelItemModels->registerItemModel(TimerData::countdownStartItemModel()); + panelItemModels->registerItemModel(TimerData::persistentItemModel()); Board::Type board = firmware->getBoard(); - lock = true; - memset(modules, 0, sizeof(modules)); QRegExp rx(CHAR_FOR_NAMES_REGEX); @@ -1112,7 +1078,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge for (int i = 0; i < CPN_MAX_TIMERS; i++) { if (i < timersCount) { - timers[i] = new TimerPanel(this, model, model.timers[i], generalSettings, firmware, prevFocus, rawSwitchFilteredModel); + timers[i] = new TimerPanel(this, model, model.timers[i], generalSettings, firmware, prevFocus, panelFilteredModels, panelItemModels); ui->gridLayout->addWidget(timers[i], 1+i, 1); connect(timers[i], &TimerPanel::modified, this, &SetupPanel::modified); connect(timers[i], &TimerPanel::nameChanged, this, &SetupPanel::onTimerNameChanged); @@ -1148,6 +1114,9 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge ui->toplcdTimer->hide(); } + ui->throttleSource->setModel(panelFilteredModels->getItemModel(FIM_THRSOURCE)); + ui->throttleSource->setField(model.thrTraceSrc, this); + if (!firmware->getCapability(HasDisplayText)) { ui->displayText->hide(); ui->editText->hide(); @@ -1279,8 +1248,8 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge SetupPanel::~SetupPanel() { delete ui; - delete rawSwitchFilteredModel; - delete thrSourceFilteredModel; + delete panelFilteredModels; + delete panelItemModels; } void SetupPanel::on_extendedLimits_toggled(bool checked) @@ -1314,14 +1283,6 @@ void SetupPanel::on_trimIncrement_currentIndexChanged(int index) emit modified(); } -void SetupPanel::on_throttleSource_currentIndexChanged(int index) -{ - if (!lock) { - model->thrTraceSrc = ui->throttleSource->currentData().toUInt(); - emit modified(); - } -} - void SetupPanel::on_throttleTrimSwitch_currentIndexChanged(int index) { if (!lock) { @@ -1380,28 +1341,6 @@ void SetupPanel::on_image_currentIndexChanged(int index) } } -void SetupPanel::populateThrottleSourceCB() -{ - Board::Type board = firmware->getBoard(); - lock = true; - ui->throttleSource->clear(); - ui->throttleSource->addItem(tr("THR"), 0); - - int idx = 1; - for (int i = 0; i < getBoardCapability(board, Board::Pots) + getBoardCapability(board, Board::Sliders); i++, idx++) { - if (RawSource(SOURCE_TYPE_STICK, 4 + i).isAvailable(model, &generalSettings, board)) { - ui->throttleSource->addItem(firmware->getAnalogInputName(4 + i), idx); - } - } - for (int i = 0; i < firmware->getCapability(Outputs); i++, idx++) { - ui->throttleSource->addItem(RawSource(SOURCE_TYPE_CH, i).toString(model, &generalSettings), idx); - } - - int thrTraceSrcIdx = ui->throttleSource->findData(model->thrTraceSrc); - ui->throttleSource->setCurrentIndex(thrTraceSrcIdx); - lock = false; -} - void SetupPanel::populateThrottleTrimSwitchCB() { Board::Type board = firmware->getBoard(); @@ -1429,7 +1368,7 @@ void SetupPanel::update() { ui->name->setText(model->name); ui->throttleReverse->setChecked(model->throttleReversed); - populateThrottleSourceCB(); + ui->throttleSource->updateValue(); populateThrottleTrimSwitchCB(); ui->throttleWarning->setChecked(!model->disableThrottleWarning); ui->trimIncrement->setCurrentIndex(model->trimInc+2); @@ -1800,6 +1739,7 @@ void SetupPanel::onItemModelUpdateComplete() void SetupPanel::updateItemModels() { sharedItemModels->update(AbstractItemModel::IMUE_Timers); + emit updated(); } void SetupPanel::onModuleUpdateItemModels() diff --git a/companion/src/modeledit/setup.h b/companion/src/modeledit/setup.h index 7409d7b25..82e69ec75 100644 --- a/companion/src/modeledit/setup.h +++ b/companion/src/modeledit/setup.h @@ -18,17 +18,15 @@ * GNU General Public License for more details. */ -#ifndef _SETUP_H_ -#define _SETUP_H_ +#pragma once #include "modeledit.h" #include "eeprominterface.h" +#include "compounditemmodels.h" +#include "filtereditemmodels.h" constexpr char MIMETYPE_TIMER[] = "application/x-companion-timer"; -class CompoundItemModelFactory; -class FilteredItemModel; - namespace Ui { class Setup; class Timer; @@ -40,21 +38,18 @@ class TimerPanel : public ModelPanel Q_OBJECT public: - TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware, - QWidget *prevFocus, FilteredItemModel * switchModel); + TimerPanel(QWidget * parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware, + QWidget * prevFocus, FilteredItemModelFactory * panelFilteredModels, CompoundItemModelFactory * panelItemModels); virtual ~TimerPanel(); virtual void update(); QWidget * getLastFocus(); private slots: - void onModeChanged(int index); - void on_value_editingFinished(); - void on_minuteBeep_toggled(bool checked); - void on_countdownBeep_currentIndexChanged(int index); - void on_name_editingFinished(); + void onNameChanged(); void onItemModelAboutToBeUpdated(); void onItemModelUpdateComplete(); + void onCountdownBeepChanged(int index); signals: void nameChanged(); @@ -63,6 +58,7 @@ class TimerPanel : public ModelPanel TimerData & timer; Ui::Timer * ui; void connectItemModelEvents(const FilteredItemModel * itemModel); + int modelsUpdateCnt; }; class ModulePanel : public ModelPanel @@ -146,7 +142,6 @@ class SetupPanel : public ModelPanel private slots: void on_name_editingFinished(); - void on_throttleSource_currentIndexChanged(int index); void on_throttleTrimSwitch_currentIndexChanged(int index); void on_throttleTrim_toggled(bool checked); void on_extendedLimits_toggled(bool checked); @@ -184,12 +179,11 @@ class SetupPanel : public ModelPanel QVector startupSwitchesCheckboxes; QVector potWarningCheckboxes; QVector centerBeepCheckboxes; - ModulePanel * modules[CPN_MAX_MODULES+1]; + ModulePanel * modules[CPN_MAX_MODULES + 1]; TimerPanel * timers[CPN_MAX_TIMERS]; void updateStartupSwitches(); void updatePotWarnings(); void updateBeepCenter(); - void populateThrottleSourceCB(); void populateThrottleTrimSwitchCB(); int timersCount; int selectedTimerIndex; @@ -199,10 +193,8 @@ class SetupPanel : public ModelPanel bool moveTimerUpAllowed() const; void swapTimerData(int idx1, int idx2); CompoundItemModelFactory * sharedItemModels; - FilteredItemModel * rawSwitchFilteredModel; - FilteredItemModel * thrSourceFilteredModel; void updateItemModels(); void connectItemModelEvents(const FilteredItemModel * itemModel); + CompoundItemModelFactory * panelItemModels; + FilteredItemModelFactory * panelFilteredModels; }; - -#endif // _SETUP_H_ diff --git a/companion/src/modeledit/setup.ui b/companion/src/modeledit/setup.ui index 8b2409191..ee0ec28a3 100644 --- a/companion/src/modeledit/setup.ui +++ b/companion/src/modeledit/setup.ui @@ -604,7 +604,7 @@ If this is checked the throttle will be reversed. Idle will be forward, trim wi - + 0 diff --git a/companion/src/modeledit/setup_timer.ui b/companion/src/modeledit/setup_timer.ui index 11f566b45..67b929bdb 100644 --- a/companion/src/modeledit/setup_timer.ui +++ b/companion/src/modeledit/setup_timer.ui @@ -9,7 +9,7 @@ 0 0 - 675 + 874 33 @@ -33,7 +33,7 @@ 0 - + 80 @@ -43,7 +43,7 @@ - + true @@ -56,7 +56,7 @@ - + @@ -68,11 +68,18 @@ + + + + Start + + + - + Minute Call @@ -109,6 +116,21 @@ QComboBox
autocombobox.h
+ + AutoLineEdit + QLineEdit +
autolineedit.h
+
+ + AutoCheckBox + QCheckBox +
autocheckbox.h
+
+ + AutoTimeEdit + QTimeEdit +
autotimeedit.h
+
diff --git a/companion/src/modelprinter.cpp b/companion/src/modelprinter.cpp index 282f53550..1d7df4f93 100644 --- a/companion/src/modelprinter.cpp +++ b/companion/src/modelprinter.cpp @@ -298,27 +298,6 @@ QString ModelPrinter::printCenterBeep() return (strl.isEmpty() ? tr("None") : strl.join(" ")); } -QString ModelPrinter::printTimer(int idx) -{ - return printTimer(model.timers[idx]); -} - -QString ModelPrinter::printTimer(const TimerData & timer) -{ - QStringList result; - if (firmware->getCapability(TimersName) && timer.name[0]) - result += tr("Name") + QString("(%1)").arg(timer.name); - result += printTimeValue(timer.val, MASK_TIMEVALUE_HRSMINS | MASK_TIMEVALUE_ZEROHRS); - result += timer.mode.toString(); - if (timer.countdownBeep) - result += tr("Countdown") + QString("(%1)").arg(printTimerCountdownBeep(timer.countdownBeep)); - if (timer.minuteBeep) - result += tr("Minute call"); - if (timer.persistent) - result += tr("Persistent") + QString("(%1)").arg(printTimerPersistent(timer.persistent)); - return result.join(", "); -} - QString ModelPrinter::printTrim(int flightModeIndex, int stickIndex) { const FlightModeData & fm = model.flightModeData[flightModeIndex]; @@ -938,36 +917,6 @@ QString ModelPrinter::printFailsafeMode(unsigned int fsmode) } } -QString ModelPrinter::printTimerCountdownBeep(unsigned int countdownBeep) -{ - switch (countdownBeep) { - case TimerData::COUNTDOWN_SILENT: - return tr("Silent"); - case TimerData::COUNTDOWN_BEEPS: - return tr("Beeps"); - case TimerData::COUNTDOWN_VOICE: - return tr("Voice"); - case TimerData::COUNTDOWN_HAPTIC: - return tr("Haptic"); - default: - return CPN_STR_UNKNOWN_ITEM; - } -} - -QString ModelPrinter::printTimerPersistent(unsigned int persistent) -{ - switch (persistent) { - case 0: - return tr("OFF"); - case 1: - return tr("Flight"); - case 2: - return tr("Manual reset"); - default: - return CPN_STR_UNKNOWN_ITEM; - } -} - QString ModelPrinter::printSettingsTrim() { QStringList str; @@ -1032,26 +981,6 @@ QString ModelPrinter::printPPMFrameLength(int ppmFL) return QString::number(result); } -QString ModelPrinter::printTimerName(int idx) -{ - QString result; - result = tr("Tmr") + QString("%1").arg(idx+1); - if (firmware->getCapability(TimersName) && model.timers[idx].name[0]) - result.append(":" + QString(model.timers[idx].name)); - - return result; -} - -QString ModelPrinter::printTimerTimeValue(unsigned int val) -{ - return printTimeValue(val, MASK_TIMEVALUE_HRSMINS | MASK_TIMEVALUE_ZEROHRS); -} - -QString ModelPrinter::printTimerMinuteBeep(bool mb) -{ - return printBoolean(mb, BOOLEAN_YESNO); -} - QString ModelPrinter::printTelemetryProtocol(unsigned int val) { switch (val) { diff --git a/companion/src/modelprinter.h b/companion/src/modelprinter.h index ea2eab2d8..8be56bd64 100644 --- a/companion/src/modelprinter.h +++ b/companion/src/modelprinter.h @@ -67,8 +67,6 @@ class ModelPrinter: public QObject QString printTrim(int flightModeIndex, int stickIndex); QString printGlobalVar(int flightModeIndex, int gvarIndex); QString printRotaryEncoder(int flightModeIndex, int reIndex); - QString printTimer(int idx); - QString printTimer(const TimerData & timer); QString printInputName(int idx); QString printInputLine(int idx); QString printInputLine(const ExpoData & ed); @@ -104,13 +102,8 @@ class ModelPrinter: public QObject QString printFailsafe(int idx); QString printFailsafeMode(unsigned int fsmode); QString printFailsafeValue(int val); - QString printTimerCountdownBeep(unsigned int countdownBeep); - QString printTimerPersistent(unsigned int persistent); QString printPPMFrameLength(int ppmFL); - QString printTimerName(int idx); QString printTimeValue(const int value, const unsigned int mask); - QString printTimerMinuteBeep(bool mb); - QString printTimerTimeValue(unsigned int val); QString printTelemetryProtocol(unsigned int val); QString printLabelValue(const QString & lbl, const QString & val, const bool sep = false); QString printLabelValues(const QString & lbl, const QStringList & vals, const bool sep = false); diff --git a/companion/src/multimodelprinter.cpp b/companion/src/multimodelprinter.cpp index 17cb30be4..0ebef1884 100644 --- a/companion/src/multimodelprinter.cpp +++ b/companion/src/multimodelprinter.cpp @@ -334,18 +334,19 @@ QString MultiModelPrinter::printTimers() QString str; MultiColumns columns(modelPrinterMap.size()); columns.appendSectionTableStart(); - columns.appendRowHeader(QStringList() << tr("Timers") << tr("Time") << tr("Switch") << tr("Countdown") << tr("Min.call") << tr("Persist")); + columns.appendRowHeader(QStringList() << tr("Timers") << tr("Time") << tr("Switch") << tr("Countdown") << tr("Start") << tr("Min.call") << tr("Persist")); for (int i=0; igetCapability(Timers); i++) { columns.appendRowStart(); columns.appendCellStart(20, true); - COMPARE(modelPrinter->printTimerName(i)); + COMPARE(model->timers[i].nameToString(i)); columns.appendCellEnd(true); - COMPARECELLWIDTH(modelPrinter->printTimerTimeValue(model->timers[i].val), 15); - COMPARECELLWIDTH(model->timers[i].mode.toString(), 15); - COMPARECELLWIDTH(modelPrinter->printTimerCountdownBeep(model->timers[i].countdownBeep), 15); - COMPARECELLWIDTH(modelPrinter->printTimerMinuteBeep(model->timers[i].minuteBeep), 15); - COMPARECELLWIDTH(modelPrinter->printTimerPersistent(model->timers[i].persistent), 20); + COMPARECELLWIDTH(model->timers[i].valToString(), 10); + COMPARECELLWIDTH(model->timers[i].mode.toString(), 10); + COMPARECELLWIDTH(model->timers[i].countdownBeepToString(), 10); + COMPARECELLWIDTH(model->timers[i].countdownStartToString(), 10); + COMPARECELLWIDTH(DataHelpers::boolToString(model->timers[i].minuteBeep, DataHelpers::BOOL_FMT_YESNO), 10); + COMPARECELLWIDTH(model->timers[i].persistentToString(false), 15); columns.appendRowEnd(); } columns.appendTableEnd(); diff --git a/companion/src/shared/CMakeLists.txt b/companion/src/shared/CMakeLists.txt index 2fbbafbf9..ffd5942bf 100644 --- a/companion/src/shared/CMakeLists.txt +++ b/companion/src/shared/CMakeLists.txt @@ -16,6 +16,7 @@ set(shared_HDRS genericpanel.h hexspinbox.h autoprecisioncombobox.h + autotimeedit.h ) qt5_wrap_cpp(shared_SRCS ${shared_HDRS}) diff --git a/companion/src/shared/autobitsetcheckbox.h b/companion/src/shared/autobitsetcheckbox.h index ea86db956..af831948e 100644 --- a/companion/src/shared/autobitsetcheckbox.h +++ b/companion/src/shared/autobitsetcheckbox.h @@ -34,7 +34,8 @@ class AutoBitsetCheckBox: public QCheckBox Q_PROPERTY(int toggleMask READ toggleMask WRITE setToggleMask) public: - explicit AutoBitsetCheckBox(QWidget *parent = nullptr) : AutoBitsetCheckBox(QString(), parent) {} + explicit AutoBitsetCheckBox(QWidget *parent = nullptr) : + AutoBitsetCheckBox(QString(), parent) {} explicit AutoBitsetCheckBox(const QString &text, QWidget *parent = nullptr) : QCheckBox(text, parent) { @@ -42,26 +43,32 @@ class AutoBitsetCheckBox: public QCheckBox } // int field constructors - explicit AutoBitsetCheckBox(int & field, int bitmask, const QString &text = QString(), QWidget *parent = nullptr) : AutoBitsetCheckBox(field, bitmask, false, text, parent) {} - explicit AutoBitsetCheckBox(int & field, int bitmask, bool invert, const QString &text = QString(), QWidget *parent = nullptr) : QCheckBox(text, parent) + explicit AutoBitsetCheckBox(int & field, int bitmask, const QString &text = QString(), QWidget *parent = nullptr) : + AutoBitsetCheckBox(field, bitmask, false, text, parent) {} + explicit AutoBitsetCheckBox(int & field, int bitmask, bool invert, const QString &text = QString(), QWidget *parent = nullptr) : + QCheckBox(text, parent) { setField(field, bitmask, invert); init(); } - explicit AutoBitsetCheckBox(int & field, int bitmask, int toggleMask, const QString &text = QString(), QWidget *parent = nullptr) : QCheckBox(text, parent) + explicit AutoBitsetCheckBox(int & field, int bitmask, int toggleMask, const QString &text = QString(), QWidget *parent = nullptr) : + QCheckBox(text, parent) { setField(field, bitmask, false, toggleMask); init(); } // unsigned field constructors - explicit AutoBitsetCheckBox(unsigned & field, int bitmask, const QString &text = QString(), QWidget *parent = nullptr) : AutoBitsetCheckBox(field, bitmask, false, text, parent) {} - explicit AutoBitsetCheckBox(unsigned & field, int bitmask, bool invert, const QString &text = QString(), QWidget *parent = nullptr) : QCheckBox(text, parent) + explicit AutoBitsetCheckBox(unsigned & field, int bitmask, const QString &text = QString(), QWidget *parent = nullptr) : + AutoBitsetCheckBox(field, bitmask, false, text, parent) {} + explicit AutoBitsetCheckBox(unsigned & field, int bitmask, bool invert, const QString &text = QString(), QWidget *parent = nullptr) : + QCheckBox(text, parent) { setField(field, bitmask, invert); init(); } - explicit AutoBitsetCheckBox(unsigned & field, int bitmask, int toggleMask, const QString &text = QString(), QWidget *parent = nullptr) : QCheckBox(text, parent) + explicit AutoBitsetCheckBox(unsigned & field, int bitmask, int toggleMask, const QString &text = QString(), QWidget *parent = nullptr) : + QCheckBox(text, parent) { setField(field, bitmask, false, toggleMask); init(); @@ -104,6 +111,8 @@ class AutoBitsetCheckBox: public QCheckBox void updateValue() { + if (m_panel && m_panel->lock) + return; if (!m_field) return; const bool oldLock = setLocked(true); diff --git a/companion/src/shared/autocheckbox.h b/companion/src/shared/autocheckbox.h index f5b233fed..1c1a7207c 100644 --- a/companion/src/shared/autocheckbox.h +++ b/companion/src/shared/autocheckbox.h @@ -21,23 +21,23 @@ #pragma once #include -#include "modeledit/modeledit.h" +#include "genericpanel.h" class AutoCheckBox: public QCheckBox { Q_OBJECT public: - explicit AutoCheckBox(QWidget *parent = 0): + explicit AutoCheckBox(QWidget * parent = nullptr): QCheckBox(parent), - field(NULL), - panel(NULL), + field(nullptr), + panel(nullptr), lock(false) { connect(this, SIGNAL(toggled(bool)), this, SLOT(onToggled(bool))); } - void setField(bool & field, ModelPanel * panel=NULL) + void setField(bool & field, GenericPanel * panel = nullptr) { this->field = &field; this->panel = panel; @@ -51,26 +51,31 @@ class AutoCheckBox: public QCheckBox void updateValue() { - lock = true; if (field) { + lock = true; setChecked(*field); + lock = false; } - lock = false; } + signals: + void currentDataChanged(bool value); + protected slots: void onToggled(bool checked) { + if (panel && panel->lock) + return; if (field && !lock) { *field = checked; - if (panel) { + emit currentDataChanged(checked); + if (panel) emit panel->modified(); - } } } protected: - bool * field; - ModelPanel * panel; - bool lock; + bool *field = nullptr; + GenericPanel *panel = nullptr; + bool lock = false; }; diff --git a/companion/src/shared/autocombobox.h b/companion/src/shared/autocombobox.h index 784abaefa..ca6054555 100644 --- a/companion/src/shared/autocombobox.h +++ b/companion/src/shared/autocombobox.h @@ -22,14 +22,23 @@ #include #include "genericpanel.h" +#include "rawsource.h" +#include "rawswitch.h" class AutoComboBox: public QComboBox { Q_OBJECT public: - explicit AutoComboBox(QWidget *parent = nullptr): - QComboBox(parent) + explicit AutoComboBox(QWidget * parent = nullptr): + QComboBox(parent), + field(nullptr), + panel(nullptr), + next(0), + lock(false), + hasModel(false), + rawSource(nullptr), + rawSwitch(nullptr) { connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(onCurrentIndexChanged(int))); } @@ -69,16 +78,38 @@ class AutoComboBox: public QComboBox } } - void setField(unsigned int & field, GenericPanel * panel=nullptr) + void setField(unsigned int & field, GenericPanel * panel = nullptr) { this->field = (int *)&field; + this->rawSource = nullptr; + this->rawSwitch = nullptr; this->panel = panel; updateValue(); } - void setField(int & field, GenericPanel * panel=nullptr) + void setField(int & field, GenericPanel * panel = nullptr) { this->field = &field; + this->rawSource = nullptr; + this->rawSwitch = nullptr; + this->panel = panel; + updateValue(); + } + + void setField(RawSource & field, GenericPanel * panel = nullptr) + { + this->rawSource = &field; + this->rawSwitch = nullptr; + this->field = nullptr; + this->panel = panel; + updateValue(); + } + + void setField(RawSwitch & field, GenericPanel * panel = nullptr) + { + this->rawSwitch = &field; + this->rawSource = nullptr; + this->field = nullptr; this->panel = panel; updateValue(); } @@ -103,10 +134,18 @@ class AutoComboBox: public QComboBox void updateValue() { - if (!field) + if (!field && !rawSource && !rawSwitch) return; + lock = true; - setCurrentIndex(findData(*field)); + + if (field) + setCurrentIndex(findData(*field)); + else if (rawSource) + setCurrentIndex(findData(rawSource->toValue())); + else if (rawSwitch) + setCurrentIndex(findData(rawSwitch->toValue())); + lock = false; } @@ -118,21 +157,37 @@ class AutoComboBox: public QComboBox { if (panel && panel->lock) return; - if (index > -1) { - const int val = itemData(index).toInt(); - if (field && !lock) { - *field = val; - if (panel) - emit panel->modified(); - } - emit currentDataChanged(val); + if (lock || index < 0) + return; + + bool ok; + const int val = itemData(index).toInt(&ok); + if (!ok) + return; + + if (field && *field != val) { + *field = val; } + else if (rawSource && rawSource->toValue() != val) { + *rawSource = RawSource(val); + } + else if (rawSwitch && rawSwitch->toValue() != val) { + *rawSwitch = RawSwitch(val); + } + else + return; + + emit currentDataChanged(val); + if (panel) + emit panel->modified(); } protected: - int * field = nullptr; - GenericPanel * panel = nullptr; + int *field = nullptr; + GenericPanel *panel = nullptr; int next = 0; bool lock = false; bool hasModel = false; + RawSource *rawSource = nullptr; + RawSwitch *rawSwitch = nullptr; }; diff --git a/companion/src/shared/autodoublespinbox.h b/companion/src/shared/autodoublespinbox.h index 6560b6ea2..a6466269e 100644 --- a/companion/src/shared/autodoublespinbox.h +++ b/companion/src/shared/autodoublespinbox.h @@ -21,7 +21,7 @@ #pragma once #include -#include "modeledit/modeledit.h" +#include "genericpanel.h" #if __GNUC__ #include #endif @@ -31,23 +31,23 @@ class AutoDoubleSpinBox: public QDoubleSpinBox Q_OBJECT public: - explicit AutoDoubleSpinBox(QWidget *parent = 0): + explicit AutoDoubleSpinBox(QWidget * parent = nullptr): QDoubleSpinBox(parent), - field(NULL), - panel(NULL), + field(nullptr), + panel(nullptr), lock(false) { connect(this, SIGNAL(valueChanged(double)), this, SLOT(onValueChanged(double))); } - void setField(int & field, ModelPanel * panel=NULL) + void setField(int & field, GenericPanel * panel = nullptr) { this->field = &field; this->panel = panel; updateValue(); } - void setField(unsigned int & field, ModelPanel * panel=NULL) + void setField(unsigned int & field, GenericPanel * panel = nullptr) { this->field = (int *)&field; this->panel = panel; @@ -57,7 +57,9 @@ class AutoDoubleSpinBox: public QDoubleSpinBox void updateValue() { if (field) { - setValue(float(*field)/multiplier()); + lock = true; + setValue(float(*field) / multiplier()); + lock = false; } } @@ -80,11 +82,17 @@ class AutoDoubleSpinBox: public QDoubleSpinBox } } + signals: + void currentDataChanged(double value); + protected slots: void onValueChanged(double value) { + if (panel && panel->lock) + return; if (field && !lock) { *field = round(value * multiplier()); + emit currentDataChanged(value); if (panel) { emit panel->modified(); } @@ -92,7 +100,7 @@ class AutoDoubleSpinBox: public QDoubleSpinBox } protected: - int * field; - ModelPanel * panel; - bool lock; + int * field = nullptr; + GenericPanel * panel = nullptr; + bool lock = false; }; diff --git a/companion/src/shared/autohexspinbox.h b/companion/src/shared/autohexspinbox.h index d7df46bd6..40cc24da4 100644 --- a/companion/src/shared/autohexspinbox.h +++ b/companion/src/shared/autohexspinbox.h @@ -21,23 +21,23 @@ #pragma once #include "hexspinbox.h" -#include "modeledit/modeledit.h" +#include "genericpanel.h" class AutoHexSpinBox: public HexSpinBox { Q_OBJECT public: - explicit AutoHexSpinBox(QWidget *parent = 0): + explicit AutoHexSpinBox(QWidget * parent = nullptr): HexSpinBox(parent), - field(NULL), - panel(NULL), + field(nullptr), + panel(nullptr), lock(false) { connect(this, SIGNAL(valueChanged(int)), this, SLOT(onValueChanged(int))); } - void setField(unsigned int & field, ModelPanel * panel=NULL) + void setField(unsigned int & field, GenericPanel * panel = nullptr) { this->field = &field; this->panel = panel; @@ -47,15 +47,23 @@ class AutoHexSpinBox: public HexSpinBox void updateValue() { if (field) { + lock = true; setValue(*field); + lock = false; } } + signals: + void currentDataChanged(int value); + protected slots: void onValueChanged(int value) { + if (panel && panel->lock) + return; if (field && !lock) { *field = value; + emit currentDataChanged(value); if (panel) { emit panel->modified(); } @@ -63,7 +71,7 @@ class AutoHexSpinBox: public HexSpinBox } protected: - unsigned int * field; - ModelPanel * panel; - bool lock; + unsigned int * field = nullptr; + GenericPanel * panel = nullptr; + bool lock = false; }; diff --git a/companion/src/shared/autolineedit.h b/companion/src/shared/autolineedit.h index 0f888e6df..b2815796c 100644 --- a/companion/src/shared/autolineedit.h +++ b/companion/src/shared/autolineedit.h @@ -29,11 +29,11 @@ class AutoLineEdit: public QLineEdit Q_OBJECT public: - explicit AutoLineEdit(QWidget *parent = nullptr, bool updateOnChange = false): + explicit AutoLineEdit(QWidget * parent = nullptr, bool updateOnChange = false): QLineEdit(parent), field(NULL), - strField(NULL), - panel(NULL), + strField(nullptr), + panel(nullptr), lock(false) { if (updateOnChange) @@ -76,7 +76,9 @@ class AutoLineEdit: public QLineEdit protected slots: void onEdited() { - if ((panel && panel->lock) || lock) + if (panel && panel->lock) + return; + if (lock) return; if (field) @@ -86,15 +88,15 @@ class AutoLineEdit: public QLineEdit else return; + emit currentDataChanged(); + if (panel) emit panel->modified(); - - emit currentDataChanged(); } protected: char * field; - QString * strField; - GenericPanel * panel; - bool lock; + QString * strField = nullptr; + GenericPanel * panel = nullptr; + bool lock = false; }; diff --git a/companion/src/shared/autoprecisioncombobox.h b/companion/src/shared/autoprecisioncombobox.h index e93059199..72dd89406 100644 --- a/companion/src/shared/autoprecisioncombobox.h +++ b/companion/src/shared/autoprecisioncombobox.h @@ -123,7 +123,7 @@ class AutoPrecisionComboBox: public QComboBox if (*m_field != val) { *m_field = rangecheckDecimals(val); updateValue(); - emit valueChanged(); + emit currentDataChanged(value); } } @@ -134,7 +134,7 @@ class AutoPrecisionComboBox: public QComboBox if (*m_field != value) { *m_field = rangecheckDecimals(value); updateValue(); - emit valueChanged(); + emit currentDataChanged((int)value); } } @@ -160,7 +160,7 @@ class AutoPrecisionComboBox: public QComboBox } signals: - void valueChanged(); + void currentDataChanged(int index); protected slots: void init() @@ -203,13 +203,13 @@ class AutoPrecisionComboBox: public QComboBox void onCurrentIndexChanged(int index) { - if (index < 0) + if (index < 0 || (m_panel && m_panel->lock) || m_lock) return; - if (m_field && !m_lock) { + if (m_field) { *m_field = itemData(index).toUInt(); + emit currentDataChanged(index); if (m_panel) emit m_panel->modified(); - emit valueChanged(); } } diff --git a/companion/src/shared/autotimeedit.h b/companion/src/shared/autotimeedit.h new file mode 100644 index 000000000..2ba75d70e --- /dev/null +++ b/companion/src/shared/autotimeedit.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#pragma once + +#include +#include "genericpanel.h" + +class AutoTimeEdit: public QTimeEdit +{ + Q_OBJECT + + public: + explicit AutoTimeEdit(QWidget * parent = nullptr): + QTimeEdit(parent), + field(nullptr), + panel(nullptr), + lock(false) + { + connect(this, SIGNAL(timeChanged(QTime)), this, SLOT(onTimeChanged(QTime))); + } + + void setField(unsigned int & field, GenericPanel * panel = nullptr) + { + this->field = &field; + this->panel = panel; + updateValue(); + } + + void setMinimumTime(const QTime time) + { + QTimeEdit::setMinimumTime(time); + } + + void setMaximumTime(const QTime time) + { + QTimeEdit::setMaximumTime(time); + } + + void setEnabled(bool enabled) + { + QTimeEdit::setEnabled(enabled); + } + + void updateValue() + { + if (field) { + lock = true; + int hour = *field / 3600; + int min = (*field - (hour * 3600)) / 60; + int sec = (*field - (hour * 3600)) % 60; + setTime(QTime(hour, min, sec)); + lock = false; + } + } + + signals: + void currentDataChanged(unsigned int value); + + protected slots: + void onTimeChanged(QTime time) + { + if (panel && panel->lock) + return; + if (!field || lock) + return; + + unsigned int val = time.hour() * 3600 + time.minute() * 60 + time.second(); + if (*field != val) { + *field = val; + emit currentDataChanged(val); + if (panel) + emit panel->modified(); + } + } + + protected: + unsigned int *field = nullptr; + GenericPanel *panel = nullptr; + bool lock = false; +}; + diff --git a/companion/src/shared/genericpanel.h b/companion/src/shared/genericpanel.h index bbb9b7254..88c7f841b 100644 --- a/companion/src/shared/genericpanel.h +++ b/companion/src/shared/genericpanel.h @@ -39,6 +39,8 @@ class GenericPanel : public QWidget friend class AutoLineEdit; friend class GVarGroup; friend class AutoPrecisionComboBox; + friend class AutoBitsetCheckBox; + friend class AutoTimeEdit; public: GenericPanel(QWidget *parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware);