diff --git a/companion/src/firmwares/modeldata.cpp b/companion/src/firmwares/modeldata.cpp
index 679e90f5f..c6159f1e8 100644
--- a/companion/src/firmwares/modeldata.cpp
+++ b/companion/src/firmwares/modeldata.cpp
@@ -26,6 +26,7 @@
#include "radiodataconversionstate.h"
#include "helpers.h"
#include "adjustmentreference.h"
+#include "compounditemmodels.h"
ModelData::ModelData()
{
@@ -1550,3 +1551,72 @@ void ModelData::limitsSet(const int index, const QByteArray & data)
memcpy(&limitData[index], data.constData(), sizeof(LimitData));
}
+
+QString ModelData::trainerModeToString() const
+{
+ return trainerModeToString(trainerMode);
+}
+
+// static
+QString ModelData::trainerModeToString(int value)
+{
+ switch (value) {
+ case TRAINER_MODE_MASTER_JACK:
+ return tr("Master/Jack");
+ case TRAINER_MODE_SLAVE_JACK:
+ return tr("Slave/Jack");
+ case TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE:
+ return tr("Master/SBUS Module");
+ case TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE:
+ return tr("Master/CPPM Module");
+ case TRAINER_MODE_MASTER_BATTERY_COMPARTMENT:
+ return tr("Master/Battery");
+ case TRAINER_MODE_MASTER_BLUETOOTH:
+ return tr("Master/Bluetooth");
+ case TRAINER_MODE_SLAVE_BLUETOOTH:
+ return tr("Slave/Bluetooth");
+ case TRAINER_MODE_MULTI:
+ return tr("Master/Multi");
+ default:
+ return CPN_STR_UNKNOWN_ITEM;
+ }
+}
+
+// static
+bool ModelData::isTrainerModeAvailable(const GeneralSettings & generalSettings, const Firmware * firmware, const int value)
+{
+ if (value < 0 || value >= TRAINER_MODE_COUNT)
+ return false;
+
+ bool ret = true;
+ const Board::Type board = firmware->getBoard();
+
+ if (!IS_TARANIS(board) || IS_ACCESS_RADIO(board, Firmware::getCurrentVariant()->getId())) {
+ if (value >= TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE && value <= TRAINER_MODE_MASTER_BATTERY_COMPARTMENT)
+ ret = false;
+ }
+ else if (generalSettings.auxSerialMode != UART_MODE_SBUS_TRAINER && value == TRAINER_MODE_MASTER_BATTERY_COMPARTMENT)
+ ret = false;
+
+ if (generalSettings.bluetoothMode != GeneralSettings::BLUETOOTH_MODE_TRAINER && value >= TRAINER_MODE_MASTER_BLUETOOTH && value <= TRAINER_MODE_SLAVE_BLUETOOTH)
+ ret = false;
+
+ if (!IS_RADIOMASTER_TX16S(board) && value == TRAINER_MODE_MULTI)
+ ret = false;
+
+ return ret;
+}
+
+// static
+AbstractStaticItemModel * ModelData::trainerModeItemModel(const GeneralSettings & generalSettings, const Firmware * firmware)
+{
+ AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
+ mdl->setName(AIM_MODELDATA_TRAINERMODE);
+
+ for (int i = 0; i < TRAINER_MODE_COUNT; i++) {
+ mdl->appendToItemList(trainerModeToString(i), i, isTrainerModeAvailable(generalSettings, firmware, i));
+ }
+
+ mdl->loadItemList();
+ return mdl;
+}
diff --git a/companion/src/firmwares/modeldata.h b/companion/src/firmwares/modeldata.h
index f834a0779..1a3854714 100644
--- a/companion/src/firmwares/modeldata.h
+++ b/companion/src/firmwares/modeldata.h
@@ -39,6 +39,9 @@
class GeneralSettings;
class RadioDataConversionState;
+class AbstractStaticItemModel;
+
+constexpr char AIM_MODELDATA_TRAINERMODE[] {"modeldata.trainermode"};
#define CHAR_FOR_NAMES " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-."
#define CHAR_FOR_NAMES_REGEX "[ A-Za-z0-9_.-,]*"
@@ -96,14 +99,15 @@ typedef char TopbarData[216+1];
#endif
enum TrainerMode {
- TRAINER_MODE_MASTER_TRAINER_JACK,
- TRAINER_MODE_SLAVE,
+ TRAINER_MODE_MASTER_JACK,
+ TRAINER_MODE_SLAVE_JACK,
TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE,
TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE,
TRAINER_MODE_MASTER_BATTERY_COMPARTMENT,
TRAINER_MODE_MASTER_BLUETOOTH,
TRAINER_MODE_SLAVE_BLUETOOTH,
- TRAINER_MODE_MULTI
+ TRAINER_MODE_MULTI,
+ TRAINER_MODE_COUNT
};
#define INPUT_NAME_LEN 4
@@ -274,6 +278,11 @@ class ModelData {
void limitsMove(const int index, const int offset);
void limitsSet(const int index, const QByteArray & data);
+ QString trainerModeToString() const;
+ static QString trainerModeToString(const int value);
+ static bool isTrainerModeAvailable(const GeneralSettings & generalSettings, const Firmware * firmware, const int value);
+ static AbstractStaticItemModel * trainerModeItemModel(const GeneralSettings & generalSettings, const Firmware * firmware);
+
protected:
void removeGlobalVar(int & var);
diff --git a/companion/src/firmwares/moduledata.h b/companion/src/firmwares/moduledata.h
index 8acec18b0..04e936758 100644
--- a/companion/src/firmwares/moduledata.h
+++ b/companion/src/firmwares/moduledata.h
@@ -146,14 +146,6 @@ enum MultiModuleRFProtocols {
MODULE_SUBTYPE_MULTI_LAST = MODULE_SUBTYPE_MULTI_E016HV2
};
-enum TrainerProtocol {
- TRAINER_MASTER_JACK,
- TRAINER_SLAVE_JACK,
- TRAINER_MASTER_SBUS_MODULE,
- TRAINER_MASTER_CPPM_MODULE,
- TRAINER_MASTER_SBUS_BATT_COMPARTMENT
-};
-
enum ModuleSubtypeR9M {
MODULE_SUBTYPE_R9M_FCC,
MODULE_SUBTYPE_R9M_EU,
diff --git a/companion/src/firmwares/opentx/opentxeeprom.cpp b/companion/src/firmwares/opentx/opentxeeprom.cpp
index b82e76795..e43a4014e 100644
--- a/companion/src/firmwares/opentx/opentxeeprom.cpp
+++ b/companion/src/firmwares/opentx/opentxeeprom.cpp
@@ -2556,6 +2556,15 @@ void OpenTxModelData::beforeExport()
}
modelData.switchWarningStates = newSwitchWarningStates;
}
+
+ // TODO remove when enum not radio specific requires eeprom change and conversion
+ if (modelData.trainerMode > TRAINER_MODE_SLAVE_JACK) {
+ if (!IS_TARANIS(board)) {
+ modelData.trainerMode -= 2;
+ if (!IS_RADIOMASTER_TX16S(board))
+ modelData.trainerMode -= 1;
+ }
+ }
}
void OpenTxModelData::afterImport()
@@ -2577,6 +2586,15 @@ void OpenTxModelData::afterImport()
if (version <= 218 && IS_HORUS_X10(board) && modelData.thrTraceSrc > 3) {
modelData.thrTraceSrc += 2;
}
+
+ // TODO remove when enum not radio specific requires eeprom change and conversion
+ if (modelData.trainerMode > TRAINER_MODE_SLAVE_JACK) {
+ if (!IS_TARANIS(board)) {
+ modelData.trainerMode += 2;
+ if (!IS_RADIOMASTER_TX16S(board))
+ modelData.trainerMode += 1;
+ }
+ }
}
OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type board, unsigned int version, unsigned int variant):
diff --git a/companion/src/modeledit/setup.cpp b/companion/src/modeledit/setup.cpp
index de6609591..0eec2a206 100644
--- a/companion/src/modeledit/setup.cpp
+++ b/companion/src/modeledit/setup.cpp
@@ -32,6 +32,7 @@
constexpr char FIM_TIMERSWITCH[] {"Timer Switch"};
constexpr char FIM_THRSOURCE[] {"Throttle Source"};
+constexpr char FIM_TRAINERMODE[] {"Trainer Mode"};
TimerPanel::TimerPanel(QWidget * parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware,
QWidget * prevFocus, FilteredItemModelFactory * panelFilteredModels, CompoundItemModelFactory * panelItemModels):
@@ -186,7 +187,8 @@ void TimerPanel::onCountdownBeepChanged(int index)
quint8 ModulePanel::failsafesValueDisplayType = ModulePanel::FAILSAFE_DISPLAY_PERCENT;
-ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & module, GeneralSettings & generalSettings, Firmware * firmware, int moduleIdx):
+ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & module, GeneralSettings & generalSettings, Firmware * firmware, int moduleIdx,
+ FilteredItemModelFactory * panelFilteredItemModels):
ModelPanel(parent, model, generalSettings, firmware),
module(module),
moduleIdx(moduleIdx),
@@ -198,30 +200,17 @@ ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & modul
ui->label_module->setText(ModuleData::indexToString(moduleIdx, firmware));
if (moduleIdx < 0) {
- if (!IS_TARANIS(firmware->getBoard()) || IS_ACCESS_RADIO(firmware->getBoard(), Firmware::getCurrentVariant()->getId())) {
- ui->trainerMode->setItemData(TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE, 0, Qt::UserRole - 1);
- ui->trainerMode->setItemData(TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE, 0, Qt::UserRole - 1);
- ui->trainerMode->setItemData(TRAINER_MODE_MASTER_BATTERY_COMPARTMENT, 0, Qt::UserRole - 1);
- }
- else if (generalSettings.auxSerialMode != UART_MODE_SBUS_TRAINER) {
- ui->trainerMode->setItemData(TRAINER_MODE_MASTER_BATTERY_COMPARTMENT, 0, Qt::UserRole - 1);
- }
-
- if (generalSettings.bluetoothMode != 2) {
- ui->trainerMode->setItemData(TRAINER_MODE_MASTER_BLUETOOTH, 0, Qt::UserRole - 1);
- ui->trainerMode->setItemData(TRAINER_MODE_SLAVE_BLUETOOTH, 0, Qt::UserRole - 1);
- }
-
- if (!IS_FAMILY_T16(firmware->getBoard())) {
- ui->trainerMode->setItemData(TRAINER_MODE_MULTI, 0, Qt::UserRole - 1);
- }
-
- ui->trainerMode->setCurrentIndex(model.trainerMode);
+ ui->formLayout_col1->setSpacing(0);
if (!IS_HORUS_OR_TARANIS(firmware->getBoard())) {
ui->label_trainerMode->hide();
ui->trainerMode->hide();
}
- ui->formLayout_col1->setSpacing(0);
+ else {
+ if (panelFilteredItemModels)
+ ui->trainerMode->setModel(panelFilteredItemModels->getItemModel(FIM_TRAINERMODE));
+ ui->trainerMode->setField(model.trainerMode);
+ connect(ui->trainerMode, SIGNAL(currentDataChanged(int)), this, SLOT(update()));
+ }
}
else {
ui->label_trainerMode->hide();
@@ -455,11 +444,11 @@ void ModulePanel::update()
}
}
else if (IS_HORUS_OR_TARANIS(board)) {
- if (model->trainerMode == TRAINER_SLAVE_JACK) {
- mask |= MASK_PPM_FIELDS | MASK_CHANNELS_RANGE | MASK_CHANNELS_COUNT;
+ if (model->trainerMode == TRAINER_MODE_SLAVE_JACK) {
+ mask |= MASK_PPM_FIELDS | MASK_SBUSPPM_FIELDS | MASK_CHANNELS_RANGE | MASK_CHANNELS_COUNT;
}
}
- else if (model->trainerMode != TRAINER_MASTER_JACK) {
+ else if (model->trainerMode != TRAINER_MODE_MASTER_JACK) {
mask |= MASK_PPM_FIELDS | MASK_CHANNELS_RANGE | MASK_CHANNELS_COUNT;
}
@@ -651,15 +640,6 @@ void ModulePanel::update()
ui->rxFreq->setVisible((mask & MASK_RX_FREQ));
}
-void ModulePanel::on_trainerMode_currentIndexChanged(int index)
-{
- if (!lock && model->trainerMode != (unsigned)index) {
- model->trainerMode = index;
- update();
- emit modified();
- }
-}
-
void ModulePanel::onProtocolChanged(int index)
{
if (!lock && module.protocol != ui->protocol->itemData(index).toUInt()) {
@@ -1010,6 +990,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
panelItemModels->registerItemModel(TimerData::countdownBeepItemModel());
panelItemModels->registerItemModel(TimerData::countdownStartItemModel());
panelItemModels->registerItemModel(TimerData::persistentItemModel());
+ panelFilteredModels->registerItemModel(new FilteredItemModel(ModelData::trainerModeItemModel(generalSettings, firmware)), FIM_TRAINERMODE);
Board::Type board = firmware->getBoard();
@@ -1249,7 +1230,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
}
if (firmware->getCapability(ModelTrainerEnable)) {
- modules[CPN_MAX_MODULES] = new ModulePanel(this, model, model.moduleData[CPN_MAX_MODULES], generalSettings, firmware, -1);
+ modules[CPN_MAX_MODULES] = new ModulePanel(this, model, model.moduleData[CPN_MAX_MODULES], generalSettings, firmware, -1, panelFilteredModels);
ui->modulesLayout->addWidget(modules[CPN_MAX_MODULES]);
connect(modules[CPN_MAX_MODULES], &ModulePanel::modified, this, &SetupPanel::modified);
}
diff --git a/companion/src/modeledit/setup.h b/companion/src/modeledit/setup.h
index 955f2189b..d2c5391ac 100644
--- a/companion/src/modeledit/setup.h
+++ b/companion/src/modeledit/setup.h
@@ -66,7 +66,8 @@ class ModulePanel : public ModelPanel
Q_OBJECT
public:
- ModulePanel(QWidget * parent, ModelData & model, ModuleData & module, GeneralSettings & generalSettings, Firmware * firmware, int moduleIdx);
+ ModulePanel(QWidget * parent, ModelData & model, ModuleData & module, GeneralSettings & generalSettings, Firmware * firmware, int moduleIdx,
+ FilteredItemModelFactory * panelFilteredItemModels = nullptr);
virtual ~ModulePanel();
virtual void update();
@@ -81,7 +82,6 @@ class ModulePanel : public ModelPanel
private slots:
void setupFailsafes();
- void on_trainerMode_currentIndexChanged(int index);
void onProtocolChanged(int index);
void on_ppmDelay_editingFinished();
void on_channelsCount_editingFinished();
diff --git a/companion/src/modeledit/setup_module.ui b/companion/src/modeledit/setup_module.ui
index 652975acd..f78bd2772 100644
--- a/companion/src/modeledit/setup_module.ui
+++ b/companion/src/modeledit/setup_module.ui
@@ -1019,7 +1019,7 @@
-
-
+
0
@@ -1035,46 +1035,6 @@
QComboBox::AdjustToContents
-
-
-
- Master/Jack
-
-
- -
-
- Slave/Jack
-
-
- -
-
- Master/SBUS Module
-
-
- -
-
- Master/CPPM Module
-
-
- -
-
- Master/SBUS in battery compartment
-
-
- -
-
- Master/Bluetooth
-
-
- -
-
- Slave/Bluetooth
-
-
- -
-
- Master/Multi
-
-
-
diff --git a/companion/src/modelprinter.cpp b/companion/src/modelprinter.cpp
index 1d7df4f93..25bee2498 100644
--- a/companion/src/modelprinter.cpp
+++ b/companion/src/modelprinter.cpp
@@ -190,9 +190,9 @@ QString ModelPrinter::printModule(int idx)
QString result;
ModuleData module = model.moduleData[(idx<0 ? CPN_MAX_MODULES : idx)];
if (idx < 0) {
- str << printLabelValue(tr("Mode"), printTrainerMode());
+ str << printLabelValue(tr("Mode"), model.trainerModeToString());
if (IS_HORUS_OR_TARANIS(firmware->getBoard())) {
- if (model.trainerMode == TRAINER_SLAVE_JACK) {
+ if (model.trainerMode == TRAINER_MODE_SLAVE_JACK) {
str << printLabelValue(tr("Channels"), QString("%1-%2").arg(module.channelsStart + 1).arg(module.channelsStart + module.channelsCount));
str << printLabelValue(tr("Frame length"), QString("%1ms").arg(printPPMFrameLength(module.ppm.frameLength)));
str << printLabelValue(tr("PPM delay"), QString("%1us").arg(module.ppm.delay));
@@ -239,31 +239,6 @@ QString ModelPrinter::printModule(int idx)
return result;
}
-QString ModelPrinter::printTrainerMode()
-{
- QString result;
- switch (model.trainerMode) {
- case TRAINER_MASTER_JACK:
- result = tr("Master/Jack");
- break;
- case TRAINER_SLAVE_JACK:
- result = tr("Slave/Jack");
- break;
- case TRAINER_MASTER_SBUS_MODULE:
- result = tr("Master/SBUS Module");
- break;
- case TRAINER_MASTER_CPPM_MODULE:
- result = tr("Master/CPPM Module");
- break;
- case TRAINER_MASTER_SBUS_BATT_COMPARTMENT:
- result = tr("Master/SBUS in battery compartment");
- break;
- default:
- result = CPN_STR_UNKNOWN_ITEM;
- }
- return result;
-}
-
QString ModelPrinter::printHeliSwashType ()
{
switch (model.swashRingData.type) {
diff --git a/companion/src/modelprinter.h b/companion/src/modelprinter.h
index 8be56bd64..6cc63a85f 100644
--- a/companion/src/modelprinter.h
+++ b/companion/src/modelprinter.h
@@ -61,7 +61,6 @@ class ModelPrinter: public QObject
QString printFlightModes(unsigned int flightModes);
QString printInputFlightModes(unsigned int flightModes);
QString printModule(int idx);
- QString printTrainerMode();
QString printCenterBeep();
QString printHeliSwashType();
QString printTrim(int flightModeIndex, int stickIndex);
diff --git a/radio/src/dataconstants.h b/radio/src/dataconstants.h
index 1c5fdc1ea..66ab681b5 100644
--- a/radio/src/dataconstants.h
+++ b/radio/src/dataconstants.h
@@ -186,6 +186,9 @@ enum ModuleIndex {
EXTERNAL_MODULE,
SPORT_MODULE,
};
+
+// TODO: simplify at an eeprom change to a single master list and use ui filters. Simplies radio conversions and both radio and companion code
+// Companion opentxeeprom.cpp will require after import and before export manipulation removed
enum TrainerMode {
TRAINER_MODE_MASTER_TRAINER_JACK,
TRAINER_MODE_SLAVE,
@@ -208,6 +211,7 @@ enum TrainerMode {
};
#endif
+// TODO: simplify at an eeprom change to a single master list and use ui filters
#define TRAINER_MODE_MIN() TRAINER_MODE_MASTER_TRAINER_JACK
#if !defined(HARDWARE_EXTERNAL_MODULE)
diff --git a/radio/src/datastructs.h b/radio/src/datastructs.h
index 765245b3e..992066203 100644
--- a/radio/src/datastructs.h
+++ b/radio/src/datastructs.h
@@ -390,7 +390,7 @@ PACK(struct TelemetrySensor {
*/
PACK(struct TrainerModuleData {
- uint8_t mode:3;
+ uint8_t mode:3; // TODO: simplify value at an eeprom change refer compile driven enum handling in dataconstants.h
uint8_t spare1:5;
uint8_t channelsStart;
int8_t channelsCount; // 0=8 channels
@@ -970,4 +970,4 @@ static inline void check_struct()
#undef CHKSIZE
}
-#endif /* BACKUP */
+#endif /* BACKUP */