feat(cpn): refactor handling of erroneous models (#7377)

This commit is contained in:
Neil Horne
2026-06-16 15:19:24 +10:00
committed by GitHub
parent 6a3349f095
commit 4ebf3486f1
7 changed files with 115 additions and 21 deletions
+1 -1
View File
@@ -2128,7 +2128,7 @@ void ModelData::validate()
QStringList ModelData::errorsList()
{
QStringList list;
QStringList list { "" };
for (int i = 0; i < CPN_MAX_INPUTS; i++) {
if (!expoData[i].isEmpty() && expoData[i].srcRaw == SOURCE_TYPE_NONE)
+15
View File
@@ -358,3 +358,18 @@ int RadioData::invalidModels()
return cnt;
}
QStringList RadioData::modelErrorsList()
{
QStringList ret;
for(auto &model: models) {
if (!model.isValid()) {
ret.append("");
ret.append(model.name);
ret.append(model.errorsList());
}
}
return ret;
}
+1
View File
@@ -68,6 +68,7 @@ class RadioData {
QString getNextModelFilename();
void validateModels();
int invalidModels();
QStringList modelErrorsList();
static QString modelSortOrderToString(int value);
static AbstractStaticItemModel * modelSortOrderItemModel();
+16 -6
View File
@@ -677,9 +677,9 @@ void MainWindow::updateMenus()
saveAsAct->setEnabled(activeChild);
closeAct->setEnabled(activeChild);
compareAct->setEnabled(activeChild);
writeSettingsAct->setEnabled(activeChild && !activeMdiChild()->invalidModels());
writeSettingsAct->setEnabled(activeChild);
readSettingsAct->setEnabled(true);
writeSettingsSDPathAct->setEnabled(activeChild && isSDPathValid() && !activeMdiChild()->invalidModels());
writeSettingsSDPathAct->setEnabled(activeChild && isSDPathValid());
readSettingsSDPathAct->setEnabled(isSDPathValid());
writeBUToRadioAct->setEnabled(false);
readBUToFileAct->setEnabled(false);
@@ -1518,12 +1518,22 @@ bool MainWindow::readSettingsFromSDPath(const QString & filename)
void MainWindow::writeSettingsSDPath()
{
StatusDialog *status = new StatusDialog(this, tr("Writing models and settings to SD path"), tr("In progress..."), 400);
if (activeMdiChild()) {
int cnt = activeMdiChild()->invalidModels();
if (activeMdiChild())
if (cnt) {
QMessageBox::critical(this, tr("Write Models and Settings to SD Path"),
tr("Operation aborted: %1 models have errors that may affect operation.\n%2")
.arg(cnt)
.arg(activeMdiChild()->modelErrorsList().join("\n")));
return;
}
StatusDialog *status = new StatusDialog(this, tr("Writing models and settings to SD path"), tr("In progress..."), 400);
activeMdiChild()->writeSettings(status, false);
delete status;
delete status;
}
}
bool MainWindow::isSDPathValid()
+57 -12
View File
@@ -38,6 +38,17 @@
#include <algorithm>
#include <ExportableTableView>
void StatusBarIcon::mouseDoubleClickEvent(QMouseEvent * event)
{
QLabel::mouseDoubleClickEvent(event);
emit doubleClicked();
}
/*
class MdiChild
*/
MdiChild::MdiChild(QWidget * parent, QWidget * parentWin, Qt::WindowFlags f):
QWidget(parent, f),
ui(new Ui::MdiChild),
@@ -352,7 +363,7 @@ void MdiChild::updateNavigation()
cboModelSortOrder->setCurrentIndex(radioData.sortOrder);
cboModelSortOrder->blockSignals(false);
}
action[ACT_GEN_SIM]->setEnabled(!invalidModels());
action[ACT_GEN_SIM]->setEnabled(true);
action[ACT_GEN_SRT]->setVisible(hasLabels);
action[ACT_MDL_DEL]->setEnabled(modelsSelected);
@@ -375,7 +386,7 @@ void MdiChild::updateNavigation()
action[ACT_MDL_WIZ]->setEnabled(singleModelSelected);
action[ACT_MDL_DFT]->setEnabled(singleModelSelected && getCurrentModel() != (int)radioData.generalSettings.currModelIndex);
action[ACT_MDL_PRT]->setEnabled(singleModelSelected);
action[ACT_MDL_SIM]->setEnabled(singleModelSelected && !invalidModels());
action[ACT_MDL_SIM]->setEnabled(singleModelSelected);
action[ACT_MDL_ERR]->setEnabled(singleModelSelected && radioData.models[getCurrentModel()].modelErrors);
emit navigationUpdated();
@@ -1285,12 +1296,35 @@ void MdiChild::setDefault()
void MdiChild::radioSimulate()
{
// safeguard as the menu actions are enabled
int cnt = radioData.invalidModels();
if (cnt) {
QMessageBox::critical(this, tr("Simulate Radio"),
tr("Operation aborted: %1 models have errors that may affect simulation.\n%2")
.arg(cnt)
.arg(radioData.modelErrorsList().join("\n")));
return;
}
startSimulation(this, radioData, -1);
}
void MdiChild::modelSimulate()
{
startSimulation(this, radioData, getCurrentModel());
int currMdlIdx = getCurrentModel();
if (currMdlIdx > -1 && !radioData.models[currMdlIdx].isValid()) {
QMessageBox::critical(this, tr("Simulate Model"),
tr("Operation aborted: selected model has errors that may affect simulation.\n%1")
.arg(radioData.models[currMdlIdx].errorsList().join("\n")));
return;
}
if (currMdlIdx < 0)
radioSimulate();
else
startSimulation(this, radioData, getCurrentModel());
}
void MdiChild::newFile(bool useProfileSettings)
@@ -1541,11 +1575,14 @@ int MdiChild::askQuestion(const QString & msg, QMessageBox::StandardButtons butt
void MdiChild::writeSettings(StatusDialog * status, bool toRadio)
{
// safeguard as the menu actions should be disabled
// safeguard as the menu actions are enabled
int cnt = radioData.invalidModels();
if (cnt) {
QMessageBox::critical(this, tr("Write Models and Settings"), tr("Operation aborted as %1 models have significant errors that may affect model operation.").arg(cnt));
QMessageBox::critical(this, tr("Write Models and Settings"),
tr("Operation aborted as %1 models have significant errors that may affect model operation.\n%2")
.arg(cnt)
.arg(radioData.modelErrorsList().join("\n")));
return;
}
@@ -1915,9 +1952,14 @@ QAction * MdiChild::actionsSeparator()
return act;
}
bool MdiChild::invalidModels()
int MdiChild::invalidModels()
{
return (bool)radioData.invalidModels();
return radioData.invalidModels();
}
QStringList MdiChild::modelErrorsList()
{
return radioData.modelErrorsList();
}
void MdiChild::modelShowErrors()
@@ -1938,7 +1980,7 @@ void MdiChild::setupStatusBar()
ui->statusBarLayout->addWidget(statusBar);
QLabel *lbl = new QLabel(tr("Models status"));
statusBar->addPermanentWidget(lbl);
statusBarIcon = new QLabel();
statusBarIcon = new StatusBarIcon(this);
statusBar->addPermanentWidget(statusBarIcon);
statusBarCount = new QLabel();
statusBar->addPermanentWidget(statusBarCount);
@@ -1949,13 +1991,16 @@ void MdiChild::updateStatusBar()
QPixmap p;
QLabel cnt;
int invalid = radioData.invalidModels();
disconnect(statusBarIcon, &StatusBarIcon::doubleClicked, nullptr, nullptr);
if (!invalidModels()) {
statusBarIcon->setToolTip(tr("No errors"));
p.load(":/images/png/tick-green.png");
}
else {
statusBarIcon->setToolTip(tr("Errors"));
} else {
statusBarIcon->setToolTip(tr("Double click to display errors"));
connect(statusBarIcon, &StatusBarIcon::doubleClicked, [this] () {
QMessageBox::critical(this, tr("Models Status"), radioData.modelErrorsList().join("\n"));
});
p.load(":/images/png/cross-red.png");
cnt.setText(QString::number(invalid));
}
@@ -2039,4 +2084,4 @@ void MdiChild::modelImport()
refresh();
setModified();
}
}
}
+18 -2
View File
@@ -44,6 +44,21 @@ class MdiChild;
class LabelsDelegate;
class LabelsProxy;
class StatusBarIcon : public QLabel
{
Q_OBJECT
public:
StatusBarIcon(QWidget * parent) : QLabel(parent) {}
virtual ~StatusBarIcon() {}
signals:
void doubleClicked();
protected:
virtual void mouseDoubleClickEvent(QMouseEvent * event);
};
class MdiChild : public QWidget
{
Q_OBJECT
@@ -91,7 +106,8 @@ class MdiChild : public QWidget
QList<QAction *> getModelActions();
QList<QAction *> getLabelsActions();
QAction * getAction(const Actions type);
bool invalidModels();
int invalidModels();
QStringList modelErrorsList();
public slots:
void newFile(bool useProfileSettings = false);
@@ -228,7 +244,7 @@ class MdiChild : public QWidget
QToolBar * labelsToolbar;
QLabel *lblLabels;
QStatusBar *statusBar;
QLabel *statusBarIcon;
StatusBarIcon *statusBarIcon;
QLabel *statusBarCount;
Firmware * firmware;
+7
View File
@@ -168,5 +168,12 @@ void ModelEdit::onTabIndexChanged(int index)
void ModelEdit::launchSimulation()
{
if (!radioData.models[modelId].isValid()) {
QMessageBox::critical(this, tr("Simulate Model"),
tr("Operation aborted: model has errors that may affect simulation.\n%1")
.arg(radioData.models[modelId].errorsList().join("\n")));
return;
}
startSimulation(this, radioData, modelId);
}