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 cc12601a01)

* Added Q_OBJECT to TreeModel and some cosmetics

(cherry picked from commit f40e64c2aa)

* Cleanup
This commit is contained in:
3djc
2017-01-28 13:46:45 +01:00
committed by Bertrand Songis
parent de68db0905
commit 2fbe5a78d1
7 changed files with 85 additions and 42 deletions
+1
View File
@@ -147,6 +147,7 @@ enum Capability {
MixersMonitor,
HasBatMeterRange,
DangerousFunctions,
HasModelCategories
};
class SimulatorInterface;
@@ -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;
}
+1 -1
View File
@@ -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();
+1 -1
View File
@@ -473,7 +473,7 @@ void ModelsListWidget::duplicate()
while (i<getCurrentFirmware()->getCapability(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;
}
+1 -2
View File
@@ -96,9 +96,8 @@ void RadioData::convert(Board::Type before, Board::Type after)
for (unsigned i=0; i<models.size(); i++) {
models[i].convert(before, after);
}
if (categories.size() == 0) {
categories.push_back(CategoryData(QObject::tr("Models").toStdString().c_str()));
categories.push_back(CategoryData(qPrintable(QObject::tr("Models"))));
for (unsigned i=0; i<models.size(); i++) {
models[i].category = 0;
}
+78 -37
View File
@@ -35,48 +35,80 @@ bool CategorizedStorageFormat::load(RadioData & radioData)
}
board = loadInterface->getBoard();
QByteArray modelsListBuffer;
if (!loadFile(modelsListBuffer, "RADIO/models.txt")) {
setError(QObject::tr("Can't extract RADIO/models.txt"));
return false;
}
QList<QByteArray> 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" <<line;
continue;
}
return true;
}
@@ -85,33 +117,42 @@ bool CategorizedStorageFormat::write(const RadioData & radioData)
// models.txt
QByteArray modelsList;
int currentCategoryIndex = -1;
// radio.bin
QByteArray radioSettingsData;
writeRadioSettingsToByteArray(radioData.generalSettings, radioSettingsData);
if (!writeFile(radioSettingsData, "RADIO/radio.bin")) {
return false;
}
// all models
for (unsigned int i=0; i<radioData.models.size(); i++) {
const ModelData & model = radioData.models[i];
if (!model.isEmpty()) {
QString modelFilename = QString("MODELS/%1").arg(model.filename);
QByteArray modelData;
writeModelToByteArray(model, modelData);
if (!writeFile(modelData, modelFilename)) {
return false;
}
if (model.isEmpty()) continue;
QString modelFilename = QString("MODELS/%1").arg(model.filename);
QByteArray modelData;
writeModelToByteArray(model, modelData);
if (!writeFile(modelData, modelFilename)) {
return false;
}
if (getCurrentFirmware()->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;
}
+1 -1
View File
@@ -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;
}