From ec56d2dbdbae9a074304f39772990d66604ab52d Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Thu, 8 Dec 2016 21:26:08 +0100 Subject: [PATCH] =?UTF-8?q?[Companion]=20MdiChild=20now=20use=20a=20QTreeW?= =?UTF-8?q?idget=20instead=20of=20a=20QListWidget=20(=E2=80=A6=20(#4096)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Companion] MdiChild now use a QTreeWidget instead of a QListWidget (for Horus compatibility) * [Companion] Horus models.txt parsing / writing implemented * Fix for QT53 (#4109) --- companion/src/eeprominterface.h | 29 +- companion/src/firmwares/er9x/er9xeeprom.cpp | 2 +- .../src/firmwares/ersky9x/ersky9xeeprom.cpp | 2 +- .../src/firmwares/opentx/opentxeeprom.cpp | 9 +- .../src/firmwares/opentx/opentxinterface.cpp | 183 +++--- companion/src/helpers.cpp | 2 +- companion/src/mdichild.cpp | 33 +- companion/src/mdichild.h | 11 +- companion/src/mdichild.ui | 6 +- companion/src/modeledit/setup.cpp | 8 +- companion/src/modeledit/setup_module.ui | 4 +- companion/src/modelslist.cpp | 521 ++++++++++-------- companion/src/modelslist.h | 11 +- companion/src/storage/storage_sdcard.cpp | 5 +- companion/src/storage/xmlinterface.cpp | 2 +- 15 files changed, 443 insertions(+), 385 deletions(-) diff --git a/companion/src/eeprominterface.h b/companion/src/eeprominterface.h index f7b06a609..08de67b62 100644 --- a/companion/src/eeprominterface.h +++ b/companion/src/eeprominterface.h @@ -1079,7 +1079,9 @@ class ModelData { QVector mixes(int channel) const; bool used; + char category[15+1]; char name[15+1]; + char filename[16+1]; TimerData timers[CPN_MAX_TIMERS]; bool noGlobalFunctions; bool thrTrim; // Enable Throttle Trim @@ -1208,7 +1210,8 @@ class GeneralSettings { int calibMid[CPN_MAX_STICKS+CPN_MAX_POTS+CPN_MAX_MOUSE_ANALOGS]; int calibSpanNeg[CPN_MAX_STICKS+CPN_MAX_POTS+CPN_MAX_MOUSE_ANALOGS]; int calibSpanPos[CPN_MAX_STICKS+CPN_MAX_POTS+CPN_MAX_MOUSE_ANALOGS]; - unsigned int currModel; // 0..15 + unsigned int currModelIndex; + char currModelFilename[16+1]; unsigned int contrast; unsigned int vBatWarn; int txVoltageCalibration; @@ -1321,6 +1324,30 @@ class RadioData { public: GeneralSettings generalSettings; ModelData models[CPN_MAX_MODELS]; + + void setCurrentModel(unsigned int index) + { + generalSettings.currModelIndex = index; + strcpy(generalSettings.currModelFilename, models[index].filename); + } + + QString getNextModelFilename() + { + char filename[sizeof(ModelData::filename)]; + int index = 0; + bool found = true; + while (found) { + sprintf(filename, "model%d.bin", ++index); + found = false; + for (int i=0; i(modelData.customScreenData[i], true, "Custom screen blob")); + internalField.Append(new CharField<610>(modelData.customScreenData[i], false, "Custom screen blob")); } - internalField.Append(new CharField<216>(modelData.topbarData, true, "Top bar blob")); + internalField.Append(new CharField<216>(modelData.topbarData, false, "Top bar blob")); internalField.Append(new SpareBitsField<8>()); // current view } } @@ -3512,7 +3512,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, BoardEnum bo internalField.Append(new UnsignedField<16>(chkSum)); if (!IS_HORUS(board)) { - internalField.Append(new UnsignedField<8>(generalData.currModel)); + internalField.Append(new UnsignedField<8>(generalData.currModelIndex)); internalField.Append(new UnsignedField<8>(generalData.contrast)); } internalField.Append(new UnsignedField<8>(generalData.vBatWarn)); @@ -3711,8 +3711,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, BoardEnum bo for (int i=0; i(generalData.sliderName[i], "Slider name")); } - static char modelName[17+1] = "model1.bin\0 "; - internalField.Append(new CharField<17>(modelName, true, "Model name")); + internalField.Append(new CharField<17>(generalData.currModelFilename, true, "Current model filename")); } else if (IS_TARANIS(board) && version >= 217) { for (int i=0; i(radioData.generalSettings, storage.radio); - - // all models - QList models = storage.getModelsFileNames(); - qDebug() << "We have" << models.size() << "models:"; - - int index = 0; - for (QList::iterator it = storage.models.begin(); it != storage.models.end(); ++it, ++index) { - loadFromByteArray(radioData.models[index], it->data); - radioData.models[index].used = true; + + // Models + int modelIndex = 0; + QString modelList = QString(storage.modelList); + QList lines = storage.modelList.split('\n'); + QString category = QObject::tr("Unknown"); + foreach (const QByteArray & line, lines) { + if (!line.isEmpty()) { + if (line.startsWith('[') && line.endsWith(']')) { + category = line.mid(1, line.size() - 2); + } + else { + qDebug() << "Loading" << line; + foreach (const ModelFile &model, storage.models) { + if (line == model.filename) { + loadFromByteArray(radioData.models[modelIndex], model.data); + strncpy(radioData.models[modelIndex].filename, line.data(), sizeof(radioData.models[modelIndex].filename)); + strncpy(radioData.models[modelIndex].category, category.toStdString().c_str(), sizeof(radioData.models[modelIndex].category)); + radioData.models[modelIndex].used = true; + modelIndex++; + } + } + } + } } - + return 0; } @@ -253,37 +264,43 @@ int OpenTxEepromInterface::saveFile(const RadioData & radioData, const QString & { StorageSdcard storage; uint8_t version = getLastDataVersion(board); - + // models.txt - storage.modelList = QByteArray("[Models]\n"); - + storage.modelList = QByteArray(); + QString currentCategory = ""; + // radio.bin saveToByteArray(radioData.generalSettings, storage.radio, version); - + // all models for (int i=0; i(model, modelData, version); ModelFile modelFile = { modelFilename, modelData }; storage.models.append(modelFile); - storage.modelList.append(QString(" ") + modelFilename + "\n"); + QString modelCategory = model.category; + if (currentCategory != modelCategory) { + storage.modelList.append(QString().sprintf("[%s]\n", model.category)); + currentCategory = modelCategory; + } + storage.modelList.append(modelFilename + "\n"); } } - + storage.write(filename); - + return 0; } unsigned long OpenTxEepromInterface::load(RadioData &radioData, const uint8_t * eeprom, int size) { std::cout << "trying " << getName() << " import..."; - + std::bitset errors; - + if (size != getEEpromSize()) { if (size == 4096) { int notnull = false; @@ -309,24 +326,24 @@ unsigned long OpenTxEepromInterface::load(RadioData &radioData, const uint8_t * return errors.to_ulong(); } } - + if (!efile->EeFsOpen((uint8_t *) eeprom, size, board)) { std::cout << " wrong file system\n"; errors.set(WRONG_FILE_SYSTEM); return errors.to_ulong(); } - + efile->openRd(FILE_GENERAL); - + uint8_t version; if (efile->readRlc2(&version, 1) != 1) { std::cout << " no\n"; errors.set(UNKNOWN_ERROR); return errors.to_ulong(); } - + std::cout << " version " << (unsigned int) version; - + EepromLoadErrors version_error = checkVersion(version); if (version_error == OLD_VERSION) { errors.set(version_error); @@ -337,13 +354,13 @@ unsigned long OpenTxEepromInterface::load(RadioData &radioData, const uint8_t * errors.set(version_error); return errors.to_ulong(); } - + if (!loadRadioSettingsFromRLE(radioData.generalSettings, efile, version)) { std::cout << " ko\n"; errors.set(UNKNOWN_ERROR); return errors.to_ulong(); } - + std::cout << " variant " << radioData.generalSettings.variant; for (int i = 0; i < getMaxModels(); i++) { if (!loadModelFromRLE(radioData.models[i], efile, i, version, radioData.generalSettings.variant)) { @@ -352,7 +369,7 @@ unsigned long OpenTxEepromInterface::load(RadioData &radioData, const uint8_t * return errors.to_ulong(); } } - + std::cout << " ok\n"; errors.set(ALL_OK); return errors.to_ulong(); @@ -375,27 +392,27 @@ uint8_t OpenTxEepromInterface::getLastDataVersion(BoardEnum board) int OpenTxEepromInterface::save(uint8_t * eeprom, RadioData & radioData, uint8_t version, uint32_t variant) { EEPROMWarnings.clear(); - + if (version == 0) { version = getLastDataVersion(board); } - + int size = getEEpromSize(); - + efile->EeFsCreate(eeprom, size, board, version); - + if (board == BOARD_M128) { variant |= M128_VARIANT; } else if (board == BOARD_TARANIS_X9E) { variant |= TARANIS_X9E_VARIANT; } - + int result = saveRadioSettings(radioData.generalSettings, board, version, variant); if (!result) { return 0; } - + for (int i = 0; i < getMaxModels(); i++) { if (!radioData.models[i].isEmpty()) { result = saveModel(i, radioData.models[i], version, variant); @@ -404,7 +421,7 @@ int OpenTxEepromInterface::save(uint8_t * eeprom, RadioData & radioData, uint8_t } } } - + if (!EEPROMWarnings.empty()) { QString msg; int noErrorsToDisplay = std::min((int) EEPROMWarnings.size(), 10); @@ -420,7 +437,7 @@ int OpenTxEepromInterface::save(uint8_t * eeprom, RadioData & radioData, uint8_t QObject::tr("Warning"), QObject::tr("EEPROM saved with these warnings:") + "\n" + msg); } - + return size; } @@ -428,15 +445,15 @@ int OpenTxEepromInterface::getSize(const ModelData &model) { if (IS_SKY9X(board)) return 0; - + if (model.isEmpty()) return 0; - + QByteArray tmp(EESIZE_MAX, 0); efile->EeFsCreate((uint8_t *) tmp.data(), EESIZE_MAX, board, 255/*version max*/); - + OpenTxModelData open9xModel((ModelData &) model, board, 255/*version max*/, GetCurrentFirmware()->getVariantNumber()); - + QByteArray eeprom; open9xModel.Export(eeprom); int sz = efile->writeRlc2(0, FILE_TYP_MODEL, (const uint8_t *) eeprom.constData(), eeprom.size()); @@ -450,13 +467,13 @@ int OpenTxEepromInterface::getSize(const GeneralSettings &settings) { if (IS_SKY9X(board)) return 0; - + QByteArray tmp(EESIZE_MAX, 0); efile->EeFsCreate((uint8_t *) tmp.data(), EESIZE_MAX, board, 255); - + OpenTxGeneralData open9xGeneral((GeneralSettings &) settings, board, 255, GetCurrentFirmware()->getVariantNumber()); // open9xGeneral.Dump(); - + QByteArray eeprom; open9xGeneral.Export(eeprom); int sz = efile->writeRlc2(0, FILE_TYP_GENERAL, (const uint8_t *) eeprom.constData(), eeprom.size()); @@ -798,9 +815,9 @@ QString OpenTxFirmware::getAnalogInputName(unsigned int index) QObject::tr("Ail") }; return sticks[index]; } - + index -= 4; - + if (IS_9X(board) || IS_2560(board) || IS_SKY9X(board)) { const QString pots[] = { QObject::tr("P1"), QObject::tr("P2"), @@ -899,10 +916,10 @@ bool OpenTxFirmware::isTelemetrySourceAvailable(int source) { if (IS_TARANIS(board) && (source == TELEMETRY_SOURCE_RSSI_TX)) return false; - + if (source == TELEMETRY_SOURCE_DTE) return false; - + return true; } @@ -1057,7 +1074,7 @@ EepromLoadErrors OpenTxEepromInterface::checkVersion(unsigned int version) default: return NOT_OPENTX; } - + return ALL_OK; } @@ -1090,7 +1107,7 @@ bool OpenTxEepromInterface::checkVariant(unsigned int version, unsigned int vari return false; } } - + return true; } @@ -1118,15 +1135,15 @@ OpenTxEepromInterface::loadModelFromBackup(ModelData & model, const uint8_t * da unsigned long OpenTxEepromInterface::loadBackup(RadioData &radioData, const uint8_t * eeprom, int esize, int index) { std::bitset errors; - + std::cout << "trying " << getName() << " backup import..."; - + if (esize < 8 || memcmp(eeprom, "o9x", 3) != 0) { std::cout << " no\n"; errors.set(WRONG_SIZE); return errors.to_ulong(); } - + BoardEnum backupBoard = (BoardEnum) -1; switch (eeprom[3]) { case 0x33: @@ -1143,20 +1160,20 @@ unsigned long OpenTxEepromInterface::loadBackup(RadioData &radioData, const uint errors.set(UNKNOWN_BOARD); return errors.to_ulong(); } - + if (backupBoard != board) { std::cout << " not right board\n"; errors.set(WRONG_BOARD); return errors.to_ulong(); } - + uint8_t version = eeprom[4]; uint8_t bcktype = eeprom[5]; uint16_t size = ((uint16_t) eeprom[7] << 8) + eeprom[6]; uint16_t variant = ((uint16_t) eeprom[9] << 8) + eeprom[8]; - + std::cout << " version " << (unsigned int) version << " "; - + EepromLoadErrors version_error = checkVersion(version); if (version_error == OLD_VERSION) { errors.set(version_error); @@ -1167,13 +1184,13 @@ unsigned long OpenTxEepromInterface::loadBackup(RadioData &radioData, const uint errors.set(version_error); return errors.to_ulong(); } - + if (size > esize - 8) { std::cout << " wrong size\n"; errors.set(WRONG_SIZE); return errors.to_ulong(); } - + if (bcktype == 'M') { if (!loadModelFromBackup(radioData.models[index], &eeprom[8], size, version, variant)) { std::cout << " ko\n"; @@ -1186,7 +1203,7 @@ unsigned long OpenTxEepromInterface::loadBackup(RadioData &radioData, const uint errors.set(BACKUP_NOT_SUPPORTED); return errors.to_ulong(); } - + std::cout << " ok\n"; errors.set(ALL_OK); return errors.to_ulong(); @@ -1205,7 +1222,7 @@ QString OpenTxFirmware::getFirmwareUrl() { QString url = getFirmwareBaseUrl(); QByteArray data = QUrl::toPercentEncoding(id); - + if (IS_ARM(board)) url.append(QString("/getfw.php?fw=%1.bin").arg((QString) data)); else @@ -1275,7 +1292,7 @@ void addOpenTxLcdOptions(OpenTxFirmware * firmware) void registerOpenTxFirmwares() { OpenTxFirmware * firmware; - + Option ext_options[] = {{"frsky", QObject::tr("Support for frsky telemetry mod"), FRSKY_VARIANT}, {"telemetrez", QObject::tr("Support for telemetry easy board"), FRSKY_VARIANT}, {"jeti", QObject::tr("Support for jeti telemetry mod"), 0}, @@ -1295,36 +1312,36 @@ void registerOpenTxFirmwares() Option dsm2_options[] = {{"DSM2", QObject::tr("Support for DSM2 modules"), 0}, {"DSM2PPM", QObject::tr("Support for DSM2 modules using ppm instead of true serial"), 0}, {NULL}}; - + /* FrSky Taranis X9D+ board */ firmware = new OpenTxFirmware("opentx-x9d+", QObject::tr("FrSky Taranis X9D+"), BOARD_TARANIS_X9DP); addOpenTxTaranisOptions(firmware); firmwares.push_back(firmware); - + /* FrSky Taranis X9D board */ firmware = new OpenTxFirmware("opentx-x9d", QObject::tr("FrSky Taranis X9D"), BOARD_TARANIS_X9D); firmware->addOption("haptic", QObject::tr("Haptic module installed")); addOpenTxTaranisOptions(firmware); firmwares.push_back(firmware); - + /* FrSky Taranis X9E board */ firmware = new OpenTxFirmware("opentx-x9e", QObject::tr("FrSky Taranis X9E"), BOARD_TARANIS_X9E); firmware->addOption("shutdownconfirm", QObject::tr("Confirmation before radio shutdown")); firmware->addOption("horussticks", QObject::tr("Horus gimbals installed (Hall sensors)")); addOpenTxTaranisOptions(firmware); firmwares.push_back(firmware); - + /* FrSky X7D board */ firmware = new OpenTxFirmware("opentx-x7d", QObject::tr("FrSky X7D"), BOARD_X7D); addOpenTxTaranisOptions(firmware); firmwares.push_back(firmware); - + /* FrSky Horus board */ firmware = new OpenTxFirmware("opentx-horus", QObject::tr("FrSky Horus"), BOARD_HORUS); addOpenTxFrskyOptions(firmware); firmware->addOption("pcbdev", QObject::tr("Use ONLY with first DEV pcb version")); firmwares.push_back(firmware); - + /* 9XR-Pro */ firmware = new OpenTxFirmware("opentx-9xrpro", QObject::tr("Turnigy 9XR-PRO"), BOARD_9XRPRO); firmware->addOption("heli", QObject::tr("Enable HELI menu and cyclic mix support")); @@ -1344,7 +1361,7 @@ void registerOpenTxFirmwares() firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); addOpenTxCommonOptions(firmware); firmwares.push_back(firmware); - + /* 9XR board with M128 chip */ firmware = new OpenTxFirmware("opentx-9xr128", QObject::tr("Turnigy 9XR with m128 chip"), BOARD_M128); firmware->addOptions(extr_options); @@ -1373,7 +1390,7 @@ void registerOpenTxFirmwares() firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); addOpenTxCommonOptions(firmware); firmwares.push_back(firmware); - + /* 9XR board */ firmware = new OpenTxFirmware("opentx-9xr", QObject::tr("Turnigy 9XR"), BOARD_STOCK); firmware->addOptions(extr_options); @@ -1407,7 +1424,7 @@ void registerOpenTxFirmwares() firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); addOpenTxCommonOptions(firmware); firmwares.push_back(firmware); - + /* 9x board */ firmware = new OpenTxFirmware("opentx-9x", QObject::tr("9X with stock board"), BOARD_STOCK); firmware->addOptions(ext_options); @@ -1444,7 +1461,7 @@ void registerOpenTxFirmwares() firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); addOpenTxCommonOptions(firmware); firmwares.push_back(firmware); - + /* 9x board with M128 chip */ firmware = new OpenTxFirmware("opentx-9x128", QObject::tr("9X with stock board and m128 chip"), BOARD_M128); firmware->addOptions(ext_options); @@ -1475,7 +1492,7 @@ void registerOpenTxFirmwares() firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); addOpenTxCommonOptions(firmware); firmwares.push_back(firmware); - + /* ar9x board */ firmware = new OpenTxFirmware("opentx-ar9x", QObject::tr("9X with AR9X board"), BOARD_AR9X); firmware->addOption("heli", QObject::tr("Enable HELI menu and cyclic mix support")); @@ -1498,7 +1515,7 @@ void registerOpenTxFirmwares() // firmware->addOption("volume", QObject::tr("i2c volume control added")); addOpenTxCommonOptions(firmware); firmwares.push_back(firmware); - + /* Sky9x board */ firmware = new OpenTxFirmware("opentx-sky9x", QObject::tr("9X with Sky9x board"), BOARD_SKY9X); firmware->addOption("heli", QObject::tr("Enable HELI menu and cyclic mix support")); @@ -1519,7 +1536,7 @@ void registerOpenTxFirmwares() firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); addOpenTxCommonOptions(firmware); firmwares.push_back(firmware); - + /* Gruvin9x board */ firmware = new OpenTxFirmware("opentx-gruvin9x", QObject::tr("9X with Gruvin9x board"), BOARD_GRUVIN9X); firmware->addOption("heli", QObject::tr("Enable heli menu and cyclic mix support")); @@ -1545,7 +1562,7 @@ void registerOpenTxFirmwares() firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); addOpenTxCommonOptions(firmware); firmwares.push_back(firmware); - + /* MEGA2560 board */ firmware = new OpenTxFirmware("opentx-mega2560", QObject::tr("DIY MEGA2560 radio"), BOARD_MEGA2560); addOpenTxLcdOptions(firmware); @@ -1576,7 +1593,7 @@ void registerOpenTxFirmwares() firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); addOpenTxCommonOptions(firmware); firmwares.push_back(firmware); - + default_firmware_variant = GetFirmware("opentx-x9d+"); current_firmware_variant = default_firmware_variant; } diff --git a/companion/src/helpers.cpp b/companion/src/helpers.cpp index 436cd4822..7908afd35 100644 --- a/companion/src/helpers.cpp +++ b/companion/src/helpers.cpp @@ -813,7 +813,7 @@ void startSimulation(QWidget * parent, RadioData & radioData, int modelIdx) unsigned int flags = 0; if (modelIdx >= 0) { flags |= SIMULATOR_FLAGS_NOTX; - simuData->generalSettings.currModel = modelIdx; + simuData->setCurrentModel(modelIdx); } if (radioData.generalSettings.stickMode & 1) { flags |= SIMULATOR_FLAGS_STICK_MODE_LEFT; diff --git a/companion/src/mdichild.cpp b/companion/src/mdichild.cpp index 88dae8cc3..ac45c4e4e 100644 --- a/companion/src/mdichild.cpp +++ b/companion/src/mdichild.cpp @@ -33,8 +33,6 @@ #include "wizarddialog.h" #include "flashfirmwaredialog.h" #include "storage_eeprom.h" -#include "storage_sdcard.h" -#include #if defined WIN32 || !defined __GNUC__ #include @@ -45,19 +43,19 @@ MdiChild::MdiChild(): QWidget(), - ui(new Ui::mdiChild), + ui(new Ui::MdiChild), firmware(GetCurrentFirmware()), isUntitled(true), fileChanged(false) { ui->setupUi(this); setWindowIcon(CompanionIcon("open.png")); - ui->SimulateTxButton->setIcon(CompanionIcon("simulate.png")); + ui->simulateButton->setIcon(CompanionIcon("simulate.png")); setAttribute(Qt::WA_DeleteOnClose); - + eepromInterfaceChanged(); - if (!(this->isMaximized() || this->isMinimized())) { + if (!(isMaximized() || isMinimized())) { adjustSize(); } } @@ -67,27 +65,14 @@ MdiChild::~MdiChild() delete ui; } -void MdiChild::qSleep(int ms) -{ - if (ms<0) - return; - -#if defined WIN32 || !defined __GNUC__ - Sleep(uint(ms)); -#else - struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 }; - nanosleep(&ts, NULL); -#endif -} - void MdiChild::eepromInterfaceChanged() { ui->modelsList->refreshList(); if (GetCurrentFirmware()->getBoard() == BOARD_HORUS && !HORUS_READY_FOR_RELEASE()) { - ui->SimulateTxButton->setEnabled(false); - } + ui->simulateButton->setEnabled(false); + } else { - ui->SimulateTxButton->setEnabled(GetCurrentFirmware()->getCapability(Simulation)); + ui->simulateButton->setEnabled(GetCurrentFirmware()->getCapability(Simulation)); } updateTitle(); } @@ -133,7 +118,7 @@ void MdiChild::setModified() documentWasModified(); } -void MdiChild::on_SimulateTxButton_clicked() +void MdiChild::on_simulateButton_clicked() { startSimulation(this, radioData, -1); } @@ -158,7 +143,7 @@ void MdiChild::modelEdit() { int row = getCurrentRow(); - if (row == 0){ + if (row == 0) { generalEdit(); } else { diff --git a/companion/src/mdichild.h b/companion/src/mdichild.h index 0bfbf67d2..34603e4f6 100644 --- a/companion/src/mdichild.h +++ b/companion/src/mdichild.h @@ -25,10 +25,10 @@ #include "eeprominterface.h" namespace Ui { -class mdiChild; +class MdiChild; } -#define ER9X_EEPROM_FILE_TYPE "ER9X_EEPROM_FILE" +#define ER9X_EEPROM_FILE_TYPE "ER9X_EEPROM_FILE" #define EEPE_EEPROM_FILE_HEADER "EEPE EEPROM FILE" #define EEPE_MODEL_FILE_HEADER "EEPE MODEL FILE" @@ -65,8 +65,7 @@ class MdiChild : public QWidget private slots: void documentWasModified(); - void on_SimulateTxButton_clicked(); - void qSleep(int ms); + void on_simulateButton_clicked(); public slots: void checkAndInitModel(int row); @@ -90,8 +89,8 @@ class MdiChild : public QWidget QString strippedName(const QString & fullFileName); bool loadOtxFile(const QString & fileName); - Ui::mdiChild * ui; - + Ui::MdiChild * ui; + QString curFile; Firmware * firmware; diff --git a/companion/src/mdichild.ui b/companion/src/mdichild.ui index 538e36b74..88f20161c 100644 --- a/companion/src/mdichild.ui +++ b/companion/src/mdichild.ui @@ -1,7 +1,7 @@ - mdiChild - + MdiChild + 0 @@ -18,7 +18,7 @@ - + Simulate Tx diff --git a/companion/src/modeledit/setup.cpp b/companion/src/modeledit/setup.cpp index e38845677..2946e1779 100644 --- a/companion/src/modeledit/setup.cpp +++ b/companion/src/modeledit/setup.cpp @@ -356,10 +356,10 @@ void ModulePanel::update() } ui->multiSubType->setCurrentIndex(module.subType); - ui->cb_autoBind->setVisible(mask & MASK_MULTIMODULE); - ui->cb_autoBind->setChecked(module.multi.autoBindMode ? Qt::Checked : Qt::Unchecked); - ui->cb_lowPower->setVisible(mask & MASK_MULTIMODULE); - ui->cb_lowPower->setChecked(module.multi.lowPowerMode ? Qt::Checked : Qt::Unchecked); + ui->autoBind->setVisible(mask & MASK_MULTIMODULE); + ui->autoBind->setChecked(module.multi.autoBindMode ? Qt::Checked : Qt::Unchecked); + ui->lowPower->setVisible(mask & MASK_MULTIMODULE); + ui->lowPower->setChecked(module.multi.lowPowerMode ? Qt::Checked : Qt::Unchecked); if (firmware->getCapability(HasFailsafe)) { diff --git a/companion/src/modeledit/setup_module.ui b/companion/src/modeledit/setup_module.ui index 846a881a9..770679f03 100644 --- a/companion/src/modeledit/setup_module.ui +++ b/companion/src/modeledit/setup_module.ui @@ -609,14 +609,14 @@ - + Bind on startup - + Low Power diff --git a/companion/src/modelslist.cpp b/companion/src/modelslist.cpp index 777906c5c..1652f27e1 100644 --- a/companion/src/modelslist.cpp +++ b/companion/src/modelslist.cpp @@ -34,25 +34,43 @@ class DragDropHeader { uint8_t models[CPN_MAX_MODELS]; }; -ModelsListWidget::ModelsListWidget(QWidget *parent): - QListWidget(parent) +ModelsListWidget::ModelsListWidget(QWidget * parent): + QTreeWidget(parent) { - setFont(QFont("Courier New",12)); - radioData = &((MdiChild *)parent)->radioData; - refreshList(); - + BoardEnum board = GetCurrentFirmware()->getBoard(); + QStringList labels; + labels << tr("Index") << tr("Name"); + if (!(IS_HORUS(board) || IS_SKY9X(board))) { + labels << tr("Size"); + } + setColumnCount(labels.size()); + setHeaderLabels(labels); + setColumnWidth(0, 50); + setColumnWidth(2, 100); + connect(this, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(OpenEditWindow())); connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(ShowContextMenu(const QPoint&))); - connect(this, SIGNAL(currentRowChanged(int)), this, SLOT(viableModelSelected(int))); + connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(onCurrentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *))); setContextMenuPolicy(Qt::CustomContextMenu); + setSelectionBehavior(QAbstractItemView::SelectRows); setSelectionMode(QAbstractItemView::ExtendedSelection); setDragEnabled(true); setAcceptDrops(true); setDragDropOverwriteMode(true); setDropIndicatorShown(true); - + if (!IS_HORUS(board)) { + setIndentation(0); + } + active_highlight_color = palette().color(QPalette::Active, QPalette::Highlight); + + radioData = &((MdiChild *)parent)->radioData; + refreshList(); + + for (int i=0; imimeData(); bool hasData = mimeData->hasFormat("application/x-companion"); - contextMenu.addAction(CompanionIcon("edit.png"), tr("&Edit"),this,SLOT(EditModel())); - contextMenu.addAction(CompanionIcon("open.png"), tr("&Restore from backup"),this,SLOT(LoadBackup())); - contextMenu.addAction(CompanionIcon("wizard.png"), tr("&Model Wizard"),this,SLOT(OpenWizard())); + contextMenu.addAction(CompanionIcon("edit.png"), tr("&Edit"), this, SLOT(EditModel())); + contextMenu.addAction(CompanionIcon("open.png"), tr("&Restore from backup"), this, SLOT(LoadBackup())); + contextMenu.addAction(CompanionIcon("wizard.png"), tr("&Model Wizard"), this, SLOT(OpenWizard())); contextMenu.addSeparator(); - contextMenu.addAction(CompanionIcon("clear.png"), tr("&Delete"),this,SLOT(confirmDelete()),tr("Delete")); - contextMenu.addAction(CompanionIcon("copy.png"), tr("&Copy"),this,SLOT(copy()),tr("Ctrl+C")); - contextMenu.addAction(CompanionIcon("cut.png"), tr("&Cut"),this,SLOT(cut()),tr("Ctrl+X")); - contextMenu.addAction(CompanionIcon("paste.png"), tr("&Paste"),this,SLOT(paste()),tr("Ctrl+V"))->setEnabled(hasData); - contextMenu.addAction(CompanionIcon("duplicate.png"), tr("D&uplicate"),this,SLOT(duplicate()),tr("Ctrl+U")); + contextMenu.addAction(CompanionIcon("clear.png"), tr("&Delete"), this, SLOT(confirmDelete()), tr("Delete")); + contextMenu.addAction(CompanionIcon("copy.png"), tr("&Copy"), this, SLOT(copy()), tr("Ctrl+C")); + contextMenu.addAction(CompanionIcon("cut.png"), tr("&Cut"), this, SLOT(cut()), tr("Ctrl+X")); + contextMenu.addAction(CompanionIcon("paste.png"), tr("&Paste"), this, SLOT(paste()), tr("Ctrl+V"))->setEnabled(hasData); + contextMenu.addAction(CompanionIcon("duplicate.png"), tr("D&uplicate"), this, SLOT(duplicate()), tr("Ctrl+U")); contextMenu.addSeparator(); - contextMenu.addAction(CompanionIcon("currentmodel.png"), tr("&Use as default"),this,SLOT(setdefault())); + contextMenu.addAction(CompanionIcon("currentmodel.png"), tr("&Use as default"), this, SLOT(setdefault())); contextMenu.addSeparator(); - contextMenu.addAction(CompanionIcon("print.png"), tr("P&rint model"),this, SLOT(print()),QKeySequence(tr("Ctrl+P"))); + contextMenu.addAction(CompanionIcon("print.png"), tr("P&rint model"), this, SLOT(print()),QKeySequence(tr("Ctrl+P"))); contextMenu.addSeparator(); - contextMenu.addAction(CompanionIcon("simulate.png"), tr("&Simulate model"),this, SLOT(simulate()),tr("Alt+S")); + contextMenu.addAction(CompanionIcon("simulate.png"), tr("&Simulate model"), this, SLOT(simulate()), tr("Alt+S")); } else { // context menu for radio settings - contextMenu.addAction(CompanionIcon("edit.png"), tr("&Edit"),this,SLOT(EditModel())); + contextMenu.addAction(CompanionIcon("edit.png"), tr("&Edit"), this, SLOT(EditModel())); } contextMenu.exec(globalPos); } +int ModelsListWidget::currentRow() const +{ + return indexOfTopLevelItem(currentItem()); +} + void ModelsListWidget::EditModel() { ((MdiChild *)parent())->modelEdit(); @@ -120,189 +143,192 @@ void ModelsListWidget::print() void ModelsListWidget::setdefault() { - if (currentRow()==0) return; - unsigned int currModel = currentRow() - 1; - if (!radioData->models[currModel].isEmpty() && radioData->generalSettings.currModel != currModel) { - radioData->generalSettings.currModel = currModel; - refreshList(); - ((MdiChild *)parent())->setModified(); + if (currentRow() > 0) { + unsigned int currModel = currentRow() - 1; + if (!radioData->models[currModel].isEmpty() && radioData->generalSettings.currModelIndex != currModel) { + radioData->setCurrentModel(currModel); + refreshList(); + ((MdiChild *) parent())->setModified(); + } } } - void ModelsListWidget::mousePressEvent(QMouseEvent *event) { - if (event->button() == Qt::LeftButton) - dragStartPosition = event->pos(); + if (event->button() == Qt::LeftButton) + dragStartPosition = event->pos(); - QListWidget::mousePressEvent(event); + QTreeWidget::mousePressEvent(event); } void ModelsListWidget::mouseMoveEvent(QMouseEvent *event) { - if (!(event->buttons() & Qt::LeftButton)) - return; - if ((event->pos() - dragStartPosition).manhattanLength() - < QApplication::startDragDistance()) - return; + if (!(event->buttons() & Qt::LeftButton)) + return; + + if ((event->pos() - dragStartPosition).manhattanLength() < QApplication::startDragDistance()) + return; - QDrag *drag = new QDrag(this); + QDrag * drag = new QDrag(this); - QByteArray gmData; - doCopy(&gmData); + QByteArray gmData; + doCopy(&gmData); - QMimeData *mimeData = new QMimeData; - mimeData->setData("application/x-companion", gmData); + QMimeData * mimeData = new QMimeData; + mimeData->setData("application/x-companion", gmData); - drag->setMimeData(mimeData); + drag->setMimeData(mimeData); - //Qt::DropAction dropAction = - drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction); + //Qt::DropAction dropAction = drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction); - //if(dropAction==Qt::MoveAction) + //if(dropAction==Qt::MoveAction) - // QListWidget::mouseMoveEvent(event); + // QTreeWidget::mouseMoveEvent(event); } void ModelsListWidget::saveSelection() { currentSelection.current_item = currentItem(); - for (int i=0; igetMaxModels()+1; ++i) - currentSelection.selected[i] = item(i)->isSelected(); + for (int i=0; igetMaxModels()+1; ++i) { + currentSelection.selected[i] = selectionModel()->isSelected(model()->index(i, 0)); + } } void ModelsListWidget::restoreSelection() { setCurrentItem(currentSelection.current_item); - for (int i=0; igetMaxModels()+1; ++i) - item(i)->setSelected(currentSelection.selected[i]); + for (int i=0; igetMaxModels()+1; ++i) { + selectionModel()->select(model()->index(i, 0), currentSelection.selected[i] ? QItemSelectionModel::Select : QItemSelectionModel::Deselect); + } } void ModelsListWidget::dragEnterEvent(QDragEnterEvent *event) { - if (event->mimeData()->hasFormat("application/x-companion")) - { - event->acceptProposedAction(); - saveSelection(); - } + if (event->mimeData()->hasFormat("application/x-companion")) { + event->acceptProposedAction(); + saveSelection(); + } } void ModelsListWidget::dragLeaveEvent(QDragLeaveEvent *) { - restoreSelection(); + restoreSelection(); } void ModelsListWidget::dragMoveEvent(QDragMoveEvent *event) { - int row=this->indexAt(event->pos()).row(); - const QMimeData *mimeData = event->mimeData(); - if (mimeData->hasFormat("application/x-companion")) - { - QByteArray gmData = mimeData->data("application/x-companion"); - event->acceptProposedAction(); - clearSelection(); - DragDropHeader *header = (DragDropHeader *)gmData.data(); - if (row >= 0) { - if (header->general_settings) - item(0)->setSelected(true); - for (int i=row, end=std::min(GetEepromInterface()->getMaxModels()+1, row+header->models_count); isetSelected(true); - } + int row = indexAt(event->pos()).row(); + const QMimeData * mimeData = event->mimeData(); + if (mimeData->hasFormat("application/x-companion")) { + QByteArray gmData = mimeData->data("application/x-companion"); + event->acceptProposedAction(); + clearSelection(); + DragDropHeader * header = (DragDropHeader *)gmData.data(); + if (row >= 0) { + if (header->general_settings) + selectionModel()->select(model()->index(0, 0), QItemSelectionModel::Select); + for (int i=row, end=std::min(GetEepromInterface()->getMaxModels()+1, row+header->models_count); iselect(model()->index(i, 0), QItemSelectionModel::Select); } + } } void ModelsListWidget::dropEvent(QDropEvent *event) { - int row = this->indexAt(event->pos()).row(); - if (row < 0) - return; + int row = this->indexAt(event->pos()).row(); + if (row < 0) + return; - // QMessageBox::warning(this, tr("Companion"),tr("Index :%1").arg(row)); - const QMimeData *mimeData = event->mimeData(); + // QMessageBox::warning(this, tr("Companion"), tr("Index :%1").arg(row)); + const QMimeData * mimeData = event->mimeData(); - if(mimeData->hasFormat("application/x-companion")) - { - QByteArray gmData = mimeData->data("application/x-companion"); - if (event->source() && event->dropAction() == Qt::MoveAction) - ((ModelsListWidget*)event->source())->doCut(&gmData); - doPaste(&gmData, row); - clearSelection(); - setCurrentItem(item(row)); - DragDropHeader *header = (DragDropHeader *)gmData.data(); - if (header->general_settings) - item(0)->setSelected(true); - for (int i=row, end=std::min(GetEepromInterface()->getMaxModels()+1, row+header->models_count); isetSelected(true); - } - event->acceptProposedAction(); + if (mimeData->hasFormat("application/x-companion")) { + QByteArray gmData = mimeData->data("application/x-companion"); + if (event->source() && event->dropAction() == Qt::MoveAction) + ((ModelsListWidget*)event->source())->doCut(&gmData); + doPaste(&gmData, row); + clearSelection(); + setCurrentItem(topLevelItem(row)); + DragDropHeader * header = (DragDropHeader *)gmData.data(); + if (header->general_settings) + selectionModel()->select(model()->index(0, 0), QItemSelectionModel::Select); + for (int i=row, end=std::min(GetEepromInterface()->getMaxModels()+1, row+header->models_count); iselect(model()->index(i, 0), QItemSelectionModel::Select); + } + event->acceptProposedAction(); } #ifndef WIN32 void ModelsListWidget::focusInEvent ( QFocusEvent * event ) { - QListWidget::focusInEvent(event); + QTreeWidget::focusInEvent(event); QPalette palette = this->palette(); palette.setColor(QPalette::Active, QPalette::Highlight, active_highlight_color); palette.setColor(QPalette::Inactive, QPalette::Highlight, active_highlight_color); - this->setPalette(palette); + setPalette(palette); } void ModelsListWidget::focusOutEvent ( QFocusEvent * event ) { - QListWidget::focusOutEvent(event); + QTreeWidget::focusOutEvent(event); QPalette palette = this->palette(); palette.setColor(QPalette::Active, QPalette::Highlight, palette.color(QPalette::Active, QPalette::Midlight)); palette.setColor(QPalette::Inactive, QPalette::Highlight, palette.color(QPalette::Active, QPalette::Midlight)); - this->setPalette(palette); + setPalette(palette); } #endif void ModelsListWidget::refreshList() { + int current = std::max(0, indexOfTopLevelItem(currentItem())); + clear(); - addItem(tr("General Settings")); + + QTreeWidgetItem * item = new QTreeWidgetItem(); + item->setText(1, tr("General Settings")); + addTopLevelItem(item); EEPROMInterface * eepromInterface = GetEepromInterface(); BoardEnum board = eepromInterface->getBoard(); // TODO here we calculate the size used by the RLE format, this is clearly not the right place to do that... int availableEEpromSize = eepromInterface->getEEpromSize() - 64; // let's consider fat - div_t divresult = div(eepromInterface->getSize(radioData->generalSettings), 15); - divresult.quot += (divresult.rem != 0 ? 1 : 0); - availableEEpromSize -= divresult.quot*16; - + availableEEpromSize -= 16 * ((eepromInterface->getSize(radioData->generalSettings) + 14) / 15); for (uint8_t i=0; igetMaxModels(); i++) { - QString item = QString().sprintf("%02d: ", i+1); + QTreeWidgetItem * item = new QTreeWidgetItem(); + item->setTextAlignment(0, Qt::AlignLeft); + item->setText(0, QString().sprintf("%02d", i+1)); if (!radioData->models[i].isEmpty()) { QString modelName; if (strlen(radioData->models[i].name) > 0) modelName = radioData->models[i].name; else modelName = QString().sprintf("Model%02d", i+1); - item += modelName; + item->setText(1, modelName); if (!IS_SKY9X(board) && !IS_HORUS(board)) { - item += QString(GetCurrentFirmware()->getCapability(ModelName)-modelName.size(), ' '); int size = eepromInterface->getSize(radioData->models[i]); - item += QString().sprintf("%5d", size); - divresult = div(size, 15); - divresult.quot += (divresult.rem != 0 ? 1 : 0); - availableEEpromSize -= divresult.quot*16; - if (i == radioData->generalSettings.currModel) { - // TODO why? - availableEEpromSize -= divresult.quot*16; + item->setText(2, QString().sprintf("%5d", size)); + size = 16 * ((size + 14) / 15); + availableEEpromSize -= size; + if (i == radioData->generalSettings.currModelIndex) { + // Because we need this space for a TEMP model each time we have to write it again + availableEEpromSize -= size; + } + } + if (i == radioData->generalSettings.currModelIndex) { + QFont font = item->font(0); + font.setBold(true); + for (int j=0; jsetFont(j, font); } } } - addItem(item); + addTopLevelItem(item); } - - if (radioData->generalSettings.currModel < (unsigned int)eepromInterface->getMaxModels()) { - QFont f = QFont("Courier New", 12); - f.setBold(true); - this->item(radioData->generalSettings.currModel+1)->setFont(f); - } - + selectionModel()->select(model()->index(current, 0), QItemSelectionModel::Current | QItemSelectionModel::Select | QItemSelectionModel::Rows); + setCurrentItem(topLevelItem(current)); + if (!IS_SKY9X(board) && !IS_HORUS(board)) { ((MdiChild*)parent())->setEEpromAvail((availableEEpromSize/16)*15); } @@ -310,129 +336,140 @@ void ModelsListWidget::refreshList() void ModelsListWidget::cut() { - copy(); - deleteSelected(false); + copy(); + deleteSelected(false); } -void ModelsListWidget::confirmDelete() { - deleteSelected(true); +void ModelsListWidget::confirmDelete() +{ + deleteSelected(true); } void ModelsListWidget::deleteSelected(bool ask=true) { - bool isModel=false; - unsigned int selModel; - QMessageBox::StandardButton ret = QMessageBox::Yes; - if(ask) { - foreach(QModelIndex index, this->selectionModel()->selectedIndexes()) { - if (index.row()>0 && !radioData->models[index.row()-1].isEmpty()) { - isModel=true; - selModel=index.row()-1; + bool isModel=false; + unsigned int selModel; + QMessageBox::StandardButton ret = QMessageBox::Yes; + if (ask) { + foreach (QModelIndex index, this->selectionModel()->selectedIndexes()) { + if (index.row()>0 && !radioData->models[index.row()-1].isEmpty()) { + isModel = true; + selModel=index.row()-1; + } + } + if (isModel) { + if (radioData->generalSettings.currModelIndex != selModel) { + ret = QMessageBox::warning(this, "Companion", tr("Delete Selected Models?"), QMessageBox::Yes | QMessageBox::No); + } + else { + ret = QMessageBox::warning(this, "Companion", tr("Cannot delete default model."), QMessageBox::Ok); + } + } + } + if (ret == QMessageBox::Yes) { + foreach (QModelIndex index, this->selectionModel()->selectedIndexes()) { + if (index.row() > 0 && radioData->generalSettings.currModelIndex != (unsigned int)(index.row()-1)) { + radioData->models[index.row()-1].clear(); + ((MdiChild *)parent())->setModified(); + } + else if (index.row()>0) { + if (ask) { + QMessageBox::warning(this, "Companion", tr("Cannot delete default model."), QMessageBox::Ok); } - } - if (isModel==true) { - if (radioData->generalSettings.currModel != selModel) { - ret = QMessageBox::warning(this, "Companion", tr("Delete Selected Models?"), QMessageBox::Yes | QMessageBox::No); - } else { - ret = QMessageBox::warning(this, "Companion", tr("Cannot delete default model."), QMessageBox::Ok); + else { + QMessageBox::warning(this, "Companion", tr("Cannot cut default model."), QMessageBox::Ok); } } } - if (ret == QMessageBox::Yes) { - foreach(QModelIndex index, this->selectionModel()->selectedIndexes()) { - if (index.row()>0 && radioData->generalSettings.currModel!=(unsigned int)(index.row()-1)) { - radioData->models[index.row()-1].clear(); - ((MdiChild *)parent())->setModified(); - } else if (index.row()>0) { - if (ask) { - ret = QMessageBox::warning(this, "Companion", tr("Cannot delete default model."), QMessageBox::Ok); - } else { - ret = QMessageBox::warning(this, "Companion", tr("Cannot cut default model."), QMessageBox::Ok); - } - } - } } } -void ModelsListWidget::doCut(QByteArray *gmData) +void ModelsListWidget::doCut(QByteArray * gmData) { - bool modified=false; - DragDropHeader *header = (DragDropHeader *)gmData->data(); - for (int i=0; imodels_count; i++) { - if (radioData->generalSettings.currModel != (unsigned int)header->models[i]-1) { - radioData->models[header->models[i]-1].clear(); - modified=true; - } - } - if (modified) { - ((MdiChild *)parent())->setModified(); + bool modified = false; + DragDropHeader * header = (DragDropHeader *)gmData->data(); + for (int i=0; imodels_count; i++) { + if (radioData->generalSettings.currModelIndex != (unsigned int)header->models[i]-1) { + radioData->models[header->models[i]-1].clear(); + modified=true; } + } + if (modified) { + ((MdiChild *)parent())->setModified(); + } } -void ModelsListWidget::doCopy(QByteArray *gmData) +void ModelsListWidget::doCopy(QByteArray * gmData) { - DragDropHeader header; - - foreach(QModelIndex index, this->selectionModel()->selectedIndexes()) - { - char row = index.row(); - if(!row) { - header.general_settings = true; - gmData->append('G'); - gmData->append((char*)&radioData->generalSettings, sizeof(GeneralSettings)); - } - else { - header.models[header.models_count++] = row; - gmData->append('M'); - gmData->append((char*)&radioData->models[row-1], sizeof(ModelData)); - } + DragDropHeader header; + + qDebug() << selectionModel()->selectedIndexes(); + foreach(QModelIndex index, selectionModel()->selectedIndexes()) { + char column = index.column(); + if (column == 0) { + char row = index.row(); + if (!row) { + header.general_settings = true; + gmData->append('G'); + gmData->append((char *) &radioData->generalSettings, sizeof(GeneralSettings)); + } + else { + header.models[header.models_count++] = row; + gmData->append('M'); + gmData->append((char *) &radioData->models[row - 1], sizeof(ModelData)); + } } + } - gmData->prepend((char *)&header, sizeof(header)); + gmData->prepend((char *)&header, sizeof(header)); } void ModelsListWidget::copy() { - QByteArray gmData; - doCopy(&gmData); + QByteArray gmData; + doCopy(&gmData); - QMimeData *mimeData = new QMimeData; - mimeData->setData("application/x-companion", gmData); + QMimeData * mimeData = new QMimeData; + mimeData->setData("application/x-companion", gmData); - QClipboard *clipboard = QApplication::clipboard(); - clipboard->setMimeData(mimeData,QClipboard::Clipboard); + QClipboard * clipboard = QApplication::clipboard(); + clipboard->setMimeData(mimeData, QClipboard::Clipboard); } -void ModelsListWidget::doPaste(QByteArray *gmData, int index) +void ModelsListWidget::doPaste(QByteArray * gmData, int index) { - //QByteArray gmData = mimeD->data("application/x-companion"); - char *gData = gmData->data()+sizeof(DragDropHeader);//new char[gmData.size() + 1]; + // QByteArray gmData = mimeD->data("application/x-companion"); + char * gData = gmData->data() + sizeof(DragDropHeader); // new char[gmData.size() + 1]; int i = sizeof(DragDropHeader); int id = index; - int ret,modified=0; + int ret, modified=0; if(!id) id++; - while((isize()) && (id<=GetEepromInterface()->getMaxModels())) { + while (isize() && id<=GetEepromInterface()->getMaxModels()) { + qDebug() << i << gmData->size(); char c = *gData; i++; gData++; - if(c=='G') { //General settings + if (c == 'G') { + // General settings ret = QMessageBox::question(this, "Companion", tr("Do you want to overwrite radio general settings?"), QMessageBox::Yes | QMessageBox::No); if (ret == QMessageBox::Yes) { radioData->generalSettings = *((GeneralSettings *)gData); - modified=1; + modified = 1; } gData += sizeof(GeneralSettings); i += sizeof(GeneralSettings); } - else { //model data + else { + // Model data if (!radioData->models[id-1].isEmpty()) { ret = QMessageBox::question(this, "Companion", tr("You are pasting on an not empty model, are you sure?"), QMessageBox::Yes | QMessageBox::No); if (ret == QMessageBox::Yes) { radioData->models[id-1] = *((ModelData *)gData); + strcpy(radioData->models[id-1].filename, radioData->getNextModelFilename().toStdString().c_str()); gData += sizeof(ModelData); i += sizeof(ModelData); id++; @@ -446,6 +483,7 @@ void ModelsListWidget::doPaste(QByteArray *gmData, int index) } else { radioData->models[id-1] = *((ModelData *)gData); + strcpy(radioData->models[id-1].filename, radioData->getNextModelFilename().toStdString().c_str()); gData += sizeof(ModelData); i += sizeof(ModelData); id++; @@ -460,92 +498,85 @@ void ModelsListWidget::doPaste(QByteArray *gmData, int index) bool ModelsListWidget::hasPasteData() { - const QClipboard *clipboard = QApplication::clipboard(); - const QMimeData *mimeData = clipboard->mimeData(); + const QClipboard *clipboard = QApplication::clipboard(); + const QMimeData *mimeData = clipboard->mimeData(); - return mimeData->hasFormat("application/x-companion"); + return mimeData->hasFormat("application/x-companion"); } void ModelsListWidget::paste() { - if (hasPasteData()) { - const QClipboard *clipboard = QApplication::clipboard(); - const QMimeData *mimeData = clipboard->mimeData(); + if (hasPasteData()) { + const QClipboard * clipboard = QApplication::clipboard(); + const QMimeData * mimeData = clipboard->mimeData(); - QByteArray gmData = mimeData->data("application/x-companion"); - doPaste(&gmData,this->currentRow()); - } + QByteArray gmData = mimeData->data("application/x-companion"); + doPaste(&gmData, currentRow()); + } } void ModelsListWidget::duplicate() { - int i = this->currentRow(); - if(i && igetMaxModels()) - { - ModelData *model = &radioData->models[i-1]; - while(igetMaxModels()) { - if (radioData->models[i].isEmpty()) { - radioData->models[i] = *model; - ((MdiChild *)parent())->setModified(); - break; - } - i++; - } - if (i==GetEepromInterface()->getMaxModels()) { - QMessageBox::warning(this, "Companion", tr("No free slot available, cannot duplicate"), QMessageBox::Ok); - } + int i = this->currentRow(); + if (i && igetMaxModels()) { + ModelData * model = &radioData->models[i-1]; + while (igetMaxModels()) { + if (radioData->models[i].isEmpty()) { + radioData->models[i] = *model; + strcpy(radioData->models[i].filename, radioData->getNextModelFilename().toStdString().c_str()); + ((MdiChild *)parent())->setModified(); + break; + } + i++; } + if (i==GetEepromInterface()->getMaxModels()) { + QMessageBox::warning(this, "Companion", tr("No free slot available, cannot duplicate"), QMessageBox::Ok); + } + } } bool ModelsListWidget::hasSelection() { - return (this->selectionModel()->hasSelection()); + return (this->selectionModel()->hasSelection()); } void ModelsListWidget::keyPressEvent(QKeyEvent *event) { - if(event->matches(QKeySequence::Delete)) - { - deleteSelected(); - return; - } + if (event->matches(QKeySequence::Delete)) { + deleteSelected(); + return; + } - if(event->matches(QKeySequence::Cut)) - { - cut(); - return; - } + if (event->matches(QKeySequence::Cut)) { + cut(); + return; + } - if(event->matches(QKeySequence::Copy)) - { - copy(); - return; - } + if (event->matches(QKeySequence::Copy)) { + copy(); + return; + } - if(event->matches(QKeySequence::Paste)) - { - paste(); - return; - } + if (event->matches(QKeySequence::Paste)) { + paste(); + return; + } - if(event->matches(QKeySequence::Underline)) - { - duplicate(); - return; - } + if (event->matches(QKeySequence::Underline)) { + duplicate(); + return; + } - QListWidget::keyPressEvent(event);//run the standard event in case we didn't catch an action + QTreeWidget::keyPressEvent(event);//run the standard event in case we didn't catch an action } -void ModelsListWidget::viableModelSelected(int idx) +void ModelsListWidget::onCurrentItemChanged(QTreeWidgetItem * current, QTreeWidgetItem *) { + int index = indexOfTopLevelItem(current); if (!isVisible()) ((MdiChild*)parent())->viableModelSelected(false); - else if (idx<1) + else if (index<1) ((MdiChild*)parent())->viableModelSelected(false); else ((MdiChild*)parent())->viableModelSelected(!radioData->models[currentRow()-1].isEmpty()); } - - - diff --git a/companion/src/modelslist.h b/companion/src/modelslist.h index 692a8e7f0..b4bc14e5c 100644 --- a/companion/src/modelslist.h +++ b/companion/src/modelslist.h @@ -26,20 +26,21 @@ struct CurrentSelection { - QListWidgetItem *current_item; + QTreeWidgetItem * current_item; bool selected[CPN_MAX_MODELS+1]; }; -class ModelsListWidget : public QListWidget +class ModelsListWidget : public QTreeWidget { Q_OBJECT public: - ModelsListWidget(QWidget *parent = 0); + ModelsListWidget(QWidget * parent = 0); bool hasSelection(); - void keyPressEvent(QKeyEvent *event); + void keyPressEvent(QKeyEvent * event); bool hasPasteData(); + int currentRow() const; protected: void dropEvent(QDropEvent *event); @@ -69,7 +70,7 @@ public slots: void setdefault(); void deleteSelected(bool ask); void confirmDelete(); - void viableModelSelected(int idx); + void onCurrentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *); private: void doCut(QByteArray *gmData); diff --git a/companion/src/storage/storage_sdcard.cpp b/companion/src/storage/storage_sdcard.cpp index 65378fe49..11ccb87a8 100644 --- a/companion/src/storage/storage_sdcard.cpp +++ b/companion/src/storage/storage_sdcard.cpp @@ -72,8 +72,7 @@ int StorageSdcard::readOtx(const QString & path) // go trough all files in an archive QRegularExpression regexModel("MODELS/\\w+.bin", QRegularExpression::CaseInsensitiveOption); - for (unsigned int i = 0; i < mz_zip_reader_get_num_files(&zip_archive); i++) - { + for (unsigned int i = 0; i < mz_zip_reader_get_num_files(&zip_archive); i++) { mz_zip_archive_file_stat file_stat; if (!mz_zip_reader_file_stat(&zip_archive, i, &file_stat)) { lastErrorMessage = QObject::tr("mz_zip_reader_file_stat() failed!"); @@ -117,9 +116,9 @@ int StorageSdcard::readOtx(const QString & path) else { qDebug() << "Unknown file " << filename; } - } mz_zip_reader_end(&zip_archive); + return 0; } diff --git a/companion/src/storage/xmlinterface.cpp b/companion/src/storage/xmlinterface.cpp index 22eb460ec..1a13bd3de 100644 --- a/companion/src/storage/xmlinterface.cpp +++ b/companion/src/storage/xmlinterface.cpp @@ -70,7 +70,7 @@ void saveRadioSettings(GeneralSettings & settings, global_settings & gs) Calibration p3Calib(settings.calibMid[6], settings.calibSpanNeg[6], settings.calibSpanPos[6]); gs.calibration(calibration(rudderCalib, throttleCalib, aileronCalib, elevatorCalib, p1Calib, p2Calib, p3Calib)); - // TODO BSS settings.currModel; + // TODO BSS settings.currModelIndex; gs.contrast(settings.contrast); gs.battery(battery(settings.txVoltageCalibration, settings.vBatWarn));