diff --git a/companion/src/firmwares/boards.cpp b/companion/src/firmwares/boards.cpp index 59979702681..3833ba6f5f6 100644 --- a/companion/src/firmwares/boards.cpp +++ b/companion/src/firmwares/boards.cpp @@ -813,10 +813,11 @@ StringTagMappingTable Boards::getTrimSourcesLookupTable(Board::Type board) QList Boards::getSupportedInternalModules(Board::Type board) { QList modules; + modules = {(int)MODULE_TYPE_NONE}; if (IS_TARANIS_X9DP_2019(board) || IS_TARANIS_X7_ACCESS(board)) { - modules = {(int)MODULE_TYPE_ISRM_PXX2}; + modules.append({(int)MODULE_TYPE_ISRM_PXX2}); } else if (IS_FLYSKY_NV14(board)) { - modules = {(int)MODULE_TYPE_FLYSKY}; + modules.append({(int)MODULE_TYPE_FLYSKY}); } else if (IS_FAMILY_HORUS_OR_T16(board) || IS_FAMILY_T12(board) || (IS_TARANIS_SMALL(board) && IS_ACCESS_RADIO(board))) { modules.append({ @@ -826,7 +827,7 @@ QList Boards::getSupportedInternalModules(Board::Type board) (int)MODULE_TYPE_MULTIMODULE, }); } else if (IS_TARANIS(board)) { - modules = {(int)MODULE_TYPE_XJT_PXX1}; + modules.append({(int)MODULE_TYPE_XJT_PXX1}); } return modules; diff --git a/companion/src/firmwares/boards.h b/companion/src/firmwares/boards.h index 330a5144765..16731d910d7 100644 --- a/companion/src/firmwares/boards.h +++ b/companion/src/firmwares/boards.h @@ -212,7 +212,6 @@ class Boards static QString potTypeToString(int value); static QString sliderTypeToString(int value); static QString switchTypeToString(int value); - static QString intModuleTypeToString(int value); static AbstractStaticItemModel * potTypeItemModel(); static AbstractStaticItemModel * sliderTypeItemModel(); static AbstractStaticItemModel * switchTypeItemModel(); @@ -221,7 +220,7 @@ class Boards static StringTagMappingTable getTrimSourcesLookupTable(Board::Type board); static QList getSupportedInternalModules(Board::Type board); static int getDefaultInternalModules(Board::Type board); - + protected: Board::Type m_boardType; diff --git a/companion/src/firmwares/moduledata.cpp b/companion/src/firmwares/moduledata.cpp index 25bb5aec990..7556c719b55 100644 --- a/companion/src/firmwares/moduledata.cpp +++ b/companion/src/firmwares/moduledata.cpp @@ -381,7 +381,7 @@ bool ModuleData::isProtocolAvailable(int moduleidx, unsigned int protocol, Gener Firmware *fw = getCurrentFirmware(); Board::Type board = fw->getBoard(); - if (moduleidx == 0 && Boards::getCapability(board, Board::HasInternalModuleSupport)) + if (moduleidx == 0) return (int)settings.internalModule == getTypeFromProtocol(protocol); QString id = fw->getId(); diff --git a/companion/src/generaledit/generaledit.cpp b/companion/src/generaledit/generaledit.cpp index 99884ed435c..d9b142af31a 100644 --- a/companion/src/generaledit/generaledit.cpp +++ b/companion/src/generaledit/generaledit.cpp @@ -66,9 +66,12 @@ GeneralEdit::GeneralEdit(QWidget * parent, RadioData & radioData, Firmware * fir addTab(new GeneralSetupPanel(this, generalSettings, firmware), tr("Setup")); addTab(new CustomFunctionsPanel(this, nullptr, generalSettings, firmware, editorItemModels), tr("Global Functions")); addTab(new TrainerPanel(this, generalSettings, firmware, editorItemModels), tr("Trainer")); - addTab(new HardwarePanel(this, generalSettings, firmware, editorItemModels), tr("Hardware")); + auto hwpnl = new HardwarePanel(this, generalSettings, firmware, editorItemModels); + addTab(hwpnl, tr("Hardware")); addTab(new CalibrationPanel(this, generalSettings, firmware), tr("Calibration")); + connect(hwpnl, &HardwarePanel::internalModuleChanged, this, [&] { intModChanged = true; }); + ui->tabWidget->setCurrentIndex( g.generalEditTab() ); } @@ -81,6 +84,8 @@ GeneralEdit::~GeneralEdit() void GeneralEdit::closeEvent(QCloseEvent *event) { g.generalEditTab(ui->tabWidget->currentIndex()); + if (intModChanged) + emit internalModuleChanged(); // for MidiChild to trap } void GeneralEdit::addTab(GenericPanel *panel, QString text) diff --git a/companion/src/generaledit/generaledit.h b/companion/src/generaledit/generaledit.h index 2ad27cb1cc7..8b5ae6cf4fe 100644 --- a/companion/src/generaledit/generaledit.h +++ b/companion/src/generaledit/generaledit.h @@ -47,6 +47,9 @@ class GeneralEdit : public QDialog GeneralEdit(QWidget * parent, RadioData & radioData, Firmware * firmware); ~GeneralEdit(); + protected: + virtual void closeEvent(QCloseEvent *event) override; + private: Ui::GeneralEdit *ui; GeneralSettings & generalSettings; @@ -60,6 +63,7 @@ class GeneralEdit : public QDialog signals: void modified(); + void internalModuleChanged(); private slots: void onTabModified(); @@ -71,6 +75,6 @@ class GeneralEdit : public QDialog Firmware * firmware; QVector panels; void addTab(GenericPanel *panel, QString text); - void closeEvent(QCloseEvent *event); CompoundItemModelFactory *editorItemModels; + bool intModChanged = false; }; diff --git a/companion/src/generaledit/hardware.cpp b/companion/src/generaledit/hardware.cpp index c084607b4bb..5754363ee76 100644 --- a/companion/src/generaledit/hardware.cpp +++ b/companion/src/generaledit/hardware.cpp @@ -132,15 +132,13 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings } if (Boards::getCapability(board, Board::HasInternalModuleSupport)) { + m_internalModule = generalSettings.internalModule; // to permit undo addLabel(tr("Internal module"), row, 0); - AutoComboBox *internalModule = new AutoComboBox(this); + internalModule = new AutoComboBox(this); internalModule->setModel(tabFilteredModels->getItemModel(FIM_INTERNALMODULES)); internalModule->setField(generalSettings.internalModule, this); addParams(row, internalModule); - connect(internalModule, &AutoComboBox::currentDataChanged, this, [=] () { - QMessageBox::warning(this, CPN_STR_APP_NAME, - tr("ALERT: Check each model's internal module protocol to ensure it is compatible!")); - }); + connect(internalModule, &AutoComboBox::currentDataChanged, this, &HardwarePanel::on_internalModuleChanged); } if (firmware->getCapability(HasTelemetryBaudrate)) { @@ -206,6 +204,21 @@ HardwarePanel::~HardwarePanel() delete tabFilteredModels; } +void HardwarePanel::on_internalModuleChanged() +{ + if (QMessageBox::warning(this, CPN_STR_APP_NAME, + tr("Warning: Changing the Internal module may invalidate the internal module protocol of the models!"), + QMessageBox::Cancel | QMessageBox::Ok, QMessageBox::Cancel) != QMessageBox::Ok) { + + generalSettings.internalModule = m_internalModule; + internalModule->updateValue(); + } + else { + m_internalModule = generalSettings.internalModule; + emit internalModuleChanged(); + } +} + void HardwarePanel::addStick(int index, int & row) { int col = 0; diff --git a/companion/src/generaledit/hardware.h b/companion/src/generaledit/hardware.h index 71636a2cc49..423d9bc86f0 100644 --- a/companion/src/generaledit/hardware.h +++ b/companion/src/generaledit/hardware.h @@ -25,6 +25,7 @@ class CompoundItemModelFactory; class FilteredItemModelFactory; class QGridLayout; +class AutoComboBox; class HardwarePanel : public GeneralPanel { @@ -34,11 +35,19 @@ class HardwarePanel : public GeneralPanel HardwarePanel(QWidget * parent, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * editorItemModels); virtual ~HardwarePanel(); + signals: + void internalModuleChanged(); + + private slots: + void on_internalModuleChanged(); + private: Board::Type board; CompoundItemModelFactory *editorItemModels; FilteredItemModelFactory *tabFilteredModels; QGridLayout *grid; + AutoComboBox *internalModule; + unsigned int m_internalModule = 0; void addStick(int index, int & row); void addPot(int index, int & row); diff --git a/companion/src/mainwindow.h b/companion/src/mainwindow.h index a93a8a84b84..207857c573b 100644 --- a/companion/src/mainwindow.h +++ b/companion/src/mainwindow.h @@ -50,6 +50,7 @@ class MainWindow : public QMainWindow void firmwareDownloadCompleted(); void firmwareChanged(); void startSync(); + void onInternalModuleChanged(); protected: QString getCompanionUpdateBaseUrl() const; diff --git a/companion/src/mdichild.cpp b/companion/src/mdichild.cpp index 4e4d36ebdbc..3df9cd3274b 100644 --- a/companion/src/mdichild.cpp +++ b/companion/src/mdichild.cpp @@ -32,6 +32,7 @@ #include "storage.h" #include "radiointerface.h" #include "radiodataconversionstate.h" +#include "filtereditemmodels.h" #include #include @@ -1095,9 +1096,15 @@ void MdiChild::pasteGeneralData(const QMimeData * mimeData) void MdiChild::generalEdit() { + if (getModelEditDialogsList()->count() > 0) { + QMessageBox::information(this, CPN_STR_APP_NAME, tr("Unable to Edit Radio Settings whilst models are open for editing.")); + return; + } + GeneralEdit * t = new GeneralEdit(this, radioData, firmware); connect(t, &GeneralEdit::modified, this, &MdiChild::setModified); - t->show(); + connect(t, &GeneralEdit::internalModuleChanged, this, &MdiChild::onInternalModuleChanged); // passed up from HardwarePanel >> GeneralEdit + t->exec(); } void MdiChild::copyGeneralSettings() @@ -1264,6 +1271,13 @@ void MdiChild::openModelEditWindow(int row) if (row < 0 && (row = getCurrentModel()) < 0) return; + QDialog * med = getModelEditDialog(row); + if (med) { + med->activateWindow(); + med->raise(); + return; + } + QApplication::setOverrideCursor(Qt::WaitCursor); checkAndInitModel(row); ModelData & model = radioData.models[row]; @@ -1628,3 +1642,62 @@ bool MdiChild::loadBackup() return false; #endif } + +QList * MdiChild::getModelEditDialogsList() +{ + QList *ret = new QList(); + + QList dlgs = findChildren(); + + for (QDialog *dlg : dlgs) { + ModelEdit * med = dynamic_cast(dlg); + if (med) + ret->append(dlg); + } + + return ret; +} + +QDialog * MdiChild::getModelEditDialog(int row) +{ + QList *dlgs = getModelEditDialogsList(); + + for (QDialog *dlg : *dlgs) { + ModelEdit * med = dynamic_cast(dlg); + if (med && med->getModelId() == row) + return med; + } + + return nullptr; +} + +void MdiChild::onInternalModuleChanged() +{ + FilteredItemModel * fim = new FilteredItemModel(ModuleData::protocolItemModel(radioData.generalSettings), 0 + 1/*flag cannot be 0*/); + + int cnt = 0; + + for (unsigned int i = 0; i < radioData.models.size(); i++) { + ModuleData & module = radioData.models[i].moduleData[0]; + bool found = false; + + for (int j = 0; j < fim->rowCount(); j++) { + if (fim->data(fim->index(j, 0), AbstractItemModel::IMDR_Id).toInt() == (int)module.protocol) { + found = true; + break; + } + } + + if (!found) { + module.clear(); + cnt++; + } + } + + if (cnt > 0) { + QMessageBox::warning(this, CPN_STR_APP_NAME, tr("Internal module protocol changed to OFF for %1 models!").arg(cnt)); + setModified(); + } + + delete fim; +} diff --git a/companion/src/mdichild.h b/companion/src/mdichild.h index af5aa49e869..47da91ce30d 100644 --- a/companion/src/mdichild.h +++ b/companion/src/mdichild.h @@ -117,6 +117,7 @@ class MdiChild : public QWidget void onItemSelected(const QModelIndex &); void onCurrentItemChanged(const QModelIndex &, const QModelIndex &); void onDataChanged(const QModelIndex & index); + void onInternalModuleChanged(); void generalEdit(); void copyGeneralSettings(); @@ -183,6 +184,10 @@ class MdiChild : public QWidget bool convertStorage(Board::Type from, Board::Type to, bool newFile = false); void showWarning(const QString & msg); int askQuestion(const QString & msg, QMessageBox::StandardButtons buttons = (QMessageBox::Yes | QMessageBox::No), QMessageBox::StandardButton defaultButton = QMessageBox::No); + QDialog * getChildDialog(QRegularExpression & regexp); + QDialog * getModelEditDialog(int row); + QList * getChildrenDialogsList(QRegularExpression & regexp); + QList * getModelEditDialogsList(); Ui::MdiChild * ui; TreeModel * modelsListModel; diff --git a/companion/src/modeledit/modeledit.cpp b/companion/src/modeledit/modeledit.cpp index c2f5b2c301f..a9db6fa9551 100644 --- a/companion/src/modeledit/modeledit.cpp +++ b/companion/src/modeledit/modeledit.cpp @@ -49,6 +49,7 @@ ModelEdit::ModelEdit(QWidget * parent, RadioData & radioData, int modelId, Firmw ui->setupUi(this); setWindowIcon(CompanionIcon("edit.png")); + setAttribute(Qt::WA_DeleteOnClose); restoreGeometry(g.modelEditGeo()); ui->pushButton->setIcon(CompanionIcon("simulate.png")); diff --git a/companion/src/modeledit/modeledit.h b/companion/src/modeledit/modeledit.h index 0bd4af9d8a1..84c02fa042c 100644 --- a/companion/src/modeledit/modeledit.h +++ b/companion/src/modeledit/modeledit.h @@ -48,6 +48,8 @@ class ModelEdit : public QDialog ModelEdit(QWidget * parent, RadioData & radioData, int modelId, Firmware * firmware); ~ModelEdit(); + int getModelId() { return modelId; } + protected: void closeEvent(QCloseEvent *event); diff --git a/companion/src/modeledit/setup.cpp b/companion/src/modeledit/setup.cpp index b838fc4b032..98b555c3bc0 100644 --- a/companion/src/modeledit/setup.cpp +++ b/companion/src/modeledit/setup.cpp @@ -28,6 +28,7 @@ #include "multiprotocols.h" #include "checklistdialog.h" #include "helpers.h" +#include "moduledata.h" #include @@ -240,6 +241,23 @@ ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & modul if (panelFilteredItemModels && moduleIdx >= 0) { int id = panelFilteredItemModels->registerItemModel(new FilteredItemModel(ModuleData::protocolItemModel(generalSettings), moduleIdx + 1/*flag cannot be 0*/), QString("Module Protocol %1").arg(moduleIdx)); ui->protocol->setModel(panelFilteredItemModels->getItemModel(id)); + + if (ui->protocol->findData(module.protocol) < 0) { + QString msg = tr("Warning: The internal module protocol %1 is incompatible with the hardware internal module %2 and has been set to OFF!"); + msg = msg.arg(module.protocolToString(module.protocol)).arg(ModuleData::typeToString(generalSettings.internalModule)); + + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setIcon( QMessageBox::Warning ); + msgBox->setText(msg); + msgBox->addButton( "Ok", QMessageBox::AcceptRole ); + msgBox->setWindowFlag(Qt::WindowStaysOnTopHint); + msgBox->setAttribute(Qt::WA_DeleteOnClose); // delete pointer after close + msgBox->setModal(false); + msgBox->show(); + + module.clear(); + } + ui->protocol->setField(module.protocol, this); }