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:
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user