diff --git a/CREDITS.txt b/CREDITS.txt index e21df1ce6..9948fe5db 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -1,6 +1,7 @@ [Main developers] Bertrand Songis (bsongis) André Bernet (kilrah) +JC D. (3djc) Michael Blandford Damjan Adamic (projectkk2glider) Franck Aguerre (jivarofad) @@ -9,6 +10,7 @@ Martin Hotař (mhotar) Maxim (Max) Paperno (mpaperno) Arne Schwabe (schwabe) Daniel Gorbea (dgatf) +Neil Horne (elecpower) [Translators] [fr] Sebastien Charpentier (LapinFou) @@ -2028,3 +2030,8 @@ Justin Digby John Magnuson (monthly) Holger Lippert Hubert Huber +David Blum +Noam Kfir +Mats gårdstad friberg +Jesper Frickmann +Alan Bunker diff --git a/companion/src/datamodels/rawitemdatamodels.cpp b/companion/src/datamodels/rawitemdatamodels.cpp index 1cba1c180..d7c1b6682 100644 --- a/companion/src/datamodels/rawitemdatamodels.cpp +++ b/companion/src/datamodels/rawitemdatamodels.cpp @@ -30,7 +30,7 @@ RawSourceItemModel::RawSourceItemModel(const GeneralSettings * const generalSett Firmware * fw = getCurrentFirmware(); addItems(SOURCE_TYPE_NONE, RawSource::NoneGroup, 1); - for (int i=0; i < fw->getCapability(LuaScripts); i++) + for (int i = 0; i < fw->getCapability(LuaScripts); i++) addItems(SOURCE_TYPE_LUA_OUTPUT, RawSource::ScriptsGroup, fw->getCapability(LuaOutputsPerScript), i * 16); addItems(SOURCE_TYPE_VIRTUAL_INPUT, RawSource::InputsGroup, fw->getCapability(VirtualInputs)); addItems(SOURCE_TYPE_STICK, RawSource::SourcesGroup, board.getCapability(Board::MaxAnalogs)); @@ -43,7 +43,7 @@ RawSourceItemModel::RawSourceItemModel(const GeneralSettings * const generalSett addItems(SOURCE_TYPE_PPM, RawSource::SourcesGroup, fw->getCapability(TrainerInputs)); addItems(SOURCE_TYPE_CH, RawSource::SourcesGroup, fw->getCapability(Outputs)); addItems(SOURCE_TYPE_SPECIAL, RawSource::TelemGroup, 5); - addItems(SOURCE_TYPE_TELEMETRY, RawSource::TelemGroup, CPN_MAX_SENSORS * 3); + addItems(SOURCE_TYPE_TELEMETRY, RawSource::TelemGroup, fw->getCapability(Sensors) * 3); addItems(SOURCE_TYPE_GVAR, RawSource::GVarsGroup, fw->getCapability(Gvars)); } @@ -67,10 +67,14 @@ void RawSourceItemModel::addItems(const RawSourceType & type, const int group, c } } -void RawSourceItemModel::update() const +void RawSourceItemModel::update() { - for (int i=0; i < rowCount(); ++i) + emit dataAboutToBeUpdated(); + + for (int i = 0; i < rowCount(); ++i) setDynamicItemData(item(i), RawSource(item(i)->data(ItemIdRole).toInt())); + + emit dataUpdateComplete(); } @@ -86,7 +90,7 @@ RawSwitchItemModel::RawSwitchItemModel(const GeneralSettings * const generalSett // Descending switch direction: NOT (!) switches addItems(SWITCH_TYPE_ACT, -1); - addItems(SWITCH_TYPE_SENSOR, -CPN_MAX_SENSORS); + addItems(SWITCH_TYPE_SENSOR, -fw->getCapability(Sensors)); addItems(SWITCH_TYPE_TELEMETRY, -1); addItems(SWITCH_TYPE_FLIGHT_MODE, -fw->getCapability(FlightModes)); addItems(SWITCH_TYPE_VIRTUAL, -fw->getCapability(LogicalSwitches)); @@ -105,7 +109,7 @@ RawSwitchItemModel::RawSwitchItemModel(const GeneralSettings * const generalSett addItems(SWITCH_TYPE_VIRTUAL, fw->getCapability(LogicalSwitches)); addItems(SWITCH_TYPE_FLIGHT_MODE, fw->getCapability(FlightModes)); addItems(SWITCH_TYPE_TELEMETRY, 1); - addItems(SWITCH_TYPE_SENSOR, CPN_MAX_SENSORS); + addItems(SWITCH_TYPE_SENSOR, fw->getCapability(Sensors)); addItems(SWITCH_TYPE_ON, 1); addItems(SWITCH_TYPE_ONE, 1); addItems(SWITCH_TYPE_ACT, 1); @@ -166,8 +170,95 @@ void RawSwitchItemModel::addItems(const RawSwitchType & type, int count) } } -void RawSwitchItemModel::update() const +void RawSwitchItemModel::update() { - for (int i=0; i < rowCount(); ++i) + emit dataAboutToBeUpdated(); + + for (int i = 0; i < rowCount(); ++i) setDynamicItemData(item(i), RawSwitch(item(i)->data(ItemIdRole).toInt())); + + emit dataUpdateComplete(); +} + +// +// CurveItemModel +// + +CurveItemModel::CurveItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent) : + AbstractRawItemDataModel(generalSettings, modelData, parent) +{ + const int count = getCurrentFirmware()->getCapability(NumCurves); + + for (int i = -count ; i <= count; ++i) { + QStandardItem * modelItem = new QStandardItem(); + modelItem->setData(i, ItemIdRole); + int flags; + if (i < 0) + flags = DataGroups::NegativeGroup; + else if (i > 0) + flags = DataGroups::PositiveGroup; + else + flags = DataGroups::NoneGroup; + modelItem->setData(flags, ItemFlagsRole); + setDynamicItemData(modelItem, i); + appendRow(modelItem); + } +} + +void CurveItemModel::setDynamicItemData(QStandardItem * item, int index) const +{ + item->setText(CurveReference(CurveReference::CURVE_REF_CUSTOM, index).toString(modelData, false)); + item->setData(true, IsAvailableRole); +} + +void CurveItemModel::update() +{ + emit dataAboutToBeUpdated(); + + for (int i = 0; i < rowCount(); ++i) + setDynamicItemData(item(i), item(i)->data(ItemIdRole).toInt()); + + emit dataUpdateComplete(); +} + +// +// CommonItemModels +// + +CommonItemModels::CommonItemModels(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent) : + QObject(parent) +{ + m_rawSourceItemModel = new RawSourceItemModel(generalSettings, modelData, parent); + m_rawSwitchItemModel = new RawSwitchItemModel(generalSettings, modelData, parent); + m_curveItemModel = new CurveItemModel(generalSettings, modelData, parent); +} + +CommonItemModels::~CommonItemModels() +{ +} + +void CommonItemModels::update(const RadioModelObjects radioModelObjects) +{ + switch (radioModelObjects) { + case RMO_CHANNELS: + case RMO_INPUTS: + case RMO_TELEMETRY_SENSORS: + case RMO_TIMERS: + m_rawSourceItemModel->update(); + break; + case RMO_FLIGHT_MODES: + case RMO_GLOBAL_VARIABLES: + case RMO_LOGICAL_SWITCHES: + m_rawSourceItemModel->update(); + m_rawSwitchItemModel->update(); + break; + case RMO_CURVES: + m_curveItemModel->update(); + break; + case RMO_SCRIPTS: + // no need to refresh + break; + default: + qDebug() << "Unknown RadioModelObject:" << radioModelObjects; + } } diff --git a/companion/src/datamodels/rawitemdatamodels.h b/companion/src/datamodels/rawitemdatamodels.h index 59eb6025e..48cb55fd2 100644 --- a/companion/src/datamodels/rawitemdatamodels.h +++ b/companion/src/datamodels/rawitemdatamodels.h @@ -36,6 +36,13 @@ class AbstractRawItemDataModel: public QStandardItemModel enum DataRoles { ItemIdRole = Qt::UserRole, ItemTypeRole, ItemFlagsRole, IsAvailableRole }; Q_ENUM(DataRoles) + enum DataGroups { + NoneGroup = 0x01, + NegativeGroup = 0x02, + PositiveGroup = 0x04 + }; + Q_ENUM(DataGroups) + explicit AbstractRawItemDataModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr) : QStandardItemModel(parent), generalSettings(generalSettings), @@ -43,7 +50,11 @@ class AbstractRawItemDataModel: public QStandardItemModel {} public slots: - virtual void update() const = 0; + virtual void update() = 0; + + signals: + void dataAboutToBeUpdated(); + void dataUpdateComplete(); protected: const GeneralSettings * generalSettings; @@ -58,7 +69,7 @@ class RawSourceItemModel: public AbstractRawItemDataModel explicit RawSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr); public slots: - void update() const override; + void update() override; protected: void setDynamicItemData(QStandardItem * item, const RawSource & src) const; @@ -73,7 +84,7 @@ class RawSwitchItemModel: public AbstractRawItemDataModel explicit RawSwitchItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr); public slots: - void update() const override; + void update() override; protected: void setDynamicItemData(QStandardItem * item, const RawSwitch & rsw) const; @@ -81,4 +92,49 @@ class RawSwitchItemModel: public AbstractRawItemDataModel }; +class CurveItemModel: public AbstractRawItemDataModel +{ + Q_OBJECT + public: + explicit CurveItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr); + + public slots: + void update() override; + + protected: + void setDynamicItemData(QStandardItem * item, int index) const; +}; + + +class CommonItemModels: public QObject +{ + Q_OBJECT + public: + enum RadioModelObjects { + RMO_CHANNELS, + RMO_CURVES, + RMO_FLIGHT_MODES, + RMO_GLOBAL_VARIABLES, + RMO_INPUTS, + RMO_LOGICAL_SWITCHES, + RMO_SCRIPTS, + RMO_TELEMETRY_SENSORS, + RMO_TIMERS + }; + Q_ENUM(RadioModelObjects) + + explicit CommonItemModels(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr); + ~CommonItemModels(); + + void update(const RadioModelObjects radioModelObjects); + RawSourceItemModel * rawSourceItemModel() const { return m_rawSourceItemModel; } + RawSwitchItemModel * rawSwitchItemModel() const { return m_rawSwitchItemModel; } + CurveItemModel * curveItemModel() const { return m_curveItemModel; } + + private: + RawSourceItemModel *m_rawSourceItemModel; + RawSwitchItemModel *m_rawSwitchItemModel; + CurveItemModel *m_curveItemModel; +}; + #endif // RAWITEMDATAMODELS_H diff --git a/companion/src/datamodels/rawitemfilteredmodel.cpp b/companion/src/datamodels/rawitemfilteredmodel.cpp index 1de9e26b2..abe9ca08e 100644 --- a/companion/src/datamodels/rawitemfilteredmodel.cpp +++ b/companion/src/datamodels/rawitemfilteredmodel.cpp @@ -19,7 +19,6 @@ */ #include "rawitemfilteredmodel.h" -#include "rawitemdatamodels.h" RawItemFilteredModel::RawItemFilteredModel(QAbstractItemModel * sourceModel, int flags, QObject * parent) : QSortFilterProxyModel(parent), @@ -30,6 +29,12 @@ RawItemFilteredModel::RawItemFilteredModel(QAbstractItemModel * sourceModel, int setFilterFlags(flags); setDynamicSortFilter(true); setSourceModel(sourceModel); + + AbstractRawItemDataModel * itemModel = qobject_cast(sourceModel); + if (itemModel) { + connect(itemModel, &AbstractRawItemDataModel::dataAboutToBeUpdated, this, &RawItemFilteredModel::onDataAboutToBeUpdated); + connect(itemModel, &AbstractRawItemDataModel::dataUpdateComplete, this, &RawItemFilteredModel::onDataUpdateComplete); + } } void RawItemFilteredModel::setFilterFlags(int flags) @@ -56,19 +61,17 @@ bool RawItemFilteredModel::filterAcceptsRow(int sourceRow, const QModelIndex & s void RawItemFilteredModel::update() const { - AbstractRawItemDataModel * model = qobject_cast(sourceModel()); - if (model) - model->update(); + AbstractRawItemDataModel * itemModel = qobject_cast(sourceModel()); + if (itemModel) + itemModel->update(); } - -RawSourceFilterItemModel::RawSourceFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, int flags, QObject * parent) : - RawItemFilteredModel(new RawSourceItemModel(generalSettings, modelData, parent), flags, parent) +void RawItemFilteredModel::onDataAboutToBeUpdated() { + emit dataAboutToBeUpdated(); } - -RawSwitchFilterItemModel::RawSwitchFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, int context, QObject * parent) : - RawItemFilteredModel(new RawSwitchItemModel(generalSettings, modelData, parent), context, parent) +void RawItemFilteredModel::onDataUpdateComplete() { + emit dataUpdateComplete(); } diff --git a/companion/src/datamodels/rawitemfilteredmodel.h b/companion/src/datamodels/rawitemfilteredmodel.h index 2d95dff71..3274460f7 100644 --- a/companion/src/datamodels/rawitemfilteredmodel.h +++ b/companion/src/datamodels/rawitemfilteredmodel.h @@ -21,54 +21,43 @@ #ifndef RAWITEMFILTEREDMODEL_H #define RAWITEMFILTEREDMODEL_H +#include "rawitemdatamodels.h" + #include class GeneralSettings; class ModelData; -class RawSourceItemModel; -class RawSwitchItemModel; class RawItemFilteredModel: public QSortFilterProxyModel { Q_OBJECT public: + enum DataFilters { + AllFilter = AbstractRawItemDataModel::NegativeGroup | AbstractRawItemDataModel::NoneGroup | AbstractRawItemDataModel::PositiveGroup, + AllExcludeNoneFilter = AllFilter &~ AbstractRawItemDataModel::NoneGroup, + NegativeFilter = AbstractRawItemDataModel::NegativeGroup | AbstractRawItemDataModel::NoneGroup, + NegativeExcludeNoneFilter = AbstractRawItemDataModel::NegativeGroup, + PositiveFilter = AbstractRawItemDataModel::PositiveGroup | AbstractRawItemDataModel::NoneGroup, + PositiveExcludeNoneFilter = AbstractRawItemDataModel::PositiveGroup + }; + Q_ENUM(DataFilters) + explicit RawItemFilteredModel(QAbstractItemModel * sourceModel, int flags, QObject * parent = nullptr); explicit RawItemFilteredModel(QAbstractItemModel * sourceModel, QObject * parent = nullptr) : RawItemFilteredModel(sourceModel, 0, parent) {} public slots: void setFilterFlags(int flags); void update() const; + void onDataAboutToBeUpdated(); + void onDataUpdateComplete(); + + signals: + void dataAboutToBeUpdated(); + void dataUpdateComplete(); protected: bool filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const override; int filterFlags; }; - - -// The specialized "convenience" types below can go away once centralalized RawSource/RawSwitch item models are established. -// These proxy classes will automatically create a source model of the corresponding type. - -class RawSwitchFilterItemModel: public RawItemFilteredModel -{ - Q_OBJECT - public: - using RawItemFilteredModel::RawItemFilteredModel; - - explicit RawSwitchFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, int context, QObject * parent = nullptr); -}; - - -class RawSourceFilterItemModel: public RawItemFilteredModel -{ - Q_OBJECT - public: - using RawItemFilteredModel::RawItemFilteredModel; - - explicit RawSourceFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, int flags, QObject * parent = nullptr); - - explicit RawSourceFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr) : - RawSourceFilterItemModel(generalSettings, modelData, 0, parent) {} -}; - #endif // RAWITEMFILTEREDMODEL_H diff --git a/companion/src/firmwares/curvereference.h b/companion/src/firmwares/curvereference.h index cb5be4e73..c6984d7ae 100644 --- a/companion/src/firmwares/curvereference.h +++ b/companion/src/firmwares/curvereference.h @@ -36,6 +36,15 @@ class CurveReference { CURVE_REF_CUSTOM }; + enum CurveRefGroups { + NoneGroup = 0x001, + NegativeGroup = 0x002, + PositiveGroup = 0x004, + + AllCurveRefGroups = NoneGroup | NegativeGroup | PositiveGroup, + PositiveCurveRefGroups = AllCurveRefGroups &~ NegativeGroup + }; + CurveReference() { clear(); } CurveReference(CurveRefType type, int value): @@ -51,6 +60,14 @@ class CurveReference { QString toString(const ModelData * model = NULL, bool verbose = true) const; bool isSet() const { return type != CURVE_REF_DIFF || value != 0; } + + bool operator == ( const CurveReference & other) const { + return (this->type == other.type) && (this->value == other.value); + } + + bool operator != ( const CurveReference & other) const { + return (this->type != other.type) || (this->value != other.value); + } }; #endif // CURVEREFERENCE_H diff --git a/companion/src/firmwares/customfunctiondata.cpp b/companion/src/firmwares/customfunctiondata.cpp index 42d84d570..017e100ea 100644 --- a/companion/src/firmwares/customfunctiondata.cpp +++ b/companion/src/firmwares/customfunctiondata.cpp @@ -126,20 +126,15 @@ void CustomFunctionData::populateResetParams(const ModelData * model, QComboBox b->addItem(tr("REa"), val++); b->addItem(tr("REb"), val++); } - if ((int)value < b->count()) { - b->setCurrentIndex(value); - } if (model) { - for (unsigned i=0; igetCapability(Sensors); ++i) { if (model->sensorData[i].isAvailable()) { - RawSource item = RawSource(SOURCE_TYPE_TELEMETRY, 3*i); - b->addItem(item.toString(model), val+i); - if (value == val+i) { - b->setCurrentIndex(b->count()-1); - } + RawSource item = RawSource(SOURCE_TYPE_TELEMETRY, 3 * i); + b->addItem(item.toString(model), val + i); } } } + b->setCurrentIndex(b->findData(value)); } void CustomFunctionData::populatePlaySoundParams(QStringList & qs) diff --git a/companion/src/firmwares/modeldata.cpp b/companion/src/firmwares/modeldata.cpp index e38958249..930df092c 100644 --- a/companion/src/firmwares/modeldata.cpp +++ b/companion/src/firmwares/modeldata.cpp @@ -723,11 +723,15 @@ int ModelData::updateReference() updateAssignFunc(cfd); if (!cfd->isEmpty()) { updateSwitchRef(cfd->swtch); - if (cfd->func == FuncVolume || cfd->func == FuncBacklight || cfd->func == FuncPlayValue || (cfd->func >= FuncAdjustGV1 && cfd->func <= FuncAdjustGVLast && (cfd->adjustMode == FUNC_ADJUST_GVAR_GVAR || cfd->adjustMode == FUNC_ADJUST_GVAR_SOURCE))) { + if (cfd->func == FuncVolume || cfd->func == FuncBacklight || cfd->func == FuncPlayValue || + (cfd->func >= FuncAdjustGV1 && cfd->func <= FuncAdjustGVLast && (cfd->adjustMode == FUNC_ADJUST_GVAR_GVAR || cfd->adjustMode == FUNC_ADJUST_GVAR_SOURCE))) { updateSourceIntRef(cfd->param); if (cfd->param == 0) cfd->clear(); } + else if (cfd->func == FuncReset) { + updateResetParam(cfd); + } } } } @@ -847,7 +851,7 @@ void ModelData::updateTypeIndexRef(R & curRef, const T type, const int idxAdj, c newRef.clear(); else { newRef.type = (T)defType; - newRef.index = defIndex + idxAdj; + newRef.index = defIndex; } break; case REF_UPD_ACT_SHIFT: @@ -904,7 +908,7 @@ void ModelData::updateTypeValueRef(R & curRef, const T type, const int idxAdj, c newRef.clear(); else { newRef.type = (T)defType; - newRef.value = defValue + idxAdj; + newRef.value = defValue; } break; case REF_UPD_ACT_SHIFT: @@ -972,7 +976,7 @@ void ModelData::updateAssignFunc(CustomFunctionData * cfd) { const int invalidateRef = -1; int newRef = (int)cfd->func; - int idxAdj; + int idxAdj = 0; switch (updRefInfo.type) { @@ -989,7 +993,7 @@ void ModelData::updateAssignFunc(CustomFunctionData * cfd) case REF_UPD_TYPE_TIMER: if (cfd->func < FuncSetTimer1 || cfd->func > FuncSetTimer3) // TODO refactor to FuncSetTimerLast return; - idxAdj = FuncSetTimer1 - 2; // reverse earlier offset requiured for rawsource + idxAdj = FuncSetTimer1 - 2; // reverse earlier offset required for rawsource break; default: return; @@ -1374,3 +1378,64 @@ void ModelData::sortMixes() memcpy(&mixData[0], &sortedMixData[0], CPN_MAX_MIXERS * sizeof(MixData)); } + +void ModelData::updateResetParam(CustomFunctionData * cfd) +{ + + if (cfd->func != FuncReset) + return; + + const int invalidateRef = -1; + int newRef = cfd->param; + int idxAdj = 0; + Firmware *firmware = getCurrentFirmware(); + + switch (updRefInfo.type) + { + case REF_UPD_TYPE_SENSOR: + idxAdj = 5/*3 Timers + Flight + Telemetery*/ + firmware->getCapability(RotaryEncoders); + if (cfd->param < idxAdj || cfd->param > (idxAdj + firmware->getCapability(Sensors))) + return; + break; + default: + return; + } + + switch (updRefInfo.action) + { + case REF_UPD_ACT_CLEAR: + if (newRef != (updRefInfo.index1 + idxAdj)) + return; + newRef = invalidateRef; + break; + case REF_UPD_ACT_SHIFT: + if (newRef < (updRefInfo.index1 + idxAdj)) + return; + + newRef += updRefInfo.shift; + + if (newRef < (updRefInfo.index1 + idxAdj) || newRef > (updRefInfo.maxindex + idxAdj)) + newRef = invalidateRef; + break; + case REF_UPD_ACT_SWAP: + if (newRef == updRefInfo.index1 + idxAdj) + newRef = updRefInfo.index2 + idxAdj; + else if (newRef == updRefInfo.index2 + idxAdj) + newRef = updRefInfo.index1 + idxAdj; + break; + default: + qDebug() << "Error - unhandled action:" << updRefInfo.action; + return; + } + + if (newRef == invalidateRef) { + cfd->clear(); + //qDebug() << "Function cleared"; + updRefInfo.updcnt++; + } + else if (cfd->param != newRef) { + //qDebug() << "Updated reference:" << cfd->param << " -> " << newRef; + cfd->param = newRef; + updRefInfo.updcnt++; + } +} diff --git a/companion/src/firmwares/modeldata.h b/companion/src/firmwares/modeldata.h index 0afc66b72..7eacdc26d 100644 --- a/companion/src/firmwares/modeldata.h +++ b/companion/src/firmwares/modeldata.h @@ -338,6 +338,7 @@ class ModelData { value = swtch.toValue(); } void sortMixes(); + void updateResetParam(CustomFunctionData * cfd); }; #endif // MODELDATA_H diff --git a/companion/src/firmwares/opentx/opentxinterface.cpp b/companion/src/firmwares/opentx/opentxinterface.cpp index 2e35c51db..04f02eb29 100644 --- a/companion/src/firmwares/opentx/opentxinterface.cpp +++ b/companion/src/firmwares/opentx/opentxinterface.cpp @@ -1202,19 +1202,19 @@ void registerOpenTxFirmwares() firmware->addOption("horussticks", Firmware::tr("Horus gimbals installed (Hall sensors)")); addOpenTxTaranisOptions(firmware); registerOpenTxFirmware(firmware); - addOpenTxRfOptions(firmware, EU + FLEX + AFHDS3); + addOpenTxRfOptions(firmware, EU + FLEX); /* FrSky X9-Lite board */ firmware = new OpenTxFirmware("opentx-x9lite", Firmware::tr("FrSky Taranis X9-Lite"), BOARD_TARANIS_X9LITE); addOpenTxTaranisOptions(firmware); registerOpenTxFirmware(firmware); - addOpenTxRfOptions(firmware, FLEX + AFHDS3); + addOpenTxRfOptions(firmware, FLEX); /* FrSky X9-LiteS board */ firmware = new OpenTxFirmware("opentx-x9lites", Firmware::tr("FrSky Taranis X9-Lite S"), BOARD_TARANIS_X9LITES); addOpenTxTaranisOptions(firmware); registerOpenTxFirmware(firmware); - addOpenTxRfOptions(firmware, FLEX + AFHDS3); + addOpenTxRfOptions(firmware, FLEX); /* FrSky X7 board */ firmware = new OpenTxFirmware("opentx-x7", Firmware::tr("FrSky Taranis X7 / X7S"), BOARD_TARANIS_X7); @@ -1232,7 +1232,7 @@ void registerOpenTxFirmwares() firmware = new OpenTxFirmware("opentx-xlites", Firmware::tr("FrSky Taranis X-Lite S/PRO"), BOARD_TARANIS_XLITES); addOpenTxTaranisOptions(firmware); registerOpenTxFirmware(firmware); - addOpenTxRfOptions(firmware, FLEX + AFHDS3); + addOpenTxRfOptions(firmware, FLEX); /* FrSky X-Lite board */ firmware = new OpenTxFirmware("opentx-xlite", Firmware::tr("FrSky Taranis X-Lite"), BOARD_TARANIS_XLITE); @@ -1273,7 +1273,7 @@ void registerOpenTxFirmwares() firmware->addOption("internalmulti", Firmware::tr("Support for MULTI internal module")); addOpenTxFontOptions(firmware); registerOpenTxFirmware(firmware); - addOpenTxRfOptions(firmware, FLEX + AFHDS3); + addOpenTxRfOptions(firmware, FLEX); /* Jumper T16 board */ firmware = new OpenTxFirmware("opentx-t16", Firmware::tr("Jumper T16 / T16+ / T16 Pro"), BOARD_JUMPER_T16); @@ -1292,7 +1292,7 @@ void registerOpenTxFirmwares() firmware->addOption("lua", Firmware::tr("Enable Lua custom scripts screen")); addOpenTxFontOptions(firmware); registerOpenTxFirmware(firmware); - addOpenTxRfOptions(firmware, FLEX + AFHDS3); + addOpenTxRfOptions(firmware, FLEX); /* Radiomaster TX16S board */ firmware = new OpenTxFirmware("opentx-tx16s", Firmware::tr("Radiomaster TX16S / SE / Hall / Masterfire"), BOARD_RADIOMASTER_TX16S); diff --git a/companion/src/firmwares/rawswitch.cpp b/companion/src/firmwares/rawswitch.cpp index 10d3f7fa3..7aef46922 100644 --- a/companion/src/firmwares/rawswitch.cpp +++ b/companion/src/firmwares/rawswitch.cpp @@ -59,7 +59,7 @@ QString RawSwitch::toString(Board::Type board, const GeneralSettings * const gen tr("THs"), tr("TH%"), tr("THt") }; - const QStringList directionIndicators = QStringList() + static const QStringList directionIndicators = QStringList() << CPN_STR_SW_INDICATOR_UP << CPN_STR_SW_INDICATOR_NEUT << CPN_STR_SW_INDICATOR_DN; diff --git a/companion/src/generaledit/CMakeLists.txt b/companion/src/generaledit/CMakeLists.txt index 827c37ddf..2c458c719 100644 --- a/companion/src/generaledit/CMakeLists.txt +++ b/companion/src/generaledit/CMakeLists.txt @@ -28,4 +28,4 @@ qt5_wrap_ui(generaledit_SRCS ${generaledit_UIS}) qt5_wrap_cpp(generaledit_SRCS ${generaledit_HDRS}) add_library(generaledit ${generaledit_SRCS}) -target_link_libraries(generaledit PRIVATE ${CPN_COMMON_LIB} Qt5::Multimedia) +target_link_libraries(generaledit PRIVATE datamodels ${CPN_COMMON_LIB} Qt5::Multimedia) diff --git a/companion/src/generaledit/generaledit.cpp b/companion/src/generaledit/generaledit.cpp index 34d090e65..bff9d3f83 100644 --- a/companion/src/generaledit/generaledit.cpp +++ b/companion/src/generaledit/generaledit.cpp @@ -28,6 +28,7 @@ #include "hardware.h" #include "../modeledit/customfunctions.h" #include "verticalscrollarea.h" +#include "rawitemdatamodels.h" GeneralEdit::GeneralEdit(QWidget * parent, RadioData & radioData, Firmware * firmware) : QDialog(parent), @@ -55,8 +56,10 @@ GeneralEdit::GeneralEdit(QWidget * parent, RadioData & radioData, Firmware * fir } } + commonItemModels = new CommonItemModels(&generalSettings, nullptr, this); + addTab(new GeneralSetupPanel(this, generalSettings, firmware), tr("Setup")); - addTab(new CustomFunctionsPanel(this, NULL, generalSettings, firmware), tr("Global Functions")); + addTab(new CustomFunctionsPanel(this, nullptr, generalSettings, firmware, commonItemModels), tr("Global Functions")); addTab(new TrainerPanel(this, generalSettings, firmware), tr("Trainer")); addTab(new HardwarePanel(this, generalSettings, firmware), tr("Hardware")); addTab(new CalibrationPanel(this, generalSettings, firmware), tr("Calibration")); diff --git a/companion/src/generaledit/generaledit.h b/companion/src/generaledit/generaledit.h index 1c1d096a5..3f73a9e01 100644 --- a/companion/src/generaledit/generaledit.h +++ b/companion/src/generaledit/generaledit.h @@ -25,6 +25,8 @@ #include "eeprominterface.h" #include "genericpanel.h" +class CommonItemModels; + namespace Ui { class GeneralEdit; } @@ -56,7 +58,7 @@ class GeneralEdit : public QDialog void getGeneralSwitchDefPos(int i, bool val); void setSwitchDefPos(); void updateVarioPitchRange(); - + signals: void modified(); @@ -71,7 +73,7 @@ class GeneralEdit : public QDialog QVector panels; void addTab(GenericPanel *panel, QString text); void closeEvent(QCloseEvent *event); - + CommonItemModels *commonItemModels; }; #endif // _GENERALEDIT_H_ diff --git a/companion/src/helpers.cpp b/companion/src/helpers.cpp index 2b0f62503..68de4d9b2 100644 --- a/companion/src/helpers.cpp +++ b/companion/src/helpers.cpp @@ -742,7 +742,8 @@ GpsCoord extractGpsCoordinates(const QString & position) return result; } -TableLayout::TableLayout(QWidget * parent, int rowCount, const QStringList & headerLabels) +TableLayout::TableLayout(QWidget * parent, int rowCount, const QStringList & headerLabels) : + QObject(parent) { #if defined(TABLE_LAYOUT) tableWidget = new QTableWidget(parent); diff --git a/companion/src/helpers.h b/companion/src/helpers.h index 8a7399c56..3fb270a6b 100644 --- a/companion/src/helpers.h +++ b/companion/src/helpers.h @@ -208,8 +208,9 @@ private: GpsCoord extractGpsCoordinates(const QString & position); -class TableLayout +class TableLayout: public QObject { + Q_OBJECT public: TableLayout(QWidget * parent, int rowCount, const QStringList & headerLabels); // ~TableLayout() ; diff --git a/companion/src/modeledit/channels.cpp b/companion/src/modeledit/channels.cpp index 6442cc2fb..d2818368e 100644 --- a/companion/src/modeledit/channels.cpp +++ b/companion/src/modeledit/channels.cpp @@ -20,6 +20,7 @@ #include "channels.h" #include "helpers.h" +#include "rawitemfilteredmodel.h" LimitsGroup::LimitsGroup(Firmware * firmware, TableLayout * tableLayout, int row, int col, int & value, const ModelData & model, int min, int max, int deflt, ModelPanel * panel): firmware(firmware), @@ -95,15 +96,17 @@ void LimitsGroup::updateMinMax(int max) } } } - -Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware): - ModelPanel(parent, model, generalSettings, firmware) +ChannelsPanel::ChannelsPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels): + ModelPanel(parent, model, generalSettings, firmware), + commonItemModels(commonItemModels) { - Stopwatch s1("Channels"); - chnCapability = firmware->getCapability(Outputs); int channelNameMaxLen = firmware->getCapability(ChannelsName); + curveFilteredModel = new RawItemFilteredModel(commonItemModels->curveItemModel(), RawItemFilteredModel::AllFilter, this); + connect(curveFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &ChannelsPanel::onModelDataAboutToBeUpdated); + connect(curveFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &ChannelsPanel::onModelDataUpdateComplete); + QStringList headerLabels; headerLabels << "#"; if (channelNameMaxLen > 0) { @@ -118,8 +121,6 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera headerLabels << tr("Linear Subtrim"); TableLayout *tableLayout = new TableLayout(this, chnCapability, headerLabels); - s1.report("header"); - for (int i = 0; i < chnCapability; i++) { int col = 0; @@ -165,6 +166,7 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera if (IS_HORUS_OR_TARANIS(firmware->getBoard())) { curveCB[i] = new QComboBox(this); curveCB[i]->setProperty("index", i); + curveCB[i]->setModel(curveFilteredModel); connect(curveCB[i], SIGNAL(currentIndexChanged(int)), this, SLOT(curveEdited())); tableLayout->addWidget(i, col++, curveCB[i]); } @@ -193,15 +195,13 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera } } update(); - s1.report("add elements"); disableMouseScrolling(); tableLayout->resizeColumnsToContents(); tableLayout->pushRowsUp(chnCapability+1); - s1.report("end"); } -Channels::~Channels() +ChannelsPanel::~ChannelsPanel() { // compiler warning if delete[] for (int i = 0; i < CPN_MAX_CHNOUT; i++) { @@ -216,7 +216,7 @@ Channels::~Channels() } } -void Channels::symlimitsEdited() +void ChannelsPanel::symlimitsEdited() { if (!lock) { QCheckBox *ckb = qobject_cast(sender()); @@ -226,17 +226,20 @@ void Channels::symlimitsEdited() } } -void Channels::nameEdited() +void ChannelsPanel::nameEdited() { if (!lock) { QLineEdit *le = qobject_cast(sender()); int index = le->property("index").toInt(); - strcpy(model->limitData[index].name, le->text().toLatin1()); - emit modified(); + if (model->limitData[index].name != le->text()) { + strcpy(model->limitData[index].name, le->text().toLatin1()); + updateItemModels(); + emit modified(); + } } } -void Channels::refreshExtendedLimits() +void ChannelsPanel::refreshExtendedLimits() { int channelMax = model->getChannelsMax(); @@ -248,7 +251,7 @@ void Channels::refreshExtendedLimits() emit modified(); } -void Channels::invEdited() +void ChannelsPanel::invEdited() { if (!lock) { QComboBox *cb = qobject_cast(sender()); @@ -258,17 +261,20 @@ void Channels::invEdited() } } -void Channels::curveEdited() +void ChannelsPanel::curveEdited() { if (!lock) { QComboBox *cb = qobject_cast(sender()); int index = cb->property("index").toInt(); - model->limitData[index].curve = CurveReference(CurveReference::CURVE_REF_CUSTOM, cb->itemData(cb->currentIndex()).toInt()); - emit modified(); + // ignore unnecessary updates that could be triggered by updates to the data model + if (model->limitData[index].curve != CurveReference(CurveReference::CURVE_REF_CUSTOM, cb->itemData(cb->currentIndex()).toInt())) { + model->limitData[index].curve = CurveReference(CurveReference::CURVE_REF_CUSTOM, cb->itemData(cb->currentIndex()).toInt()); + emit modified(); + } } } -void Channels::ppmcenterEdited() +void ChannelsPanel::ppmcenterEdited() { if (!lock) { QSpinBox *sb = qobject_cast(sender()); @@ -278,51 +284,49 @@ void Channels::ppmcenterEdited() } } -void Channels::update() +void ChannelsPanel::update() { for (int i = 0; i < chnCapability; i++) { updateLine(i); } } -void Channels::updateLine(int i) +void ChannelsPanel::updateLine(int i) { lock = true; + LimitData &chn = model->limitData[i]; + if (firmware->getCapability(ChannelsName) > 0) { - name[i]->setText(model->limitData[i].name); + name[i]->setText(chn.name); } - chnOffset[i]->setValue(model->limitData[i].offset); - chnMin[i]->setValue(model->limitData[i].min); - chnMax[i]->setValue(model->limitData[i].max); - invCB[i]->setCurrentIndex((model->limitData[i].revert) ? 1 : 0); + chnOffset[i]->setValue(chn.offset); + chnMin[i]->setValue(chn.min); + chnMax[i]->setValue(chn.max); + invCB[i]->setCurrentIndex((chn.revert) ? 1 : 0); if (IS_HORUS_OR_TARANIS(firmware->getBoard())) { - int numcurves = firmware->getCapability(NumCurves); - curveCB[i]->clear(); - for (int j = -numcurves; j <= numcurves; j++) { - curveCB[i]->addItem(CurveReference(CurveReference::CURVE_REF_CUSTOM, j).toString(model, false), j); - } - curveCB[i]->setCurrentIndex(model->limitData[i].curve.value + numcurves); + curveCB[i]->setCurrentIndex(curveCB[i]->findData(chn.curve.value)); } if (firmware->getCapability(PPMCenter)) { - centerSB[i]->setValue(model->limitData[i].ppmCenter + 1500); + centerSB[i]->setValue(chn.ppmCenter + 1500); } if (firmware->getCapability(SYMLimits)) { - symlimitsChk[i]->setChecked(model->limitData[i].symetrical); + symlimitsChk[i]->setChecked(chn.symetrical); } lock = false; } -void Channels::cmPaste() +void ChannelsPanel::cmPaste() { QByteArray data; if (hasClipboardData(&data)) { memcpy(&model->limitData[selectedIndex], data.constData(), sizeof(LimitData)); updateLine(selectedIndex); + updateItemModels(); emit modified(); } } -void Channels::cmDelete() +void ChannelsPanel::cmDelete() { if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Delete Channel. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) return; @@ -335,10 +339,11 @@ void Channels::cmDelete() updateLine(i); } + updateItemModels(); emit modified(); } -void Channels::cmCopy() +void ChannelsPanel::cmCopy() { QByteArray data; data.append((char*)&model->limitData[selectedIndex], sizeof(LimitData)); @@ -347,7 +352,7 @@ void Channels::cmCopy() QApplication::clipboard()->setMimeData(mimeData,QClipboard::Clipboard); } -void Channels::cmCut() +void ChannelsPanel::cmCut() { if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Cut Channel. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) return; @@ -356,7 +361,7 @@ void Channels::cmCut() cmClear(false); } -void Channels::onCustomContextMenuRequested(QPoint pos) +void ChannelsPanel::onCustomContextMenuRequested(QPoint pos) { QLabel *label = (QLabel *)sender(); selectedIndex = label->property("index").toInt(); @@ -378,7 +383,7 @@ void Channels::onCustomContextMenuRequested(QPoint pos) contextMenu.exec(globalPos); } -bool Channels::hasClipboardData(QByteArray * data) const +bool ChannelsPanel::hasClipboardData(QByteArray * data) const { const QClipboard * clipboard = QApplication::clipboard(); const QMimeData * mimeData = clipboard->mimeData(); @@ -390,32 +395,32 @@ bool Channels::hasClipboardData(QByteArray * data) const return false; } -bool Channels::insertAllowed() const +bool ChannelsPanel::insertAllowed() const { return ((selectedIndex < chnCapability - 1) && (model->limitData[chnCapability - 1].isEmpty())); } -bool Channels::moveDownAllowed() const +bool ChannelsPanel::moveDownAllowed() const { return selectedIndex < chnCapability - 1; } -bool Channels::moveUpAllowed() const +bool ChannelsPanel::moveUpAllowed() const { return selectedIndex > 0; } -void Channels::cmMoveUp() +void ChannelsPanel::cmMoveUp() { swapData(selectedIndex, selectedIndex - 1); } -void Channels::cmMoveDown() +void ChannelsPanel::cmMoveDown() { swapData(selectedIndex, selectedIndex + 1); } -void Channels::cmClear(bool prompt) +void ChannelsPanel::cmClear(bool prompt) { if (prompt) { if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear Channel. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) @@ -425,10 +430,11 @@ void Channels::cmClear(bool prompt) model->limitData[selectedIndex].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_CHANNEL, ModelData::REF_UPD_ACT_CLEAR, selectedIndex); updateLine(selectedIndex); + updateItemModels(); emit modified(); } -void Channels::cmClearAll() +void ChannelsPanel::cmClearAll() { if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear all Channels. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) return; @@ -438,19 +444,21 @@ void Channels::cmClearAll() model->updateAllReferences(ModelData::REF_UPD_TYPE_CHANNEL, ModelData::REF_UPD_ACT_CLEAR, i); updateLine(i); } + updateItemModels(); emit modified(); } -void Channels::cmInsert() +void ChannelsPanel::cmInsert() { memmove(&model->limitData[selectedIndex + 1], &model->limitData[selectedIndex], (CPN_MAX_CHNOUT - (selectedIndex + 1)) * sizeof(LimitData)); model->limitData[selectedIndex].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_CHANNEL, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, 1); update(); + updateItemModels(); emit modified(); } -void Channels::swapData(int idx1, int idx2) +void ChannelsPanel::swapData(int idx1, int idx2) { if ((idx1 != idx2) && (!model->limitData[idx1].isEmpty() || !model->limitData[idx2].isEmpty())) { LimitData chntmp = model->limitData[idx2]; @@ -461,6 +469,23 @@ void Channels::swapData(int idx1, int idx2) model->updateAllReferences(ModelData::REF_UPD_TYPE_CHANNEL, ModelData::REF_UPD_ACT_SWAP, idx1, idx2); updateLine(idx1); updateLine(idx2); + updateItemModels(); emit modified(); } } + +void ChannelsPanel::onModelDataAboutToBeUpdated() +{ + lock = true; +} + +void ChannelsPanel::onModelDataUpdateComplete() +{ + update(); + lock = false; +} + +void ChannelsPanel::updateItemModels() +{ + commonItemModels->update(CommonItemModels::RMO_CHANNELS); +} diff --git a/companion/src/modeledit/channels.h b/companion/src/modeledit/channels.h index d20923a35..a481feec2 100644 --- a/companion/src/modeledit/channels.h +++ b/companion/src/modeledit/channels.h @@ -26,6 +26,9 @@ #include +class CommonItemModels; +class RawItemFilteredModel; + constexpr char MIMETYPE_CHANNEL[] = "application/x-companion-channel"; class GVarGroup; @@ -49,13 +52,13 @@ class LimitsGroup double displayStep; }; -class Channels : public ModelPanel +class ChannelsPanel : public ModelPanel { Q_OBJECT public: - Channels(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware); - ~Channels(); + ChannelsPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels); + ~ChannelsPanel(); public slots: void refreshExtendedLimits(); @@ -78,6 +81,8 @@ class Channels : public ModelPanel void cmClear(bool prompt = true); void cmClearAll(); void onCustomContextMenuRequested(QPoint pos); + void onModelDataAboutToBeUpdated(); + void onModelDataUpdateComplete(); private: bool hasClipboardData(QByteArray * data = nullptr) const; @@ -95,6 +100,9 @@ class Channels : public ModelPanel QCheckBox *symlimitsChk[CPN_MAX_CHNOUT]; int selectedIndex; int chnCapability; + CommonItemModels * commonItemModels; + RawItemFilteredModel *curveFilteredModel; + void updateItemModels(); }; #endif // _CHANNELS_H_ diff --git a/companion/src/modeledit/curves.cpp b/companion/src/modeledit/curves.cpp index da056964e..9e60f30c3 100644 --- a/companion/src/modeledit/curves.cpp +++ b/companion/src/modeledit/curves.cpp @@ -23,6 +23,7 @@ #include "node.h" #include "edge.h" #include "helpers.h" +#include "rawitemfilteredmodel.h" #define GFX_MARGIN 16 @@ -108,10 +109,11 @@ float curveSymmetricalX(float x, float coeff, float yMin, float yMid, float yMax return y; } -Curves::Curves(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware): +CurvesPanel::CurvesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels): ModelPanel(parent, model, generalSettings, firmware), ui(new Ui::Curves), - currentCurve(0) + currentCurve(0), + commonItemModels(commonItemModels) { ui->setupUi(this); @@ -230,12 +232,12 @@ Curves::Curves(QWidget * parent, ModelData & model, GeneralSettings & generalSet lock = false; } -Curves::~Curves() +CurvesPanel::~CurvesPanel() { delete ui; } -void Curves::editCurve() +void CurvesPanel::editCurve() { QPushButton *button = (QPushButton *)sender(); int index = button->property("index").toInt(); @@ -243,7 +245,7 @@ void Curves::editCurve() update(); } -void Curves::plotCurve(bool checked) +void CurvesPanel::plotCurve(bool checked) { QCheckBox *chk = (QCheckBox *)sender(); int index = chk->property("index").toInt(); @@ -251,7 +253,7 @@ void Curves::plotCurve(bool checked) updateCurve(); } -void Curves::update() +void CurvesPanel::update() { lock = true; @@ -266,12 +268,12 @@ void Curves::update() lock = false; } -void Curves::setCurrentCurve(int index) +void CurvesPanel::setCurrentCurve(int index) { currentCurve = index; } -void Curves::updateCurveType() +void CurvesPanel::updateCurveType() { lock = true; @@ -297,7 +299,7 @@ void Curves::updateCurveType() lock = false; } -void Curves::updateCurve() +void CurvesPanel::updateCurve() { lock = true; @@ -371,7 +373,7 @@ void Curves::updateCurve() lock = false; } -void Curves::updateCurvePoints() +void CurvesPanel::updateCurvePoints() { lock = true; @@ -405,7 +407,7 @@ void Curves::updateCurvePoints() lock = false; } -void Curves::onPointEdited() +void CurvesPanel::onPointEdited() { if (!lock) { int index = sender()->property("index").toInt(); @@ -417,7 +419,7 @@ void Curves::onPointEdited() } } -void Curves::onNodeMoved(int x, int y) +void CurvesPanel::onNodeMoved(int x, int y) { if (!lock) { lock = true; @@ -435,20 +437,20 @@ void Curves::onNodeMoved(int x, int y) } } -void Curves::onNodeFocus() +void CurvesPanel::onNodeFocus() { int index = sender()->property("index").toInt(); spny[index]->setFocus(); } -void Curves::onNodeUnfocus() +void CurvesPanel::onNodeUnfocus() { int index = sender()->property("index").toInt(); spny[index]->clearFocus(); updateCurve(); } -bool Curves::allowCurveType(int points, CurveData::CurveType type) +bool CurvesPanel::allowCurveType(int points, CurveData::CurveType type) { int totalpoints = 0; for (int i = 0; i < maxCurves; i++) { @@ -466,7 +468,7 @@ bool Curves::allowCurveType(int points, CurveData::CurveType type) } } -void Curves::on_curvePoints_currentIndexChanged(int index) +void CurvesPanel::on_curvePoints_currentIndexChanged(int index) { if (!lock) { int numpoints = ((QComboBox *)sender())->itemData(index).toInt(); @@ -489,7 +491,7 @@ void Curves::on_curvePoints_currentIndexChanged(int index) } } -void Curves::on_curveCustom_currentIndexChanged(int index) +void CurvesPanel::on_curveCustom_currentIndexChanged(int index) { if (!lock) { CurveData::CurveType type = (CurveData::CurveType)index; @@ -513,20 +515,23 @@ void Curves::on_curveCustom_currentIndexChanged(int index) } } -void Curves::on_curveSmooth_currentIndexChanged(int index) +void CurvesPanel::on_curveSmooth_currentIndexChanged(int index) { model->curves[currentCurve].smooth = index; update(); } -void Curves::on_curveName_editingFinished() +void CurvesPanel::on_curveName_editingFinished() { - memset(model->curves[currentCurve].name, 0, sizeof(model->curves[currentCurve].name)); - strcpy(model->curves[currentCurve].name, ui->curveName->text().toLatin1()); - emit modified(); + if (ui->curveName->text() != model->curves[currentCurve].name) { + memset(model->curves[currentCurve].name, 0, sizeof(model->curves[currentCurve].name)); + strcpy(model->curves[currentCurve].name, ui->curveName->text().toLatin1()); + updateItemModels(); + emit modified(); + } } -void Curves::resizeEvent(QResizeEvent *event) +void CurvesPanel::resizeEvent(QResizeEvent *event) { QRect qr = ui->curvePreview->contentsRect(); ui->curvePreview->scene()->setSceneRect(GFX_MARGIN, GFX_MARGIN, qr.width() - GFX_MARGIN * 2, qr.height() - GFX_MARGIN * 2); @@ -534,7 +539,7 @@ void Curves::resizeEvent(QResizeEvent *event) ModelPanel::resizeEvent(event); } -void Curves::on_curveType_currentIndexChanged(int index) +void CurvesPanel::on_curveType_currentIndexChanged(int index) { unsigned int flags = templates[index].flags; ui->curveCoeffLabel->setVisible(flags & CURVE_COEFF_ENABLE); @@ -548,7 +553,7 @@ void Curves::on_curveType_currentIndexChanged(int index) ui->yMin->setValue(-100); } -void Curves::addTemplate(QString name, unsigned int flags, curveFunction function) +void CurvesPanel::addTemplate(QString name, unsigned int flags, curveFunction function) { CurveCreatorTemplate tmpl; tmpl.name = name; @@ -558,7 +563,7 @@ void Curves::addTemplate(QString name, unsigned int flags, curveFunction functio ui->curveType->addItem(name); } -void Curves::on_curveApply_clicked() +void CurvesPanel::on_curveApply_clicked() { int index = ui->curveType->currentIndex(); int numpoints = model->curves[currentCurve].count; @@ -595,14 +600,14 @@ void Curves::on_curveApply_clicked() emit modified(); } -void Curves::onPointSizeEdited() +void CurvesPanel::onPointSizeEdited() { if (!lock) { update(); } } -void Curves::onNodeDelete() +void CurvesPanel::onNodeDelete() { int index = sender()->property("index").toInt(); int numpoints = model->curves[currentCurve].count; @@ -620,7 +625,7 @@ void Curves::onNodeDelete() } } -void Curves::onSceneNewPoint(int x, int y) +void CurvesPanel::onSceneNewPoint(int x, int y) { if ((model->curves[currentCurve].type == CurveData::CURVE_TYPE_CUSTOM) && (model->curves[currentCurve].count < CPN_MAX_POINTS)) { int newidx = 0; @@ -651,7 +656,7 @@ void Curves::onSceneNewPoint(int x, int y) } } -void Curves::onCustomContextMenuRequested(QPoint pos) +void CurvesPanel::onCustomContextMenuRequested(QPoint pos) { QPushButton *button = (QPushButton *)sender(); selectedIndex = button->property("index").toInt(); @@ -673,7 +678,7 @@ void Curves::onCustomContextMenuRequested(QPoint pos) contextMenu.exec(globalPos); } -bool Curves::hasClipboardData(QByteArray * data) const +bool CurvesPanel::hasClipboardData(QByteArray * data) const { const QClipboard * clipboard = QApplication::clipboard(); const QMimeData * mimeData = clipboard->mimeData(); @@ -685,22 +690,22 @@ bool Curves::hasClipboardData(QByteArray * data) const return false; } -bool Curves::insertAllowed() const +bool CurvesPanel::insertAllowed() const { return ((selectedIndex < maxCurves - 1) && (model->curves[maxCurves - 1].isEmpty())); } -bool Curves::moveDownAllowed() const +bool CurvesPanel::moveDownAllowed() const { return selectedIndex < maxCurves - 1; } -bool Curves::moveUpAllowed() const +bool CurvesPanel::moveUpAllowed() const { return selectedIndex > 0; } -void Curves::cmClear(bool prompt) +void CurvesPanel::cmClear(bool prompt) { if (prompt) { if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear Curve. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) @@ -710,10 +715,11 @@ void Curves::cmClear(bool prompt) model->curves[selectedIndex].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_CURVE, ModelData::REF_UPD_ACT_CLEAR, selectedIndex); update(); + updateItemModels(); emit modified(); } -void Curves::cmClearAll() +void CurvesPanel::cmClearAll() { if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear all Curves. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) return; @@ -723,10 +729,11 @@ void Curves::cmClearAll() model->updateAllReferences(ModelData::REF_UPD_TYPE_CURVE, ModelData::REF_UPD_ACT_CLEAR, i); } update(); + updateItemModels(); emit modified(); } -void Curves::cmCopy() +void CurvesPanel::cmCopy() { QByteArray data; data.append((char*)&model->curves[selectedIndex], sizeof(CurveData)); @@ -735,7 +742,7 @@ void Curves::cmCopy() QApplication::clipboard()->setMimeData(mimeData,QClipboard::Clipboard); } -void Curves::cmCut() +void CurvesPanel::cmCut() { if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Cut Curve. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) return; @@ -743,7 +750,7 @@ void Curves::cmCut() cmClear(false); } -void Curves::cmDelete() +void CurvesPanel::cmDelete() { if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Delete Curve. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) return; @@ -752,40 +759,43 @@ void Curves::cmDelete() model->curves[maxCurves - 1].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_CURVE, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, -1); update(); + updateItemModels(); emit modified(); } -void Curves::cmInsert() +void CurvesPanel::cmInsert() { memmove(&model->curves[selectedIndex + 1], &model->curves[selectedIndex], (CPN_MAX_CURVES - (selectedIndex + 1)) * sizeof(CurveData)); model->curves[selectedIndex].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_CURVE, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, 1); update(); + updateItemModels(); emit modified(); } -void Curves::cmMoveDown() +void CurvesPanel::cmMoveDown() { swapData(selectedIndex, selectedIndex + 1); } -void Curves::cmMoveUp() +void CurvesPanel::cmMoveUp() { swapData(selectedIndex, selectedIndex - 1); } -void Curves::cmPaste() +void CurvesPanel::cmPaste() { QByteArray data; if (hasClipboardData(&data)) { CurveData *cd = &model->curves[selectedIndex]; memcpy(cd, data.constData(), sizeof(CurveData)); update(); + updateItemModels(); emit modified(); } } -void Curves::swapData(int idx1, int idx2) +void CurvesPanel::swapData(int idx1, int idx2) { if ((idx1 != idx2) && (!model->curves[idx1].isEmpty() || !model->curves[idx2].isEmpty())) { CurveData cdtmp = model->curves[idx2]; @@ -795,10 +805,16 @@ void Curves::swapData(int idx1, int idx2) memcpy(cd1, &cdtmp, sizeof(CurveData)); model->updateAllReferences(ModelData::REF_UPD_TYPE_CURVE, ModelData::REF_UPD_ACT_SWAP, idx1, idx2); update(); + updateItemModels(); emit modified(); } } +void CurvesPanel::updateItemModels() +{ + commonItemModels->update(CommonItemModels::RMO_CURVES); +} + CustomScene::CustomScene(QGraphicsView * view) : QGraphicsScene(view) { diff --git a/companion/src/modeledit/curves.h b/companion/src/modeledit/curves.h index 34d1a675e..8df3a8528 100644 --- a/companion/src/modeledit/curves.h +++ b/companion/src/modeledit/curves.h @@ -26,6 +26,8 @@ #include #include +class CommonItemModels; + constexpr char MIMETYPE_CURVE[] = "application/x-companion-curve"; namespace Ui { @@ -54,13 +56,13 @@ class CustomScene : public QGraphicsScene virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent * event) override; }; -class Curves : public ModelPanel +class CurvesPanel : public ModelPanel { Q_OBJECT public: - Curves(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware); - virtual ~Curves(); + CurvesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels); + virtual ~CurvesPanel(); virtual void update(); @@ -119,6 +121,8 @@ class Curves : public ModelPanel bool moveDownAllowed() const; bool moveUpAllowed() const; void swapData(int idx1, int idx2); + CommonItemModels * commonItemModels; + void updateItemModels(); }; #endif // _CURVES_H_ diff --git a/companion/src/modeledit/customfunctions.cpp b/companion/src/modeledit/customfunctions.cpp index 36dba9c97..abdd2e39c 100644 --- a/companion/src/modeledit/customfunctions.cpp +++ b/companion/src/modeledit/customfunctions.cpp @@ -41,7 +41,7 @@ RepeatComboBox::RepeatComboBox(QWidget *parent, int & repeatParam): addItem(tr("No repeat"), 0); - for (unsigned int i=step; i<=60; i+=step) { + for (unsigned int i = step; i <= 60; i += step) { addItem(tr("%1s").arg(i), i); } @@ -66,24 +66,36 @@ void RepeatComboBox::update() setCurrentIndex(value); } -CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware): +CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels): GenericPanel(parent, model, generalSettings, firmware), functions(model ? model->customFn : generalSettings.customFn), + commonItemModels(commonItemModels), mediaPlayerCurrent(-1), - mediaPlayer(nullptr) + mediaPlayer(nullptr), + modelsUpdateCnt(0) { - Stopwatch s1("CustomFunctionsPanel - populate"); lock = true; fswCapability = model ? firmware->getCapability(CustomFunctions) : firmware->getCapability(GlobalFunctions); - rawSwitchItemModel = new RawSwitchFilterItemModel(&generalSettings, model, model ? RawSwitch::SpecialFunctionsContext : RawSwitch::GlobalFunctionsContext, this); - rawSrcAllItemModel = new RawSourceFilterItemModel(&generalSettings, model, this); - rawSrcInputsItemModel = new RawSourceFilterItemModel(rawSrcAllItemModel->sourceModel(), RawSource::InputSourceGroups, this); - rawSrcGVarsItemModel = new RawSourceFilterItemModel(rawSrcAllItemModel->sourceModel(), RawSource::GVarsGroup, this); + rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), model ? RawSwitch::SpecialFunctionsContext : RawSwitch::GlobalFunctionsContext, this); + connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &CustomFunctionsPanel::onModelDataAboutToBeUpdated); + connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &CustomFunctionsPanel::onModelDataUpdateComplete); + + rawSourceAllModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), this); + connect(rawSourceAllModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &CustomFunctionsPanel::onModelDataAboutToBeUpdated); + connect(rawSourceAllModel, &RawItemFilteredModel::dataUpdateComplete, this, &CustomFunctionsPanel::onModelDataUpdateComplete); + + rawSourceInputsModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), RawSource::InputSourceGroups, this); + connect(rawSourceInputsModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &CustomFunctionsPanel::onModelDataAboutToBeUpdated); + connect(rawSourceInputsModel, &RawItemFilteredModel::dataUpdateComplete, this, &CustomFunctionsPanel::onModelDataUpdateComplete); + + rawSourceGVarsModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), RawSource::GVarsGroup, this); + connect(rawSourceGVarsModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &CustomFunctionsPanel::onModelDataAboutToBeUpdated); + connect(rawSourceGVarsModel, &RawItemFilteredModel::dataUpdateComplete, this, &CustomFunctionsPanel::onModelDataUpdateComplete); if (!firmware->getCapability(VoicesAsNumbers)) { tracksSet = getFilesSet(getSoundsPath(generalSettings), QStringList() << "*.wav" << "*.WAV", firmware->getCapability(VoicesMaxLength)); - for (int i=0; igetBoard())) { scriptsSet = getFilesSet(g.profile[g.id()].sdPath() + "/SCRIPTS/FUNCTIONS", QStringList() << "*.lua", firmware->getCapability(VoicesMaxLength)); - for (int i=0; isetContextMenuPolicy(Qt::CustomContextMenu); @@ -123,9 +132,9 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, label->setMouseTracking(true); label->setProperty("index", i); if (model) - label->setText(tr("SF%1").arg(i+1)); + label->setText(tr("SF%1").arg(i + 1)); else - label->setText(tr("GF%1").arg(i+1)); + label->setText(tr("GF%1").arg(i + 1)); label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); connect(label, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onCustomContextMenuRequested(QPoint))); tableLayout->addWidget(i, 0, label); @@ -133,7 +142,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, // The switch fswtchSwtch[i] = new QComboBox(this); - fswtchSwtch[i]->setModel(rawSwitchItemModel); + fswtchSwtch[i]->setModel(rawSwitchFilteredModel); fswtchSwtch[i]->setCurrentIndex(fswtchSwtch[i]->findData(functions[i].swtch.toValue())); fswtchSwtch[i]->setProperty("index", i); fswtchSwtch[i]->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Minimum); @@ -198,7 +207,6 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, fswtchParamArmT[i]->setEditable(true); fswtchParamArmT[i]->setSizeAdjustPolicy(QComboBox::AdjustToContents); paramLayout->addWidget(fswtchParamArmT[i]); - connect(fswtchParamArmT[i], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited())); connect(fswtchParamArmT[i], SIGNAL(editTextChanged ( const QString)), this, SLOT(customFunctionEdited())); @@ -221,31 +229,24 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, QHBoxLayout * repeatLayout = new QHBoxLayout(); tableLayout->addLayout(i, 4, repeatLayout); fswtchRepeat[i] = new RepeatComboBox(this, functions[i].repeatParam); - repeatLayout->addWidget(fswtchRepeat[i], i+1); - connect(fswtchRepeat[i], SIGNAL(modified()), this, SLOT(onChildModified())); + repeatLayout->addWidget(fswtchRepeat[i], i + 1); + connect(fswtchRepeat[i], SIGNAL(modified()), this, SLOT(onRepeatModified())); fswtchEnable[i] = new QCheckBox(this); fswtchEnable[i]->setProperty("index", i); fswtchEnable[i]->setText(tr("ON")); fswtchEnable[i]->setFixedWidth(200); - repeatLayout->addWidget(fswtchEnable[i], i+1); + repeatLayout->addWidget(fswtchEnable[i], i + 1); connect(fswtchEnable[i], SIGNAL(stateChanged(int)), this, SLOT(customFunctionEdited())); } - s1.report("add items"); - disableMouseScrolling(); - s1.report("disableMouseScrolling"); - - lock = false; + tableLayout->resizeColumnsToContents(); + tableLayout->setColumnWidth(3, 300); + tableLayout->pushRowsUp(fswCapability + 1); update(); - s1.report("update"); - tableLayout->resizeColumnsToContents(); - s1.report("resizeColumnsToContents"); - tableLayout->setColumnWidth(3, 300); - tableLayout->pushRowsUp(fswCapability+1); - s1.report("end"); + lock = false; } CustomFunctionsPanel::~CustomFunctionsPanel() @@ -254,15 +255,6 @@ CustomFunctionsPanel::~CustomFunctionsPanel() stopSound(mediaPlayerCurrent); } -void CustomFunctionsPanel::updateDataModels() -{ - const bool oldLock = lock; - lock = true; - rawSwitchItemModel->update(); - rawSrcAllItemModel->update(); - lock = oldLock; -} - void CustomFunctionsPanel::onMediaPlayerStateChanged(QMediaPlayer::State state) { if (state != QMediaPlayer::PlayingState) @@ -343,6 +335,7 @@ void CustomFunctionsPanel::toggleSound(bool play) #define CUSTOM_FUNCTION_BL_COLOR (1<<9) #define CUSTOM_FUNCTION_SHOW_FUNC (1<<10) + void CustomFunctionsPanel::customFunctionEdited() { if (!lock) { @@ -369,162 +362,155 @@ void CustomFunctionsPanel::functionEdited() } } -void CustomFunctionsPanel::onChildModified() +void CustomFunctionsPanel::onRepeatModified() { emit modified(); } void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) { - CustomFunctionData & cfn = functions[i]; - AssignFunc func = (AssignFunc)fswtchFunc[i]->currentData().toInt(); + CustomFunctionData & cfn = functions[i]; + AssignFunc func = (AssignFunc)fswtchFunc[i]->currentData().toInt(); - unsigned int widgetsMask = 0; - if (modified) { - cfn.swtch = RawSwitch(fswtchSwtch[i]->currentData().toInt()); - cfn.func = func; - cfn.enabled = fswtchEnable[i]->isChecked(); - } + unsigned int widgetsMask = 0; + if (modified) { + cfn.swtch = RawSwitch(fswtchSwtch[i]->currentData().toInt()); + cfn.func = func; + cfn.enabled = fswtchEnable[i]->isChecked(); + } + else { + fswtchSwtch[i]->setCurrentIndex(fswtchSwtch[i]->findData(cfn.swtch.toValue())); + fswtchFunc[i]->setCurrentIndex(fswtchFunc[i]->findData(cfn.func)); + } - if (!cfn.isEmpty()) { - widgetsMask |= CUSTOM_FUNCTION_SHOW_FUNC; + if (!cfn.isEmpty()) { + widgetsMask |= CUSTOM_FUNCTION_SHOW_FUNC; - if (func >= FuncOverrideCH1 && func <= FuncOverrideCH32) { - if (model) { - int channelsMax = model->getChannelsMax(true); - fswtchParam[i]->setDecimals(0); - fswtchParam[i]->setSingleStep(1); - fswtchParam[i]->setMinimum(-channelsMax); - fswtchParam[i]->setMaximum(channelsMax); - if (modified) { - cfn.param = fswtchParam[i]->value(); - } - fswtchParam[i]->setValue(cfn.param); - widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM | CUSTOM_FUNCTION_ENABLE; + if (func >= FuncOverrideCH1 && func <= FuncOverrideCH32) { + if (model) { + int channelsMax = model->getChannelsMax(true); + fswtchParam[i]->setDecimals(0); + fswtchParam[i]->setSingleStep(1); + fswtchParam[i]->setMinimum(-channelsMax); + fswtchParam[i]->setMaximum(channelsMax); + if (modified) { + cfn.param = fswtchParam[i]->value(); } + fswtchParam[i]->setValue(cfn.param); + widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM | CUSTOM_FUNCTION_ENABLE; } - else if (func == FuncLogs) { - fswtchParam[i]->setDecimals(1); - fswtchParam[i]->setMinimum(0); - fswtchParam[i]->setMaximum(25.5); - fswtchParam[i]->setSingleStep(0.1); + } + else if (func == FuncLogs) { + fswtchParam[i]->setDecimals(1); + fswtchParam[i]->setMinimum(0); + fswtchParam[i]->setMaximum(25.5); + fswtchParam[i]->setSingleStep(0.1); + if (modified) + cfn.param = fswtchParam[i]->value() * 10.0; + fswtchParam[i]->setValue(cfn.param / 10.0); + widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM; + } + else if (func >= FuncAdjustGV1 && func <= FuncAdjustGVLast) { + int gvidx = func - FuncAdjustGV1; + if (modified) + cfn.adjustMode = fswtchGVmode[i]->currentIndex(); + fswtchGVmode[i]->setCurrentIndex(cfn.adjustMode); + widgetsMask |= CUSTOM_FUNCTION_GV_MODE | CUSTOM_FUNCTION_ENABLE; + if (cfn.adjustMode == FUNC_ADJUST_GVAR_CONSTANT || cfn.adjustMode == FUNC_ADJUST_GVAR_INCDEC) { if (modified) - cfn.param = fswtchParam[i]->value()*10.0; - fswtchParam[i]->setValue(cfn.param/10.0); - widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM; - } - else if (func >= FuncAdjustGV1 && func <= FuncAdjustGVLast) { - int gvidx = func - FuncAdjustGV1; - if (modified) - cfn.adjustMode = fswtchGVmode[i]->currentIndex(); - fswtchGVmode[i]->setCurrentIndex(cfn.adjustMode); - widgetsMask |= CUSTOM_FUNCTION_GV_MODE | CUSTOM_FUNCTION_ENABLE; - if (cfn.adjustMode == FUNC_ADJUST_GVAR_CONSTANT || cfn.adjustMode == FUNC_ADJUST_GVAR_INCDEC) { - if (modified) - cfn.param = fswtchParam[i]->value() * model->gvarData[gvidx].multiplierSet(); - fswtchParam[i]->setDecimals(model->gvarData[gvidx].prec); - fswtchParam[i]->setSingleStep(model->gvarData[gvidx].multiplierGet()); - fswtchParam[i]->setSuffix(model->gvarData[gvidx].unitToString()); - if (cfn.adjustMode==FUNC_ADJUST_GVAR_INCDEC) { - double rng = abs(model->gvarData[gvidx].getMax() - model->gvarData[gvidx].getMin()); - rng *= model->gvarData[gvidx].multiplierGet(); - fswtchParam[i]->setMinimum(-rng); - fswtchParam[i]->setMaximum(rng); - } - else { - fswtchParam[i]->setMinimum(model->gvarData[gvidx].getMinPrec()); - fswtchParam[i]->setMaximum(model->gvarData[gvidx].getMaxPrec()); - } - fswtchParam[i]->setValue(cfn.param * model->gvarData[gvidx].multiplierGet()); - widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM; + cfn.param = fswtchParam[i]->value() * model->gvarData[gvidx].multiplierSet(); + fswtchParam[i]->setDecimals(model->gvarData[gvidx].prec); + fswtchParam[i]->setSingleStep(model->gvarData[gvidx].multiplierGet()); + fswtchParam[i]->setSuffix(model->gvarData[gvidx].unitToString()); + if (cfn.adjustMode == FUNC_ADJUST_GVAR_INCDEC) { + double rng = abs(model->gvarData[gvidx].getMax() - model->gvarData[gvidx].getMin()); + rng *= model->gvarData[gvidx].multiplierGet(); + fswtchParam[i]->setMinimum(-rng); + fswtchParam[i]->setMaximum(rng); } else { - if (modified) - cfn.param = fswtchParamT[i]->currentData().toInt(); - populateFuncParamCB(fswtchParamT[i], func, cfn.param, cfn.adjustMode); - widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM; + fswtchParam[i]->setMinimum(model->gvarData[gvidx].getMinPrec()); + fswtchParam[i]->setMaximum(model->gvarData[gvidx].getMaxPrec()); } + fswtchParam[i]->setValue(cfn.param * model->gvarData[gvidx].multiplierGet()); + widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM; } - else if (func == FuncReset) { + else { + if (modified) + cfn.param = fswtchParamT[i]->currentData().toInt(); + populateFuncParamCB(fswtchParamT[i], func, cfn.param, cfn.adjustMode); + widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM; + } + } + else if (func == FuncReset) { + if (modified) + cfn.param = fswtchParamT[i]->currentData().toInt(); + populateFuncParamCB(fswtchParamT[i], func, cfn.param); + widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM | CUSTOM_FUNCTION_ENABLE; + } + else if (func >= FuncSetTimer1 && func <= FuncSetTimer3) { + if (modified) + cfn.param = fswtchParamTime[i]->timeInSeconds(); + RawSourceRange range = RawSource(SOURCE_TYPE_SPECIAL, func - FuncSetTimer1 + 2).getRange(model, generalSettings); + fswtchParamTime[i]->setTimeRange((int)range.min, (int)range.max); + fswtchParamTime[i]->setTime(cfn.param); + widgetsMask |= CUSTOM_FUNCTION_TIME_PARAM | CUSTOM_FUNCTION_ENABLE; + } + else if (func >= FuncSetFailsafeInternalModule && func <= FuncBindExternalModule) { + widgetsMask |= CUSTOM_FUNCTION_ENABLE; + } + else if (func == FuncVolume || func == FuncBacklight) { + if (modified) + cfn.param = fswtchParamT[i]->currentData().toInt(); + populateFuncParamCB(fswtchParamT[i], func, cfn.param); + widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM | CUSTOM_FUNCTION_ENABLE; + } + else if (func == FuncPlaySound || func == FuncPlayHaptic || func == FuncPlayValue || func == FuncPlayPrompt || func == FuncPlayBoth || func == FuncBackgroundMusic) { + if (func != FuncBackgroundMusic) { + widgetsMask |= CUSTOM_FUNCTION_REPEAT; + fswtchRepeat[i]->update(); + } + if (func == FuncPlayValue) { if (modified) cfn.param = fswtchParamT[i]->currentData().toInt(); populateFuncParamCB(fswtchParamT[i], func, cfn.param); - widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM | CUSTOM_FUNCTION_ENABLE; + widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM | CUSTOM_FUNCTION_REPEAT; } - else if (func >= FuncSetTimer1 && func <= FuncSetTimer3) { - if (modified) - cfn.param = fswtchParamTime[i]->timeInSeconds(); - RawSourceRange range = RawSource(SOURCE_TYPE_SPECIAL, func - FuncSetTimer1 + 2).getRange(model, generalSettings); - fswtchParamTime[i]->setTimeRange((int)range.min, (int)range.max); - fswtchParamTime[i]->setTime(cfn.param); - widgetsMask |= CUSTOM_FUNCTION_TIME_PARAM | CUSTOM_FUNCTION_ENABLE; - } - else if (func >= FuncSetFailsafeInternalModule && func <= FuncBindExternalModule) { - widgetsMask |= CUSTOM_FUNCTION_ENABLE; - } - else if (func == FuncVolume || func == FuncBacklight) { - if (modified) - cfn.param = fswtchParamT[i]->currentData().toInt(); - populateFuncParamCB(fswtchParamT[i], func, cfn.param); - widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM | CUSTOM_FUNCTION_ENABLE; - } - else if (func == FuncPlaySound || func == FuncPlayHaptic || func == FuncPlayValue || func == FuncPlayPrompt || func == FuncPlayBoth || func == FuncBackgroundMusic) { - if (func != FuncBackgroundMusic) { - widgetsMask |= CUSTOM_FUNCTION_REPEAT; - fswtchRepeat[i]->update(); - } - if (func == FuncPlayValue) { - if (modified) - cfn.param = fswtchParamT[i]->currentData().toInt(); - populateFuncParamCB(fswtchParamT[i], func, cfn.param); - widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM | CUSTOM_FUNCTION_REPEAT; - } - else if (func == FuncPlayPrompt || func == FuncPlayBoth) { - if (firmware->getCapability(VoicesAsNumbers)) { - fswtchParam[i]->setDecimals(0); - fswtchParam[i]->setSingleStep(1); - fswtchParam[i]->setMinimum(0); - if (func == FuncPlayPrompt) { - widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM | CUSTOM_FUNCTION_REPEAT | CUSTOM_FUNCTION_GV_TOOGLE; - } - else { - widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM | CUSTOM_FUNCTION_REPEAT; - fswtchParamGV[i]->setChecked(false); - } - fswtchParam[i]->setMaximum(func == FuncPlayBoth ? 254 : 255); - if (modified) { - if (fswtchParamGV[i]->isChecked()) { - fswtchParam[i]->setMinimum(1); - cfn.param = std::min(fswtchParam[i]->value(),5.0)+(fswtchParamGV[i]->isChecked() ? 250 : 0); - } - else { - cfn.param = fswtchParam[i]->value(); - } - } - if (cfn.param>250 && (func!=FuncPlayBoth)) { - fswtchParamGV[i]->setChecked(true); - fswtchParam[i]->setValue(cfn.param-250); - fswtchParam[i]->setMaximum(5); - } - else { - fswtchParamGV[i]->setChecked(false); - fswtchParam[i]->setValue(cfn.param); - } - if (cfn.param < 251) - widgetsMask |= CUSTOM_FUNCTION_PLAY; + else if (func == FuncPlayPrompt || func == FuncPlayBoth) { + if (firmware->getCapability(VoicesAsNumbers)) { + fswtchParam[i]->setDecimals(0); + fswtchParam[i]->setSingleStep(1); + fswtchParam[i]->setMinimum(0); + if (func == FuncPlayPrompt) { + widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM | CUSTOM_FUNCTION_REPEAT | CUSTOM_FUNCTION_GV_TOOGLE; } else { - widgetsMask |= CUSTOM_FUNCTION_FILE_PARAM; - if (modified) { - Helpers::getFileComboBoxValue(fswtchParamArmT[i], cfn.paramarm, firmware->getCapability(VoicesMaxLength)); + widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM | CUSTOM_FUNCTION_REPEAT; + fswtchParamGV[i]->setChecked(false); + } + fswtchParam[i]->setMaximum(func == FuncPlayBoth ? 254 : 255); + if (modified) { + if (fswtchParamGV[i]->isChecked()) { + fswtchParam[i]->setMinimum(1); + cfn.param = std::min(fswtchParam[i]->value(),5.0)+(fswtchParamGV[i]->isChecked() ? 250 : 0); } - Helpers::populateFileComboBox(fswtchParamArmT[i], tracksSet, cfn.paramarm); - if (fswtchParamArmT[i]->currentText() != "----") { - widgetsMask |= CUSTOM_FUNCTION_PLAY; + else { + cfn.param = fswtchParam[i]->value(); } } + if (cfn.param > 250 && (func != FuncPlayBoth)) { + fswtchParamGV[i]->setChecked(true); + fswtchParam[i]->setValue(cfn.param - 250); + fswtchParam[i]->setMaximum(5); + } + else { + fswtchParamGV[i]->setChecked(false); + fswtchParam[i]->setValue(cfn.param); + } + if (cfn.param < 251) + widgetsMask |= CUSTOM_FUNCTION_PLAY; } - else if (func == FuncBackgroundMusic) { + else { widgetsMask |= CUSTOM_FUNCTION_FILE_PARAM; if (modified) { Helpers::getFileComboBoxValue(fswtchParamArmT[i], cfn.paramarm, firmware->getCapability(VoicesMaxLength)); @@ -534,58 +520,68 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) widgetsMask |= CUSTOM_FUNCTION_PLAY; } } - else if (func == FuncPlaySound) { - if (modified) - cfn.param = (uint8_t)fswtchParamT[i]->currentIndex(); - populateFuncParamCB(fswtchParamT[i], func, cfn.param); - widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM; - } - else if (func == FuncPlayHaptic) { - if (modified) - cfn.param = (uint8_t)fswtchParamT[i]->currentIndex(); - populateFuncParamCB(fswtchParamT[i], func, cfn.param); - widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM; - } } - else if (func == FuncPlayScript) { + else if (func == FuncBackgroundMusic) { widgetsMask |= CUSTOM_FUNCTION_FILE_PARAM; if (modified) { - Helpers::getFileComboBoxValue(fswtchParamArmT[i], cfn.paramarm, 8); + Helpers::getFileComboBoxValue(fswtchParamArmT[i], cfn.paramarm, firmware->getCapability(VoicesMaxLength)); + } + Helpers::populateFileComboBox(fswtchParamArmT[i], tracksSet, cfn.paramarm); + if (fswtchParamArmT[i]->currentText() != "----") { + widgetsMask |= CUSTOM_FUNCTION_PLAY; } - Helpers::populateFileComboBox(fswtchParamArmT[i], scriptsSet, cfn.paramarm); } - else { + else if (func == FuncPlaySound) { if (modified) - cfn.param = fswtchParam[i]->value(); - fswtchParam[i]->setDecimals(0); - fswtchParam[i]->setSingleStep(1); - fswtchParam[i]->setValue(cfn.param); - if (func <= FuncInstantTrim) { - widgetsMask |= CUSTOM_FUNCTION_ENABLE; - } + cfn.param = (uint8_t)fswtchParamT[i]->currentIndex(); + populateFuncParamCB(fswtchParamT[i], func, cfn.param); + widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM; + } + else if (func == FuncPlayHaptic) { + if (modified) + cfn.param = (uint8_t)fswtchParamT[i]->currentIndex(); + populateFuncParamCB(fswtchParamT[i], func, cfn.param); + widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM; } } + else if (func == FuncPlayScript) { + widgetsMask |= CUSTOM_FUNCTION_FILE_PARAM; + if (modified) { + Helpers::getFileComboBoxValue(fswtchParamArmT[i], cfn.paramarm, 8); + } + Helpers::populateFileComboBox(fswtchParamArmT[i], scriptsSet, cfn.paramarm); + } + else { + if (modified) + cfn.param = fswtchParam[i]->value(); + fswtchParam[i]->setDecimals(0); + fswtchParam[i]->setSingleStep(1); + fswtchParam[i]->setValue(cfn.param); + if (func <= FuncInstantTrim) { + widgetsMask |= CUSTOM_FUNCTION_ENABLE; + } + } + } - fswtchFunc[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_SHOW_FUNC); - fswtchParam[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_NUMERIC_PARAM); - fswtchParamTime[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_TIME_PARAM); - fswtchParamGV[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_GV_TOOGLE); - fswtchParamT[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_SOURCE_PARAM); - fswtchParamArmT[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_FILE_PARAM); - fswtchEnable[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_ENABLE); - if (widgetsMask & CUSTOM_FUNCTION_ENABLE) - fswtchEnable[i]->setChecked(cfn.enabled); - else - fswtchEnable[i]->setChecked(false); - fswtchRepeat[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_REPEAT); - fswtchGVmode[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_GV_MODE); - fswtchBLcolor[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_BL_COLOR); - playBT[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_PLAY); + fswtchFunc[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_SHOW_FUNC); + fswtchParam[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_NUMERIC_PARAM); + fswtchParamTime[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_TIME_PARAM); + fswtchParamGV[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_GV_TOOGLE); + fswtchParamT[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_SOURCE_PARAM); + fswtchParamArmT[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_FILE_PARAM); + fswtchEnable[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_ENABLE); + if (widgetsMask & CUSTOM_FUNCTION_ENABLE) + fswtchEnable[i]->setChecked(cfn.enabled); + else + fswtchEnable[i]->setChecked(false); + fswtchRepeat[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_REPEAT); + fswtchGVmode[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_GV_MODE); + fswtchBLcolor[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_BL_COLOR); + playBT[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_PLAY); } void CustomFunctionsPanel::update() { - updateDataModels(); lock = true; for (int i = 0; i < fswCapability; i++) { refreshCustomFunction(i); @@ -660,16 +656,16 @@ void CustomFunctionsPanel::populateFuncCB(QComboBox *b, unsigned int value) { b->clear(); for (unsigned int i = 0; i < FuncCount; i++) { - if (((i>=FuncOverrideCH1 && i<=FuncOverrideCH32) && (!model || !firmware->getCapability(SafetyChannelCustomFunction))) || - ((i==FuncVolume || i==FuncBackgroundMusic || i==FuncBackgroundMusicPause) && !firmware->getCapability(HasVolume)) || - ((i==FuncPlayScript && !IS_HORUS_OR_TARANIS(firmware->getBoard()))) || - ((i==FuncPlayHaptic) && !firmware->getCapability(Haptic)) || - ((i==FuncPlayBoth) && !firmware->getCapability(HasBeeper)) || - ((i==FuncLogs) && !firmware->getCapability(HasSDLogs)) || - ((i==FuncSetTimer3) && firmware->getCapability(Timers) < 3) || - ((i==FuncScreenshot) && !IS_HORUS_OR_TARANIS(firmware->getBoard())) || - ((i>=FuncRangeCheckInternalModule && i<=FuncBindExternalModule) && (!model || !firmware->getCapability(DangerousFunctions))) || - ((i>=FuncAdjustGV1 && i<=FuncAdjustGVLast) && (!model || !firmware->getCapability(Gvars))) + if (((i >= FuncOverrideCH1 && i <= FuncOverrideCH32) && (!model || !firmware->getCapability(SafetyChannelCustomFunction))) || + ((i == FuncVolume || i == FuncBackgroundMusic || i == FuncBackgroundMusicPause) && !firmware->getCapability(HasVolume)) || + ((i == FuncPlayScript && !IS_HORUS_OR_TARANIS(firmware->getBoard()))) || + ((i == FuncPlayHaptic) && !firmware->getCapability(Haptic)) || + ((i == FuncPlayBoth) && !firmware->getCapability(HasBeeper)) || + ((i == FuncLogs) && !firmware->getCapability(HasSDLogs)) || + ((i == FuncSetTimer3) && firmware->getCapability(Timers) < 3) || + ((i == FuncScreenshot) && !IS_HORUS_OR_TARANIS(firmware->getBoard())) || + ((i >= FuncRangeCheckInternalModule && i <= FuncBindExternalModule) && (!model || !firmware->getCapability(DangerousFunctions))) || + ((i >= FuncAdjustGV1 && i <= FuncAdjustGVLast) && (!model || !firmware->getCapability(Gvars))) ) { // skipped continue; @@ -711,21 +707,21 @@ void CustomFunctionsPanel::populateFuncParamCB(QComboBox *b, uint function, unsi CustomFunctionData::populateResetParams(model, b, value); } else if (function == FuncVolume || function == FuncBacklight) { - b->setModel(rawSrcInputsItemModel); + b->setModel(rawSourceInputsModel); b->setCurrentIndex(b->findData(value)); } else if (function == FuncPlayValue) { - b->setModel(rawSrcAllItemModel); + b->setModel(rawSourceAllModel); b->setCurrentIndex(b->findData(value)); } else if (function >= FuncAdjustGV1 && function <= FuncAdjustGVLast) { switch (adjustmode) { case 1: - b->setModel(rawSrcInputsItemModel); + b->setModel(rawSourceInputsModel); b->setCurrentIndex(b->findData(value)); break; case 2: - b->setModel(rawSrcGVarsItemModel); + b->setModel(rawSourceGVarsModel); b->setCurrentIndex(b->findData(value)); break; } @@ -830,3 +826,23 @@ bool CustomFunctionsPanel::moveUpAllowed() const { return selectedIndex > 0; } + +void CustomFunctionsPanel::onModelDataAboutToBeUpdated() +{ + lock = true; + modelsUpdateCnt++; +} + +void CustomFunctionsPanel::onModelDataUpdateComplete() +{ + modelsUpdateCnt--; + if (modelsUpdateCnt < 1) { + lock = true; + for (int i = 0; i < fswCapability; i++) { + fswtchSwtch[i]->setCurrentIndex(fswtchSwtch[i]->findData(functions[i].swtch.toValue())); + fswtchFunc[i]->setCurrentIndex(fswtchFunc[i]->findData(functions[i].func)); + } + update(); + lock = false; + } +} diff --git a/companion/src/modeledit/customfunctions.h b/companion/src/modeledit/customfunctions.h index 54a83ddcf..9b3e3d238 100644 --- a/companion/src/modeledit/customfunctions.h +++ b/companion/src/modeledit/customfunctions.h @@ -26,8 +26,8 @@ #include -class RawSourceFilterItemModel; -class RawSwitchFilterItemModel; +class CommonItemModels; +class RawItemFilteredModel; class TimerEdit; constexpr char MIMETYPE_CUSTOM_FUNCTION[] = "application/x-companion-custom-function"; @@ -55,7 +55,7 @@ class CustomFunctionsPanel : public GenericPanel Q_OBJECT public: - CustomFunctionsPanel(QWidget *parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware); + CustomFunctionsPanel(QWidget *parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels); ~CustomFunctionsPanel(); virtual void update(); @@ -64,12 +64,11 @@ class CustomFunctionsPanel : public GenericPanel CustomFunctionData * functions; private slots: - void updateDataModels(); void customFunctionEdited(); void functionEdited(); void onCustomContextMenuRequested(QPoint pos); void refreshCustomFunction(int index, bool modified=false); - void onChildModified(); + void onRepeatModified(); bool playSound(int index); void stopSound(int index); void toggleSound(bool play); @@ -84,6 +83,8 @@ class CustomFunctionsPanel : public GenericPanel void cmInsert(); void cmClear(bool prompt = true); void cmClearAll(); + void onModelDataAboutToBeUpdated(); + void onModelDataUpdateComplete(); private: void populateFuncCB(QComboBox *b, unsigned int value); @@ -95,10 +96,11 @@ class CustomFunctionsPanel : public GenericPanel bool moveUpAllowed() const; void swapData(int idx1, int idx2); void resetCBsAndRefresh(int idx); - RawSwitchFilterItemModel * rawSwitchItemModel; - RawSourceFilterItemModel * rawSrcAllItemModel; - RawSourceFilterItemModel * rawSrcInputsItemModel; - RawSourceFilterItemModel * rawSrcGVarsItemModel; + CommonItemModels * commonItemModels; + RawItemFilteredModel * rawSwitchFilteredModel; + RawItemFilteredModel * rawSourceAllModel; + RawItemFilteredModel * rawSourceInputsModel; + RawItemFilteredModel * rawSourceGVarsModel; QSet tracksSet; QSet scriptsSet; @@ -119,7 +121,7 @@ class CustomFunctionsPanel : public GenericPanel int selectedIndex; int fswCapability; - + int modelsUpdateCnt; }; #endif // _CUSTOMFUNCTIONS_H_ diff --git a/companion/src/modeledit/expodialog.cpp b/companion/src/modeledit/expodialog.cpp index 95aaeca66..5206fc08a 100644 --- a/companion/src/modeledit/expodialog.cpp +++ b/companion/src/modeledit/expodialog.cpp @@ -24,7 +24,8 @@ #include "helpers.h" ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, GeneralSettings & generalSettings, - Firmware * firmware, QString & inputName) : + Firmware * firmware, QString & inputName, RawItemFilteredModel * rawSourceModel, + RawItemFilteredModel * rawSwitchModel) : QDialog(parent), ui(new Ui::ExpoDialog), model(model), @@ -36,9 +37,10 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G lock(false) { ui->setupUi(this); - QLabel * lb_fp[CPN_MAX_FLIGHT_MODES] = {ui->lb_FP0,ui->lb_FP1,ui->lb_FP2,ui->lb_FP3,ui->lb_FP4,ui->lb_FP5,ui->lb_FP6,ui->lb_FP7,ui->lb_FP8 }; - QCheckBox * tmp[CPN_MAX_FLIGHT_MODES] = {ui->cb_FP0,ui->cb_FP1,ui->cb_FP2,ui->cb_FP3,ui->cb_FP4,ui->cb_FP5,ui->cb_FP6,ui->cb_FP7,ui->cb_FP8 }; - for (int i=0; ilb_FP0, ui->lb_FP1, ui->lb_FP2, ui->lb_FP3, ui->lb_FP4, ui->lb_FP5, ui->lb_FP6, ui->lb_FP7, ui->lb_FP8 }; + QCheckBox * tmp[CPN_MAX_FLIGHT_MODES] = {ui->cb_FP0, ui->cb_FP1, ui->cb_FP2, ui->cb_FP3, ui->cb_FP4, ui->cb_FP5, ui->cb_FP6, ui->cb_FP7, ui->cb_FP8 }; + for (int i = 0; i < CPN_MAX_FLIGHT_MODES; i++) { cb_fp[i] = tmp[i]; } @@ -52,14 +54,14 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G curveGroup = new CurveGroup(ui->curveTypeCB, ui->curveGVarCB, ui->curveValueCB, ui->curveValueSB, ed->curve, model, firmware->getCapability(HasInputDiff) ? 0 : (HIDE_DIFF | HIDE_NEGATIVE_CURVES)); - ui->switchesCB->setModel(new RawSwitchFilterItemModel(&generalSettings, &model, RawSwitch::MixesContext, this)); + ui->switchesCB->setModel(rawSwitchModel); ui->switchesCB->setCurrentIndex(ui->switchesCB->findData(ed->swtch.toValue())); - ui->sideCB->setCurrentIndex(ed->mode-1); + ui->sideCB->setCurrentIndex(ed->mode - 1); if (!firmware->getCapability(FlightModes)) { ui->label_phases->hide(); - for (int i=0; ihide(); cb_fp[i]->hide(); } @@ -69,13 +71,13 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G ui->label_phases->setContextMenuPolicy(Qt::CustomContextMenu); connect(ui->label_phases, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(label_phases_customContextMenuRequested(const QPoint &))); int mask = 1; - for (int i=0; iflightModes & mask) == 0) { cb_fp[i]->setChecked(true); } mask <<= 1; } - for (int i=firmware->getCapability(FlightModes); igetCapability(FlightModes); i < CPN_MAX_FLIGHT_MODES; i++) { lb_fp[i]->hide(); cb_fp[i]->hide(); } @@ -83,9 +85,8 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G if (firmware->getCapability(VirtualInputs)) { ui->inputName->setMaxLength(firmware->getCapability(InputsLength)); - ui->sourceCB->setModel(new RawSourceFilterItemModel(&generalSettings, &model, (RawSource::InputSourceGroups & ~RawSource::InputsGroup) | RawSource::TelemGroup, this)); + ui->sourceCB->setModel(rawSourceModel); ui->sourceCB->setCurrentIndex(ui->sourceCB->findData(ed->srcRaw.toValue())); - ui->sourceCB->removeItem(0); ui->inputName->setValidator(new QRegExpValidator(rx, this)); ui->inputName->setText(inputName); } @@ -98,8 +99,8 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G ui->trimCB->hide(); } - for(int i=0; i < getBoardCapability(getCurrentBoard(), Board::NumTrims); i++) { - ui->trimCB->addItem(RawSource(SOURCE_TYPE_TRIM, i).toString(), i+1); + for(int i = 0; i < getBoardCapability(getCurrentBoard(), Board::NumTrims); i++) { + ui->trimCB->addItem(RawSource(SOURCE_TYPE_TRIM, i).toString(), i + 1); } ui->trimCB->setCurrentIndex(1 - ed->carryTrim); @@ -124,7 +125,7 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G connect(ui->trimCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesChanged())); connect(ui->switchesCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesChanged())); connect(ui->sideCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesChanged())); - for (int i=0; igetCapability(VirtualInputs)) { @@ -181,7 +182,7 @@ void ExpoDialog::valuesChanged() } ed->flightModes = 0; - for (int i=CPN_MAX_FLIGHT_MODES-1; i>=0 ; i--) { + for (int i = CPN_MAX_FLIGHT_MODES - 1; i >= 0 ; i--) { if (!cb_fp[i]->checkState()) { ed->flightModes++; } @@ -212,7 +213,7 @@ void ExpoDialog::label_phases_customContextMenuRequested(const QPoint & pos) void ExpoDialog::fmClearAll() { lock = true; - for (int i=0; isetChecked(false); } lock = false; @@ -222,7 +223,7 @@ void ExpoDialog::fmClearAll() void ExpoDialog::fmSetAll() { lock = true; - for (int i=0; isetChecked(true); } lock = false; @@ -232,7 +233,7 @@ void ExpoDialog::fmSetAll() void ExpoDialog::fmInvertAll() { lock = true; - for (int i=0; isetChecked(!cb_fp[i]->isChecked()); } lock = false; diff --git a/companion/src/modeledit/expodialog.h b/companion/src/modeledit/expodialog.h index e1355e147..8bd0f52e4 100644 --- a/companion/src/modeledit/expodialog.h +++ b/companion/src/modeledit/expodialog.h @@ -27,6 +27,7 @@ class GVarGroup; class CurveGroup; +class RawItemFilteredModel; namespace Ui { class ExpoDialog; @@ -36,7 +37,8 @@ class ExpoDialog : public QDialog { Q_OBJECT public: ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expodata, GeneralSettings & generalSettings, - Firmware * firmware, QString & inputName); + Firmware * firmware, QString & inputName, RawItemFilteredModel * rawSourceItemModel, + RawItemFilteredModel * rawSwitchItemModel); ~ExpoDialog(); protected: diff --git a/companion/src/modeledit/flightmodes.cpp b/companion/src/modeledit/flightmodes.cpp index 12082091d..32188feea 100644 --- a/companion/src/modeledit/flightmodes.cpp +++ b/companion/src/modeledit/flightmodes.cpp @@ -24,14 +24,15 @@ #include "helpers.h" #include "customdebug.h" -FlightModePanel::FlightModePanel(QWidget * parent, ModelData & model, int phaseIdx, GeneralSettings & generalSettings, Firmware * firmware, RawSwitchFilterItemModel * switchModel): +FlightModePanel::FlightModePanel(QWidget * parent, ModelData & model, int phaseIdx, GeneralSettings & generalSettings, Firmware * firmware, RawItemFilteredModel * rawSwitchFilteredModel): ModelPanel(parent, model, generalSettings, firmware), ui(new Ui::FlightMode), phaseIdx(phaseIdx), - phase(model.flightModeData[phaseIdx]), - rawSwitchItemModel(NULL) + phase(model.flightModeData[phaseIdx]) { ui->setupUi(this); + connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &FlightModePanel::onModelDataAboutToBeUpdated); + connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &FlightModePanel::onModelDataUpdateComplete); ui->labelName->setContextMenuPolicy(Qt::CustomContextMenu); ui->labelName->setToolTip(tr("Popup menu available")); @@ -56,8 +57,8 @@ FlightModePanel::FlightModePanel(QWidget * parent, ModelData & model, int phaseI // Flight mode switch if (phaseIdx > 0) { - ui->swtch->setModel(switchModel); - connect(ui->swtch, SIGNAL(activated(int)), this, SLOT(phaseSwitchChanged(int))); + ui->swtch->setModel(rawSwitchFilteredModel); + connect(ui->swtch, SIGNAL(currentIndexChanged(int)), this, SLOT(phaseSwitch_currentIndexChanged(int))); } else { ui->swtch->hide(); @@ -316,8 +317,6 @@ void FlightModePanel::update() for (int i = 0; i < reCount; i++) { updateRotaryEncoder(i); } - - emit nameModified(); } void FlightModePanel::updateGVar(int index) @@ -390,17 +389,18 @@ void FlightModePanel::phaseName_editingFinished() { QLineEdit *lineEdit = qobject_cast(sender()); strcpy(phase.name, lineEdit->text().toLatin1()); + emit phaseNameChanged(); emit modified(); - emit nameModified(); } -void FlightModePanel::phaseSwitchChanged(int index) +void FlightModePanel::phaseSwitch_currentIndexChanged(int index) { if (!lock) { bool ok; const RawSwitch rs(ui->swtch->itemData(index).toInt(&ok)); if (ok && phase.swtch.toValue() != rs.toValue()) { phase.swtch = rs; + emit phaseSwitchChanged(); emit modified(); } } @@ -457,7 +457,7 @@ void FlightModePanel::phaseGVValue_editingFinished() QDoubleSpinBox *spinBox = qobject_cast(sender()); int gvar = spinBox->property("index").toInt(); phase.gvars[gvar] = spinBox->value() * model->gvarData[gvar].multiplierSet(); - emit datachanged(); + updateGVar(gvar); emit modified(); } } @@ -469,7 +469,7 @@ void FlightModePanel::GVName_editingFinished() int gvar = lineedit->property("index").toInt(); memset(&model->gvarData[gvar].name, 0, sizeof(model->gvarData[gvar].name)); strcpy(model->gvarData[gvar].name, lineedit->text().toLatin1()); - emit datachanged(); + emit gvNameChanged(); emit modified(); } } @@ -488,7 +488,7 @@ void FlightModePanel::phaseGVUse_currentIndexChanged(int index) } if (model->isGVarLinkedCircular(phaseIdx, gvar)) QMessageBox::warning(this, "Companion", tr("Warning: Global variable links back to itself. Flight Mode 0 value used.")); - emit datachanged(); + updateGVar(gvar); emit modified(); lock = false; } @@ -500,7 +500,7 @@ void FlightModePanel::phaseGVUnit_currentIndexChanged(int index) QComboBox *comboBox = qobject_cast(sender()); int gvar = comboBox->property("index").toInt(); model->gvarData[gvar].unit = index; - emit datachanged(); + updateGVar(gvar); emit modified(); } } @@ -511,7 +511,7 @@ void FlightModePanel::phaseGVPrec_currentIndexChanged(int index) QComboBox *comboBox = qobject_cast(sender()); int gvar = comboBox->property("index").toInt(); model->gvarData[gvar].prec = index; - emit datachanged(); + updateGVar(gvar); emit modified(); } } @@ -534,7 +534,7 @@ void FlightModePanel::phaseGVMin_editingFinished() } } } - emit datachanged(); + updateGVar(gvar); emit modified(); } } @@ -557,7 +557,7 @@ void FlightModePanel::phaseGVMax_editingFinished() } } } - emit datachanged(); + updateGVar(gvar); emit modified(); } } @@ -741,7 +741,8 @@ void FlightModePanel::cmClear(bool prompt) model->updateAllReferences(ModelData::REF_UPD_TYPE_FLIGHT_MODE, ModelData::REF_UPD_ACT_CLEAR, phaseIdx); - emit datachanged(); + update(); + emit phaseDataChanged(); emit modified(); } @@ -767,7 +768,7 @@ void FlightModePanel::cmClearAll() model->updateAllReferences(ModelData::REF_UPD_TYPE_GLOBAL_VARIABLE, ModelData::REF_UPD_ACT_CLEAR, i); } - emit datachanged(); + emit phaseDataChanged(); emit modified(); } @@ -846,7 +847,7 @@ void FlightModePanel::cmDelete() model->updateAllReferences(ModelData::REF_UPD_TYPE_FLIGHT_MODE, ModelData::REF_UPD_ACT_SHIFT, phaseIdx, 0, -1); - emit datachanged(); + emit phaseDataChanged(); emit modified(); } @@ -897,7 +898,7 @@ void FlightModePanel::cmInsert() model->updateAllReferences(ModelData::REF_UPD_TYPE_FLIGHT_MODE, ModelData::REF_UPD_ACT_SHIFT, phaseIdx, 0, 1); - emit datachanged(); + emit phaseDataChanged(); emit modified(); } @@ -946,7 +947,7 @@ void FlightModePanel::cmPaste() } } - emit datachanged(); + emit phaseDataChanged(); emit modified(); } } @@ -1035,7 +1036,7 @@ void FlightModePanel::swapData(int idx1, int idx2) } model->updateAllReferences(ModelData::REF_UPD_TYPE_FLIGHT_MODE, ModelData::REF_UPD_ACT_SWAP, idx1, idx2); - emit datachanged(); + emit phaseDataChanged(); emit modified(); } @@ -1162,7 +1163,8 @@ void FlightModePanel::gvCmClear(bool prompt) } phase.gvars[gvIdx] = phase.linkedGVarFlightModeZero(phaseIdx); } - emit datachanged(); + updateGVar(gvIdx); + emit gvNameChanged(); emit modified(); } @@ -1186,7 +1188,10 @@ void FlightModePanel::gvCmClearAll() phase.gvars[i] = phase.linkedGVarFlightModeZero(phaseIdx); } } - emit datachanged(); + for (int i = 0; i < gvCount; i++) { + updateGVar(i); + } + emit gvNameChanged(); emit modified(); } @@ -1261,8 +1266,13 @@ void FlightModePanel::gvCmDelete() for (int j = 0; j < fmCount; j++) { model->flightModeData[j].gvars[maxidx] = model->flightModeData[j].linkedGVarFlightModeZero(j); } + model->updateAllReferences(ModelData::REF_UPD_TYPE_GLOBAL_VARIABLE, ModelData::REF_UPD_ACT_SHIFT, gvIdx, 0, -1); - emit datachanged(); + + for (int i = 0; i < gvCount; i++) { + updateGVar(i); + } + emit gvNameChanged(); emit modified(); } @@ -1279,7 +1289,10 @@ void FlightModePanel::gvCmInsert() model->flightModeData[j].gvars[gvIdx] = model->flightModeData[j].linkedGVarFlightModeZero(j); } model->updateAllReferences(ModelData::REF_UPD_TYPE_GLOBAL_VARIABLE, ModelData::REF_UPD_ACT_SHIFT, gvIdx, 0, 1); - emit datachanged(); + for (int i = 0; i < gvCount; i++) { + updateGVar(i); + } + emit gvNameChanged(); emit modified(); } @@ -1322,7 +1335,8 @@ void FlightModePanel::gvCmPaste() else phase.gvars[gvIdx] = val; } - emit datachanged(); + updateGVar(gvIdx); + emit gvNameChanged(); emit modified(); } @@ -1340,33 +1354,51 @@ void FlightModePanel::gvSwapData(int idx1, int idx2) model->flightModeData[j].gvars[idx1] = valtmp; } model->updateAllReferences(ModelData::REF_UPD_TYPE_GLOBAL_VARIABLE, ModelData::REF_UPD_ACT_SWAP, idx1, idx2); - emit datachanged(); + updateGVar(idx1); + updateGVar(idx2); + emit gvNameChanged(); emit modified(); } } +void FlightModePanel::onModelDataAboutToBeUpdated() +{ + lock = true; +} + +void FlightModePanel::onModelDataUpdateComplete() +{ + update(); + lock = false; +} + /**********************************************************/ -FlightModesPanel::FlightModesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware): +FlightModesPanel::FlightModesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels): ModelPanel(parent, model, generalSettings, firmware), - modesCount(firmware->getCapability(FlightModes)) + commonItemModels(commonItemModels) { - - RawSwitchFilterItemModel * swModel = new RawSwitchFilterItemModel(&generalSettings, &model, RawSwitch::MixesContext, this); - connect(this, &FlightModesPanel::updated, swModel, &RawSwitchFilterItemModel::update); + rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), RawSwitch::MixesContext, this); + modesCount = firmware->getCapability(FlightModes); QGridLayout * gridLayout = new QGridLayout(this); tabWidget = new QTabWidget(this); for (int i = 0; i < modesCount; i++) { - FlightModePanel * tab = new FlightModePanel(tabWidget, model, i, generalSettings, firmware, swModel); + FlightModePanel * tab = new FlightModePanel(tabWidget, model, i, generalSettings, firmware, rawSwitchFilteredModel); tab->setProperty("index", i); - connect(tab, &FlightModePanel::datachanged, this, &FlightModesPanel::update); - connect(tab, &FlightModePanel::modified, this, &FlightModesPanel::modified); - connect(tab, &FlightModePanel::nameModified, this, &FlightModesPanel::onPhaseNameChanged); - connect(this, &FlightModesPanel::updated, tab, &FlightModePanel::update); + connect(tab, &FlightModePanel::modified, this, &FlightModesPanel::modified); + connect(tab, &FlightModePanel::phaseDataChanged, this, &FlightModesPanel::onPhaseNameChanged); + connect(tab, &FlightModePanel::phaseNameChanged, this, &FlightModesPanel::onPhaseNameChanged); + connect(tab, &FlightModePanel::phaseSwitchChanged, this, &FlightModesPanel::updateItemModels); + connect(tab, &FlightModePanel::gvNameChanged, this, &FlightModesPanel::updateItemModels); + + connect(this, &FlightModesPanel::updated, tab, &FlightModePanel::update); tabWidget->addTab(tab, getTabName(i)); + panels << tab; } + connect(tabWidget, &QTabWidget::currentChanged, this, &FlightModesPanel::onTabIndexChanged); gridLayout->addWidget(tabWidget, 0, 0, 1, 1); + onTabIndexChanged(0); } FlightModesPanel::~FlightModesPanel() @@ -1391,9 +1423,22 @@ void FlightModesPanel::onPhaseNameChanged() { int index = sender()->property("index").toInt(); tabWidget->setTabText(index, getTabName(index)); + updateItemModels(); } void FlightModesPanel::update() { emit updated(); } + +void FlightModesPanel::updateItemModels() +{ + commonItemModels->update(CommonItemModels::RMO_FLIGHT_MODES); + commonItemModels->update(CommonItemModels::RMO_GLOBAL_VARIABLES); +} + +void FlightModesPanel::onTabIndexChanged(int index) +{ + if (index < panels.size()) + panels.at(index)->update(); +} diff --git a/companion/src/modeledit/flightmodes.h b/companion/src/modeledit/flightmodes.h index 61e25c59a..ca3619c6c 100644 --- a/companion/src/modeledit/flightmodes.h +++ b/companion/src/modeledit/flightmodes.h @@ -24,7 +24,8 @@ #include "modeledit.h" #include "eeprominterface.h" -class RawSwitchFilterItemModel; +class CommonItemModels; +class RawItemFilteredModel; constexpr char MIMETYPE_FLIGHTMODE[] = "application/x-companion-flightmode"; constexpr char MIMETYPE_GVAR_PARAMS[] = "application/x-companion-gvar-params"; @@ -40,18 +41,20 @@ class FlightModePanel : public ModelPanel Q_OBJECT public: - FlightModePanel(QWidget *parent, ModelData &model, int modeIdx, GeneralSettings & generalSettings, Firmware * firmware, RawSwitchFilterItemModel * switchModel); + FlightModePanel(QWidget *parent, ModelData &model, int modeIdx, GeneralSettings & generalSettings, Firmware * firmware, RawItemFilteredModel * rawSwitchFilteredModel); virtual ~FlightModePanel(); virtual void update(); signals: - void nameModified(); - void datachanged(); + void gvNameChanged(); + void phaseDataChanged(); + void phaseNameChanged(); + void phaseSwitchChanged(); private slots: void phaseName_editingFinished(); - void phaseSwitchChanged(int index); + void phaseSwitch_currentIndexChanged(int index); void phaseFadeIn_editingFinished(); void phaseFadeOut_editingFinished(); void phaseTrimUse_currentIndexChanged(int index); @@ -87,6 +90,8 @@ class FlightModePanel : public ModelPanel void gvCmPaste(); void gvCmMoveDown(); void gvCmMoveUp(); + void onModelDataAboutToBeUpdated(); + void onModelDataUpdateComplete(); private: Ui::FlightMode *ui; @@ -111,7 +116,6 @@ class FlightModePanel : public ModelPanel QVector trimsUse; QVector trimsValue; QVector trimsSlider; - RawSwitchFilterItemModel * rawSwitchItemModel; Board::Type board; void trimUpdate(unsigned int trim); @@ -141,7 +145,7 @@ class FlightModesPanel : public ModelPanel Q_OBJECT public: - FlightModesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware); + FlightModesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels); virtual ~FlightModesPanel(); public slots: @@ -152,13 +156,17 @@ class FlightModesPanel : public ModelPanel private slots: void onPhaseNameChanged(); + void onTabIndexChanged(int index); private: QString getTabName(int index); int modesCount; QTabWidget *tabWidget; - + CommonItemModels *commonItemModels; + RawItemFilteredModel *rawSwitchFilteredModel; + QVector panels; + void updateItemModels(); }; #endif // _FLIGHTMODES_H_ diff --git a/companion/src/modeledit/heli.cpp b/companion/src/modeledit/heli.cpp index c0a4e39d8..1b8607799 100644 --- a/companion/src/modeledit/heli.cpp +++ b/companion/src/modeledit/heli.cpp @@ -23,19 +23,26 @@ #include "helpers.h" #include "rawitemfilteredmodel.h" -HeliPanel::HeliPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware): +HeliPanel::HeliPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels): ModelPanel(parent, model, generalSettings, firmware), - ui(new Ui::Heli) + ui(new Ui::Heli), + commonItemModels(commonItemModels) { ui->setupUi(this); - rawSourceItemModel = new RawSourceFilterItemModel(&generalSettings, &model, RawSource::InputSourceGroups, this); + rawSourceFilteredModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), RawSource::InputSourceGroups, this); + connect(rawSourceFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &HeliPanel::onModelDataAboutToBeUpdated); + connect(rawSourceFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &HeliPanel::onModelDataUpdateComplete); connect(ui->swashType, SIGNAL(currentIndexChanged(int)), this, SLOT(edited())); connect(ui->swashRingVal, SIGNAL(editingFinished()), this, SLOT(edited())); + ui->swashCollectiveSource->setModel(rawSourceFilteredModel); connect(ui->swashCollectiveSource, SIGNAL(currentIndexChanged(int)), this, SLOT(edited())); + if (firmware->getCapability(VirtualInputs)) { + ui->swashAileronSource->setModel(rawSourceFilteredModel); connect(ui->swashAileronSource, SIGNAL(currentIndexChanged(int)), this, SLOT(edited())); + ui->swashElevatorSource->setModel(rawSourceFilteredModel); connect(ui->swashElevatorSource, SIGNAL(currentIndexChanged(int)), this, SLOT(edited())); connect(ui->swashAileronWeight, SIGNAL(editingFinished()), this, SLOT(edited())); connect(ui->swashElevatorWeight, SIGNAL(editingFinished()), this, SLOT(edited())); @@ -66,27 +73,15 @@ HeliPanel::~HeliPanel() delete ui; } -void HeliPanel::updateDataModels() -{ - const bool oldLock = lock; - lock = true; - rawSourceItemModel->update(); - lock = oldLock; -} - void HeliPanel::update() { lock = true; - updateDataModels(); ui->swashType->setCurrentIndex(model->swashRingData.type); - ui->swashCollectiveSource->setModel(rawSourceItemModel); ui->swashCollectiveSource->setCurrentIndex(ui->swashCollectiveSource->findData(model->swashRingData.collectiveSource.toValue())); ui->swashRingVal->setValue(model->swashRingData.value); if (firmware->getCapability(VirtualInputs)) { - ui->swashElevatorSource->setModel(rawSourceItemModel); ui->swashElevatorSource->setCurrentIndex(ui->swashElevatorSource->findData(model->swashRingData.elevatorSource.toValue())); - ui->swashAileronSource->setModel(rawSourceItemModel); ui->swashAileronSource->setCurrentIndex(ui->swashAileronSource->findData(model->swashRingData.aileronSource.toValue())); ui->swashElevatorWeight->setValue(model->swashRingData.elevatorWeight); ui->swashAileronWeight->setValue(model->swashRingData.aileronWeight); @@ -122,3 +117,14 @@ void HeliPanel::edited() emit modified(); } } + +void HeliPanel::onModelDataAboutToBeUpdated() +{ + lock = true; +} + +void HeliPanel::onModelDataUpdateComplete() +{ + update(); + lock = false; +} diff --git a/companion/src/modeledit/heli.h b/companion/src/modeledit/heli.h index 5a27c7c26..ee9a3ac36 100644 --- a/companion/src/modeledit/heli.h +++ b/companion/src/modeledit/heli.h @@ -23,7 +23,8 @@ #include "modeledit.h" -class RawSourceFilterItemModel; +class CommonItemModels; +class RawItemFilteredModel; namespace Ui { class Heli; @@ -34,17 +35,19 @@ class HeliPanel : public ModelPanel Q_OBJECT public: - HeliPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware); + HeliPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels); ~HeliPanel(); void update(); private slots: - void updateDataModels(); void edited(); + void onModelDataAboutToBeUpdated(); + void onModelDataUpdateComplete(); private: Ui::Heli *ui; - RawSourceFilterItemModel * rawSourceItemModel; + CommonItemModels * commonItemModels; + RawItemFilteredModel * rawSourceFilteredModel; }; #endif // _HELI_H_ diff --git a/companion/src/modeledit/inputs.cpp b/companion/src/modeledit/inputs.cpp index 2e65c788c..f50797260 100644 --- a/companion/src/modeledit/inputs.cpp +++ b/companion/src/modeledit/inputs.cpp @@ -21,12 +21,22 @@ #include "inputs.h" #include "expodialog.h" #include "helpers.h" +#include "rawitemfilteredmodel.h" -InputsPanel::InputsPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware): +InputsPanel::InputsPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels): ModelPanel(parent, model, generalSettings, firmware), expoInserted(false), - modelPrinter(firmware, generalSettings, model) + modelPrinter(firmware, generalSettings, model), + commonItemModels(commonItemModels) { + rawSourceFilteredModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), (RawSource::InputSourceGroups & ~ RawSource::NoneGroup & ~RawSource::InputsGroup), this); + connect(rawSourceFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &InputsPanel::onModelDataAboutToBeUpdated); + connect(rawSourceFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &InputsPanel::onModelDataUpdateComplete); + + rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), RawSwitch::MixesContext, this); + connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &InputsPanel::onModelDataAboutToBeUpdated); + connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &InputsPanel::onModelDataUpdateComplete); + inputsCount = firmware->getCapability(VirtualInputs); if (inputsCount == 0) inputsCount = CPN_MAX_STICKS; @@ -180,13 +190,14 @@ void InputsPanel::gm_openExpo(int index) if (firmware->getCapability(VirtualInputs)) inputName = model->inputNames[ed.chn]; - ExpoDialog *g = new ExpoDialog(this, *model, &ed, generalSettings, firmware, inputName); - if (g->exec()) { + ExpoDialog *dlg = new ExpoDialog(this, *model, &ed, generalSettings, firmware, inputName, rawSourceFilteredModel, rawSwitchFilteredModel); + if (dlg->exec()) { model->expoData[index] = ed; if (firmware->getCapability(VirtualInputs)) strncpy(model->inputNames[ed.chn], inputName.toLatin1().data(), INPUT_NAME_LEN); - emit modified(); update(); + updateItemModels(); + emit modified(); } else { if (expoInserted) { @@ -195,6 +206,7 @@ void InputsPanel::gm_openExpo(int index) expoInserted=false; update(); } + delete dlg; } int InputsPanel::getExpoIndex(unsigned int dch) @@ -239,8 +251,9 @@ void InputsPanel::exposDelete(bool prompt) } exposDeleteList(list, prompt); - emit modified(); update(); + updateItemModels(); + emit modified(); } void InputsPanel::exposCut() @@ -313,8 +326,9 @@ void InputsPanel::pasteExpoMimeData(const QMimeData * mimeData, int destIdx) i += sizeof(ExpoData); } - emit modified(); update(); + updateItemModels(); + emit modified(); } } @@ -481,8 +495,9 @@ void InputsPanel::moveExpoList(bool down) } } if (mod) { - emit modified(); update(); + updateItemModels(); + emit modified(); } setSelectedByExpoList(highlightList); } @@ -520,8 +535,9 @@ void InputsPanel::clearExpos() for (int i = 0; i < inputsCount; i++) { model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_CLEAR, i); } - emit modified(); update(); + updateItemModels(); + emit modified(); } } @@ -569,6 +585,7 @@ void InputsPanel::cmInputClear() } model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_CLEAR, inputIdx); update(); + updateItemModels(); emit modified(); } @@ -592,6 +609,7 @@ void InputsPanel::cmInputDelete() model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_SHIFT, inputIdx, 0, -1); update(); + updateItemModels(); emit modified(); } @@ -610,6 +628,7 @@ void InputsPanel::cmInputInsert() model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_SHIFT, inputIdx, 0, 1); update(); + updateItemModels(); emit modified(); } @@ -671,6 +690,7 @@ void InputsPanel::cmInputSwapData(int idx1, int idx2) model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_SWAP, idx1, idx2); update(); + updateItemModels(); emit modified(); } @@ -705,3 +725,19 @@ int InputsPanel::getInputIndexFromSelected() } return idx; } + +void InputsPanel::onModelDataAboutToBeUpdated() +{ + lock = true; +} + +void InputsPanel::onModelDataUpdateComplete() +{ + update(); + lock = false; +} + +void InputsPanel::updateItemModels() +{ + commonItemModels->update(CommonItemModels::RMO_INPUTS); +} diff --git a/companion/src/modeledit/inputs.h b/companion/src/modeledit/inputs.h index 9922f2873..436d61278 100644 --- a/companion/src/modeledit/inputs.h +++ b/companion/src/modeledit/inputs.h @@ -25,6 +25,9 @@ #include "mixerslistwidget.h" #include "modelprinter.h" +class CommonItemModels; +class RawItemFilteredModel; + constexpr char MIMETYPE_EXPO[] = "application/x-companion-expo"; class InputsPanel : public ModelPanel @@ -32,7 +35,7 @@ class InputsPanel : public ModelPanel Q_OBJECT public: - InputsPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware); + InputsPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels); virtual ~InputsPanel(); virtual void update(); @@ -59,6 +62,8 @@ class InputsPanel : public ModelPanel void cmInputInsert(); void cmInputMoveDown(); void cmInputMoveUp(); + void onModelDataAboutToBeUpdated(); + void onModelDataUpdateComplete(); private: bool expoInserted; @@ -67,6 +72,9 @@ class InputsPanel : public ModelPanel ModelPrinter modelPrinter; int selectedIdx; int inputIdx; + CommonItemModels * commonItemModels; + RawItemFilteredModel *rawSourceFilteredModel; + RawItemFilteredModel *rawSwitchFilteredModel; int getExpoIndex(unsigned int dch); bool gm_insertExpo(int idx); @@ -87,6 +95,7 @@ class InputsPanel : public ModelPanel bool isExpoIndex(const int index); int getIndexFromSelected(); int getInputIndexFromSelected(); + void updateItemModels(); }; #endif // _INPUTS_H_ diff --git a/companion/src/modeledit/logicalswitches.cpp b/companion/src/modeledit/logicalswitches.cpp index e70d63568..cacd5c6fd 100644 --- a/companion/src/modeledit/logicalswitches.cpp +++ b/companion/src/modeledit/logicalswitches.cpp @@ -24,16 +24,20 @@ #include -LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware): +LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels): ModelPanel(parent, model, generalSettings, firmware), - selectedIndex(0) + commonItemModels(commonItemModels), + selectedIndex(0), + modelsUpdateCnt(0) { - Stopwatch s1("LogicalSwitchesPanel"); - - rawSwitchItemModel = new RawSwitchFilterItemModel(&generalSettings, &model, RawSwitch::LogicalSwitchesContext, this); + rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), RawSwitch::LogicalSwitchesContext, this); + connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &LogicalSwitchesPanel::onModelDataAboutToBeUpdated); + connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &LogicalSwitchesPanel::onModelDataUpdateComplete); const int srcGroups = firmware->getCapability(GvarsInCS) ? 0 : (RawSource::AllSourceGroups & ~RawSource::GVarsGroup); - rawSourceItemModel = new RawSourceFilterItemModel(&generalSettings, &model, srcGroups, this); + rawSourceFilteredModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), srcGroups, this); + connect(rawSourceFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &LogicalSwitchesPanel::onModelDataAboutToBeUpdated); + connect(rawSourceFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &LogicalSwitchesPanel::onModelDataUpdateComplete); lsCapability = firmware->getCapability(LogicalSwitches); lsCapabilityExt = firmware->getCapability(LogicalSwitchesExt); @@ -45,16 +49,13 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, } TableLayout * tableLayout = new TableLayout(this, lsCapability, headerLabels); - s1.report("header"); - const int channelsMax = model.getChannelsMax(true); - lock = true; - for (int i=0; isetProperty("index", i); - label->setText(RawSwitch(SWITCH_TYPE_VIRTUAL, i+1).toString()); + label->setText(RawSwitch(SWITCH_TYPE_VIRTUAL, i + 1).toString()); label->setContextMenuPolicy(Qt::CustomContextMenu); label->setToolTip(tr("Popup menu available")); label->setMouseTracking(true); @@ -123,7 +124,8 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, // AND cbAndSwitch[i] = new QComboBox(this); cbAndSwitch[i]->setProperty("index", i); - populateAndSwitchCB(cbAndSwitch[i]); + cbAndSwitch[i]->setModel(rawSwitchFilteredModel); + cbAndSwitch[i]->setVisible(true); connect(cbAndSwitch[i], SIGNAL(currentIndexChanged(int)), this, SLOT(onAndSwitchChanged(int))); tableLayout->addWidget(i, 4, cbAndSwitch[i]); @@ -152,72 +154,63 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, } } - s1.report("added elements"); - disableMouseScrolling(); - lock = false; - update(); tableLayout->resizeColumnsToContents(); tableLayout->pushRowsUp(lsCapability+1); - s1.report("end"); } LogicalSwitchesPanel::~LogicalSwitchesPanel() { } -void LogicalSwitchesPanel::updateDataModels() -{ - const bool oldLock = lock; - lock = true; - rawSwitchItemModel->update(); - rawSourceItemModel->update(); - lock = oldLock; -} - void LogicalSwitchesPanel::onFunctionChanged() { - int i = sender()->property("index").toInt(); - unsigned newFunc = cbFunction[i]->currentData().toUInt(); + if (!lock) { + int i = sender()->property("index").toInt(); + unsigned newFunc = cbFunction[i]->currentData().toUInt(); - if (model->logicalSw[i].func == newFunc) - return; + if (model->logicalSw[i].func == newFunc) + return; - const unsigned oldFunc = model->logicalSw[i].func; - CSFunctionFamily oldFuncFamily = model->logicalSw[i].getFunctionFamily(); - model->logicalSw[i].func = newFunc; - CSFunctionFamily newFuncFamily = model->logicalSw[i].getFunctionFamily(); - - if (oldFuncFamily != newFuncFamily) { - model->logicalSw[i].clear(); + unsigned oldFunc = model->logicalSw[i].func; + CSFunctionFamily oldFuncFamily = model->logicalSw[i].getFunctionFamily(); model->logicalSw[i].func = newFunc; - if (newFuncFamily == LS_FAMILY_TIMER) { - model->logicalSw[i].val1 = -119; - model->logicalSw[i].val2 = -119; + CSFunctionFamily newFuncFamily = model->logicalSw[i].getFunctionFamily(); + + if (oldFuncFamily != newFuncFamily || newFunc == LS_FN_OFF) { + model->logicalSw[i].clear(); + model->logicalSw[i].func = newFunc; + if (newFuncFamily == LS_FAMILY_TIMER) { + model->logicalSw[i].val1 = -119; + model->logicalSw[i].val2 = -119; + } + else if (newFuncFamily == LS_FAMILY_EDGE) { + model->logicalSw[i].val2 = -129; + } } - else if (newFuncFamily == LS_FAMILY_EDGE) { - model->logicalSw[i].val2 = -129; - } - } - if (bool(oldFunc) != bool(newFunc)) - update(); - else + updateLine(i); - emit modified(); + if (oldFunc == LS_FN_OFF || newFunc == LS_FN_OFF) + updateItemModels(); + + emit modified(); + } } void LogicalSwitchesPanel::onV1Changed(int value) { if (!lock) { int i = sender()->property("index").toInt(); - model->logicalSw[i].val1 = cbSource1[i]->itemData(value).toInt(); - if (model->logicalSw[i].getFunctionFamily() == LS_FAMILY_VOFS) { - if (!offsetChangedAt(i)) - updateLine(i); - } - else { - emit modified(); + if (model->logicalSw[i].val1 != cbSource1[i]->itemData(value).toInt()) { + model->logicalSw[i].val1 = cbSource1[i]->itemData(value).toInt(); + if (model->logicalSw[i].getFunctionFamily() == LS_FAMILY_VOFS) { + if (!offsetChangedAt(i)) + updateLine(i); + } + else { + emit modified(); + } } } } @@ -226,8 +219,10 @@ void LogicalSwitchesPanel::onV2Changed(int value) { if (!lock) { int i = sender()->property("index").toInt(); - model->logicalSw[i].val2 = cbSource2[i]->itemData(value).toInt(); - emit modified(); + if (model->logicalSw[i].val2 != cbSource2[i]->itemData(value).toInt()) { + model->logicalSw[i].val2 = cbSource2[i]->itemData(value).toInt(); + emit modified(); + } } } @@ -235,8 +230,10 @@ void LogicalSwitchesPanel::onAndSwitchChanged(int value) { if (!lock) { int index = sender()->property("index").toInt(); - model->logicalSw[index].andsw = cbAndSwitch[index]->itemData(value).toInt(); - emit modified(); + if (model->logicalSw[index].andsw != cbAndSwitch[index]->itemData(value).toInt()) { + model->logicalSw[index].andsw = cbAndSwitch[index]->itemData(value).toInt(); + emit modified(); + } } } @@ -244,7 +241,7 @@ void LogicalSwitchesPanel::onDurationChanged(double duration) { if (!lock) { int index = sender()->property("index").toInt(); - model->logicalSw[index].duration = (uint8_t)round(duration*10); + model->logicalSw[index].duration = (uint8_t)round(duration * 10); emit modified(); } } @@ -253,7 +250,7 @@ void LogicalSwitchesPanel::onDelayChanged(double delay) { if (!lock) { int index = sender()->property("index").toInt(); - model->logicalSw[index].delay = (uint8_t)round(delay*10); + model->logicalSw[index].delay = (uint8_t)round(delay * 10); emit modified(); } } @@ -326,9 +323,9 @@ void LogicalSwitchesPanel::updateTimerParam(QDoubleSpinBox *sb, int timer, doubl sb->setMinimum(minimum); sb->setMaximum(175); float value = ValToTim(timer); - if (value>=60) + if (value >= 60) sb->setSingleStep(1); - else if (value>=2) + else if (value >= 2) sb->setSingleStep(0.5); else sb->setSingleStep(0.1); @@ -347,16 +344,14 @@ void LogicalSwitchesPanel::updateTimerParam(QDoubleSpinBox *sb, int timer, doubl void LogicalSwitchesPanel::updateLine(int i) { + const bool savelock = lock; lock = true; - unsigned int mask; + unsigned int mask = 0; cbFunction[i]->setCurrentIndex(cbFunction[i]->findData(model->logicalSw[i].func)); cbAndSwitch[i]->setCurrentIndex(cbAndSwitch[i]->findData(RawSwitch(model->logicalSw[i].andsw).toValue())); - if (!model->logicalSw[i].func) { - mask = 0; - } - else { + if (!model->logicalSw[i].isEmpty()) { mask = LINE_ENABLED | DELAY_ENABLED | DURATION_ENABLED; switch (model->logicalSw[i].getFunctionFamily()) @@ -367,7 +362,7 @@ void LogicalSwitchesPanel::updateLine(int i) RawSource source = RawSource(model->logicalSw[i].val1); RawSourceRange range = source.getRange(model, generalSettings, model->logicalSw[i].getRangeFlags()); double value = range.step * model->logicalSw[i].val2 + range.offset; /* TODO+source.getRawOffset(model)*/ - cbSource1[i]->setModel(rawSourceItemModel); + cbSource1[i]->setModel(rawSourceFilteredModel); cbSource1[i]->setCurrentIndex(cbSource1[i]->findData(source.toValue())); if (source.isTimeBased()) { mask |= VALUE_TO_VISIBLE; @@ -396,27 +391,27 @@ void LogicalSwitchesPanel::updateLine(int i) case LS_FAMILY_STICKY: // no break case LS_FAMILY_VBOOL: mask |= SOURCE1_VISIBLE | SOURCE2_VISIBLE; - cbSource1[i]->setModel(rawSwitchItemModel); + cbSource1[i]->setModel(rawSwitchFilteredModel); cbSource1[i]->setCurrentIndex(cbSource1[i]->findData(model->logicalSw[i].val1)); - cbSource2[i]->setModel(rawSwitchItemModel); + cbSource2[i]->setModel(rawSwitchFilteredModel); cbSource2[i]->setCurrentIndex(cbSource2[i]->findData(model->logicalSw[i].val2)); break; case LS_FAMILY_EDGE: mask |= SOURCE1_VISIBLE | VALUE2_VISIBLE | VALUE3_VISIBLE; mask &= ~DELAY_ENABLED; - cbSource1[i]->setModel(rawSwitchItemModel); + cbSource1[i]->setModel(rawSwitchFilteredModel); cbSource1[i]->setCurrentIndex(cbSource1[i]->findData(model->logicalSw[i].val1)); updateTimerParam(dsbOffset[i], model->logicalSw[i].val2, 0.0); - updateTimerParam(dsbOffset2[i], model->logicalSw[i].val2+model->logicalSw[i].val3, ValToTim(TimToVal(dsbOffset[i]->value())-1)); + updateTimerParam(dsbOffset2[i], model->logicalSw[i].val2 + model->logicalSw[i].val3, ValToTim(TimToVal(dsbOffset[i]->value()) - 1)); dsbOffset2[i]->setSuffix((model->logicalSw[i].val3) ? "" : tr(" (infinite)")); break; case LS_FAMILY_VCOMP: mask |= SOURCE1_VISIBLE | SOURCE2_VISIBLE; - cbSource1[i]->setModel(rawSourceItemModel); + cbSource1[i]->setModel(rawSourceFilteredModel); cbSource1[i]->setCurrentIndex(cbSource1[i]->findData(model->logicalSw[i].val1)); - cbSource2[i]->setModel(rawSourceItemModel); + cbSource2[i]->setModel(rawSourceFilteredModel); cbSource2[i]->setCurrentIndex(cbSource2[i]->findData(model->logicalSw[i].val2)); break; @@ -439,12 +434,12 @@ void LogicalSwitchesPanel::updateLine(int i) dsbDuration[i]->setVisible(mask & DURATION_ENABLED); dsbDelay[i]->setVisible(mask & DELAY_ENABLED); if (mask & DURATION_ENABLED) - dsbDuration[i]->setValue(model->logicalSw[i].duration/10.0); + dsbDuration[i]->setValue(model->logicalSw[i].duration / 10.0); if (mask & DELAY_ENABLED) - dsbDelay[i]->setValue(model->logicalSw[i].delay/10.0); + dsbDelay[i]->setValue(model->logicalSw[i].delay / 10.0); } - lock = false; + lock = savelock; } void LogicalSwitchesPanel::populateFunctionCB(QComboBox *b) @@ -475,7 +470,7 @@ void LogicalSwitchesPanel::populateFunctionCB(QComboBox *b) }; b->clear(); - for (int i=0; isetMaxVisibleItems(10); } -void LogicalSwitchesPanel::populateAndSwitchCB(QComboBox *b) -{ - b->setModel(rawSwitchItemModel); - b->setVisible(true); -} - void LogicalSwitchesPanel::update() { - updateDataModels(); - for (int i=0; ilogicalSw[selectedIndex], data.constData(), sizeof(LogicalSwitchData)); - updateDataModels(); updateLine(selectedIndex); + updateItemModels(); emit modified(); } } @@ -519,6 +507,7 @@ void LogicalSwitchesPanel::cmDelete() model->updateAllReferences(ModelData::REF_UPD_TYPE_LOGICAL_SWITCH, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, -1); update(); + updateItemModels(); emit modified(); } @@ -528,7 +517,7 @@ void LogicalSwitchesPanel::cmCopy() data.append((char*)&model->logicalSw[selectedIndex], sizeof(LogicalSwitchData)); QMimeData *mimeData = new QMimeData; mimeData->setData(MIMETYPE_LOGICAL_SWITCH, data); - QApplication::clipboard()->setMimeData(mimeData,QClipboard::Clipboard); + QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard); } void LogicalSwitchesPanel::cmCut() @@ -539,7 +528,6 @@ void LogicalSwitchesPanel::cmCut() cmClear(false); } -// TODO make something generic here! void LogicalSwitchesPanel::onCustomContextMenuRequested(QPoint pos) { QLabel *label = (QLabel *)sender(); @@ -608,7 +596,8 @@ void LogicalSwitchesPanel::cmClear(bool prompt) model->logicalSw[selectedIndex].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_LOGICAL_SWITCH, ModelData::REF_UPD_ACT_CLEAR, selectedIndex); - update(); + updateLine(selectedIndex); + updateItemModels(); emit modified(); } @@ -617,11 +606,12 @@ void LogicalSwitchesPanel::cmClearAll() if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear all Logical Switches. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) return; - for (int i=0; ilogicalSw[i].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_LOGICAL_SWITCH, ModelData::REF_UPD_ACT_CLEAR, i); } update(); + updateItemModels(); emit modified(); } @@ -631,6 +621,7 @@ void LogicalSwitchesPanel::cmInsert() model->logicalSw[selectedIndex].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_LOGICAL_SWITCH, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, 1); update(); + updateItemModels(); emit modified(); } @@ -643,7 +634,30 @@ void LogicalSwitchesPanel::swapData(int idx1, int idx2) memcpy(lsw2, lsw1, sizeof(LogicalSwitchData)); memcpy(lsw1, &lstmp, sizeof(LogicalSwitchData)); model->updateAllReferences(ModelData::REF_UPD_TYPE_LOGICAL_SWITCH, ModelData::REF_UPD_ACT_SWAP, idx1, idx2); - update(); + updateLine(idx1); + updateLine(idx2); + updateItemModels(); emit modified(); } } + +void LogicalSwitchesPanel::updateItemModels() +{ + lock = true; + commonItemModels->update(CommonItemModels::RMO_LOGICAL_SWITCHES); +} + +void LogicalSwitchesPanel::onModelDataAboutToBeUpdated() +{ + lock = true; + modelsUpdateCnt++; +} + +void LogicalSwitchesPanel::onModelDataUpdateComplete() +{ + modelsUpdateCnt--; + if (modelsUpdateCnt < 1) { + update(); + lock = false; + } +} diff --git a/companion/src/modeledit/logicalswitches.h b/companion/src/modeledit/logicalswitches.h index 62aa69f30..87a360408 100644 --- a/companion/src/modeledit/logicalswitches.h +++ b/companion/src/modeledit/logicalswitches.h @@ -24,8 +24,8 @@ #include "modeledit.h" #include "radiodata.h" -class RawSwitchFilterItemModel; -class RawSourceFilterItemModel; +class CommonItemModels; +class RawItemFilteredModel; class TimerEdit; constexpr char MIMETYPE_LOGICAL_SWITCH[] = "application/x-companion-logical-switch"; @@ -35,13 +35,12 @@ class LogicalSwitchesPanel : public ModelPanel Q_OBJECT public: - LogicalSwitchesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware); + LogicalSwitchesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels); virtual ~LogicalSwitchesPanel(); virtual void update(); private slots: - void updateDataModels(); void onFunctionChanged(); void onV1Changed(int value); void onV2Changed(int value); @@ -61,6 +60,8 @@ class LogicalSwitchesPanel : public ModelPanel void cmInsert(); void cmClear(bool prompt = true); void cmClearAll(); + void onModelDataAboutToBeUpdated(); + void onModelDataUpdateComplete(); private: QComboBox * cbFunction[CPN_MAX_LOGICAL_SWITCHES]; @@ -73,11 +74,11 @@ class LogicalSwitchesPanel : public ModelPanel QDoubleSpinBox * dsbDelay[CPN_MAX_LOGICAL_SWITCHES]; QComboBox * cbSource1[CPN_MAX_LOGICAL_SWITCHES]; QComboBox * cbSource2[CPN_MAX_LOGICAL_SWITCHES]; - RawSwitchFilterItemModel * rawSwitchItemModel; - RawSourceFilterItemModel * rawSourceItemModel; + CommonItemModels * commonItemModels; + RawItemFilteredModel * rawSwitchFilteredModel; + RawItemFilteredModel * rawSourceFilteredModel; int selectedIndex; void populateFunctionCB(QComboBox *b); - void populateAndSwitchCB(QComboBox *b); void updateTimerParam(QDoubleSpinBox *sb, int timer, double minimum=0); int lsCapability; int lsCapabilityExt; @@ -86,6 +87,8 @@ class LogicalSwitchesPanel : public ModelPanel bool insertAllowed() const; bool moveDownAllowed() const; bool moveUpAllowed() const; + int modelsUpdateCnt; + void updateItemModels(); }; #endif // _LOGICALSWITCHES_H_ diff --git a/companion/src/modeledit/mixerdialog.cpp b/companion/src/modeledit/mixerdialog.cpp index 1b17e9471..dd2aa121d 100644 --- a/companion/src/modeledit/mixerdialog.cpp +++ b/companion/src/modeledit/mixerdialog.cpp @@ -24,7 +24,8 @@ #include "rawitemfilteredmodel.h" #include "helpers.h" -MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata, GeneralSettings & generalSettings, Firmware * firmware) : +MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata, GeneralSettings & generalSettings, Firmware * firmware, + RawItemFilteredModel * rawSourceModel, RawItemFilteredModel * rawSwitchModel) : QDialog(parent), ui(new Ui::MixerDialog), model(model), @@ -34,18 +35,18 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata, lock(false) { ui->setupUi(this); + QRegExp rx(CHAR_FOR_NAMES_REGEX); - QLabel * lb_fp[CPN_MAX_FLIGHT_MODES] = {ui->lb_FP0,ui->lb_FP1,ui->lb_FP2,ui->lb_FP3,ui->lb_FP4,ui->lb_FP5,ui->lb_FP6,ui->lb_FP7,ui->lb_FP8 }; - QCheckBox * tmp[CPN_MAX_FLIGHT_MODES] = {ui->cb_FP0,ui->cb_FP1,ui->cb_FP2,ui->cb_FP3,ui->cb_FP4,ui->cb_FP5,ui->cb_FP6,ui->cb_FP7,ui->cb_FP8 }; - for (int i=0; ilb_FP0, ui->lb_FP1, ui->lb_FP2, ui->lb_FP3, ui->lb_FP4, ui->lb_FP5, ui->lb_FP6, ui->lb_FP7, ui->lb_FP8 }; + QCheckBox * tmp[CPN_MAX_FLIGHT_MODES] = {ui->cb_FP0, ui->cb_FP1, ui->cb_FP2, ui->cb_FP3, ui->cb_FP4, ui->cb_FP5, ui->cb_FP6, ui->cb_FP7, ui->cb_FP8 }; + for (int i = 0; i < CPN_MAX_FLIGHT_MODES; i++) { cb_fp[i] = tmp[i]; } - this->setWindowTitle(tr("DEST -> %1").arg(RawSource(SOURCE_TYPE_CH, md->destCh-1).toString(&model, &generalSettings))); + this->setWindowTitle(tr("DEST -> %1").arg(RawSource(SOURCE_TYPE_CH, md->destCh - 1).toString(&model, &generalSettings))); - ui->sourceCB->setModel(new RawSourceFilterItemModel(&generalSettings, &model, RawSource::InputSourceGroups | RawSource::ScriptsGroup, this)); + ui->sourceCB->setModel(rawSourceModel); ui->sourceCB->setCurrentIndex(ui->sourceCB->findData(md->srcRaw.toValue())); - ui->sourceCB->removeItem(0); int limit = firmware->getCapability(OffsetWeight); @@ -62,7 +63,7 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata, } if (!firmware->getCapability(VirtualInputs)) { - for(int i=0; i < CPN_MAX_STICKS; i++) { + for(int i = 0; i < CPN_MAX_STICKS; i++) { ui->trimCB->addItem(firmware->getAnalogInputName(i)); } } @@ -82,7 +83,7 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata, if (!firmware->getCapability(FlightModes)) { ui->label_phases->hide(); - for (int i=0; ihide(); cb_fp[i]->hide(); } @@ -92,40 +93,40 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata, ui->label_phases->setContextMenuPolicy(Qt::CustomContextMenu); connect(ui->label_phases, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(label_phases_customContextMenuRequested(const QPoint &))); int mask = 1; - for (int i=0; iflightModes & mask) == 0) { cb_fp[i]->setChecked(true); } mask <<= 1; } - for (int i=firmware->getCapability(FlightModes); igetCapability(FlightModes); i < CPN_MAX_FLIGHT_MODES; i++) { lb_fp[i]->hide(); cb_fp[i]->hide(); } } - ui->switchesCB->setModel(new RawSwitchFilterItemModel(&generalSettings, &model, RawSwitch::MixesContext, this)); + ui->switchesCB->setModel(rawSwitchModel); ui->switchesCB->setCurrentIndex(ui->switchesCB->findData(md->swtch.toValue())); ui->warningCB->setCurrentIndex(md->mixWarn); ui->mltpxCB->setCurrentIndex(md->mltpx); int scale=firmware->getCapability(SlowScale); float range=firmware->getCapability(SlowRange); - ui->slowDownSB->setMaximum(range/scale); - ui->slowDownSB->setSingleStep(1.0/scale); - ui->slowDownSB->setDecimals((scale==1 ? 0 :1)); + ui->slowDownSB->setMaximum(range / scale); + ui->slowDownSB->setSingleStep(1.0 / scale); + ui->slowDownSB->setDecimals((scale == 1 ? 0 : 1)); ui->slowDownSB->setValue((float)md->speedDown/scale); - ui->slowUpSB->setMaximum(range/scale); - ui->slowUpSB->setSingleStep(1.0/scale); - ui->slowUpSB->setDecimals((scale==1 ? 0 :1)); + ui->slowUpSB->setMaximum(range / scale); + ui->slowUpSB->setSingleStep(1.0 / scale); + ui->slowUpSB->setDecimals((scale == 1 ? 0 : 1)); ui->slowUpSB->setValue((float)md->speedUp/scale); - ui->delayDownSB->setMaximum(range/scale); - ui->delayDownSB->setSingleStep(1.0/scale); - ui->delayDownSB->setDecimals((scale==1 ? 0 :1)); - ui->delayDownSB->setValue((float)md->delayDown/scale); - ui->delayUpSB->setMaximum(range/scale); - ui->delayUpSB->setSingleStep(1.0/scale); - ui->delayUpSB->setDecimals((scale==1 ? 0 :1)); - ui->delayUpSB->setValue((float)md->delayUp/scale); + ui->delayDownSB->setMaximum(range / scale); + ui->delayDownSB->setSingleStep(1.0 / scale); + ui->delayDownSB->setDecimals((scale == 1 ? 0 : 1)); + ui->delayDownSB->setValue((float)md->delayDown / scale); + ui->delayUpSB->setMaximum(range / scale); + ui->delayUpSB->setSingleStep(1.0 / scale); + ui->delayUpSB->setDecimals((scale == 1 ? 0 : 1)); + ui->delayUpSB->setValue((float)md->delayUp / scale); QTimer::singleShot(0, this, SLOT(shrink())); valuesChanged(); @@ -147,10 +148,10 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata, MixerDialog::~MixerDialog() { + delete ui; delete gvWeightGroup; delete gvOffsetGroup; delete curveGroup; - delete ui; } void MixerDialog::changeEvent(QEvent *e) @@ -176,20 +177,20 @@ void MixerDialog::valuesChanged() ui->MixDR_CB->setEnabled(drVisible); ui->label_MixDR->setEnabled(drVisible); } - md->carryTrim = -(ui->trimCB->currentIndex()-1); + md->carryTrim = -(ui->trimCB->currentIndex() - 1); md->noExpo = ui->MixDR_CB->checkState() ? 0 : 1; md->swtch = RawSwitch(ui->switchesCB->itemData(ui->switchesCB->currentIndex()).toInt()); md->mixWarn = ui->warningCB->currentIndex(); md->mltpx = (MltpxValue)ui->mltpxCB->currentIndex(); int scale = firmware->getCapability(SlowScale); - md->delayDown = round(ui->delayDownSB->value()*scale); - md->delayUp = round(ui->delayUpSB->value()*scale); - md->speedDown = round(ui->slowDownSB->value()*scale); - md->speedUp = round(ui->slowUpSB->value()*scale); + md->delayDown = round(ui->delayDownSB->value() * scale); + md->delayUp = round(ui->delayUpSB->value() * scale); + md->speedDown = round(ui->slowDownSB->value() * scale); + md->speedUp = round(ui->slowUpSB->value() * scale); strcpy(md->name, ui->mixerName->text().toLatin1()); md->flightModes = 0; - for (int i=CPN_MAX_FLIGHT_MODES-1; i>=0 ; i--) { + for (int i = CPN_MAX_FLIGHT_MODES - 1; i >= 0 ; i--) { if (!cb_fp[i]->checkState()) { md->flightModes++; } @@ -220,7 +221,7 @@ void MixerDialog::label_phases_customContextMenuRequested(const QPoint & pos) void MixerDialog::fmClearAll() { lock = true; - for (int i=0; isetChecked(false); } lock = false; @@ -230,7 +231,7 @@ void MixerDialog::fmClearAll() void MixerDialog::fmSetAll() { lock = true; - for (int i=0; isetChecked(true); } lock = false; @@ -240,7 +241,7 @@ void MixerDialog::fmSetAll() void MixerDialog::fmInvertAll() { lock = true; - for (int i=0; isetChecked(!cb_fp[i]->isChecked()); } lock = false; diff --git a/companion/src/modeledit/mixerdialog.h b/companion/src/modeledit/mixerdialog.h index 93f061d0d..a49a87e8f 100644 --- a/companion/src/modeledit/mixerdialog.h +++ b/companion/src/modeledit/mixerdialog.h @@ -26,6 +26,7 @@ class GVarGroup; class CurveGroup; +class RawItemFilteredModel; namespace Ui { class MixerDialog; @@ -34,7 +35,8 @@ namespace Ui { class MixerDialog : public QDialog { Q_OBJECT public: - MixerDialog(QWidget *parent, ModelData & model, MixData *mixdata, GeneralSettings & generalSettings, Firmware * firmware); + MixerDialog(QWidget *parent, ModelData & model, MixData *mixdata, GeneralSettings & generalSettings, Firmware * firmware, + RawItemFilteredModel * rawSourceModel, RawItemFilteredModel * rawSwitchModel); ~MixerDialog(); protected: diff --git a/companion/src/modeledit/mixes.cpp b/companion/src/modeledit/mixes.cpp index 4d0f5f4cd..1e2097fe9 100644 --- a/companion/src/modeledit/mixes.cpp +++ b/companion/src/modeledit/mixes.cpp @@ -20,13 +20,23 @@ #include "mixes.h" #include "helpers.h" +#include "rawitemfilteredmodel.h" -MixesPanel::MixesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware): +MixesPanel::MixesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware,CommonItemModels * commonItemModels): ModelPanel(parent, model, generalSettings, firmware), mixInserted(false), highlightedSource(0), - modelPrinter(firmware, generalSettings, model) + modelPrinter(firmware, generalSettings, model), + commonItemModels(commonItemModels) { + rawSourceFilteredModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), ((RawSource::InputSourceGroups | RawSource::ScriptsGroup) & ~ RawSource::NoneGroup), this); + connect(rawSourceFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &MixesPanel::onModelDataAboutToBeUpdated); + connect(rawSourceFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &MixesPanel::onModelDataUpdateComplete); + + rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), RawSwitch::MixesContext, this); + connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &MixesPanel::onModelDataAboutToBeUpdated); + connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &MixesPanel::onModelDataUpdateComplete); + QGridLayout * mixesLayout = new QGridLayout(this); mixersListWidget = new MixersListWidget(this, false); // TODO enum @@ -175,8 +185,8 @@ void MixesPanel::gm_openMix(int index) MixData mixd(model->mixData[index]); - MixerDialog *g = new MixerDialog(this, *model, &mixd, generalSettings, firmware); - if(g->exec()) { + MixerDialog *dlg = new MixerDialog(this, *model, &mixd, generalSettings, firmware, rawSourceFilteredModel, rawSwitchFilteredModel); + if(dlg->exec()) { model->mixData[index] = mixd; emit modified(); update(); @@ -188,6 +198,7 @@ void MixesPanel::gm_openMix(int index) mixInserted = false; update(); } + delete dlg; } int MixesPanel::getMixerIndex(unsigned int dch) @@ -529,3 +540,14 @@ void MixesPanel::clearMixes() update(); } } + +void MixesPanel::onModelDataAboutToBeUpdated() +{ + lock = true; +} + +void MixesPanel::onModelDataUpdateComplete() +{ + update(); + lock = false; +} diff --git a/companion/src/modeledit/mixes.h b/companion/src/modeledit/mixes.h index 95765465e..cba4ed556 100644 --- a/companion/src/modeledit/mixes.h +++ b/companion/src/modeledit/mixes.h @@ -26,12 +26,15 @@ #include "mixerdialog.h" #include "modelprinter.h" +class CommonItemModels; +class RawItemFilteredModel; + class MixesPanel : public ModelPanel { Q_OBJECT public: - MixesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware); + MixesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels); virtual ~MixesPanel(); virtual void update(); @@ -50,7 +53,6 @@ class MixesPanel : public ModelPanel void moveMixDown(); void mixerHighlight(); - void mixerlistWidget_customContextMenuRequested(QPoint pos); void mixerlistWidget_doubleClicked(QModelIndex index); void mixerlistWidget_KeyPress(QKeyEvent *event); @@ -58,11 +60,17 @@ class MixesPanel : public ModelPanel void mimeMixerDropped(int index, const QMimeData *data, Qt::DropAction action); void pasteMixerMimeData(const QMimeData * mimeData, int destIdx); + void onModelDataAboutToBeUpdated(); + void onModelDataUpdateComplete(); + private: MixersListWidget * mixersListWidget; bool mixInserted; unsigned int highlightedSource; ModelPrinter modelPrinter; + CommonItemModels * commonItemModels; + RawItemFilteredModel *rawSourceFilteredModel; + RawItemFilteredModel *rawSwitchFilteredModel; int getMixerIndex(unsigned int dch); bool gm_insertMix(int idx); diff --git a/companion/src/modeledit/modeledit.cpp b/companion/src/modeledit/modeledit.cpp index af3166c7f..41989ba53 100644 --- a/companion/src/modeledit/modeledit.cpp +++ b/companion/src/modeledit/modeledit.cpp @@ -33,6 +33,7 @@ #include "customfunctions.h" #include "telemetry.h" #include "appdata.h" +#include "rawitemdatamodels.h" ModelEdit::ModelEdit(QWidget * parent, RadioData & radioData, int modelId, Firmware * firmware) : QDialog(parent), @@ -48,33 +49,55 @@ ModelEdit::ModelEdit(QWidget * parent, RadioData & radioData, int modelId, Firmw setWindowIcon(CompanionIcon("edit.png")); restoreGeometry(g.modelEditGeo()); ui->pushButton->setIcon(CompanionIcon("simulate.png")); - SetupPanel * setupPanel = new SetupPanel(this, radioData.models[modelId], radioData.generalSettings, firmware); + + GeneralSettings &generalSettings = radioData.generalSettings; + ModelData &model = radioData.models[modelId]; + + commonItemModels = new CommonItemModels(&generalSettings, &model, this); + s1.report("Init"); + + SetupPanel * setupPanel = new SetupPanel(this, model, generalSettings, firmware, commonItemModels); addTab(setupPanel, tr("Setup")); - if (firmware->getCapability(Heli)) - addTab(new HeliPanel(this, radioData.models[modelId], radioData.generalSettings, firmware), tr("Heli")); - addTab(new FlightModesPanel(this, radioData.models[modelId], radioData.generalSettings, firmware), tr("Flight Modes")); - addTab(new InputsPanel(this, radioData.models[modelId], radioData.generalSettings, firmware), tr("Inputs")); - s1.report("inputs"); - addTab(new MixesPanel(this, radioData.models[modelId], radioData.generalSettings, firmware), tr("Mixes")); + s1.report("Setup"); + + if (firmware->getCapability(Heli)) { + addTab(new HeliPanel(this, model, generalSettings, firmware, commonItemModels), tr("Heli")); + s1.report("Heli"); + } + + addTab(new FlightModesPanel(this, model, generalSettings, firmware, commonItemModels), tr("Flight Modes")); + s1.report("Flight Modes"); + + addTab(new InputsPanel(this, model, generalSettings, firmware, commonItemModels), tr("Inputs")); + s1.report("Inputs"); + + addTab(new MixesPanel(this, model, generalSettings, firmware, commonItemModels), tr("Mixes")); s1.report("Mixes"); - Channels * chnPanel = new Channels(this, radioData.models[modelId], radioData.generalSettings, firmware); - addTab(chnPanel, tr("Outputs")); + + ChannelsPanel * channelsPanel = new ChannelsPanel(this, model, generalSettings, firmware, commonItemModels); + addTab(channelsPanel, tr("Outputs")); s1.report("Outputs"); - addTab(new Curves(this, radioData.models[modelId], radioData.generalSettings, firmware), tr("Curves")); - addTab(new LogicalSwitchesPanel(this, radioData.models[modelId], radioData.generalSettings, firmware), tr("Logical Switches")); - s1.report("LS"); - addTab(new CustomFunctionsPanel(this, &radioData.models[modelId], radioData.generalSettings, firmware), tr("Special Functions")); - s1.report("CF"); - if (firmware->getCapability(Telemetry)) - addTab(new TelemetryPanel(this, radioData.models[modelId], radioData.generalSettings, firmware), tr("Telemetry")); - onTabIndexChanged(ui->tabWidget->currentIndex()); // make sure to trigger update on default tab panel + addTab(new CurvesPanel(this, model, generalSettings, firmware, commonItemModels), tr("Curves")); + s1.report("Curves"); - connect(setupPanel, &SetupPanel::extendedLimitsToggled, chnPanel, &Channels::refreshExtendedLimits); + addTab(new LogicalSwitchesPanel(this, model, generalSettings, firmware, commonItemModels), tr("Logical Switches")); + s1.report("Logical Switches"); + + addTab(new CustomFunctionsPanel(this, &model, generalSettings, firmware, commonItemModels), tr("Special Functions")); + s1.report("Special Functions"); + + if (firmware->getCapability(Telemetry)) { + addTab(new TelemetryPanel(this, model, generalSettings, firmware, commonItemModels), tr("Telemetry")); + s1.report("Telemetry"); + } + + connect(setupPanel, &SetupPanel::extendedLimitsToggled, channelsPanel, &ChannelsPanel::refreshExtendedLimits); connect(ui->tabWidget, &QTabWidget::currentChanged, this, &ModelEdit::onTabIndexChanged); connect(ui->pushButton, &QPushButton::clicked, this, &ModelEdit::launchSimulation); - s1.report("end"); + onTabIndexChanged(ui->tabWidget->currentIndex()); // make sure to trigger update on default tab panel + gStopwatch.report("ModelEdit end constructor"); } diff --git a/companion/src/modeledit/modeledit.h b/companion/src/modeledit/modeledit.h index 969ae85d7..9095101bf 100644 --- a/companion/src/modeledit/modeledit.h +++ b/companion/src/modeledit/modeledit.h @@ -25,6 +25,7 @@ #include "genericpanel.h" class RadioData; +class CommonItemModels; namespace Ui { class ModelEdit; @@ -62,6 +63,7 @@ class ModelEdit : public QDialog RadioData & radioData; Firmware * firmware; QVector panels; + CommonItemModels * commonItemModels; void addTab(GenericPanel *panel, QString text); void launchSimulation(); diff --git a/companion/src/modeledit/setup.cpp b/companion/src/modeledit/setup.cpp index 5d4dfec79..d6768c850 100644 --- a/companion/src/modeledit/setup.cpp +++ b/companion/src/modeledit/setup.cpp @@ -31,13 +31,14 @@ #include -TimerPanel::TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware, QWidget * prevFocus, RawSwitchFilterItemModel * switchModel): +TimerPanel::TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware, QWidget * prevFocus, RawItemFilteredModel * rawSwitchFilteredModel): ModelPanel(parent, model, generalSettings, firmware), timer(timer), ui(new Ui::Timer) { - ui->setupUi(this); + connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &TimerPanel::onModelDataAboutToBeUpdated); + connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &TimerPanel::onModelDataUpdateComplete); lock = true; @@ -48,11 +49,10 @@ TimerPanel::TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, Ge } else { ui->name->setMaxLength(length); - //ui->name->setText(timer.name); } // Mode - ui->mode->setModel(switchModel); + ui->mode->setModel(rawSwitchFilteredModel); ui->mode->setCurrentIndex(ui->mode->findData(timer.mode.toValue())); connect(ui->mode, SIGNAL(activated(int)), this, SLOT(onModeChanged(int))); @@ -94,6 +94,7 @@ TimerPanel::~TimerPanel() void TimerPanel::update() { lock = true; + ui->name->setText(timer.name); int hour = timer.val / 3600; @@ -114,7 +115,7 @@ void TimerPanel::update() 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->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->countdownBeep->updateValue(); @@ -131,7 +132,7 @@ QWidget * TimerPanel::getLastFocus() void TimerPanel::on_value_editingFinished() { if (!lock) { - unsigned val = ui->value->time().hour()*3600 + ui->value->time().minute()*60 + ui->value->time().second(); + 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(); @@ -165,11 +166,23 @@ void TimerPanel::on_name_editingFinished() 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::onModelDataAboutToBeUpdated() +{ + lock = true; +} + +void TimerPanel::onModelDataUpdateComplete() +{ + update(); + lock = false; +} + /******************************************************************************/ #define FAILSAFE_CHANNEL_HOLD 2000 @@ -237,19 +250,19 @@ ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & modul } // The protocols available on this board - for (unsigned int i=0; iisAvailable((PulsesProtocol) i, moduleIdx)) { ui->protocol->addItem(ModuleData::protocolToString(i), i); if (i == module.protocol) - ui->protocol->setCurrentIndex(ui->protocol->count()-1); + ui->protocol->setCurrentIndex(ui->protocol->count() - 1); } } - for (int i=0; i<=MODULE_SUBTYPE_MULTI_LAST; i++) { + for (int i = 0; i <= MODULE_SUBTYPE_MULTI_LAST; i++) { if (i == MODULE_SUBTYPE_MULTI_SCANNER) continue; ui->multiProtocol->addItem(Multiprotocols::protocolToString(i), i); } - for (int i=MODULE_SUBTYPE_MULTI_LAST + 1; i <= 124; i++) { + for (int i = MODULE_SUBTYPE_MULTI_LAST + 1; i <= 124; i++) { ui->multiProtocol->addItem(QString::number(i + 3), i); } @@ -327,7 +340,7 @@ void ModulePanel::setupFailsafes() else { QLabel * label = new QLabel(this); label->setProperty("index", i); - label->setText(QString::number(i+1)); + label->setText(QString::number(i + 1)); QComboBox * combo = new QComboBox(this); combo->setProperty("index", i); @@ -506,7 +519,7 @@ void ModulePanel::update() ui->ppmFrameLength->setVisible(mask & MASK_SBUSPPM_FIELDS); ui->ppmFrameLength->setMinimum(module.channelsCount * (model->extendedLimits ? 2.250 : 2)+3.5); ui->ppmFrameLength->setMaximum(firmware->getCapability(PPMFrameLength)); - ui->ppmFrameLength->setValue(22.5+((double)module.ppm.frameLength)*0.5); + ui->ppmFrameLength->setValue(22.5 + ((double)module.ppm.frameLength) * 0.5); // Antenna mode on Horus and XLite if (mask & MASK_ANTENNA) { @@ -600,17 +613,17 @@ void ModulePanel::update() ui->registrationIdLabel->setVisible(mask & MASK_ACCESS); ui->registrationId->setVisible(mask & MASK_ACCESS); - ui->rx1Label->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<0))); - ui->clearRx1->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<0))); - ui->rx1->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<0))); + ui->rx1Label->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1 << 0))); + ui->clearRx1->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1 << 0))); + ui->rx1->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1 << 0))); - ui->rx2Label->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<1))); - ui->clearRx2->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<1))); - ui->rx2->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<1))); + ui->rx2Label->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1 << 1))); + ui->clearRx2->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1 << 1))); + ui->rx2->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1 << 1))); - ui->rx3Label->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<2))); - ui->clearRx3->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<2))); - ui->rx3->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<2))); + ui->rx3Label->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1 << 2))); + ui->clearRx3->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1 << 2))); + ui->rx3->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1 << 2))); // Failsafes ui->label_failsafeMode->setVisible(mask & MASK_FAILSAFES); @@ -703,8 +716,8 @@ void ModulePanel::on_channelsCount_editingFinished() { if (!lock && module.channelsCount != ui->channelsCount->value()) { module.channelsCount = ui->channelsCount->value(); - update(); emit channelsRangeChanged(); + update(); emit modified(); } } @@ -713,8 +726,8 @@ void ModulePanel::on_channelsStart_editingFinished() { if (!lock && module.channelsStart != (unsigned)ui->channelsStart->value() - 1) { module.channelsStart = (unsigned)ui->channelsStart->value() - 1; - update(); emit channelsRangeChanged(); + update(); emit modified(); } } @@ -738,7 +751,7 @@ void ModulePanel::on_rxNumber_editingFinished() void ModulePanel::on_ppmFrameLength_editingFinished() { - int val = (ui->ppmFrameLength->value()-22.5) / 0.5; + int val = (ui->ppmFrameLength->value() - 22.5) / 0.5; if (module.ppm.frameLength != val) { module.ppm.frameLength = val; emit modified(); @@ -762,8 +775,8 @@ void ModulePanel::onMultiProtocolChanged(int index) module.multi.rfProtocol = (unsigned int)rfProtocol; unsigned int maxSubTypes = multiProtocols.getProtocol(index).numSubTypes(); if (rfProtocol > MODULE_SUBTYPE_MULTI_LAST) - maxSubTypes=8; - module.subType = std::min(module.subType, maxSubTypes -1); + maxSubTypes = 8; + module.subType = std::min(module.subType, maxSubTypes - 1); module.channelsCount = module.getMaxChannelCount(); update(); emit modified(); @@ -957,19 +970,19 @@ void ModulePanel::onClearAccessRxClicked() QPushButton *button = qobject_cast(sender()); if (button == ui->clearRx1) { - module.access.receivers &= ~(1<<0); + module.access.receivers &= ~(1 << 0); ui->rx1->clear(); update(); emit modified(); } else if (button == ui->clearRx2) { - module.access.receivers &= ~(1<<1); + module.access.receivers &= ~(1 << 1); ui->rx2->clear(); update(); emit modified(); } else if (button == ui->clearRx3) { - module.access.receivers &= ~(1<<2); + module.access.receivers &= ~(1 << 2); ui->rx3->clear(); update(); emit modified(); @@ -978,18 +991,20 @@ void ModulePanel::onClearAccessRxClicked() /******************************************************************************/ -SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware): +SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels): ModelPanel(parent, model, generalSettings, firmware), - ui(new Ui::Setup) + ui(new Ui::Setup), + commonItemModels(commonItemModels) { + ui->setupUi(this); + rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), RawSwitch::TimersContext, this); + Board::Type board = firmware->getBoard(); lock = true; memset(modules, 0, sizeof(modules)); - ui->setupUi(this); - QRegExp rx(CHAR_FOR_NAMES_REGEX); ui->name->setValidator(new QRegExpValidator(rx, this)); ui->name->setMaxLength(firmware->getCapability(ModelName)); @@ -1007,7 +1022,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge foreach ( QString file, qd.entryList(filters, QDir::Files) ) { QFileInfo fi(file); QString temp = fi.fileName(); - if (!items.contains(temp) && temp.length() <= 6+4) { + if (!items.contains(temp) && temp.length() <= 6 + 4) { items.append(temp); } } @@ -1017,7 +1032,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge foreach (QString file, qd.entryList(filters, QDir::Files)) { QFileInfo fi(file); QString temp = fi.completeBaseName(); - if (!items.contains(temp) && temp.length() <= 10+4) { + if (!items.contains(temp) && temp.length() <= 10 + 4) { items.append(temp); } } @@ -1030,7 +1045,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge foreach (QString file, items) { ui->image->addItem(file); if (file == model.bitmap) { - ui->image->setCurrentIndex(ui->image->count()-1); + ui->image->setCurrentIndex(ui->image->count() - 1); QString fileName = path; fileName.append(model.bitmap); if (!IS_FAMILY_HORUS_OR_T16(board)) @@ -1062,18 +1077,16 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge } QWidget * prevFocus = ui->image; - RawSwitchFilterItemModel * swModel = new RawSwitchFilterItemModel(&generalSettings, &model, RawSwitch::TimersContext, this); - connect(this, &SetupPanel::updated, swModel, &RawSwitchFilterItemModel::update); timersCount = firmware->getCapability(Timers); for (int i = 0; i < CPN_MAX_TIMERS; i++) { if (i < timersCount) { - timers[i] = new TimerPanel(this, model, model.timers[i], generalSettings, firmware, prevFocus, swModel); + timers[i] = new TimerPanel(this, model, model.timers[i], generalSettings, firmware, prevFocus, rawSwitchFilteredModel); ui->gridLayout->addWidget(timers[i], 1+i, 1); connect(timers[i], &TimerPanel::modified, this, &SetupPanel::modified); + connect(timers[i], &TimerPanel::nameChanged, this, &SetupPanel::onTimerNameChanged); connect(this, &SetupPanel::updated, timers[i], &TimerPanel::update); - connect(this, &SetupPanel::timerUpdated, timers[i], &TimerPanel::update); prevFocus = timers[i]->getLastFocus(); // TODO more reliable method required QLabel *label = findChild(QString("label_timer%1").arg(i + 1)); @@ -1095,7 +1108,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge if (firmware->getCapability(HasTopLcd)) { ui->toplcdTimer->setField(model.toplcdTimer, this); for (int i = 0; i < CPN_MAX_TIMERS; i++) { - if (itoplcdTimer->addItem(tr("Timer %1").arg(i + 1), i); } } @@ -1118,12 +1131,12 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge prevFocus = ui->trimsDisplay; int analogs = CPN_MAX_STICKS + getBoardCapability(board, Board::Pots) + getBoardCapability(board, Board::Sliders); int genAryIdx = 0; - for (int i=0; i < analogs + firmware->getCapability(RotaryEncoders); i++) { + for (int i = 0; i < analogs + firmware->getCapability(RotaryEncoders); i++) { RawSource src((i < analogs) ? SOURCE_TYPE_STICK : SOURCE_TYPE_ROTARY_ENCODER, (i < analogs) ? i : analogs - i); QCheckBox * checkbox = new QCheckBox(this); checkbox->setProperty("index", i); checkbox->setText(src.toString(&model, &generalSettings)); - ui->centerBeepLayout->addWidget(checkbox, 0, i+1); + ui->centerBeepLayout->addWidget(checkbox, 0, i + 1); connect(checkbox, SIGNAL(toggled(bool)), this, SLOT(onBeepCenterToggled(bool))); centerBeepCheckboxes << checkbox; if (IS_HORUS_OR_TARANIS(board)) { @@ -1139,7 +1152,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge } // Startup switches warnings - for (int i=0; isetText(src.toString(&model, &generalSettings)); slider->setMaximum(switchInfo.config == Board::SWITCH_3POS ? 2 : 1); cb->setProperty("index", i); - ui->switchesStartupLayout->addWidget(label, 0, i+1); + ui->switchesStartupLayout->addWidget(label, 0, i + 1); ui->switchesStartupLayout->setAlignment(label, Qt::AlignCenter); - ui->switchesStartupLayout->addWidget(slider, 1, i+1); + ui->switchesStartupLayout->addWidget(slider, 1, i + 1); ui->switchesStartupLayout->setAlignment(slider, Qt::AlignCenter); - ui->switchesStartupLayout->addWidget(cb, 2, i+1); + ui->switchesStartupLayout->addWidget(cb, 2, i + 1); ui->switchesStartupLayout->setAlignment(cb, Qt::AlignCenter); connect(slider, SIGNAL(valueChanged(int)), this, SLOT(startupSwitchEdited(int))); connect(cb, SIGNAL(toggled(bool)), this, SLOT(startupSwitchToggled(bool))); @@ -1181,12 +1194,12 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge // Pot warnings prevFocus = ui->potWarningMode; if (IS_HORUS_OR_TARANIS(board)) { - for (int i=0; isetProperty("index", i); cb->setText(src.toString(&model, &generalSettings)); - ui->potWarningLayout->addWidget(cb, 0, i+1); + ui->potWarningLayout->addWidget(cb, 0, i + 1); connect(cb, SIGNAL(toggled(bool)), this, SLOT(potWarningToggled(bool))); potWarningCheckboxes << cb; if (src.isPot(&genAryIdx) && !generalSettings.isPotAvailable(genAryIdx)) { @@ -1264,7 +1277,7 @@ void SetupPanel::on_extendedTrims_toggled(bool checked) void SetupPanel::on_trimIncrement_currentIndexChanged(int index) { - model->trimInc = index-2; + model->trimInc = index - 2; emit modified(); } @@ -1341,13 +1354,13 @@ void SetupPanel::populateThrottleSourceCB() ui->throttleSource->clear(); ui->throttleSource->addItem(tr("THR"), 0); - int idx=1; - for (int i=0; ithrottleSource->addItem(firmware->getAnalogInputName(4+i), idx); + 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; igetCapability(Outputs); i++, idx++) { + for (int i = 0; i < firmware->getCapability(Outputs); i++, idx++) { ui->throttleSource->addItem(RawSource(SOURCE_TYPE_CH, i).toString(model, &generalSettings), idx); } @@ -1394,7 +1407,7 @@ void SetupPanel::update() updatePotWarnings(); } - for (int i=0; iupdate(); } @@ -1405,7 +1418,7 @@ void SetupPanel::update() void SetupPanel::updateBeepCenter() { - for (int i=0; isetChecked(model->beepANACenter & (0x01 << i)); } } @@ -1417,20 +1430,20 @@ void SetupPanel::updateStartupSwitches() uint64_t switchStates = model->switchWarningStates; uint64_t value; - for (int i=0; iproperty("index").toInt(); bool enabled = !(model->switchWarningEnable & (1 << index)); if (IS_HORUS_OR_TARANIS(firmware->getBoard())) { - value = (switchStates >> (2*index)) & 0x03; + value = (switchStates >> (2 * index)) & 0x03; if (generalSettings.switchConfig[index] != Board::SWITCH_3POS && value == 2) { value = 1; } } else { - value = (i==0 ? switchStates & 0x3 : switchStates & 0x1); - switchStates >>= (i==0 ? 2 : 1); + value = (i == 0 ? switchStates & 0x3 : switchStates & 0x1); + switchStates >>= (i == 0 ? 2 : 1); } slider->setValue(value); slider->setEnabled(enabled); @@ -1456,7 +1469,7 @@ void SetupPanel::startupSwitchEdited(int value) mask = 0x03; } else { - shift = index+1; + shift = index + 1; mask = 0x01ull << shift; } } @@ -1497,7 +1510,7 @@ void SetupPanel::updatePotWarnings() { lock = true; ui->potWarningMode->setCurrentIndex(model->potsWarningMode); - for (int i=0; iproperty("index").toInt(); checkbox->setChecked(!model->potsWarnEnabled[index]); @@ -1627,7 +1640,7 @@ void SetupPanel::cmTimerClear(bool prompt) model->timers[selectedTimerIndex].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_TIMER, ModelData::REF_UPD_ACT_CLEAR, selectedTimerIndex); - emit timerUpdated(); + updateItemModels(); emit modified(); } @@ -1640,7 +1653,7 @@ void SetupPanel::cmTimerClearAll() model->timers[i].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_TIMER, ModelData::REF_UPD_ACT_CLEAR, i); } - emit timerUpdated(); + updateItemModels(); emit modified(); } @@ -1674,7 +1687,7 @@ void SetupPanel::cmTimerDelete() } model->timers[maxidx].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_TIMER, ModelData::REF_UPD_ACT_SHIFT, selectedTimerIndex, 0, -1); - emit timerUpdated(); + updateItemModels(); emit modified(); } @@ -1687,7 +1700,7 @@ void SetupPanel::cmTimerInsert() } model->timers[selectedTimerIndex].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_TIMER, ModelData::REF_UPD_ACT_SHIFT, selectedTimerIndex, 0, 1); - emit timerUpdated(); + updateItemModels(); emit modified(); } @@ -1707,7 +1720,7 @@ void SetupPanel::cmTimerPaste() if (hasTimerClipboardData(&data)) { TimerData *td = &model->timers[selectedTimerIndex]; memcpy(td, data.constData(), sizeof(TimerData)); - emit timerUpdated(); + updateItemModels(); emit modified(); } } @@ -1721,7 +1734,17 @@ void SetupPanel::swapTimerData(int idx1, int idx2) memcpy(td2, td1, sizeof(TimerData)); memcpy(td1, &tdtmp, sizeof(TimerData)); model->updateAllReferences(ModelData::REF_UPD_TYPE_TIMER, ModelData::REF_UPD_ACT_SWAP, idx1, idx2); - emit timerUpdated(); + updateItemModels(); emit modified(); } } + +void SetupPanel::onTimerNameChanged() +{ + updateItemModels(); +} + +void SetupPanel::updateItemModels() +{ + commonItemModels->update(CommonItemModels::RMO_TIMERS); +} diff --git a/companion/src/modeledit/setup.h b/companion/src/modeledit/setup.h index e0c3df507..c56e63ea1 100644 --- a/companion/src/modeledit/setup.h +++ b/companion/src/modeledit/setup.h @@ -26,7 +26,8 @@ constexpr char MIMETYPE_TIMER[] = "application/x-companion-timer"; -class RawSwitchFilterItemModel; +class CommonItemModels; +class RawItemFilteredModel; namespace Ui { class Setup; @@ -39,7 +40,7 @@ class TimerPanel : public ModelPanel Q_OBJECT public: - TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware, QWidget *prevFocus, RawSwitchFilterItemModel * switchModel); + TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware, QWidget *prevFocus, RawItemFilteredModel * switchModel); virtual ~TimerPanel(); virtual void update(); @@ -50,6 +51,11 @@ class TimerPanel : public ModelPanel void on_value_editingFinished(); void on_minuteBeep_toggled(bool checked); void on_name_editingFinished(); + void onModelDataAboutToBeUpdated(); + void onModelDataUpdateComplete(); + + signals: + void nameChanged(); private: TimerData & timer; @@ -125,7 +131,7 @@ class SetupPanel : public ModelPanel Q_OBJECT public: - SetupPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware); + SetupPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels); virtual ~SetupPanel(); virtual void update(); @@ -133,7 +139,6 @@ class SetupPanel : public ModelPanel signals: void extendedLimitsToggled(); void updated(); - void timerUpdated(); private slots: void on_name_editingFinished(); @@ -164,6 +169,7 @@ class SetupPanel : public ModelPanel void cmTimerPaste(); void cmTimerMoveDown(); void cmTimerMoveUp(); + void onTimerNameChanged(); private: Ui::Setup *ui; @@ -185,6 +191,9 @@ class SetupPanel : public ModelPanel bool moveTimerDownAllowed() const; bool moveTimerUpAllowed() const; void swapTimerData(int idx1, int idx2); -}; + CommonItemModels * commonItemModels; + RawItemFilteredModel * rawSwitchFilteredModel; + void updateItemModels(); + }; #endif // _SETUP_H_ diff --git a/companion/src/modeledit/telemetry.cpp b/companion/src/modeledit/telemetry.cpp index b34caa89e..e980c3943 100644 --- a/companion/src/modeledit/telemetry.cpp +++ b/companion/src/modeledit/telemetry.cpp @@ -28,18 +28,20 @@ #include -TelemetryCustomScreen::TelemetryCustomScreen(QWidget *parent, ModelData & model, FrSkyScreenData & screen, GeneralSettings & generalSettings, Firmware * firmware, RawSourceFilterItemModel * srcModel): +TelemetryCustomScreen::TelemetryCustomScreen(QWidget *parent, ModelData & model, FrSkyScreenData & screen, GeneralSettings & generalSettings, Firmware * firmware, RawItemFilteredModel * rawSourceModel): ModelPanel(parent, model, generalSettings, firmware), ui(new Ui::TelemetryCustomScreen), screen(screen) { ui->setupUi(this); + connect(rawSourceModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &TelemetryCustomScreen::onModelDataAboutToBeUpdated); + connect(rawSourceModel, &RawItemFilteredModel::dataUpdateComplete, this, &TelemetryCustomScreen::onModelDataUpdateComplete); for (int l = 0; l < firmware->getCapability(TelemetryCustomScreensLines); l++) { for (int c = 0; c < firmware->getCapability(TelemetryCustomScreensFieldsPerLine); c++) { fieldsCB[l][c] = new QComboBox(this); fieldsCB[l][c]->setProperty("index", c + (l << 8)); - fieldsCB[l][c]->setModel(srcModel); + fieldsCB[l][c]->setModel(rawSourceModel); ui->screenNumsLayout->addWidget(fieldsCB[l][c], l, c, 1, 1); connect(fieldsCB[l][c], SIGNAL(activated(int)), this, SLOT(customFieldChanged(int))); } @@ -48,7 +50,7 @@ TelemetryCustomScreen::TelemetryCustomScreen(QWidget *parent, ModelData & model, for (int l = 0; l < firmware->getCapability(TelemetryCustomScreensBars); l++) { barsCB[l] = new QComboBox(this); barsCB[l]->setProperty("index", l); - barsCB[l]->setModel(srcModel); + barsCB[l]->setModel(rawSourceModel); connect(barsCB[l], SIGNAL(activated(int)), this, SLOT(barSourceChanged(int))); ui->screenBarsLayout->addWidget(barsCB[l], l, 0, 1, 1); @@ -287,6 +289,17 @@ void TelemetryCustomScreen::barTimeChanged() } } +void TelemetryCustomScreen::onModelDataAboutToBeUpdated() +{ + lock = true; +} + +void TelemetryCustomScreen::onModelDataUpdateComplete() +{ + update(); + lock = false; +} + /******************************************************/ TelemetrySensorPanel::TelemetrySensorPanel(QWidget *parent, SensorData & sensor, int sensorIndex, int sensorCapability, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware): @@ -305,6 +318,7 @@ TelemetrySensorPanel::TelemetrySensorPanel(QWidget *parent, SensorData & sensor, QFontMetrics *f = new QFontMetrics(QFont()); QSize sz; sz = f->size(Qt::TextSingleLine, "TELE00"); + delete f; ui->numLabel->setMinimumWidth(sz.width()); ui->numLabel->setContextMenuPolicy(Qt::CustomContextMenu); ui->numLabel->setToolTip(tr("Popup menu available")); @@ -505,7 +519,6 @@ void TelemetrySensorPanel::on_name_editingFinished() if (!lock) { strcpy(sensor.label, ui->name->text().toLatin1()); emit dataModified(); - emit modified(); } } @@ -535,7 +548,6 @@ void TelemetrySensorPanel::on_formula_currentIndexChanged(int index) sensor.unit = SensorData::UNIT_METERS; } emit dataModified(); - emit modified(); } } @@ -631,7 +643,6 @@ void TelemetrySensorPanel::cmPaste() if (hasClipboardData(&data)) { memcpy(&sensor, data.constData(), sizeof(SensorData)); emit dataModified(); - emit modified(); } } @@ -645,7 +656,6 @@ void TelemetrySensorPanel::cmClear(bool prompt) sensor.clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_CLEAR, selectedIndex); emit dataModified(); - emit modified(); } void TelemetrySensorPanel::cmClearAll() @@ -678,11 +688,13 @@ void TelemetrySensorPanel::cmMoveDown() /******************************************************/ -TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware): +TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels): ModelPanel(parent, model, generalSettings, firmware), - ui(new Ui::Telemetry) + ui(new Ui::Telemetry), + commonItemModels(commonItemModels) { ui->setupUi(this); + rawSourceFilteredModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), this); sensorCapability = firmware->getCapability(Sensors); if (sensorCapability > CPN_MAX_SENSORS) // TODO should be role of getCapability @@ -696,11 +708,12 @@ TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettin ui->varioCenterSilent->setField(model.frsky.varioCenterSilent, this); ui->A1GB->hide(); ui->A2GB->hide(); + for (int i = 0; i < sensorCapability; ++i) { TelemetrySensorPanel * panel = new TelemetrySensorPanel(this, model.sensorData[i], i, sensorCapability, model, generalSettings, firmware); ui->sensorsLayout->addWidget(panel); sensorPanels[i] = panel; - connect(panel, SIGNAL(dataModified()), this, SLOT(update())); + connect(panel, SIGNAL(dataModified()), this, SLOT(on_dataModifiedSensor())); connect(panel, SIGNAL(modified()), this, SLOT(onModified())); connect(panel, SIGNAL(clearAllSensors()), this, SLOT(on_clearAllSensors())); connect(panel, SIGNAL(insertSensor(int)), this, SLOT(on_insertSensor(int))); @@ -717,15 +730,11 @@ TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettin ui->topbarGB->hide(); } - RawSourceFilterItemModel * srcModel = (new RawSourceFilterItemModel(&generalSettings, &model, this)); - connect(this, &TelemetryPanel::updated, srcModel, &RawSourceFilterItemModel::update); - for (int i = 0; i < firmware->getCapability(TelemetryCustomScreens); i++) { - TelemetryCustomScreen * tab = new TelemetryCustomScreen(this, model, model.frsky.screens[i], generalSettings, firmware, srcModel); + TelemetryCustomScreen * tab = new TelemetryCustomScreen(this, model, model.frsky.screens[i], generalSettings, firmware, rawSourceFilteredModel); ui->customScreens->addTab(tab, tr("Telemetry screen %1").arg(i + 1)); telemetryCustomScreens[i] = tab; connect(tab, &TelemetryCustomScreen::modified, this, &TelemetryPanel::onModified); - connect(this, &TelemetryPanel::updated, tab, &TelemetryCustomScreen::update); } disableMouseScrolling(); @@ -759,79 +768,78 @@ void TelemetryPanel::update() sensorPanels[i]->update(); } - emit updated(); + for (int i = 0; i < firmware->getCapability(TelemetryCustomScreens); i++) { + telemetryCustomScreens[i]->update(); + } } void TelemetryPanel::setup() { - QString firmware_id = g.profile[g.id()].fwType(); + lock = true; - lock = true; + ui->telemetryProtocol->addItem(tr("FrSky S.PORT"), 0); + ui->telemetryProtocol->addItem(tr("FrSky D"), 1); + if (IS_9XRPRO(firmware->getBoard()) || + (IS_TARANIS(firmware->getBoard()) && generalSettings.auxSerialMode == 2)) { + ui->telemetryProtocol->addItem(tr("FrSky D (cable)"), 2); + } + ui->telemetryProtocol->setCurrentIndex(model->telemetryProtocol); + ui->ignoreSensorIds->setField(model->frsky.ignoreSensorIds, this); + ui->disableTelemetryAlarms->setField(model->rssiAlarms.disabled); - ui->telemetryProtocol->addItem(tr("FrSky S.PORT"), 0); - ui->telemetryProtocol->addItem(tr("FrSky D"), 1); - if (IS_9XRPRO(firmware->getBoard()) || - (IS_TARANIS(firmware->getBoard()) && generalSettings.auxSerialMode == 2)) { - ui->telemetryProtocol->addItem(tr("FrSky D (cable)"), 2); - } - ui->telemetryProtocol->setCurrentIndex(model->telemetryProtocol); - ui->ignoreSensorIds->setField(model->frsky.ignoreSensorIds, this); - ui->disableTelemetryAlarms->setField(model->rssiAlarms.disabled); + ui->rssiAlarmWarningSB->setValue(model->rssiAlarms.warning); + ui->rssiAlarmCriticalSB->setValue(model->rssiAlarms.critical); - ui->rssiAlarmWarningSB->setValue(model->rssiAlarms.warning); - ui->rssiAlarmCriticalSB->setValue(model->rssiAlarms.critical); + ui->rssiSourceLabel->show(); + ui->rssiSourceLabel->setText(tr("Source")); + ui->rssiSourceCB->setField(model->rssiSource, this); + ui->rssiSourceCB->show(); + populateTelemetrySourcesComboBox(ui->rssiSourceCB, model, false); - ui->rssiSourceLabel->show(); - ui->rssiSourceLabel->setText(tr("Source")); - ui->rssiSourceCB->setField(model->rssiSource, this); - ui->rssiSourceCB->show(); - populateTelemetrySourcesComboBox(ui->rssiSourceCB, model, false); + ui->rssiAlarmWarningCB->hide(); + ui->rssiAlarmCriticalCB->hide(); + ui->rssiAlarmWarningLabel->setText(tr("Low Alarm")); + ui->rssiAlarmCriticalLabel->setText(tr("Critical Alarm")); - ui->rssiAlarmWarningCB->hide(); - ui->rssiAlarmCriticalCB->hide(); - ui->rssiAlarmWarningLabel->setText(tr("Low Alarm")); - ui->rssiAlarmCriticalLabel->setText(tr("Critical Alarm")); - - int varioCap = firmware->getCapability(HasVario); - if (!varioCap) { - ui->varioLimitMax_DSB->hide(); + if (!firmware->getCapability(HasVario)) { + ui->varioLimitMax_DSB->hide(); + ui->varioLimitMin_DSB->hide(); + ui->varioLimitCenterMin_DSB->hide(); + ui->varioLimitCenterMax_DSB->hide(); + ui->varioLimit_label->hide(); + ui->VarioLabel_1->hide(); + ui->VarioLabel_2->hide(); + ui->VarioLabel_3->hide(); + ui->VarioLabel_4->hide(); + ui->varioSource->hide(); + ui->varioSource_label->hide(); + } + else { + if (!firmware->getCapability(HasVarioSink)) { ui->varioLimitMin_DSB->hide(); ui->varioLimitCenterMin_DSB->hide(); - ui->varioLimitCenterMax_DSB->hide(); - ui->varioLimit_label->hide(); ui->VarioLabel_1->hide(); ui->VarioLabel_2->hide(); - ui->VarioLabel_3->hide(); - ui->VarioLabel_4->hide(); - ui->varioSource->hide(); - ui->varioSource_label->hide(); - } - else { - if (!firmware->getCapability(HasVarioSink)) { - ui->varioLimitMin_DSB->hide(); - ui->varioLimitCenterMin_DSB->hide(); - ui->VarioLabel_1->hide(); - ui->VarioLabel_2->hide(); - } - ui->varioLimitMin_DSB->setValue(model->frsky.varioMin - 10); - ui->varioLimitMax_DSB->setValue(model->frsky.varioMax + 10); - ui->varioLimitCenterMax_DSB->setValue((model->frsky.varioCenterMax / 10.0) + 0.5); - ui->varioLimitCenterMin_DSB->setValue((model->frsky.varioCenterMin / 10.0) - 0.5); } + ui->varioLimitMin_DSB->setValue(model->frsky.varioMin - 10); + ui->varioLimitMax_DSB->setValue(model->frsky.varioMax + 10); + ui->varioLimitCenterMax_DSB->setValue((model->frsky.varioCenterMax / 10.0) + 0.5); + ui->varioLimitCenterMin_DSB->setValue((model->frsky.varioCenterMin / 10.0) - 0.5); + } - ui->altimetryGB->setVisible(firmware->getCapability(HasVario)), - ui->frskyProtoCB->setDisabled(firmware->getCapability(NoTelemetryProtocol)); + ui->altimetryGB->setVisible(firmware->getCapability(HasVario)), + ui->frskyProtoCB->setDisabled(firmware->getCapability(NoTelemetryProtocol)); - if (firmware->getCapability(Telemetry)) { - ui->frskyProtoCB->addItem(tr("Winged Shadow How High")); - } - else { - ui->frskyProtoCB->addItem(tr("Winged Shadow How High (not supported)")); - } + if (firmware->getCapability(Telemetry)) { + ui->frskyProtoCB->addItem(tr("Winged Shadow How High")); + } + else { + ui->frskyProtoCB->addItem(tr("Winged Shadow How High (not supported)")); + } - ui->variousGB->hide(); + ui->variousGB->hide(); - lock = false; + lock = false; } void TelemetryPanel::populateVarioSource() @@ -972,6 +980,7 @@ void TelemetryPanel::on_clearAllSensors() model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_CLEAR, i); } + updateItemModels(); update(); emit modified(); } @@ -982,6 +991,7 @@ void TelemetryPanel::on_insertSensor(int selectedIndex) model->sensorData[selectedIndex].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, 1); + updateItemModels(); update(); emit modified(); } @@ -995,6 +1005,7 @@ void TelemetryPanel::on_deleteSensor(int selectedIndex) model->sensorData[CPN_MAX_SENSORS - 1].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, -1); + updateItemModels(); update(); emit modified(); } @@ -1018,7 +1029,20 @@ void TelemetryPanel::swapData(int idx1, int idx2) memcpy(sd2, sd1, sizeof(SensorData)); memcpy(sd1, &sdtmp, sizeof(SensorData)); model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_SWAP, idx1, idx2); + updateItemModels(); update(); emit modified(); } } + +void TelemetryPanel::on_dataModifiedSensor() +{ + updateItemModels(); + update(); + emit modified(); +} + +void TelemetryPanel::updateItemModels() +{ + commonItemModels->update(CommonItemModels::RMO_TELEMETRY_SENSORS); +} diff --git a/companion/src/modeledit/telemetry.h b/companion/src/modeledit/telemetry.h index cddade217..9719c7df6 100644 --- a/companion/src/modeledit/telemetry.h +++ b/companion/src/modeledit/telemetry.h @@ -27,7 +27,8 @@ constexpr char MIMETYPE_TELE_SENSOR[] = "application/x-companion-tele-sensor"; class AutoComboBox; -class RawSourceFilterItemModel; +class CommonItemModels; +class RawItemFilteredModel; class TimerEdit; namespace Ui { @@ -41,7 +42,7 @@ class TelemetryCustomScreen: public ModelPanel Q_OBJECT public: - TelemetryCustomScreen(QWidget *parent, ModelData & model, FrSkyScreenData & screen, GeneralSettings & generalSettings, Firmware * firmware, RawSourceFilterItemModel * srcModel); + TelemetryCustomScreen(QWidget *parent, ModelData & model, FrSkyScreenData & screen, GeneralSettings & generalSettings, Firmware * firmware, RawItemFilteredModel * rawSourceModel); ~TelemetryCustomScreen(); void update(); @@ -53,6 +54,8 @@ class TelemetryCustomScreen: public ModelPanel void barMinChanged(double value); void barMaxChanged(double value); void barTimeChanged(); + void onModelDataAboutToBeUpdated(); + void onModelDataUpdateComplete(); private: void updateBar(int line); @@ -122,7 +125,7 @@ class TelemetryPanel : public ModelPanel Q_OBJECT public: - TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware); + TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels); virtual ~TelemetryPanel(); virtual void update(); @@ -148,12 +151,15 @@ class TelemetryPanel : public ModelPanel void on_deleteSensor(int index); void on_moveUpSensor(int index); void on_moveDownSensor(int index); + void on_dataModifiedSensor(); private: Ui::Telemetry *ui; TelemetryCustomScreen * telemetryCustomScreens[4]; TelemetrySensorPanel * sensorPanels[CPN_MAX_SENSORS]; int sensorCapability; + CommonItemModels * commonItemModels; + RawItemFilteredModel * rawSourceFilteredModel; void setup(); void telBarUpdate(); @@ -161,6 +167,7 @@ class TelemetryPanel : public ModelPanel void populateCurrentSource(); void populateVarioSource(); void swapData(int idx1, int idx2); + void updateItemModels(); }; #endif // _TELEMETRY_H_ diff --git a/radio/src/gui/480x272/model_outputs.cpp b/radio/src/gui/480x272/model_outputs.cpp index 300f8909b..70ac2f76f 100644 --- a/radio/src/gui/480x272/model_outputs.cpp +++ b/radio/src/gui/480x272/model_outputs.cpp @@ -96,6 +96,14 @@ bool menuModelLimits(event_t event) uint32_t sub = menuVerticalPosition; + if (sub < MAX_OUTPUT_CHANNELS) { +#if defined(PPM_CENTER_ADJUSTABLE) || defined(PPM_UNIT_US) + lcdDrawNumber(LCD_W / 2, MENU_TITLE_TOP + 1, PPM_CH_CENTER(sub)+channelOutputs[sub]/2, MENU_TITLE_COLOR, 0, "", STR_US); +#else + lcdDrawNumber(LCD_W / 2, MENU_TITLE_TOP + 1, calcRESXto1000(channelOutputs[sub]), PREC1 | MENU_TITLE_COLOR); +#endif + } + if (sub=0) { drawColumnHeader(STR_LIMITS_HEADERS, NULL, menuHorizontalPosition); } diff --git a/radio/src/gui/common/stdlcd/view_telemetry.cpp b/radio/src/gui/common/stdlcd/view_telemetry.cpp index d4b2bac0b..ecdb96aa9 100644 --- a/radio/src/gui/common/stdlcd/view_telemetry.cpp +++ b/radio/src/gui/common/stdlcd/view_telemetry.cpp @@ -35,8 +35,8 @@ enum NavigationDirection { #define EVT_KEY_PREVIOUS_VIEW(evt) (evt == EVT_KEY_LONG(KEY_LEFT) && IS_SHIFT_PRESSED()) #define EVT_KEY_NEXT_VIEW(evt) (evt == EVT_KEY_LONG(KEY_RIGHT) && IS_SHIFT_PRESSED()) #elif defined(NAVIGATION_X7_TX12) - #define EVT_KEY_PREVIOUS_VIEW(evt) (evt == EVT_KEY_FIRST(KEY_UP)) - #define EVT_KEY_NEXT_VIEW(evt) (evt == EVT_KEY_FIRST(KEY_DOWN)) + #define EVT_KEY_PREVIOUS_VIEW(evt) (evt == EVT_KEY_FIRST(KEY_PAGEUP)) + #define EVT_KEY_NEXT_VIEW(evt) (evt == EVT_KEY_FIRST(KEY_PAGEDN)) #elif defined(NAVIGATION_X7) || defined(NAVIGATION_X9D) #define EVT_KEY_PREVIOUS_VIEW(evt) (evt == EVT_KEY_LONG(KEY_PAGE)) #define EVT_KEY_NEXT_VIEW(evt) (evt == EVT_KEY_BREAK(KEY_PAGE)) diff --git a/radio/src/mixer.cpp b/radio/src/mixer.cpp index 56abde109..4992e608f 100644 --- a/radio/src/mixer.cpp +++ b/radio/src/mixer.cpp @@ -539,14 +539,25 @@ int getStickTrimValue(int stick, int stickValue) return trim; } -int getSourceTrimValue(int source, int stickValue=0) +int getSourceTrimOrigin(int source) { if (source >= MIXSRC_Rud && source <= MIXSRC_Ail) - return getStickTrimValue(source - MIXSRC_Rud, stickValue); + return source - MIXSRC_Rud; else if (source >= MIXSRC_FIRST_INPUT && source <= MIXSRC_LAST_INPUT) - return getStickTrimValue(virtualInputsTrims[source - MIXSRC_FIRST_INPUT], stickValue); + return virtualInputsTrims[source - MIXSRC_FIRST_INPUT]; else + return -1; +} + +int getSourceTrimValue(int source, int stickValue=0) +{ + auto origin = getSourceTrimOrigin(source); + if (origin >= 0) { + return getStickTrimValue(origin, stickValue); + } + else { return 0; + } } uint8_t mixerCurrentFlightMode; @@ -741,13 +752,16 @@ void evalFlightModeMixes(uint8_t mode, uint8_t tick10ms) } if (applyOffsetAndCurve) { - - //========== TRIMS ================ - if (!(mode & e_perout_mode_notrims)) { - if (md->carryTrim == 0) { - v += getSourceTrimValue(md->srcRaw, v); + bool applyTrims = !(mode & e_perout_mode_notrims); + if (!applyTrims && g_model.thrTrim) { + auto origin = getSourceTrimOrigin(md->srcRaw); + if (origin == g_model.getThrottleStickTrimSource() - MIXSRC_FIRST_TRIM) { + applyTrims = true; } } + if (applyTrims && md->carryTrim == 0) { + v += getSourceTrimValue(md->srcRaw, v); + } } int32_t weight = GET_GVAR_PREC1(MD_WEIGHT(md), GV_RANGELARGE_NEG, GV_RANGELARGE, mixerCurrentFlightMode); diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index f6b60cb7e..e127cf2e0 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -1119,7 +1119,7 @@ void checkTrims() else { phase = getTrimFlightMode(mixerCurrentFlightMode, idx); before = getTrimValue(phase, idx); - thro = (idx==THR_STICK && g_model.thrTrim); + thro = (idx == (g_model.getThrottleStickTrimSource() - MIXSRC_FIRST_TRIM) && g_model.thrTrim); } #else phase = getTrimFlightMode(mixerCurrentFlightMode, idx); @@ -1824,24 +1824,27 @@ void moveTrimsToOffsets() // copy state of 3 primary to subtrim pauseMixerCalculations(); evalFlightModeMixes(e_perout_mode_noinput, 0); // do output loop - zero input sticks and trims - for (uint8_t i=0; icarryTrim = TRIM_ELE; + expo = expoAddress(ELE_STICK); + expo->carryTrim = TRIM_THR; + + anaInValues[THR_STICK] = 0; + setTrimValue(0, MIXSRC_TrimEle - MIXSRC_FIRST_TRIM, 100); + setTrimValue(0, MIXSRC_TrimThr - MIXSRC_FIRST_TRIM, -100); + evalMixes(1); + EXPECT_EQ(channelOutputs[2], 200); // THR output value is reflecting 100 Ele trim + moveTrimsToOffsets(); + evalMixes(1); + EXPECT_EQ(channelOutputs[2], 200); // THR output value remains unchanged + EXPECT_EQ(getTrimValue(0, MIXSRC_TrimThr - MIXSRC_FIRST_TRIM), 0); // back to neutral + EXPECT_EQ(g_model.limitData[2].offset, 195); // value transferred + EXPECT_EQ(getTrimValue(0, MIXSRC_TrimEle - MIXSRC_FIRST_TRIM), 0); // back to neutral + EXPECT_EQ(g_model.limitData[1].offset, -195); // value transferred +} + +TEST_F(TrimsTest, MoveTrimsToOffsetsWithCrosstrimsAndTrimIdle) +{ + // Trim idle only + // Cross trims + g_model.limitData[2].offset = 0; + g_model.limitData[1].offset = 0; + g_model.thrTrim = 1; + g_model.thrTrimSw = MIXSRC_TrimEle - MIXSRC_FIRST_TRIM; + ExpoData *expo = expoAddress(THR_STICK); + expo->carryTrim = TRIM_ELE; + expo = expoAddress(ELE_STICK); + expo->carryTrim = TRIM_THR; + + anaInValues[THR_STICK] = -1024; // Min stick + setTrimValue(0, MIXSRC_TrimEle - MIXSRC_FIRST_TRIM, 100); + setTrimValue(0, MIXSRC_TrimThr - MIXSRC_FIRST_TRIM, -100); + evalMixes(1); + EXPECT_EQ(channelOutputs[2], -574); // THR output value is reflecting 100 ele trim idle + moveTrimsToOffsets(); + + // Trim affecting Throttle (now Ele because of crosstrims) should not be affected + EXPECT_EQ(getTrimValue(0, MIXSRC_TrimEle - MIXSRC_FIRST_TRIM), 100); // unchanged + EXPECT_EQ(g_model.limitData[2].offset, 0); // THR chan offset unchanged + + // Other trims should + EXPECT_EQ(getTrimValue(0, MIXSRC_TrimThr - MIXSRC_FIRST_TRIM), 0); // back to neutral + EXPECT_EQ(g_model.limitData[1].offset, -195); // Ele chan offset transfered + evalMixes(1); + EXPECT_EQ(channelOutputs[2], -574); // THR output value is still reflecting 100 trim idle +} + TEST_F(TrimsTest, InstantTrim) { anaInValues[AIL_STICK] = 50; diff --git a/radio/util/build-firmware.py b/radio/util/build-firmware.py index 907e358dd..66d9f053d 100755 --- a/radio/util/build-firmware.py +++ b/radio/util/build-firmware.py @@ -93,13 +93,11 @@ def main(): maxsize = 65536 * 8 elif options[optcount] == "x7": cmake_options["PCB"] = "X7" - cmake_options["AFHDS3"] = "YES" firmware_options = options_taranis_x7 maxsize = 65536 * 8 elif options[optcount] == "x7access": cmake_options["PCB"] = "X7" cmake_options["PCBREV"] = "ACCESS" - cmake_options["AFHDS3"] = "YES" firmware_options = options_taranis_x7 maxsize = 65536 * 8 elif board_name == "xlite": @@ -121,7 +119,6 @@ def main(): elif board_name == "x9d+2019": cmake_options["PCB"] = "X9D+" cmake_options["PCBREV"] = "2019" - cmake_options["AFHDS3"] = "YES" firmware_options = options_taranis_x9dp maxsize = 65536 * 8 elif board_name == "x9e":