diff --git a/companion/src/firmwares/eeprominterface.h b/companion/src/firmwares/eeprominterface.h index 1027428f3..0aacb422a 100644 --- a/companion/src/firmwares/eeprominterface.h +++ b/companion/src/firmwares/eeprominterface.h @@ -286,17 +286,19 @@ class Firmware typedef QList OptionsList; - explicit Firmware(const QString & id, const QString & name, Board::Type board) : - Firmware(nullptr, id, name, board) + explicit Firmware(const QString & id, const QString & name, Board::Type board, const QString & downloadId = QString(), const QString & simulatorId = QString()) : + Firmware(nullptr, id, name, board, downloadId, simulatorId) { } - explicit Firmware(Firmware * base, const QString & id, const QString & name, Board::Type board) : + explicit Firmware(Firmware * base, const QString & id, const QString & name, Board::Type board, const QString & downloadId = QString(), const QString & simulatorId = QString()) : id(id), name(name), board(board), variantBase(0), base(base), eepromInterface(nullptr), + downloadId(downloadId), + simulatorId(simulatorId), analogInputNamesLookupTable(Boards::getAnalogNamesLookupTable(board)), switchesLookupTable(Boards::getSwitchesLookupTable(board)), trimSwitchesLookupTable(Boards::getTrimSwitchesLookupTable(board)), @@ -432,6 +434,9 @@ class Firmware STRINGTAGMAPPINGFUNCS(rawSourceSpecialTypesLookupTable, RawSourceSpecialTypes); STRINGTAGMAPPINGFUNCS(rawSourceCyclicLookupTable, RawSourceCyclic); + const QString getDownloadId() { return getFirmwareBase()->downloadId.isEmpty() ? getFlavour() : getFirmwareBase()->downloadId; } + const QString getSimulatorId() { return getFirmwareBase()->simulatorId.isEmpty() ? getId() : getFirmwareBase()->simulatorId; } + protected: QString id; QString name; @@ -439,6 +444,8 @@ class Firmware unsigned int variantBase; Firmware * base; EEPROMInterface * eepromInterface; + QString downloadId; + QString simulatorId; // used by YAML encode and decode const StringTagMappingTable analogInputNamesLookupTable; diff --git a/companion/src/firmwares/opentx/opentxinterface.cpp b/companion/src/firmwares/opentx/opentxinterface.cpp index 8962e20c5..c20a83961 100644 --- a/companion/src/firmwares/opentx/opentxinterface.cpp +++ b/companion/src/firmwares/opentx/opentxinterface.cpp @@ -784,14 +784,14 @@ int OpenTxFirmware::getCapability(::Capability capability) IS_TARANIS_X7(board) || IS_JUMPER_TPRO(board) || IS_TARANIS_X9LITE(board) || IS_RADIOMASTER_TX12(board) || IS_RADIOMASTER_TX12_MK2(board) || IS_RADIOMASTER_ZORRO(board) || - IS_RADIOMASTER_BOXER(board) || IS_RADIOMASTER_TX16S(board) || + IS_RADIOMASTER_BOXER(board) || IS_RADIOMASTER_TX16S(board) || IS_JUMPER_T18(board)); case HasSoftwareSerialPower: return IS_RADIOMASTER_TX16S(board); case HasIntModuleMulti: return id.contains("internalmulti") || IS_RADIOMASTER_TX16S(board) || IS_JUMPER_T18(board) || IS_RADIOMASTER_TX12(board) || IS_JUMPER_TLITE(board) || IS_BETAFPV_LR3PRO(board) || - (IS_RADIOMASTER_ZORRO(board) && !id.contains("internalelrs")) || + (IS_RADIOMASTER_ZORRO(board) && !id.contains("internalelrs")) || IS_RADIOMASTER_BOXER(board); case HasIntModuleCRSF: return id.contains("internalcrsf"); @@ -1199,14 +1199,14 @@ void registerOpenTxFirmwares() OpenTxFirmware * firmware; /* FrSky Taranis X9D+ board */ - firmware = new OpenTxFirmware(FIRMWAREID("x9d+"), Firmware::tr("FrSky Taranis X9D+"), BOARD_TARANIS_X9DP); + firmware = new OpenTxFirmware(FIRMWAREID("x9d+"), Firmware::tr("FrSky Taranis X9D+"), BOARD_TARANIS_X9DP, "x9dp"); firmware->addOption("noras", Firmware::tr("Disable RAS (SWR)")); addOpenTxTaranisOptions(firmware); registerOpenTxFirmware(firmware); addOpenTxRfOptions(firmware, EU + FLEX + AFHDS3); /* FrSky Taranis X9D+ 2019 board */ - firmware = new OpenTxFirmware(FIRMWAREID("x9d+2019"), Firmware::tr("FrSky Taranis X9D+ 2019"), BOARD_TARANIS_X9DP_2019); + firmware = new OpenTxFirmware(FIRMWAREID("x9d+2019"), Firmware::tr("FrSky Taranis X9D+ 2019"), BOARD_TARANIS_X9DP_2019, "x9dp2019"); addOpenTxTaranisOptions(firmware); registerOpenTxFirmware(firmware); addOpenTxRfOptions(firmware, FLEX); @@ -1246,7 +1246,7 @@ void registerOpenTxFirmwares() addOpenTxRfOptions(firmware, EU + FLEX); /* FrSky X7 Access board */ - firmware = new OpenTxFirmware(FIRMWAREID("x7access"), Firmware::tr("FrSky Taranis X7 / X7S Access"), BOARD_TARANIS_X7_ACCESS); + firmware = new OpenTxFirmware(FIRMWAREID("x7access"), Firmware::tr("FrSky Taranis X7 / X7S Access"), BOARD_TARANIS_X7_ACCESS, "x7-access"); addOpenTxTaranisOptions(firmware); registerOpenTxFirmware(firmware); addOpenTxRfOptions(firmware, FLEX); @@ -1272,7 +1272,7 @@ void registerOpenTxFirmwares() addOpenTxRfOptions(firmware, EU + FLEX); /* FrSky X10 Express board */ - firmware = new OpenTxFirmware(FIRMWAREID("x10express"), Firmware::tr("FrSky Horus X10 Express / X10S Express"), BOARD_X10_EXPRESS); + firmware = new OpenTxFirmware(FIRMWAREID("x10express"), Firmware::tr("FrSky Horus X10 Express / X10S Express"), BOARD_X10_EXPRESS, "x10-access"); addOpenTxFrskyOptions(firmware); registerOpenTxFirmware(firmware); addOpenTxRfOptions(firmware, FLEX); diff --git a/companion/src/firmwares/opentx/opentxinterface.h b/companion/src/firmwares/opentx/opentxinterface.h index 9f01ee508..894143bc3 100644 --- a/companion/src/firmwares/opentx/opentxinterface.h +++ b/companion/src/firmwares/opentx/opentxinterface.h @@ -88,13 +88,13 @@ class OpenTxFirmware: public Firmware public: OpenTxFirmware(const QString & id, OpenTxFirmware * parent): - Firmware(parent, id, parent->getName(), parent->getBoard()) + Firmware(parent, id, parent->getName(), parent->getBoard(), parent->getDownloadId(), parent->getSimulatorId()) { setEEpromInterface(parent->getEEpromInterface()); } - OpenTxFirmware(const QString & id, const QString & name, const Board::Type board): - Firmware(id, name, board) + OpenTxFirmware(const QString & id, const QString & name, const Board::Type board, const QString & downloadId = QString(), const QString & simulatorId = QString()): + Firmware(id, name, board, downloadId, simulatorId) { // Note: these align with the radio NOT computer locales - TODO harmonise with ISO and one list!!! addLanguage("en"); diff --git a/companion/src/helpers.cpp b/companion/src/helpers.cpp index ccdda040c..38983c644 100644 --- a/companion/src/helpers.cpp +++ b/companion/src/helpers.cpp @@ -332,8 +332,8 @@ bool isSimulatorRunning() { return simulatorRunning; } void startSimulation(QWidget * parent, RadioData & radioData, int modelIdx) { - QString fwId = SimulatorLoader::findSimulatorByFirmwareName(getCurrentFirmware()->getId()); - if (fwId.isEmpty()) { + QString simulatorId = SimulatorLoader::findSimulatorByName(getCurrentFirmware()->getSimulatorId()); + if (simulatorId.isEmpty()) { QMessageBox::warning(NULL, CPN_STR_TTL_WARNING, QCoreApplication::translate("Companion", "Simulator for this firmware is not yet available")); @@ -348,7 +348,7 @@ void startSimulation(QWidget * parent, RadioData & radioData, int modelIdx) simuData->setCurrentModel(modelIdx); } - SimulatorMainWindow * dialog = new SimulatorMainWindow(parent, fwId, flags); + SimulatorMainWindow * dialog = new SimulatorMainWindow(parent, simulatorId, flags); dialog->setWindowModality(Qt::ApplicationModal); dialog->setAttribute(Qt::WA_DeleteOnClose); diff --git a/companion/src/simulation/simulator.h b/companion/src/simulation/simulator.h index 52ffc04e2..d572eea56 100644 --- a/companion/src/simulation/simulator.h +++ b/companion/src/simulation/simulator.h @@ -32,7 +32,7 @@ #define SIMULATOR_FLAGS_NOTX 0x01 // simulating a single model from Companion #define SIMULATOR_FLAGS_STANDALONE 0x02 // started from stanalone simulator -#define SIMULATOR_OPTIONS_VERSION 2 +#define SIMULATOR_OPTIONS_VERSION 3 namespace Simulator { @@ -129,13 +129,16 @@ struct SimulatorOptions QByteArray windowState; // SimulatorMainWindow dock/toolbar/options UI state QByteArray dbgConsoleState; // DebugOutput UI state QByteArray radioOutputsState; // RadioOutputsWidget UI state + // added in v3 + QString simulatorId; quint16 loadedVersion() const { return m_version; } //! loaded structure definition version (0 if none/error) friend QDataStream & operator << (QDataStream &out, const SimulatorOptions & o) { out << quint16(SIMULATOR_OPTIONS_VERSION) << o.startupDataType << o.firmwareId << o.dataFile << o.dataFolder - << o.sdPath << o.windowGeometry << o.controlsState << o.lcdColor << o.windowState << o.dbgConsoleState << o.radioOutputsState; + << o.sdPath << o.windowGeometry << o.controlsState << o.lcdColor << o.windowState << o.dbgConsoleState << o.radioOutputsState + << o.simulatorId; return out; } @@ -147,6 +150,8 @@ struct SimulatorOptions >> o.sdPath >> o.windowGeometry >> o.controlsState >> o.lcdColor; if (o.m_version >= 2) in >> o.windowState >> o.dbgConsoleState >> o.radioOutputsState; + if (o.m_version >= 3) + in >> o.simulatorId; } else { qWarning() << "Error loading SimulatorOptions, saved version not valid:" << o.m_version << "Expected <=" << SIMULATOR_OPTIONS_VERSION; @@ -176,7 +181,7 @@ struct SimulatorOptions friend QDebug operator << (QDebug d, const SimulatorOptions & o) { QDebugStateSaver saver(d); - d.nospace() << "SimulatorOptions: firmwareId=" << o.firmwareId << "; dataFile=" << o.dataFile << "; dataFolder=" << o.dataFolder + d.nospace() << "SimulatorOptions: firmwareId=" << o.firmwareId << "; simulatorId=" << o.simulatorId << "; dataFile=" << o.dataFile << "; dataFolder=" << o.dataFolder << "; sdPath=" << o.sdPath << "; startupDataType=" << o.startupDataType; return d; } diff --git a/companion/src/simulation/simulatorinterface.cpp b/companion/src/simulation/simulatorinterface.cpp index 9643e0eeb..bb0d24486 100644 --- a/companion/src/simulation/simulatorinterface.cpp +++ b/companion/src/simulation/simulatorinterface.cpp @@ -109,7 +109,7 @@ void SimulatorLoader::unregisterSimulators() delete lib; } -QString SimulatorLoader::findSimulatorByFirmwareName(const QString & name) +QString SimulatorLoader::findSimulatorByName(const QString & name) { int pos; QString ret; @@ -133,7 +133,7 @@ QString SimulatorLoader::findSimulatorByFirmwareName(const QString & name) SimulatorInterface * SimulatorLoader::loadSimulator(const QString & name) { SimulatorInterface * si = NULL; - QString libname = findSimulatorByFirmwareName(name); + QString libname = findSimulatorByName(name); if (libname.isEmpty()) { qWarning() << "Simulator" << name << "not found."; @@ -166,7 +166,7 @@ bool SimulatorLoader::unloadSimulator(const QString & name) { bool ret = false; #if SIMULATOR_INTERFACE_LOADER_DYNAMIC - QString simuName = findSimulatorByFirmwareName(name); + QString simuName = findSimulatorByName(name); if (simuName.isEmpty()) return ret; diff --git a/companion/src/simulation/simulatorinterface.h b/companion/src/simulation/simulatorinterface.h index 3af09c3f9..5c08e6559 100644 --- a/companion/src/simulation/simulatorinterface.h +++ b/companion/src/simulation/simulatorinterface.h @@ -184,7 +184,7 @@ class SimulatorLoader static void registerSimulators(); static void unregisterSimulators(); static QStringList getAvailableSimulators(); - static QString findSimulatorByFirmwareName(const QString & name); + static QString findSimulatorByName(const QString & name); static SimulatorInterface * loadSimulator(const QString & name); static bool unloadSimulator(const QString & name); diff --git a/companion/src/simulation/simulatormainwindow.cpp b/companion/src/simulation/simulatormainwindow.cpp index b0d40f024..711c3cc22 100644 --- a/companion/src/simulation/simulatormainwindow.cpp +++ b/companion/src/simulation/simulatormainwindow.cpp @@ -41,7 +41,7 @@ extern AppData g; // ensure what "g" means const quint16 SimulatorMainWindow::m_savedUiStateVersion = 2; -SimulatorMainWindow::SimulatorMainWindow(QWidget *parent, const QString & firmwareId, quint8 flags, Qt::WindowFlags wflags) : +SimulatorMainWindow::SimulatorMainWindow(QWidget *parent, const QString & simulatorId, quint8 flags, Qt::WindowFlags wflags) : QMainWindow(parent, wflags), ui(new Ui::SimulatorMainWindow), m_simulatorWidget(NULL), @@ -52,7 +52,7 @@ SimulatorMainWindow::SimulatorMainWindow(QWidget *parent, const QString & firmwa m_telemetryDockWidget(NULL), m_trainerDockWidget(NULL), m_outputsDockWidget(NULL), - m_simulatorId(firmwareId), + m_simulatorId(simulatorId), m_exitStatusCode(0), m_radioProfileId(g.sessionId()), m_radioSizeConstraint(Qt::Horizontal | Qt::Vertical), @@ -61,7 +61,7 @@ SimulatorMainWindow::SimulatorMainWindow(QWidget *parent, const QString & firmwa m_showMenubar(true) { if (m_simulatorId.isEmpty()) { - m_simulatorId = SimulatorLoader::findSimulatorByFirmwareName(getCurrentFirmware()->getId()); + m_simulatorId = SimulatorLoader::findSimulatorByName(getCurrentFirmware()->getSimulatorId()); } m_simulator = SimulatorLoader::loadSimulator(m_simulatorId); if (!m_simulator) { diff --git a/companion/src/simulation/simulatormainwindow.h b/companion/src/simulation/simulatormainwindow.h index e6e6be10f..c678582dc 100644 --- a/companion/src/simulation/simulatormainwindow.h +++ b/companion/src/simulation/simulatormainwindow.h @@ -49,7 +49,7 @@ class SimulatorMainWindow : public QMainWindow Q_OBJECT public: - explicit SimulatorMainWindow(QWidget * parent, const QString & firmwareId = "", quint8 flags=0, Qt::WindowFlags wflags = Qt::WindowFlags()); + explicit SimulatorMainWindow(QWidget * parent, const QString & simulatorId = "", quint8 flags=0, Qt::WindowFlags wflags = Qt::WindowFlags()); ~SimulatorMainWindow(); int getExitStatus(QString * msg = Q_NULLPTR); diff --git a/companion/src/simulation/simulatorstartupdialog.cpp b/companion/src/simulation/simulatorstartupdialog.cpp index 8d70a2b50..4e40e9fec 100644 --- a/companion/src/simulation/simulatorstartupdialog.cpp +++ b/companion/src/simulation/simulatorstartupdialog.cpp @@ -24,8 +24,11 @@ #include "appdata.h" #include "constants.h" #include "simulatorinterface.h" +#include "eeprominterface.h" #include +#include +#include using namespace Simulator; @@ -35,9 +38,12 @@ SimulatorStartupDialog::SimulatorStartupDialog(SimulatorOptions * options, int * QDialog(parent), ui(new Ui::SimulatorStartupDialog), m_options(options), - m_profileId(profId) + m_profileId(profId), + m_simProxy(nullptr) + { ui->setupUi(this); + this->setWindowIcon(QIcon(":/icon.png")); QMapIterator pi(g.getActiveProfiles()); while (pi.hasNext()) { @@ -45,7 +51,34 @@ SimulatorStartupDialog::SimulatorStartupDialog(SimulatorOptions * options, int * ui->radioProfile->addItem(pi.value(), pi.key()); } - ui->radioType->addItems(SimulatorLoader::getAvailableSimulators()); + QStandardItemModel * fwModel = new QStandardItemModel(this); + foreach(Firmware * firmware, Firmware::getRegisteredFirmwares()) { + QStandardItem * item = new QStandardItem(); + //qDebug() << "name:" << firmware->getName() << "firmware:" << firmware->getId() << "simulator:" << firmware->getSimulatorId(); + item->setText(firmware->getName()); + item->setData(firmware->getId(), IMDR_Id); + item->setData(firmware->getSimulatorId(), IMDR_SimulatorId); + fwModel->appendRow(item); + } + + QSortFilterProxyModel * fwProxy = new QSortFilterProxyModel(this); + fwProxy->setSourceModel(fwModel); + fwProxy->sort(1); + + ui->cbRadioType->setModel(fwProxy); + + QStandardItemModel * simModel = new QStandardItemModel(this); + foreach(QString sim, SimulatorLoader::getAvailableSimulators()) { + QStandardItem * item = new QStandardItem(); + item->setText(sim); + simModel->appendRow(item); + } + + m_simProxy = new QSortFilterProxyModel(this); + m_simProxy->setSourceModel(simModel); + m_simProxy->sort(1); + + ui->cbSimulator->setModel(m_simProxy); ui->optGrp_dataSource->setId(ui->optFile, SimulatorOptions::START_WITH_FILE); ui->optGrp_dataSource->setId(ui->optFolder, SimulatorOptions::START_WITH_FOLDER); @@ -58,8 +91,8 @@ SimulatorStartupDialog::SimulatorStartupDialog(SimulatorOptions * options, int * loadRadioProfile(*m_profileId); - QObject::connect(ui->radioProfile, SIGNAL(currentIndexChanged(int)), this, SLOT(onRadioProfileChanged(int))); - QObject::connect(ui->radioType, SIGNAL(currentIndexChanged(int)), this, SLOT(onRadioTypeChanged(int))); + QObject::connect(ui->radioProfile, static_cast(&QComboBox::currentIndexChanged), this, &SimulatorStartupDialog::onRadioProfileChanged); + QObject::connect(ui->cbRadioType, static_cast(&QComboBox::currentIndexChanged), this, &SimulatorStartupDialog::onRadioTypeChanged); QObject::connect(ui->btnSelectDataFile, &QToolButton::clicked, this, &SimulatorStartupDialog::onDataFileSelect); QObject::connect(ui->btnSelectDataFolder, &QToolButton::clicked, this, &SimulatorStartupDialog::onDataFolderSelect); QObject::connect(ui->btnSelectSdPath, &QToolButton::clicked, this, &SimulatorStartupDialog::onSdPathSelect); @@ -69,6 +102,7 @@ SimulatorStartupDialog::SimulatorStartupDialog(SimulatorOptions * options, int * SimulatorStartupDialog::~SimulatorStartupDialog() { delete ui; + delete m_simProxy; } void SimulatorStartupDialog::changeEvent(QEvent *e) @@ -86,12 +120,12 @@ void SimulatorStartupDialog::changeEvent(QEvent *e) // FIXME : need a better way to check for this bool SimulatorStartupDialog::usesCategorizedStorage(const QString & name) { - return name.contains(QRegExp("(x12|x10|horus|16|18|nv14)", Qt::CaseInsensitive)); + return true; } bool SimulatorStartupDialog::usesCategorizedStorage() { - return usesCategorizedStorage(ui->radioType->currentText()); + return usesCategorizedStorage(ui->cbRadioType->currentText()); } QString SimulatorStartupDialog::findRadioId(const QString & str) @@ -108,21 +142,21 @@ QString SimulatorStartupDialog::findRadioId(const QString & str) } // TODO : this could be smarter and actually look for a matching file in the folder -QString SimulatorStartupDialog::radioEepromFileName(const QString & firmwareId, QString folder) +QString SimulatorStartupDialog::radioEepromFileName(const QString & simulatorId, QString folder) { QString eepromFileName = "", ext = "bin"; if (folder.isEmpty()) folder = g.eepromDir(); - QString radioId = findRadioId(firmwareId); + QString radioId = findRadioId(simulatorId); int pos = radioId.indexOf("-"); if (pos > 0) radioId = radioId.mid(pos+1); if (usesCategorizedStorage(radioId)) ext = "etx"; - eepromFileName = QString("eeprom-%1.%2").arg(radioId, ext); + eepromFileName = QString("%1.%2").arg(radioId, ext); eepromFileName = QDir(folder).filePath(eepromFileName.toLatin1()); // qDebug() << "radioId" << radioId << "eepromFileName" << eepromFileName; @@ -163,18 +197,31 @@ void SimulatorStartupDialog::loadRadioProfile(int id) *m_options = g.profile[id].simulatorOptions(); - tmpstr = m_options->firmwareId; - if (tmpstr.isEmpty() && !g.profile[id].fwType().isEmpty()) - tmpstr = g.profile[id].fwType(); - else if (!(tmpstr2 = SimulatorLoader::findSimulatorByFirmwareName(m_options->firmwareId)).isEmpty()) - tmpstr = tmpstr2; - i = ui->radioType->findText(findRadioId(tmpstr), Qt::MatchContains); + if (m_options->firmwareId.isEmpty() && !g.profile[id].fwType().isEmpty()) + m_options->firmwareId = g.profile[id].fwType(); + + m_options->firmwareId = findRadioId(m_options->firmwareId); + + i = ui->cbRadioType->findData(m_options->firmwareId, IMDR_Id, Qt::MatchContains); if (i > -1) - ui->radioType->setCurrentIndex(i); + ui->cbRadioType->setCurrentIndex(i); + + setGlobalFirmware(m_options->firmwareId); + + // always refresh as linked simulatorId as could change over time + m_options->simulatorId = getCurrentFirmware()->getSimulatorId(); + + m_simProxy->setFilterFixedString(m_options->simulatorId); + + i = ui->cbSimulator->findText(findRadioId(m_options->simulatorId), Qt::MatchContains); + if (i > -1) + ui->cbSimulator->setCurrentIndex(i); + + //qDebug() << "firmware:" << m_options->firmwareId << "simulator:" << m_options->simulatorId; tmpstr = m_options->dataFile; if (tmpstr.isEmpty()) - tmpstr = radioEepromFileName(ui->radioType->currentText()); + tmpstr = radioEepromFileName(ui->cbRadioType->currentData().toString()); ui->dataFile->setText(tmpstr); tmpstr = m_options->dataFolder; @@ -199,8 +246,12 @@ void SimulatorStartupDialog::loadRadioProfile(int id) void SimulatorStartupDialog::accept() { + if (ui->cbSimulator->currentText() == "") + return; + *m_profileId = ui->radioProfile->currentData().toInt(); - m_options->firmwareId = ui->radioType->currentText(); + m_options->firmwareId = ui->cbRadioType->currentData().toString(); + m_options->simulatorId = ui->cbSimulator->currentText(); m_options->dataFile = ui->dataFile->text(); m_options->dataFolder = ui->dataFolder->text(); m_options->sdPath = ui->sdPath->text(); @@ -221,8 +272,21 @@ void SimulatorStartupDialog::onRadioTypeChanged(int index) { if (index < 0) return; - ui->dataFile->setText(radioEepromFileName(ui->radioType->currentText())); + + QString id = ui->cbRadioType->currentData(IMDR_Id).toString(); + ui->dataFile->setText(radioEepromFileName(id)); updateContainerTypes(); + + setGlobalFirmware(id); + + // always refresh as linked simulatorId as could change over time + id = getCurrentFirmware()->getSimulatorId(); + + m_simProxy->setFilterFixedString(id); + + const int i = ui->cbSimulator->findText(findRadioId(id), Qt::MatchContains); + if (i > -1) + ui->cbSimulator->setCurrentIndex(i); } void SimulatorStartupDialog::onDataFileSelect(bool) @@ -257,3 +321,9 @@ void SimulatorStartupDialog::onSdPathSelect(bool) ui->optSdPath->setChecked(true); } } + +void SimulatorStartupDialog::setGlobalFirmware(const QString & id) +{ + Firmware::setCurrentVariant(Firmware::getFirmwareForId(id)); + //qDebug() << "current firmware:" << getCurrentFirmware()->getId(); +} diff --git a/companion/src/simulation/simulatorstartupdialog.h b/companion/src/simulation/simulatorstartupdialog.h index ba5dc2f6a..7513f41dc 100644 --- a/companion/src/simulation/simulatorstartupdialog.h +++ b/companion/src/simulation/simulatorstartupdialog.h @@ -28,18 +28,26 @@ namespace Ui { class SimulatorStartupDialog; } +class QSortFilterProxyModel; + class SimulatorStartupDialog : public QDialog { Q_OBJECT public: + enum ItemModelDataRoles { + IMDR_Id = Qt::UserRole, + IMDR_SimulatorId + }; + Q_ENUM(ItemModelDataRoles) + explicit SimulatorStartupDialog(SimulatorOptions * options, int * profId, QWidget *parent = 0); ~SimulatorStartupDialog(); static bool usesCategorizedStorage(const QString & name); static QString findRadioId(const QString & str); - static QString radioEepromFileName(const QString & firmwareId, QString folder = ""); + static QString radioEepromFileName(const QString & simulatorId, QString folder = ""); void updateContainerTypes(); @@ -62,6 +70,9 @@ class SimulatorStartupDialog : public QDialog Ui::SimulatorStartupDialog *ui; SimulatorOptions * m_options; int * m_profileId; + QSortFilterProxyModel * m_simProxy; + + void setGlobalFirmware(const QString & id); }; #endif // SIMULATORSTARTUPDIALOG_H diff --git a/companion/src/simulation/simulatorstartupdialog.ui b/companion/src/simulation/simulatorstartupdialog.ui index 0ec41e6b1..3a523fd13 100644 --- a/companion/src/simulation/simulatorstartupdialog.ui +++ b/companion/src/simulation/simulatorstartupdialog.ui @@ -7,7 +7,7 @@ 0 0 550 - 217 + 284 @@ -97,7 +97,7 @@ Create or edit profiles using the Companion application. - + 0 @@ -110,35 +110,35 @@ The radio type specified in the selected profile is used by default. - + Data Source: - + Data File: - + Data Folder: - + SD Image Path: - + @@ -165,8 +165,8 @@ The radio type specified in the selected profile is used by default. - Radio data (.bin/.eeprom/.otx) image file to use. A new file with a default image will be created if necessary.<br /> -<b>NOTE</b>: any existing EEPROM data incompatible with the selected radio type may be overwritten! + Radio data (.etx) settings file to use. A new file with default settings will be created if necessary.<br /> +<b>NOTE</b>: any existing data incompatible with the selected radio type may be overwritten! @@ -190,7 +190,7 @@ The radio type specified in the selected profile is used by default. - + @@ -242,7 +242,7 @@ New folder(s) with default radio/model will be created here if necessary. - + @@ -294,7 +294,7 @@ The default is configured in the chosen Radio Profile. - + @@ -354,6 +354,16 @@ The default is configured in the chosen Radio Profile. + + + + Simulator: + + + + + + diff --git a/companion/src/simulation/simulatorwidget.cpp b/companion/src/simulation/simulatorwidget.cpp index bbdf635f9..65989602c 100644 --- a/companion/src/simulation/simulatorwidget.cpp +++ b/companion/src/simulation/simulatorwidget.cpp @@ -391,7 +391,7 @@ bool SimulatorWidget::useTempDataPath(bool deleteOnClose) } } -// This will save radio data from temporary folder structure back into an .etx file, eg. for Horus. +// This will save radio data from temporary folder structure back into an .etx file bool SimulatorWidget::saveTempData() { bool ret = false; @@ -919,7 +919,7 @@ void SimulatorWidget::onjoystickButtonValueChanged(int button, bool state) int btn = g.jsButton[button].button_idx(); int swtch = btn & JS_BUTTON_SWITCH_MASK; - + if (swtch < ttlSwitches) { if (btn & JS_BUTTON_3POS_DN) { // 3POS Down diff --git a/companion/src/simulator.cpp b/companion/src/simulator.cpp index f92c70593..70990795e 100644 --- a/companion/src/simulator.cpp +++ b/companion/src/simulator.cpp @@ -60,7 +60,7 @@ void showMessage(const QString & message, enum QMessageBox::Icon icon = QMessage QMessageBox msgBox; msgBox.setText("
" + message.toHtmlEscaped() + "
"); msgBox.setIcon(icon); - msgBox.setWindowTitle(QApplication::translate("SimulatorMain", "OpenTx Simulator")); + msgBox.setWindowTitle(QApplication::translate("SimulatorMain", "EdgeTx Simulator")); msgBox.exec(); } @@ -123,7 +123,7 @@ CommandLineParseResult cliOptions(SimulatorOptions * simOptions, int * profileId QApplication::translate("SimulatorMain", "path")); const QCommandLineOption optStart(QStringList() << "start-with" << "w", - QApplication::translate("SimulatorMain", "Data source type to use (applicable to Horus only). One of:") + " (file|folder|sd)", + QApplication::translate("SimulatorMain", "Data source type to use. One of:") + " (file|folder|sd)", QApplication::translate("SimulatorMain", "type")); cliOptions.addPositionalArgument(QApplication::translate("SimulatorMain", "data-source"), @@ -180,9 +180,9 @@ CommandLineParseResult cliOptions(SimulatorOptions * simOptions, int * profileId cliOptsFound = true; } - if (cliOptsFound || (simOptions->dataFile.isEmpty() && !simOptions->firmwareId.isEmpty())) { + if (cliOptsFound || (simOptions->dataFile.isEmpty() && !simOptions->simulatorId.isEmpty())) { // this constructs a new default radio data file name in the user-configured eeprom directory - simOptions->dataFile = SimulatorStartupDialog::radioEepromFileName(simOptions->firmwareId, g.eepromDir()); + simOptions->dataFile = SimulatorStartupDialog::radioEepromFileName(simOptions->simulatorId, g.eepromDir()); } if (cliOptions.isSet(optSdDir)) { @@ -231,11 +231,8 @@ CommandLineParseResult cliOptions(SimulatorOptions * simOptions, int * profileId int main(int argc, char *argv[]) { - -#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) /* From doc: This attribute must be set before Q(Gui)Application is constructed. */ QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); -#endif QApplication app(argc, argv); app.setApplicationName(APP_SIMULATOR); @@ -291,8 +288,13 @@ int main(int argc, char *argv[]) SimulatorOptions simOptions = g.profile[profileId].simulatorOptions(); // TODO : defaults should be set in Profile::init() - if (simOptions.firmwareId.isEmpty()) - simOptions.firmwareId = SimulatorLoader::findSimulatorByFirmwareName(g.profile[profileId].fwType()); + if (simOptions.firmwareId.isEmpty()) { + simOptions.firmwareId = g.profile[profileId].fwType(); + } + + // do not used saved simulatorId always refresh + simOptions.simulatorId = SimulatorLoader::findSimulatorByName(Firmware::getFirmwareForId(simOptions.firmwareId)->getSimulatorId()); + if (simOptions.dataFolder.isEmpty()) simOptions.dataFolder = g.eepromDir(); if (simOptions.sdPath.isEmpty()) @@ -309,7 +311,7 @@ int main(int argc, char *argv[]) return finish(1); // Present GUI startup options dialog if necessary - if (cliResult == CommandLineNone || profileId == -1 || simOptions.firmwareId.isEmpty() || (simOptions.dataFile.isEmpty() && simOptions.dataFolder.isEmpty())) { + if (cliResult == CommandLineNone || profileId == -1 || simOptions.simulatorId.isEmpty() || (simOptions.dataFile.isEmpty() && simOptions.dataFolder.isEmpty())) { SimulatorStartupDialog * dlg = new SimulatorStartupDialog(&simOptions, &profileId); int ret = dlg->exec(); delete dlg; @@ -322,14 +324,14 @@ int main(int argc, char *argv[]) // Validate startup options QString resultMsg; - if (profileId < 0 || simOptions.firmwareId.isEmpty() || (simOptions.dataFile.isEmpty() && simOptions.dataFolder.isEmpty() && simOptions.sdPath.isEmpty())) { + if (profileId < 0 || simOptions.simulatorId.isEmpty() || (simOptions.dataFile.isEmpty() && simOptions.dataFolder.isEmpty() && simOptions.sdPath.isEmpty())) { resultMsg = QApplication::translate("SimulatorMain", "ERROR: Couldn't start simulator, missing radio/profile/data file/folder.\n Profile ID: [%1]; Radio ID: [%2];\nData File: [%3]"); - showMessage(resultMsg.arg(profileId).arg(simOptions.firmwareId, simOptions.dataFile), QMessageBox::Critical); + showMessage(resultMsg.arg(profileId).arg(simOptions.simulatorId, simOptions.dataFile), QMessageBox::Critical); return finish(1); } - if (!g.getActiveProfiles().contains(profileId) || !SimulatorLoader::getAvailableSimulators().contains(simOptions.firmwareId)) { + if (!g.getActiveProfiles().contains(profileId) || !SimulatorLoader::getAvailableSimulators().contains(simOptions.simulatorId)) { QTextStream stream(&resultMsg); - stream << QApplication::translate("SimulatorMain", "ERROR: Radio profile or simulator firmware not found.\nProfile ID: [%1]; Radio ID: [%2]").arg(profileId).arg(simOptions.firmwareId); + stream << QApplication::translate("SimulatorMain", "ERROR: Radio profile or simulator firmware not found.\nProfile ID: [%1]; Radio ID: [%2]").arg(profileId).arg(simOptions.simulatorId); stream << sharedHelpText(); showMessage(resultMsg, QMessageBox::Critical); return finish(1); @@ -342,12 +344,13 @@ int main(int argc, char *argv[]) // Set global firmware environment Firmware::setCurrentVariant(Firmware::getFirmwareForId(simOptions.firmwareId)); + //qDebug() << "current firmware:" << getCurrentFirmware()->getId(); int result = 0; - SimulatorMainWindow * mainWindow = new SimulatorMainWindow(NULL, simOptions.firmwareId, SIMULATOR_FLAGS_STANDALONE); + SimulatorMainWindow * mainWindow = new SimulatorMainWindow(NULL, simOptions.simulatorId, SIMULATOR_FLAGS_STANDALONE); if ((result = mainWindow->getExitStatus(&resultMsg))) { if (resultMsg.isEmpty()) - resultMsg = QApplication::translate("SimulatorMain", "Uknown error during Simulator startup."); + resultMsg = QApplication::translate("SimulatorMain", "Unknown error during Simulator startup."); showMessage(resultMsg, QMessageBox::Critical); } else if (mainWindow->setOptions(simOptions, true)) { diff --git a/companion/src/updates/updateinterface.cpp b/companion/src/updates/updateinterface.cpp index 7779d16aa..e14d50512 100644 --- a/companion/src/updates/updateinterface.cpp +++ b/companion/src/updates/updateinterface.cpp @@ -780,24 +780,7 @@ bool UpdateInterface::setFilteredAssets(const UpdateParameters::AssetParams & ap void UpdateInterface::setFirmwareFlavour() { - const QStringList currVariant = getCurrentFirmware()->getId().split('-'); - - m_params->fwFlavour = ""; - - if (currVariant.size() > 1) { - m_params->fwFlavour = currVariant.at(1); - // Companion registered firmware identities (refer opentxinterface.cpp) do not always match the EdgeTX repo fw.json file - const QMap map = { - { "x7access", "x7-access" }, - { "x9d+", "x9dp" }, - { "x9d+2019", "x9dp2019" }, - { "x9ehall", "x9e-hall" }, - { "x10express", "x10-access" } - }; - QString repofw = map[m_params->fwFlavour]; - if (!repofw.isEmpty()) - m_params->fwFlavour = repofw; - } + m_params->fwFlavour = getCurrentFirmware()->getDownloadId(); } void UpdateInterface::setLanguage() diff --git a/radio/src/targets/simu/opentxsimulator.cpp b/radio/src/targets/simu/opentxsimulator.cpp index 9a9c72395..1e7c923c9 100644 --- a/radio/src/targets/simu/opentxsimulator.cpp +++ b/radio/src/targets/simu/opentxsimulator.cpp @@ -187,7 +187,8 @@ void OpenTxSimulator::readRadioData(QByteArray & dest) { #if defined(EEPROM_SIZE) QMutexLocker lckr(&m_mtxRadioData); - memcpy(dest.data(), eeprom, std::min(EEPROM_SIZE, dest.size())); + if (eeprom) + memcpy(dest.data(), eeprom, qMin(EEPROM_SIZE, dest.size())); #endif }