Add model files loading for B&W radios
This commit is contained in:
@@ -52,6 +52,7 @@ bool loadModelsListFromYaml(std::vector<CategoryData>& categories,
|
||||
YAML::Node node = loadYamlFromByteArray(data);
|
||||
if (!node.IsSequence()) return false;
|
||||
|
||||
int modelIdx = 0;
|
||||
for (const auto& cat : node) {
|
||||
|
||||
if (!cat.IsMap()) continue;
|
||||
@@ -63,11 +64,11 @@ bool loadModelsListFromYaml(std::vector<CategoryData>& categories,
|
||||
if (!models.IsSequence()) continue;
|
||||
|
||||
for (const auto& model : models) {
|
||||
std::string filename;
|
||||
std::string filename, name;
|
||||
model["filename"] >> filename;
|
||||
std::string name;
|
||||
model["name"] >> name;
|
||||
modelFiles.push_back({filename, name, (int)categories.size() - 1});
|
||||
modelFiles.push_back(
|
||||
{filename, name, (int)categories.size() - 1, modelIdx++});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ struct EtxModelMetadata {
|
||||
std::string filename;
|
||||
std::string name;
|
||||
int category;
|
||||
int modelIdx;
|
||||
};
|
||||
|
||||
typedef std::list<EtxModelMetadata> EtxModelfiles;
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
#include "firmwares/edgetx/edgetxinterface.h"
|
||||
#include "miniz.c" // Can only be included once!
|
||||
|
||||
#include <regex>
|
||||
|
||||
bool CategorizedStorageFormat::load(RadioData & radioData)
|
||||
{
|
||||
StorageType st = getStorageType(filename);
|
||||
@@ -243,50 +245,63 @@ bool CategorizedStorageFormat::loadYaml(RadioData & radioData)
|
||||
board = (Board::Type)radioData.generalSettings.variant;
|
||||
|
||||
// get models
|
||||
EtxModelfiles modelFiles;
|
||||
|
||||
QByteArray modelslistBuffer;
|
||||
if (loadFile(modelslistBuffer, "MODELS/models.yml")) {
|
||||
|
||||
// List< { filename, category index } >
|
||||
EtxModelfiles modelFiles;
|
||||
|
||||
if (!loadModelsListFromYaml(radioData.categories, modelFiles, modelslistBuffer)) {
|
||||
setError(tr("Can't load MODELS/models.yml"));
|
||||
return false;
|
||||
}
|
||||
|
||||
radioData.models.resize(modelFiles.size());
|
||||
|
||||
int modelIdx = 0;
|
||||
for (const auto& mc : modelFiles) {
|
||||
qDebug() << "Filename: " << mc.filename.c_str() << " / Category: " << mc.category;
|
||||
|
||||
QByteArray modelBuffer;
|
||||
QString filename = "MODELS/" + QString::fromStdString(mc.filename);
|
||||
if (!loadFile(modelBuffer, filename)) {
|
||||
setError(tr("Can't extract ") + filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Please note:
|
||||
// ModelData() use memset to clear everything to 0
|
||||
//
|
||||
auto& model = radioData.models[modelIdx];
|
||||
|
||||
if (!loadModelFromYaml(model,modelBuffer)) {
|
||||
setError(tr("Can't load ") + filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
model.category = mc.category;
|
||||
model.modelIndex = modelIdx;
|
||||
strncpy(model.filename, mc.filename.c_str(), sizeof(model.filename)-1);
|
||||
|
||||
model.used = true;
|
||||
modelIdx++;
|
||||
}
|
||||
|
||||
} else {
|
||||
// fetch "MODELS/modelXX.yml"
|
||||
std::list<std::string> filelist;
|
||||
if (!getFileList(filelist)) {
|
||||
setError(tr("Can't list files"));
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::regex yml_regex("MODELS/(model([0-9]+)\\.yml)");
|
||||
for(const auto& f : filelist) {
|
||||
std::smatch match;
|
||||
if (std::regex_match(f, match, yml_regex)) {
|
||||
if (match.size() == 3) {
|
||||
std::ssub_match modelFile = match[1];
|
||||
std::ssub_match modelIdx = match[2];
|
||||
modelFiles.push_back({ modelFile.str(), "", 0, std::stoi(modelIdx.str()) });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
radioData.models.resize(modelFiles.size());
|
||||
for (const auto& mc : modelFiles) {
|
||||
qDebug() << "Filename: " << mc.filename.c_str() << " / Category: " << mc.category;
|
||||
|
||||
QByteArray modelBuffer;
|
||||
QString filename = "MODELS/" + QString::fromStdString(mc.filename);
|
||||
if (!loadFile(modelBuffer, filename)) {
|
||||
setError(tr("Can't extract ") + filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Please note:
|
||||
// ModelData() use memset to clear everything to 0
|
||||
//
|
||||
auto& model = radioData.models[mc.modelIdx];
|
||||
|
||||
if (!loadModelFromYaml(model,modelBuffer)) {
|
||||
setError(tr("Can't load ") + filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
model.category = mc.category;
|
||||
model.modelIndex = mc.modelIdx;
|
||||
strncpy(model.filename, mc.filename.c_str(), sizeof(model.filename)-1);
|
||||
|
||||
model.used = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -308,12 +323,9 @@ bool CategorizedStorageFormat::writeYaml(const RadioData & radioData)
|
||||
EtxModelfiles modelFiles;
|
||||
for (const auto& model : radioData.models) {
|
||||
|
||||
qDebug() << "Model index: " << model.modelIndex;
|
||||
if (model.isEmpty())
|
||||
continue;
|
||||
|
||||
// TODO: verify '.yml' (in case we moved from '.bin')
|
||||
|
||||
QString modelFilename;
|
||||
if (hasCategories) {
|
||||
std::string ymlFilename = patchFilenameToYaml(model.filename);
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include "storage.h"
|
||||
|
||||
#include <QtCore>
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
class CategorizedStorageFormat : public StorageFormat
|
||||
{
|
||||
@@ -41,6 +43,7 @@ class CategorizedStorageFormat : public StorageFormat
|
||||
protected:
|
||||
virtual bool loadFile(QByteArray & fileData, const QString & fileName) = 0;
|
||||
virtual bool writeFile(const QByteArray & fileData, const QString & fileName) = 0;
|
||||
virtual bool getFileList(std::list<std::string>& filelist) = 0;
|
||||
|
||||
virtual bool loadBin(RadioData & radioData);
|
||||
virtual bool writeBin(const RadioData & radioData);
|
||||
|
||||
@@ -113,3 +113,18 @@ bool EtxFormat::writeFile(const QByteArray & filedata, const QString & filename)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EtxFormat::getFileList(std::list<std::string>& filelist)
|
||||
{
|
||||
int count = (int)mz_zip_reader_get_num_files(&zip_archive);
|
||||
if (count == 0) return false;
|
||||
|
||||
mz_zip_archive_file_stat file_stat;
|
||||
for (int i=0; i<count; i++) {
|
||||
if (!mz_zip_reader_file_stat(&zip_archive, i, &file_stat)) continue;
|
||||
if (mz_zip_reader_is_file_a_directory(&zip_archive, i)) continue;
|
||||
filelist.push_back(file_stat.m_filename);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ class EtxFormat : public CategorizedStorageFormat
|
||||
protected:
|
||||
virtual bool loadFile(QByteArray & fileData, const QString & fileName);
|
||||
virtual bool writeFile(const QByteArray & fileData, const QString & fileName);
|
||||
virtual bool getFileList(std::list<std::string>& filelist);
|
||||
|
||||
mz_zip_archive zip_archive;
|
||||
};
|
||||
|
||||
@@ -46,6 +46,7 @@ class OtxFormat : public CategorizedStorageFormat
|
||||
protected:
|
||||
virtual bool loadFile(QByteArray & fileData, const QString & fileName);
|
||||
virtual bool writeFile(const QByteArray & fileData, const QString & fileName);
|
||||
virtual bool getFileList(std::list<std::string>& filelist) { return false; }
|
||||
|
||||
mz_zip_archive zip_archive;
|
||||
};
|
||||
|
||||
@@ -57,6 +57,16 @@ bool SdcardFormat::writeFile(const QByteArray & data, const QString & filename)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SdcardFormat::getFileList(std::list<std::string>& filelist)
|
||||
{
|
||||
QDir dir(filename);
|
||||
QStringList ql = dir.entryList();
|
||||
for (const auto& str : ql) {
|
||||
filelist.push_back(str.toStdString());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SdcardStorageFactory::probe(const QString & path)
|
||||
{
|
||||
return QDir(path).exists();
|
||||
|
||||
@@ -41,6 +41,7 @@ class SdcardFormat : public CategorizedStorageFormat
|
||||
protected:
|
||||
virtual bool loadFile(QByteArray & fileData, const QString & fileName);
|
||||
virtual bool writeFile(const QByteArray & fileData, const QString & fileName);
|
||||
virtual bool getFileList(std::list<std::string>& filelist);
|
||||
};
|
||||
|
||||
class SdcardStorageFactory : public DefaultStorageFactory<SdcardFormat>
|
||||
|
||||
Reference in New Issue
Block a user