diff --git a/companion/src/firmwares/edgetx/edgetxinterface.cpp b/companion/src/firmwares/edgetx/edgetxinterface.cpp index 18169054d..12aac4985 100644 --- a/companion/src/firmwares/edgetx/edgetxinterface.cpp +++ b/companion/src/firmwares/edgetx/edgetxinterface.cpp @@ -89,18 +89,37 @@ static void writeYamlToByteArray(const YAML::Node& node, QByteArray& data, bool qDebug() << data.toStdString().c_str(); } -bool loadLabelsListFromYaml(QStringList& labels, +bool loadLabelsListFromYaml(RadioData::ModelLabels& labels, + int& sortOrder, EtxModelfiles& modelFiles, const QByteArray& data) { + sortOrder = 0; labels.clear(); if (data.size() == 0) return true; YAML::Node node = loadYamlFromByteArray(data); - if (!node.IsMap()) return false; // Root Map (Labels, Models) - for (const auto& lbl : node["Labels"]) { - labels.append(QString::fromStdString(lbl.first.as())); - } + if (!node.IsMap()) return false; // Root Map (Labels, Sort, Models) + if (node["Sort"].IsScalar()) { + bool ok = false; + sortOrder = QString::fromStdString(node["Sort"].Scalar()).toUInt(&ok); + if (!ok) + sortOrder = 0; + } + + YAML::Node lbls = node["Labels"]; + if (lbls.IsMap()) { + for (YAML::const_iterator it=lbls.begin(); it!=lbls.end(); ++it) { + std::string lbl = it->first.as(); + RadioData::LabelData ld; + ld.name = QString::fromStdString(lbl); + if (lbls[lbl]["selected"]) + ld.selected = lbls[lbl]["selected"].as(); + else + ld.selected = false; + labels.append(ld); + } + } return true; } @@ -155,9 +174,12 @@ bool loadRadioSettingsFromYaml(GeneralSettings& settings, const QByteArray& data bool writeLabelsListToYaml(const RadioData &radioData, QByteArray& data) { YAML::Node node; - foreach(QString label, radioData.labels) { - node["Labels"][label.toStdString()] = YAML::Null; + foreach(RadioData::LabelData label, radioData.labels) { + node["Labels"][label.name.toStdString()] = YAML::Null; + if (label.selected) + node["Labels"][label.name.toStdString()]["selected"] = true; } + node["Sort"] = radioData.sortOrder; writeYamlToByteArray(node, data); return true; } diff --git a/companion/src/firmwares/edgetx/edgetxinterface.h b/companion/src/firmwares/edgetx/edgetxinterface.h index f5d5f03f3..b1ca32c72 100644 --- a/companion/src/firmwares/edgetx/edgetxinterface.h +++ b/companion/src/firmwares/edgetx/edgetxinterface.h @@ -37,7 +37,8 @@ struct EtxModelMetadata { typedef std::list EtxModelfiles; -bool loadLabelsListFromYaml(QStringList& labels, +bool loadLabelsListFromYaml(RadioData::ModelLabels& labels, + int& sortOrder, EtxModelfiles& modelFiles, const QByteArray& data); diff --git a/companion/src/firmwares/radiodata.cpp b/companion/src/firmwares/radiodata.cpp index 76b831218..f02a91411 100644 --- a/companion/src/firmwares/radiodata.cpp +++ b/companion/src/firmwares/radiodata.cpp @@ -22,7 +22,8 @@ #include "radiodataconversionstate.h" #include "eeprominterface.h" -RadioData::RadioData() +RadioData::RadioData() : + sortOrder(0) { models.resize(getCurrentFirmware()->getCapability(Models)); } @@ -120,8 +121,11 @@ void RadioData::addLabel(QString label) output.truncate(truncateAt); } label = QString(output); - if (labels.indexOf(label) == -1) - labels.append(label); + + if (indexOfLabel(label) < 0) { + LabelData ld = { label, false }; + labels.append(ld); + } } bool RadioData::deleteLabel(QString label) @@ -139,7 +143,9 @@ bool RadioData::deleteLabel(QString label) } // Remove the label from the global list - labels.removeAll(label); + int index = indexOfLabel(label); + if (index > -1) + labels.remove(index); // If no labels remain, add a Favorites one if (!labels.size()) { @@ -151,7 +157,7 @@ bool RadioData::deleteLabel(QString label) bool RadioData::deleteLabel(int index) { if (index >= labels.size()) return false; - QString modelLabel = labels.at(index); + QString modelLabel = labels.at(index).name; return deleteLabel(modelLabel); } @@ -188,9 +194,9 @@ bool RadioData::renameLabel(QString from, QString to) } } } - int ind = labels.indexOf(from); + int ind = indexOfLabel(from); if (ind != -1) { - labels.replace(ind, to); + labels[ind].name = to; } } return success; @@ -199,7 +205,7 @@ bool RadioData::renameLabel(QString from, QString to) bool RadioData::renameLabel(int index, QString to) { if (index >= labels.size()) return false; - QString from = labels.at(index); + QString from = labels.at(index).name; return renameLabel(from, to); } @@ -211,7 +217,7 @@ void RadioData::swapLabel(int indFrom, int indTo) indFrom < 0 || indTo < 0) return; - QString tmplbl = labels.at(indFrom); + LabelData tmplbl = labels.at(indFrom); labels.replace(indFrom, labels.at(indTo)); labels.replace(indTo, tmplbl); } @@ -258,6 +264,20 @@ void RadioData::addLabelsFromModels() } } +int RadioData::indexOfLabel(QString & label) const +{ + int index = -1; + + for (int i = 0; i < labels.size(); i++) { + if (labels.at(i).name == label) { + index = i; + break; + } + } + + return index; +} + QStringList RadioData::fromCSV(const QString &csv) { QStringList lbls = QString(csv).split(',',QString::SkipEmptyParts); diff --git a/companion/src/firmwares/radiodata.h b/companion/src/firmwares/radiodata.h index 26d291113..4bd35b28a 100644 --- a/companion/src/firmwares/radiodata.h +++ b/companion/src/firmwares/radiodata.h @@ -17,7 +17,17 @@ class RadioData { RadioData(); GeneralSettings generalSettings; - QStringList labels; + + struct LabelData { + QString name; + bool selected; + }; + + typedef QVector ModelLabels; + + ModelLabels labels; + + int sortOrder; std::vector models; void convert(RadioDataConversionState & cstate); @@ -31,6 +41,7 @@ class RadioData { bool addLabelToModel(int index, QString label); bool removeLabelFromModel(int index, QString label); void addLabelsFromModels(); + int indexOfLabel(QString & label) const; static QStringList fromCSV(const QString &csv); static QString toCSV(QStringList lbls); diff --git a/companion/src/labels.cpp b/companion/src/labels.cpp index 9980d38e4..76a0757f5 100644 --- a/companion/src/labels.cpp +++ b/companion/src/labels.cpp @@ -41,15 +41,15 @@ bool LabelsModel::setData(const QModelIndex &index, const QVariant &value, int r if (role == Qt::CheckStateRole) { if (value==Qt::Unchecked && selectedModel != -1) { - if (radioData->removeLabelFromModel(selectedModel, radioData->labels.at(index.row()))) + if (radioData->removeLabelFromModel(selectedModel, radioData->labels.at(index.row()).name)) emit modelChanged(selectedModel); } else { try{ - if (radioData->addLabelToModel(selectedModel, radioData->labels.at(index.row()))) + if (radioData->addLabelToModel(selectedModel, radioData->labels.at(index.row()).name)) emit modelChanged(selectedModel); } catch(const std::length_error& le) { emit labelsFault(tr("Unable to add label \"%1\" to model \"%2\" not enough room")\ - .arg(radioData->labels.at(index.row())).arg(le.what())); + .arg(radioData->labels.at(index.row()).name).arg(le.what())); } } emit dataChanged(this->index(index.row(), 0), @@ -60,10 +60,10 @@ bool LabelsModel::setData(const QModelIndex &index, const QVariant &value, int r QString replTo = value.toString(); if (replFrom == replTo) // User exits edit without changing return true; - if (radioData->labels.indexOf(replTo) == -1) { // Don't allow duplicates + if (radioData->indexOfLabel(replTo) == -1) { // Don't allow duplicates bool modelsChanged = false; try{ - modelsChanged = radioData->renameLabel(replFrom,replTo); + modelsChanged = radioData->renameLabel(replFrom, replTo); } catch(const std::length_error& le) { emit labelsFault(tr("Unable to rename \"%1\" to \"%2\" not enough room in model %3")\ .arg(replFrom).arg(replTo).arg(le.what())); @@ -88,7 +88,7 @@ QVariant LabelsModel::data(const QModelIndex &index, int role) const if (index.row() >= labels.size() || !index.isValid() ) return QVariant(); - QString label = radioData->labels.at(index.row()); + QString label = radioData->labels.at(index.row()).name; if (role == Qt::DisplayRole || role == Qt::EditRole) { if (index.column() == 0) { @@ -125,7 +125,7 @@ QModelIndex LabelsModel::parent(const QModelIndex &index) const int LabelsModel::rowCount(const QModelIndex &parent) const { - Q_UNUSED(parent); + Q_UNUSED(parent); return labels.size(); } @@ -158,9 +158,10 @@ bool LabelsModel::insertRows(int row, int count, const QModelIndex &parent) if (newNo == 0) newStr = QString(tr("New")); newNo++; - } while(radioData->labels.indexOf(newStr) >= 0); + } while(radioData->indexOfLabel(newStr) >= 0); // Add it to radioData - radioData->labels.insert(row+i, newStr); + RadioData::LabelData ld = { newStr , false }; + radioData->labels.insert(row + i, ld); } buildLabelsList(); return true; @@ -188,10 +189,10 @@ void LabelsModel::buildLabelsList() { labels.clear(); - int i=0; - foreach(QString lbl, radioData->labels) { + int i = 0; + foreach(RadioData::LabelData ld, radioData->labels) { LabelItem itm; - itm.label = lbl; + itm.label = ld.name; itm.radioLabelIndex = i++; labels.append(itm); } diff --git a/companion/src/storage/labeled.cpp b/companion/src/storage/labeled.cpp index 85a1559c3..ddb5a5141 100644 --- a/companion/src/storage/labeled.cpp +++ b/companion/src/storage/labeled.cpp @@ -140,7 +140,8 @@ bool LabelsStorageFormat::loadBin(RadioData & radioData) // Add a Favorites label if(getCurrentFirmware()->getCapability(HasModelLabels)) { - radioData.labels.append(tr("Favorites")); + RadioData::LabelData ld = { tr("Favorites"), false }; + radioData.labels.append(ld); } return true; } @@ -218,9 +219,10 @@ bool LabelsStorageFormat::loadYaml(RadioData & radioData) // - Update possible labels with all found in models too QByteArray labelslistBuffer; + int sortOrder = 0; if (loadFile(labelslistBuffer, "MODELS/labels.yml")) { try { - if (!loadLabelsListFromYaml(radioData.labels, modelFiles, labelslistBuffer)) { + if (!loadLabelsListFromYaml(radioData.labels, sortOrder, modelFiles, labelslistBuffer)) { setError(tr("Can't load MODELS/labels.yml")); } } catch(const std::runtime_error& e) { @@ -228,6 +230,9 @@ bool LabelsStorageFormat::loadYaml(RadioData & radioData) } } + // Save Sort Order + radioData.sortOrder = sortOrder; + // Scan for all models std::list filelist; if (!getFileList(filelist)) { @@ -308,8 +313,10 @@ bool LabelsStorageFormat::loadYaml(RadioData & radioData) radioData.addLabelsFromModels(); // If no labels, add a Favorites - if(!radioData.labels.size()) - radioData.labels.append(tr("Favorites")); + if(!radioData.labels.size()) { + RadioData::LabelData ld = { tr("Favorites"), false }; + radioData.labels.append(ld); + } } return true;