From 2fbe5a78d1ee9e7fbac15653dd09428366c83dc2 Mon Sep 17 00:00:00 2001 From: 3djc Date: Sat, 28 Jan 2017 04:46:45 -0800 Subject: [PATCH] Proposition : model number handling (#4308) * Try something for discussions * Better alternative * Typo * Improve * Change delimiter * Move delimiter to space * * Refactoring of CategorizedStorageFormat::load() and CategorizedStorageFormat::save() to support unused model slots * Fix all unsafe usages of QString::toStdString().c_str() * Fixed radio data import [Horus] (broken in 0f90ff0b65) (cherry picked from commit cc12601a01b1f5ff86d6c13d288352056f047005) * Added Q_OBJECT to TreeModel and some cosmetics (cherry picked from commit f40e64c2aa09fffdddc505f64b6dca62ce0cebe5) * Cleanup --- companion/src/eeprominterface.h | 1 + .../src/firmwares/opentx/opentxinterface.cpp | 2 + companion/src/mdichild.cpp | 2 +- companion/src/modelslist.cpp | 2 +- companion/src/radiodata.cpp | 3 +- companion/src/storage/categorized.cpp | 115 ++++++++++++------ companion/src/storage/otx.cpp | 2 +- 7 files changed, 85 insertions(+), 42 deletions(-) diff --git a/companion/src/eeprominterface.h b/companion/src/eeprominterface.h index 73a475166..db56c12e9 100644 --- a/companion/src/eeprominterface.h +++ b/companion/src/eeprominterface.h @@ -147,6 +147,7 @@ enum Capability { MixersMonitor, HasBatMeterRange, DangerousFunctions, + HasModelCategories }; class SimulatorInterface; diff --git a/companion/src/firmwares/opentx/opentxinterface.cpp b/companion/src/firmwares/opentx/opentxinterface.cpp index 80bdeec66..34b030808 100644 --- a/companion/src/firmwares/opentx/opentxinterface.cpp +++ b/companion/src/firmwares/opentx/opentxinterface.cpp @@ -763,6 +763,8 @@ int OpenTxFirmware::getCapability(Capability capability) return (IS_HORUS_OR_TARANIS(board) ? true : id.contains("battgraph")); case DangerousFunctions: return id.contains("danger") ? 1 : 0; + case HasModelCategories: + return IS_HORUS(board); default: return 0; } diff --git a/companion/src/mdichild.cpp b/companion/src/mdichild.cpp index 992966298..0c0880847 100644 --- a/companion/src/mdichild.cpp +++ b/companion/src/mdichild.cpp @@ -422,7 +422,7 @@ void MdiChild::modelAdd() model.category = categoryIndex; model.used = true; sprintf(model.filename, "model%lu.bin", (long unsigned)radioData.models.size()+1); - strcpy(model.name, tr("New model").toStdString().c_str()); + strcpy(model.name, qPrintable(tr("New model"))); radioData.models.push_back(model); radioData.setCurrentModel(radioData.models.size() - 1); setModified(); diff --git a/companion/src/modelslist.cpp b/companion/src/modelslist.cpp index 4c748d960..d8d732894 100644 --- a/companion/src/modelslist.cpp +++ b/companion/src/modelslist.cpp @@ -473,7 +473,7 @@ void ModelsListWidget::duplicate() while (igetCapability(Models)) { if (radioData->models[i].isEmpty()) { radioData->models[i] = *model; - strcpy(radioData->models[i].filename, radioData->getNextModelFilename().toStdString().c_str()); + strcpy(radioData->models[i].filename, qPrintable(radioData->getNextModelFilename())); ((MdiChild *)parent())->setModified(); break; } diff --git a/companion/src/radiodata.cpp b/companion/src/radiodata.cpp index db2e53268..849382576 100644 --- a/companion/src/radiodata.cpp +++ b/companion/src/radiodata.cpp @@ -96,9 +96,8 @@ void RadioData::convert(Board::Type before, Board::Type after) for (unsigned i=0; igetBoard(); - + QByteArray modelsListBuffer; if (!loadFile(modelsListBuffer, "RADIO/models.txt")) { setError(QObject::tr("Can't extract RADIO/models.txt")); return false; } - + QList lines = modelsListBuffer.split('\n'); int modelIndex = 0; int categoryIndex = -1; - foreach (const QByteArray & line, lines) { - if (!line.isEmpty()) { - if (line.startsWith('[') && line.endsWith(']')) { + foreach (const QByteArray & lineArray, lines) { + QString line = QString(lineArray).trimmed(); + if (line.isEmpty()) continue; + // qDebug() << "parsing line" << line; + + if (line.startsWith('[') && line.endsWith(']')) { + // ignore categories for boards that do not support them + if (getCurrentFirmware()->getCapability(HasModelCategories)) { QString name = line.mid(1, line.size() - 2); - CategoryData category(name.toStdString().c_str()); + CategoryData category(qPrintable(name)); radioData.categories.push_back(category); categoryIndex++; + qDebug() << "added category" << name; + } + continue; + } + + // determine if we have a model number + QStringList parts = line.split(QRegExp("\\s+"), QString::SkipEmptyParts); + if (parts.size() == 2) { + // parse model number + int modelNumber = parts[0].toInt(); + if (modelNumber > 0 && modelNumber > modelIndex && modelNumber < getCurrentFirmware()->getCapability(Models)) { + modelIndex = modelNumber; + qDebug() << "advanced model number to" << modelIndex; } else { - qDebug() << "Loading" << line; - QByteArray modelBuffer; - if (!loadFile(modelBuffer, QString("MODELS/%1").arg(QString(line)))) { - setError(QObject::tr("Can't extract %1").arg(QString(line))); - return false; - } - if ((int)radioData.models.size() <= modelIndex) { - radioData.models.resize(modelIndex + 1); - } - if (!loadModelFromByteArray(radioData.models[modelIndex], modelBuffer)) { - return false; - } - strncpy(radioData.models[modelIndex].filename, line.data(), sizeof(radioData.models[modelIndex].filename)); - if (strcmp(radioData.generalSettings.currModelFilename, line.data()) == 0) { - radioData.generalSettings.currModelIndex = modelIndex; - } - radioData.models[modelIndex].category = categoryIndex; - radioData.models[modelIndex].used = true; - modelIndex++; + if (modelNumber != modelIndex) qDebug() << "Invalid model number" << parts[0]; } + parts.removeFirst(); } + if (parts.size() == 1) { + // parse model file name and load + QString fileName = parts[0]; + qDebug() << "Loading model from file" << fileName << "into slot" << modelIndex; + QByteArray modelBuffer; + if (!loadFile(modelBuffer, QString("MODELS/%1").arg(fileName))) { + setError(QObject::tr("Can't extract %1").arg(fileName)); + return false; + } + if ((int)radioData.models.size() <= modelIndex) { + radioData.models.resize(modelIndex + 1); + } + if (!loadModelFromByteArray(radioData.models[modelIndex], modelBuffer)) { + return false; + } + strncpy(radioData.models[modelIndex].filename, qPrintable(fileName), sizeof(radioData.models[modelIndex].filename)); + if (IS_HORUS(board) && !strcmp(radioData.generalSettings.currModelFilename, qPrintable(fileName))) { + radioData.generalSettings.currModelIndex = modelIndex; + qDebug() << "currModelIndex =" << modelIndex; + } + if (getCurrentFirmware()->getCapability(HasModelCategories)) { + radioData.models[modelIndex].category = categoryIndex; + } + radioData.models[modelIndex].used = true; + modelIndex++; + continue; + } + + // invalid line + // TODO add to parsing report + qDebug() << "Invalid line" <getCapability(HasModelCategories)) { int categoryIndex = model.category; if (currentCategoryIndex != categoryIndex) { modelsList.append(QString().sprintf("[%s]\n", radioData.categories[model.category].name)); currentCategoryIndex = categoryIndex; } - modelsList.append(QString(model.filename) + "\n"); + } + if (IS_HORUS(getCurrentBoard())) { + modelsList.append(QString("%1\n").arg(model.filename)); + } + else { + // use format with model number and file name + // this is needed, because this kind of radios can have unused model slots + modelsList.append(QString("%1 %2\n").arg(i).arg(model.filename)); } } - + if (!writeFile(modelsList, "RADIO/models.txt")) { return false; } diff --git a/companion/src/storage/otx.cpp b/companion/src/storage/otx.cpp index 4f0d3be61..0d9c40e23 100644 --- a/companion/src/storage/otx.cpp +++ b/companion/src/storage/otx.cpp @@ -93,7 +93,7 @@ bool OtxFormat::write(const RadioData & radioData) bool OtxFormat::loadFile(QByteArray & filedata, const QString & filename) { size_t size; - void * data = mz_zip_reader_extract_file_to_heap(&zip_archive, filename.toStdString().c_str(), &size, 0); + void * data = mz_zip_reader_extract_file_to_heap(&zip_archive, qPrintable(filename), &size, 0); if (!data) { return false; }