fix(cpn): inputs and mixes must have source (#5798)
This commit is contained in:
@@ -10,6 +10,9 @@
|
||||
<file>images/track.png</file>
|
||||
<file>images/track0.png</file>
|
||||
<file>images/taranison.png</file>
|
||||
<file>images/svg/circle-green.svg</file>
|
||||
<file>images/svg/circle-orange.svg</file>
|
||||
<file>images/svg/circle-red.svg</file>
|
||||
<file>images/simulator/icons/svg/arrow_click.svg</file>
|
||||
<file>images/simulator/icons/svg/camera.svg</file>
|
||||
<file>images/simulator/icons/svg/camera-active.svg</file>
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
#include "adjustmentreference.h"
|
||||
#include "compounditemmodels.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
|
||||
ModelData::ModelData()
|
||||
{
|
||||
clear();
|
||||
@@ -1924,3 +1926,61 @@ int ModelData::getCustomScreensCount() const
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
void ModelData::validate()
|
||||
{
|
||||
modelErrors = false;
|
||||
|
||||
for (int i = 0; i < CPN_MAX_INPUTS; i++) {
|
||||
if (!expoData[i].isEmpty() && expoData[i].srcRaw == SOURCE_TYPE_NONE) {
|
||||
modelErrors = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < CPN_MAX_MIXERS; i++) {
|
||||
if (!mixData[i].isEmpty() && mixData[i].srcRaw == SOURCE_TYPE_NONE) {
|
||||
modelErrors = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QStringList ModelData::errorsList()
|
||||
{
|
||||
QStringList list;
|
||||
|
||||
for (int i = 0; i < CPN_MAX_INPUTS; i++) {
|
||||
if (!expoData[i].isEmpty() && expoData[i].srcRaw == SOURCE_TYPE_NONE)
|
||||
list.append(tr("Error - Input %1 Line %2 %3").arg(expoData[i].chn + 1).arg(getInputLine(i)).arg(tr("has no source")));
|
||||
}
|
||||
|
||||
for (int i = 0; i < CPN_MAX_MIXERS; i++) {
|
||||
if (!mixData[i].isEmpty() && mixData[i].srcRaw == SOURCE_TYPE_NONE)
|
||||
list.append(tr("Error - Mix %1 Line %2 %3").arg(mixData[i].destCh).arg(getMixLine(i)).arg(tr("has no source")));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
int ModelData::getMixLine(int index) const
|
||||
{
|
||||
int cnt = 1;
|
||||
|
||||
for (int i = index - 1; i >= 0 && mixData[i].destCh == mixData[index].destCh; i--)
|
||||
cnt++;
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
int ModelData::getInputLine(int index) const
|
||||
{
|
||||
int cnt = 1;
|
||||
|
||||
for (int i = 0; i < index; i++) {
|
||||
if (expoData[i].chn == expoData[index].chn)
|
||||
cnt++;
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
@@ -140,6 +140,7 @@ class ModelData {
|
||||
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
|
||||
bool modelErrors; // Companion only, used to highlight if data errors in models list
|
||||
|
||||
TimerData timers[CPN_MAX_TIMERS];
|
||||
bool noGlobalFunctions;
|
||||
@@ -366,11 +367,18 @@ class ModelData {
|
||||
static AbstractStaticItemModel * funcSwitchStartItemModel();
|
||||
|
||||
int getCustomScreensCount() const;
|
||||
bool hasErrors() { return modelErrors; }
|
||||
bool isValid() { return !hasErrors(); }
|
||||
void validate();
|
||||
QStringList errorsList();
|
||||
|
||||
protected:
|
||||
void removeGlobalVar(int & var);
|
||||
|
||||
private:
|
||||
int getMixLine(int index) const;
|
||||
int getInputLine(int index) const;
|
||||
|
||||
QVector<UpdateReferenceParams> *updRefList = nullptr;
|
||||
|
||||
struct UpdateReferenceInfo
|
||||
|
||||
@@ -343,3 +343,19 @@ AbstractStaticItemModel * RadioData::modelSortOrderItemModel()
|
||||
mdl->loadItemList();
|
||||
return mdl;
|
||||
}
|
||||
|
||||
void RadioData::validateModels()
|
||||
{
|
||||
for(auto &model: models)
|
||||
model.validate();
|
||||
}
|
||||
|
||||
int RadioData::invalidModels()
|
||||
{
|
||||
int cnt = 0;
|
||||
|
||||
for(auto &model: models)
|
||||
cnt += model.isValid() ? 0 : 1;
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
@@ -66,6 +66,8 @@ class RadioData {
|
||||
void setCurrentModel(unsigned int index);
|
||||
void fixModelFilenames();
|
||||
QString getNextModelFilename();
|
||||
void validateModels();
|
||||
int invalidModels();
|
||||
|
||||
static QString modelSortOrderToString(int value);
|
||||
static AbstractStaticItemModel * modelSortOrderItemModel();
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="48mm"
|
||||
height="48mm"
|
||||
viewBox="0 0 48 48"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
inkscape:version="1.4 (86a8ad7, 2024-10-11)"
|
||||
sodipodi:docname="circle-green.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:zoom="1.5197952"
|
||||
inkscape:cx="153.96812"
|
||||
inkscape:cy="139.82147"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1055"
|
||||
inkscape:window-x="-7"
|
||||
inkscape:window-y="-7"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" />
|
||||
<defs
|
||||
id="defs1" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<circle
|
||||
style="fill:#14ff14;stroke:#ffffff;stroke-width:0.204744;stroke-linejoin:round;stroke-opacity:0.99572"
|
||||
id="path1"
|
||||
cx="24"
|
||||
cy="24"
|
||||
r="21.897629" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="48mm"
|
||||
height="48mm"
|
||||
viewBox="0 0 48 48"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
inkscape:version="1.4 (86a8ad7, 2024-10-11)"
|
||||
sodipodi:docname="circle-orange.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:zoom="1.5197952"
|
||||
inkscape:cx="153.96812"
|
||||
inkscape:cy="139.82147"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1055"
|
||||
inkscape:window-x="-7"
|
||||
inkscape:window-y="-7"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" />
|
||||
<defs
|
||||
id="defs1" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<circle
|
||||
style="fill:#ff8000;stroke:#ffffff;stroke-width:0.204744;stroke-linejoin:round;stroke-opacity:0.99572;fill-opacity:1"
|
||||
id="path1"
|
||||
cx="24"
|
||||
cy="24"
|
||||
r="21.897629" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="48mm"
|
||||
height="48mm"
|
||||
viewBox="0 0 48 48"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
inkscape:version="1.4 (86a8ad7, 2024-10-11)"
|
||||
sodipodi:docname="circle-red.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:zoom="1.5197952"
|
||||
inkscape:cx="153.96812"
|
||||
inkscape:cy="139.82147"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1055"
|
||||
inkscape:window-x="-7"
|
||||
inkscape:window-y="-7"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" />
|
||||
<defs
|
||||
id="defs1" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<circle
|
||||
style="fill:#ff0000;stroke:#ffffff;stroke-width:0.204744;stroke-linejoin:round;stroke-opacity:0.99572;fill-opacity:1"
|
||||
id="path1"
|
||||
cx="24"
|
||||
cy="24"
|
||||
r="21.897629" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="48mm"
|
||||
height="48mm"
|
||||
viewBox="0 0 48 48"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
inkscape:version="1.4 (86a8ad7, 2024-10-11)"
|
||||
sodipodi:docname="circle-green.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:zoom="1.5197952"
|
||||
inkscape:cx="153.96812"
|
||||
inkscape:cy="139.82147"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1055"
|
||||
inkscape:window-x="-7"
|
||||
inkscape:window-y="-7"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" />
|
||||
<defs
|
||||
id="defs1" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<circle
|
||||
style="fill:#14ff14;stroke:#ffffff;stroke-width:0.204744;stroke-linejoin:round;stroke-opacity:0.99572"
|
||||
id="path1"
|
||||
cx="24"
|
||||
cy="24"
|
||||
r="21.897629" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="48mm"
|
||||
height="48mm"
|
||||
viewBox="0 0 48 48"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
inkscape:version="1.4 (86a8ad7, 2024-10-11)"
|
||||
sodipodi:docname="circle-orange.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:zoom="1.5197952"
|
||||
inkscape:cx="153.96812"
|
||||
inkscape:cy="139.82147"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1055"
|
||||
inkscape:window-x="-7"
|
||||
inkscape:window-y="-7"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" />
|
||||
<defs
|
||||
id="defs1" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<circle
|
||||
style="fill:#ff8000;stroke:#ffffff;stroke-width:0.204744;stroke-linejoin:round;stroke-opacity:0.99572;fill-opacity:1"
|
||||
id="path1"
|
||||
cx="24"
|
||||
cy="24"
|
||||
r="21.897629" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="48mm"
|
||||
height="48mm"
|
||||
viewBox="0 0 48 48"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
inkscape:version="1.4 (86a8ad7, 2024-10-11)"
|
||||
sodipodi:docname="circle-red.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:zoom="1.5197952"
|
||||
inkscape:cx="153.96812"
|
||||
inkscape:cy="139.82147"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1055"
|
||||
inkscape:window-x="-7"
|
||||
inkscape:window-y="-7"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" />
|
||||
<defs
|
||||
id="defs1" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<circle
|
||||
style="fill:#ff0000;stroke:#ffffff;stroke-width:0.204744;stroke-linejoin:round;stroke-opacity:0.99572;fill-opacity:1"
|
||||
id="path1"
|
||||
cx="24"
|
||||
cy="24"
|
||||
r="21.897629" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -676,9 +676,9 @@ void MainWindow::updateMenus()
|
||||
saveAsAct->setEnabled(activeChild);
|
||||
closeAct->setEnabled(activeChild);
|
||||
compareAct->setEnabled(activeChild);
|
||||
writeSettingsAct->setEnabled(activeChild);
|
||||
writeSettingsAct->setEnabled(activeChild && !activeMdiChild()->invalidModels());
|
||||
readSettingsAct->setEnabled(true);
|
||||
writeSettingsSDPathAct->setEnabled(activeChild && isSDPathValid());
|
||||
writeSettingsSDPathAct->setEnabled(activeChild && isSDPathValid() && !activeMdiChild()->invalidModels());
|
||||
readSettingsSDPathAct->setEnabled(isSDPathValid());
|
||||
writeBUToRadioAct->setEnabled(false);
|
||||
readBUToFileAct->setEnabled(false);
|
||||
@@ -889,10 +889,8 @@ void MainWindow::createActions()
|
||||
// assigned menus in createMenus()
|
||||
recentFilesAct = addAct("recentdocument.png");
|
||||
closeAct = addAct("clear.png", SLOT(closeFile()) /*, QKeySequence::Close*/); // setting/showing this shortcut interferes with the system one (Ctrl+W/Ctrl-F4)
|
||||
// TODO change to more appropriate icon sets and uncomment toolbar actions
|
||||
writeSettingsSDPathAct = addAct("folder-tree-write.png", SLOT(writeSettingsSDPath()));
|
||||
readSettingsSDPathAct = addAct("folder-tree-read.png", SLOT(readSettingsSDPath()));
|
||||
// end TODO
|
||||
exitAct = addAct("exit.png", SLOT(closeAllWindows()), QKeySequence::Quit, qApp);
|
||||
|
||||
editAppSettingsAct = addAct("apppreferences.png", SLOT(editAppSettings()), QKeySequence::Preferences);
|
||||
|
||||
@@ -63,6 +63,7 @@ MdiChild::MdiChild(QWidget * parent, QWidget * parentWin, Qt::WindowFlags f):
|
||||
if (parentWindow)
|
||||
parentWindow->setWindowIcon(windowIcon());
|
||||
|
||||
setupStatusBar();
|
||||
setupNavigation();
|
||||
initModelsList();
|
||||
|
||||
@@ -227,11 +228,12 @@ void MdiChild::setupNavigation()
|
||||
addAct(ACT_MDL_SIM, "simulate.png", SLOT(modelSimulate()), tr("Alt+S"));
|
||||
addAct(ACT_MDL_DUP, "duplicate.png", SLOT(modelDuplicate()), QKeySequence::Underline);
|
||||
|
||||
addAct(ACT_MDL_CUT, "cut.png", SLOT(cut()), QKeySequence::Cut);
|
||||
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_EXP, "save.png", SLOT(modelExport()), tr("Ctrl+Alt+S"));
|
||||
addAct(ACT_MDL_CUT, "cut.png", SLOT(cut()), QKeySequence::Cut);
|
||||
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_EXP, "save.png", SLOT(modelExport()), tr("Ctrl+Alt+S"));
|
||||
addAct(ACT_MDL_ERR, "information.png", SLOT(modelShowErrors()), tr("Ctrl+Alt+E"));
|
||||
|
||||
addAct(ACT_MDL_MOV, "arrow-right.png");
|
||||
QMenu * catsMenu = new QMenu(this);
|
||||
@@ -349,6 +351,7 @@ void MdiChild::updateNavigation()
|
||||
cboModelSortOrder->setCurrentIndex(radioData.sortOrder);
|
||||
cboModelSortOrder->blockSignals(false);
|
||||
}
|
||||
action[ACT_GEN_SIM]->setEnabled(!invalidModels());
|
||||
action[ACT_GEN_SRT]->setVisible(hasLabels);
|
||||
|
||||
action[ACT_MDL_DEL]->setEnabled(modelsSelected);
|
||||
@@ -369,7 +372,8 @@ 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);
|
||||
action[ACT_MDL_SIM]->setEnabled(singleModelSelected && !invalidModels());
|
||||
action[ACT_MDL_ERR]->setEnabled(singleModelSelected && radioData.models[getCurrentModel()].modelErrors);
|
||||
}
|
||||
|
||||
void MdiChild::retranslateUi()
|
||||
@@ -399,6 +403,7 @@ void MdiChild::retranslateUi()
|
||||
action[ACT_MDL_PRT]->setText(tr("Print Model"));
|
||||
action[ACT_MDL_SIM]->setText(tr("Simulate Model"));
|
||||
action[ACT_MDL_DUP]->setText(tr("Duplicate Model"));
|
||||
action[ACT_MDL_ERR]->setText(tr("Show Model Errors"));
|
||||
|
||||
radioToolbar->setWindowTitle(tr("Show Radio Actions Toolbar"));
|
||||
modelsToolbar->setWindowTitle(tr("Show Model Actions Toolbar"));
|
||||
@@ -444,6 +449,7 @@ QList<QAction *> MdiChild::getModelActions()
|
||||
//actGrp.append(getAction(ACT_MDL_RTR));
|
||||
actGrp.append(getAction(ACT_MDL_PRT));
|
||||
actGrp.append(getAction(ACT_MDL_SIM));
|
||||
actGrp.append(getAction(ACT_MDL_ERR));
|
||||
return actGrp;
|
||||
}
|
||||
|
||||
@@ -603,6 +609,7 @@ void MdiChild::refresh()
|
||||
}
|
||||
updateNavigation();
|
||||
updateTitle();
|
||||
updateStatusBar();
|
||||
}
|
||||
|
||||
void MdiChild::onItemActivated(const QModelIndex index)
|
||||
@@ -1204,6 +1211,7 @@ void MdiChild::openModelEditWindow(int row)
|
||||
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::setCurrentModelModified);
|
||||
connect(t, &ModelEdit::closed, this, &MdiChild::onModelEditClosed);
|
||||
gStopwatch.report("STARTING MODEL EDIT");
|
||||
t->show();
|
||||
QApplication::restoreOverrideCursor();
|
||||
@@ -1298,6 +1306,9 @@ bool MdiChild::loadFile(const QString & filename, bool resetCurrentFile)
|
||||
refresh();
|
||||
}
|
||||
|
||||
radioData.validateModels();
|
||||
updateStatusBar();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1344,8 +1355,10 @@ bool MdiChild::saveFile(const QString & filename, bool setCurrent)
|
||||
g.eepromDir(QFileInfo(filename).dir().absolutePath());
|
||||
|
||||
for (int i = 0; i < (int)radioData.models.size(); i++) {
|
||||
if (!radioData.models[i].isEmpty())
|
||||
if (!radioData.models[i].isEmpty()) {
|
||||
radioData.models[i].modelUpdated = false;
|
||||
radioData.models[i].validate();
|
||||
}
|
||||
}
|
||||
|
||||
refresh();
|
||||
@@ -1486,6 +1499,13 @@ int MdiChild::askQuestion(const QString & msg, QMessageBox::StandardButtons butt
|
||||
|
||||
void MdiChild::writeSettings(StatusDialog * status, bool toRadio) // write to Tx
|
||||
{
|
||||
// safeguard as the menu actions should be disabled
|
||||
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));
|
||||
return;
|
||||
}
|
||||
|
||||
if (g.confirmWriteModelsAndSettings()) {
|
||||
QMessageBox msgbox;
|
||||
msgbox.setText(tr("You are about to overwrite ALL models."));
|
||||
@@ -1854,3 +1874,52 @@ QAction * MdiChild::actionsSeparator()
|
||||
act->setSeparator(true);
|
||||
return act;
|
||||
}
|
||||
|
||||
bool MdiChild::invalidModels()
|
||||
{
|
||||
return (bool)radioData.invalidModels();
|
||||
}
|
||||
|
||||
void MdiChild::modelShowErrors()
|
||||
{
|
||||
ModelData &mdl = radioData.models[getCurrentModel()];
|
||||
QMessageBox::critical(this, QString("%1").arg(mdl.name), mdl.errorsList().join("\n"));
|
||||
}
|
||||
|
||||
void MdiChild::onModelEditClosed(int id)
|
||||
{
|
||||
radioData.models[id].validate();
|
||||
refresh();
|
||||
}
|
||||
|
||||
void MdiChild::setupStatusBar()
|
||||
{
|
||||
statusBar = new QStatusBar();
|
||||
ui->statusBarLayout->addWidget(statusBar);
|
||||
QLabel *lbl = new QLabel(tr("Models status"));
|
||||
statusBar->addPermanentWidget(lbl);
|
||||
statusBarIcon = new QLabel();
|
||||
statusBar->addPermanentWidget(statusBarIcon);
|
||||
statusBarCount = new QLabel();
|
||||
statusBar->addPermanentWidget(statusBarCount);
|
||||
}
|
||||
|
||||
void MdiChild::updateStatusBar()
|
||||
{
|
||||
QPixmap p;
|
||||
QLabel cnt;
|
||||
int invalid = radioData.invalidModels();
|
||||
|
||||
if (!invalidModels()) {
|
||||
statusBarIcon->setToolTip(tr("No errors"));
|
||||
p.load(":/images/svg/circle-green.svg");
|
||||
}
|
||||
else {
|
||||
statusBarIcon->setToolTip(tr("Errors"));
|
||||
p.load(":/images/svg/circle-red.svg");
|
||||
cnt.setText(QString::number(invalid));
|
||||
}
|
||||
|
||||
statusBarIcon->setPixmap(p.scaled(QSize(16, 16)));
|
||||
statusBarCount->setText(cnt.text());
|
||||
}
|
||||
|
||||
@@ -19,8 +19,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _MDICHILD_H_
|
||||
#define _MDICHILD_H_
|
||||
#pragma once
|
||||
|
||||
#include "eeprominterface.h"
|
||||
#include "modelslist.h"
|
||||
@@ -33,6 +32,7 @@
|
||||
#include <QWidget>
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QListWidget>
|
||||
#include <QStatusBar>
|
||||
|
||||
class QToolBar;
|
||||
class StatusDialog;
|
||||
@@ -70,6 +70,7 @@ class MdiChild : public QWidget
|
||||
ACT_MDL_DFT, // set as DeFaulT
|
||||
ACT_MDL_PRT, // print
|
||||
ACT_MDL_SIM,
|
||||
ACT_MDL_ERR,
|
||||
ACT_LBL_ADD, // label actions..
|
||||
ACT_LBL_DEL,
|
||||
ACT_LBL_MVU, // Move up
|
||||
@@ -89,6 +90,7 @@ class MdiChild : public QWidget
|
||||
QList<QAction *> getModelActions();
|
||||
QList<QAction *> getLabelsActions();
|
||||
QAction * getAction(const Actions type);
|
||||
bool invalidModels();
|
||||
|
||||
public slots:
|
||||
void newFile(bool createDefaults = true);
|
||||
@@ -130,6 +132,7 @@ class MdiChild : public QWidget
|
||||
void onCurrentItemChanged(const QModelIndex &, const QModelIndex &);
|
||||
void onDataChanged(const QModelIndex & index);
|
||||
void onInternalModuleChanged();
|
||||
void onModelEditClosed(int id);
|
||||
|
||||
void generalEdit();
|
||||
void copyGeneralSettings();
|
||||
@@ -153,6 +156,7 @@ class MdiChild : public QWidget
|
||||
void labelsFault(QString msg);
|
||||
void wizardEdit();
|
||||
void modelDuplicate();
|
||||
void modelShowErrors();
|
||||
|
||||
void openModelWizard(int row = -1);
|
||||
void openModelEditWindow(int row = -1);
|
||||
@@ -201,6 +205,7 @@ class MdiChild : public QWidget
|
||||
bool convertStorage(Board::Type from, Board::Type to, bool newFile = false);
|
||||
void showWarning(const QString & msg);
|
||||
int askQuestion(const QString & msg, QMessageBox::StandardButtons buttons = (QMessageBox::Yes | QMessageBox::No), QMessageBox::StandardButton defaultButton = QMessageBox::No);
|
||||
|
||||
QDialog * getChildDialog(QRegularExpression & regexp);
|
||||
QDialog * getModelEditDialog(int row);
|
||||
QList<QDialog *> * getChildrenDialogsList(QRegularExpression & regexp);
|
||||
@@ -219,6 +224,9 @@ class MdiChild : public QWidget
|
||||
QToolBar * modelsToolbar;
|
||||
QToolBar * labelsToolbar;
|
||||
QLabel *lblLabels;
|
||||
QStatusBar *statusBar;
|
||||
QLabel *statusBarIcon;
|
||||
QLabel *statusBarCount;
|
||||
|
||||
Firmware * firmware;
|
||||
RadioData radioData;
|
||||
@@ -232,6 +240,8 @@ class MdiChild : public QWidget
|
||||
QComboBox* cboModelSortOrder;
|
||||
void setModelModified(const int modelIndex, bool cascade = true);
|
||||
QAction * actionsSeparator();
|
||||
void setupStatusBar();
|
||||
void updateStatusBar();
|
||||
};
|
||||
|
||||
// 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.
|
||||
@@ -262,5 +272,3 @@ class ItemViewProxyStyle: public QProxyStyle
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _MDICHILD_H_
|
||||
|
||||
@@ -51,6 +51,9 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="statusBarLayout"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
|
||||
@@ -140,7 +140,8 @@ ModelEdit::~ModelEdit()
|
||||
|
||||
void ModelEdit::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
g.modelEditGeo( saveGeometry() );
|
||||
g.modelEditGeo(saveGeometry());
|
||||
emit closed(modelId);
|
||||
}
|
||||
|
||||
void ModelEdit::addTab(GenericPanel *panel, QString text)
|
||||
|
||||
@@ -19,8 +19,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _MODELEDIT_H_
|
||||
#define _MODELEDIT_H_
|
||||
#pragma once
|
||||
|
||||
#include <QtWidgets>
|
||||
#include "genericpanel.h"
|
||||
@@ -56,6 +55,7 @@ class ModelEdit : public QDialog
|
||||
|
||||
signals:
|
||||
void modified();
|
||||
void closed(int id);
|
||||
|
||||
private slots:
|
||||
void onTabIndexChanged(int index);
|
||||
@@ -72,5 +72,3 @@ class ModelEdit : public QDialog
|
||||
void launchSimulation();
|
||||
|
||||
};
|
||||
|
||||
#endif // _MODELEDIT_H_
|
||||
|
||||
@@ -186,6 +186,12 @@ QVariant ModelsListModel::data(const QModelIndex & index, int role) const
|
||||
}
|
||||
|
||||
if (role == Qt::ForegroundRole && item->isModel()) {
|
||||
if (index.column() == (hasLabels ? 0 : 1) && radioData->models[item->getModelIndex()].modelErrors) {
|
||||
QBrush brush;
|
||||
brush.setColor(Qt::red);
|
||||
return brush;
|
||||
}
|
||||
|
||||
int col = item->columnCount() - 1;
|
||||
if(hasLabels)
|
||||
col --;
|
||||
|
||||
Vendored
+1
-1
Submodule radio/src/thirdparty/FreeRTOS updated: dbf70559b2...a4b28e3510
Reference in New Issue
Block a user