feat(cpn): Add individual model save to yml (#1968)

- add save model(s) to context menu and toolbar
- new storage functions to support single model write
- modified yml storage format write functions
- default save directory is application sd card TEMPLATES
- model name used as default file name
This commit is contained in:
Neil Horne
2022-06-07 20:53:45 +10:00
committed by GitHub
parent e173d5b448
commit 47a90ed38f
6 changed files with 92 additions and 17 deletions
+58
View File
@@ -231,6 +231,7 @@ void MdiChild::setupNavigation()
addAct(ACT_MDL_CPY, "copy.png", SLOT(copy()), QKeySequence::Copy);
addAct(ACT_MDL_PST, "paste.png", SLOT(paste()), QKeySequence::Paste);
addAct(ACT_MDL_INS, "list.png", SLOT(insert()), QKeySequence::Italic);
addAct(ACT_MDL_SAV, "save.png", SLOT(modelSave()), tr("Ctrl+Alt+S"));
addAct(ACT_MDL_MOV, "arrow-right.png");
QMenu * catsMenu = new QMenu(this);
@@ -338,6 +339,8 @@ void MdiChild::updateNavigation()
action[ACT_MDL_PST]->setText(tr("Paste") % (numOnClipbrd ? sp % modelsAddTxt : ns));
action[ACT_MDL_INS]->setEnabled(numOnClipbrd && (hasModelSlotSelcted || catsSelected));
action[ACT_MDL_INS]->setText(tr("Insert") % QString(action[ACT_MDL_INS]->isEnabled() ? sp % modelsAddTxt : ns));
action[ACT_MDL_SAV]->setEnabled(modelsSelected);
action[ACT_MDL_SAV]->setText(tr("Save") % (modelsSelected ? sp % modelsRemvTxt : ns));
if (hasCats && action[ACT_MDL_MOV]->menu()) {
action[ACT_MDL_MOV]->setVisible(true);
@@ -386,6 +389,8 @@ void MdiChild::retranslateUi()
action[ACT_MDL_ADD]->setText(tr("Add Model"));
action[ACT_MDL_ADD]->setIconText(tr("Model"));
action[ACT_MDL_SAV]->setText(tr("Save Model"));
action[ACT_MDL_SAV]->setIconText(tr("Save"));
action[ACT_MDL_RTR]->setText(tr("Restore from Backup"));
action[ACT_MDL_WIZ]->setText(tr("Model Wizard"));
action[ACT_MDL_DFT]->setText(tr("Set as Default"));
@@ -429,6 +434,7 @@ QList<QAction *> MdiChild::getEditActions(bool incCatNew)
actGrp.append(getAction(ACT_MDL_INS));
actGrp.append(getAction(ACT_MDL_DUP));
actGrp.append(getAction(ACT_MDL_MOV));
actGrp.append(getAction(ACT_MDL_SAV));
return actGrp;
}
@@ -1814,3 +1820,55 @@ void MdiChild::openModelPrompt(int row)
return;
}
void MdiChild::modelSave()
{
saveSelectedModels();
}
unsigned MdiChild::saveModels(const QVector<int> modelIndices)
{
unsigned saves = 0;
foreach(const int idx, modelIndices) {
if (idx < 0 || idx >= (int)radioData.models.size())
continue;
const QString path(QDir::toNativeSeparators(g.profile[g.id()].sdPath() + "/TEMPLATES/" + QString(radioData.models[idx].name) + ".yml"));
qDebug() << path;
QString filename = QFileDialog::getSaveFileName(this, tr("Save model"), path, YML_FILES_FILTER);
if (filename.isEmpty())
return false;
if (QFileInfo(filename).suffix() != "yml")
return false;
Storage storage(filename);
if (!storage.writeModel(radioData, idx)) {
QMessageBox::critical(this, CPN_STR_TTL_ERROR, storage.error());
return false;
}
++saves;
}
return saves;
}
bool MdiChild::saveModel(const int modelIndex)
{
QVector<int> list = QVector<int>() << modelIndex;
if (saveModels(list) == 1)
return true;
else
return false;
}
void MdiChild::saveSelectedModels()
{
saveModels(getSelectedModels());
}
+5
View File
@@ -59,6 +59,7 @@ class MdiChild : public QWidget
ACT_MDL_DUP,
ACT_MDL_INS,
ACT_MDL_MOV,
ACT_MDL_SAV,
ACT_MDL_RTR, // ResToRe backup
ACT_MDL_WIZ,
ACT_MDL_DFT, // set as DeFaulT
@@ -132,6 +133,7 @@ class MdiChild : public QWidget
void categoryAdd();
void modelAdd();
void modelEdit();
void modelSave();
void wizardEdit();
void modelDuplicate();
void onModelMoveToCategory();
@@ -175,6 +177,9 @@ class MdiChild : public QWidget
void moveModelsToCategory(const QVector<int> models, const int toCategoryId);
void moveSelectedModelsToCat(const int toCategoryId);
unsigned countUsedModels(const int categoryId = -1);
unsigned saveModels(const QVector<int> modelIndices);
bool saveModel(const int modelIndex);
void saveSelectedModels();
void clearCutList();
void removeModelFromCutList(const int modelIndex);
+14
View File
@@ -121,6 +121,20 @@ bool Storage::write(const RadioData & radioData)
return ret;
}
bool Storage::writeModel(const RadioData & radioData, const int modelIndex)
{
bool ret = false;
foreach(StorageFactory * factory, registeredStorageFactories) {
if (factory->probe(filename)) {
StorageFormat * format = factory->instance(filename);
ret = format->writeModel(radioData, modelIndex);
delete format;
break;
}
}
return ret;
}
bool convertEEprom(const QString & sourceEEprom, const QString & destinationEEprom, const QString & firmwareFilename)
{
FirmwareInterface firmware(firmwareFilename);
+2
View File
@@ -57,6 +57,7 @@ class StorageFormat
virtual ~StorageFormat() {}
virtual bool load(RadioData & radioData) = 0;
virtual bool write(const RadioData & radioData) = 0;
virtual bool writeModel(const RadioData & radioData, const int modelIndex) { return false; }
QString error() {
return _error;
@@ -157,6 +158,7 @@ class Storage : public StorageFormat
virtual bool load(RadioData & radioData);
virtual bool write(const RadioData & radioData);
virtual bool writeModel(const RadioData & radioData, const int modelIndex);
};
void registerStorageFactories();
+10 -15
View File
@@ -40,9 +40,9 @@ bool YamlFormat::loadFile(QByteArray & filedata)
return true;
}
bool YamlFormat::writeFile(const QByteArray & filedata, const QString & filename)
bool YamlFormat::writeFile(const QByteArray & filedata)
{
QString path = this->filename + "/" + filename;
QString path = filename;
QFile file(path);
if (!file.open(QFile::WriteOnly)) {
setError(tr("Error opening file %1 in write mode:\n%2.").arg(path).arg(file.errorString()));
@@ -121,21 +121,16 @@ bool YamlFormat::load(RadioData & radioData)
return false;
}
bool YamlFormat::write(const RadioData & radioData)
bool YamlFormat::writeModel(const RadioData & radioData, const int modelIndex)
{
/* Need this test in case of a new sdcard
Board::Type board = getCurrentBoard();
if (!HAS_EEPROM_YAML(board)) {
qDebug() << "Board does not support YAML format";
if (modelIndex < 0 || modelIndex >= (int)radioData.models.size() || radioData.models[modelIndex].isEmpty())
return false;
}
// ensure directories exist on sd card
QDir dir(filename);
dir.mkdir("RADIO");
dir.mkdir("MODELS");
*/
QByteArray modelData;
writeModelToYaml(radioData.models[modelIndex], modelData);
qDebug() << "Warning: format ignored - under development";
return false; // force failure until fully developed
if (!writeFile(modelData))
return false;
return true;
}
+3 -2
View File
@@ -36,9 +36,10 @@ class YamlFormat : public StorageFormat
virtual QString name() { return "yml"; }
virtual bool load(RadioData & radioData);
virtual bool write(const RadioData & radioData);
virtual bool write(const RadioData & radioData) { return false; }
virtual bool writeModel(const RadioData & radioData, const int modelIndex) override;
protected:
bool loadFile(QByteArray & fileData);
bool writeFile(const QByteArray & fileData, const QString & fileName);
bool writeFile(const QByteArray & fileData);
};