From 71b0614503c5bfeeb43b8c71b06222173298e6c7 Mon Sep 17 00:00:00 2001 From: Neil Horne Date: Sat, 2 Sep 2023 18:37:27 +1000 Subject: [PATCH] feat(cpn): Identify new and changed models by italicising row (#3840) * enh(cpn): identify new and changed models by italicising row * enh(cpn): identify drag n drop and new from template as changed --- companion/src/firmwares/modeldata.h | 1 + companion/src/mdichild.cpp | 31 +++++++++++++++++++++++++---- companion/src/mdichild.h | 2 ++ companion/src/modelslist.cpp | 7 +++++-- 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/companion/src/firmwares/modeldata.h b/companion/src/firmwares/modeldata.h index 806f1c1d3..975fb05e9 100644 --- a/companion/src/firmwares/modeldata.h +++ b/companion/src/firmwares/modeldata.h @@ -129,6 +129,7 @@ class ModelData { char filename[16+1]; char labels[100]; int modelIndex; // Companion only, temporary index position managed by data model. + bool modelUpdated; // Companion only, used to highlight if changed in models list TimerData timers[CPN_MAX_TIMERS]; bool noGlobalFunctions; diff --git a/companion/src/mdichild.cpp b/companion/src/mdichild.cpp index 1df017be3..239a1c200 100644 --- a/companion/src/mdichild.cpp +++ b/companion/src/mdichild.cpp @@ -739,7 +739,6 @@ void MdiChild::checkAndInitModel(int row) { if (row < (int)radioData.models.size() && radioData.models[row].isEmpty()) { radioData.models[row].setDefaultValues(row, radioData.generalSettings); - setModified(); } } @@ -827,7 +826,7 @@ int MdiChild::newModel(int modelIndex) if (countUsedModels() == 1) { radioData.setCurrentModel(modelIndex); } - setModified(); + setModelModified(modelIndex); setSelectedModel(modelIndex); if (isNewModel) { @@ -987,6 +986,7 @@ void MdiChild::pasteModelData(const QMimeData * mimeData, const QModelIndex row, strcpy(radioData.models[modelIdx].filename, radioData.getNextModelFilename().toStdString().c_str()); lastSelectedModel = modelIdx; // after refresh the last pasted model will be selected modified = true; + setModelModified(modelIdx, false); // avoid unnecessary refreshes if (doMove) { deletesList.append(origMdlIdx); removeModelFromCutList(origMdlIdx); @@ -1175,7 +1175,7 @@ void MdiChild::openModelWizard(int row) int res = wizard->exec(); if (res == QDialog::Accepted && wizard->mix.complete /*TODO rather test the exec() result?*/) { radioData.models[row] = wizard->mix; - setModified(); + setModelModified(row); setSelectedModel(row); } } @@ -1200,7 +1200,7 @@ void MdiChild::openModelEditWindow(int row) ModelEdit * t = new ModelEdit(this, radioData, (row), firmware); gStopwatch.report("ModelEdit created"); t->setWindowTitle(tr("Editing model %1: ").arg(row+1) + QString(model.name) + QString(" (%1)").arg(userFriendlyCurrentFile())); - connect(t, &ModelEdit::modified, this, &MdiChild::setModified); + connect(t, &ModelEdit::modified, this, &MdiChild::setCurrentModelModified); gStopwatch.report("STARTING MODEL EDIT"); t->show(); QApplication::restoreOverrideCursor(); @@ -1336,6 +1336,13 @@ bool MdiChild::saveFile(const QString & filename, bool setCurrent) return false; } + for (int i = 0; i < (int)radioData.models.size(); i++) { + if (!radioData.models[i].isEmpty()) + radioData.models[i].modelUpdated = false; + } + + refresh(); + if (setCurrent) { setCurrentFile(filename); } @@ -1663,6 +1670,8 @@ void MdiChild::openModelTemplate(int row) for (int i = 0; i < CPN_MAX_MODULES; i++) { radioData.models[row].moduleData[i].modelId = row + 1; } + + setModelModified(row); } void MdiChild::openModelPrompt(int row) @@ -1818,3 +1827,17 @@ void MdiChild::exportSelectedModels() { exportModels(getSelectedModels()); } + +void MdiChild::setCurrentModelModified() +{ + setModelModified(getCurrentModel()); +} + +void MdiChild::setModelModified(const int modelIndex, bool cascade) +{ + if (modelIndex >= 0 && modelIndex < (int)radioData.models.size()) { + radioData.models[modelIndex].modelUpdated = true; + if (cascade) + setModified(); + } +} diff --git a/companion/src/mdichild.h b/companion/src/mdichild.h index 5d9d8933b..23f1354db 100644 --- a/companion/src/mdichild.h +++ b/companion/src/mdichild.h @@ -115,6 +115,7 @@ class MdiChild : public QWidget void updateNavigation(); void updateTitle(); void setModified(); + void setCurrentModelModified(); void retranslateUi(); void showModelsListContextMenu(const QPoint & pos); void showLabelsContextMenu(const QPoint & pos); @@ -228,6 +229,7 @@ class MdiChild : public QWidget const quint16 stateDataVersion; AbstractStaticItemModel* modelSortOrderItemModel; QComboBox* cboModelSortOrder; + void setModelModified(const int modelIndex, bool cascade = true); }; // This will draw the drop indicator across all columns of a model View (vs. in just one column), and lets us make the indicator more obvious. diff --git a/companion/src/modelslist.cpp b/companion/src/modelslist.cpp index 85eb18ece..20a164356 100644 --- a/companion/src/modelslist.cpp +++ b/companion/src/modelslist.cpp @@ -171,9 +171,12 @@ QVariant ModelsListModel::data(const QModelIndex & index, int role) const return item->data(index.column()); } - if (role == Qt::FontRole && item->isModel() && item->getModelIndex() == (int)radioData->generalSettings.currModelIndex) { + if (role == Qt::FontRole && item->isModel()) { QFont font; - font.setBold(true); + if (item->getModelIndex() == (int)radioData->generalSettings.currModelIndex) + font.setBold(true); + if (radioData->models[item->getModelIndex()].modelUpdated) + font.setItalic(true); return font; }