swift
aircraftmodelvalidationcomponent.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2019 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #include <QPointer>
7 
8 #include "ui_aircraftmodelvalidationcomponent.h"
9 
11 #include "gui/guiapplication.h"
12 
13 using namespace swift::misc;
14 using namespace swift::misc::simulation;
15 using namespace swift::core::context;
16 
17 namespace swift::gui::components
18 {
19  CAircraftModelValidationComponent::CAircraftModelValidationComponent(QWidget *parent)
21  {
22  ui->setupUi(this);
23  ui->comp_Simulator->setMode(CSimulatorSelector::ComboBox);
24  ui->comp_Simulator->setRememberSelection(false);
25  ui->comp_Messages->setNoSorting(); // keep order
26  ui->tvp_InvalidModels->setValidationContextMenu(false);
27 
28  const CAircraftMatcherSetup setup = m_matchingSettings.get();
29  ui->cb_EnableStartupCheck->setChecked(setup.doVerificationAtStartup());
30  ui->cb_OnlyIfErrorsOrWarnings->setChecked(setup.onlyShowVerificationWarningsAndErrors());
31 
32  connect(ui->cb_EnableStartupCheck, &QCheckBox::toggled, this,
33  &CAircraftModelValidationComponent::onCheckAtStartupChanged);
34  connect(ui->cb_OnlyIfErrorsOrWarnings, &QCheckBox::toggled, this,
35  &CAircraftModelValidationComponent::onOnlyErrorWarningChanged);
36 
37  connect(ui->pb_TempDisableInvalid, &QPushButton::released, this,
38  &CAircraftModelValidationComponent::onTempDisabledButtonClicked, Qt::QueuedConnection);
39  connect(ui->pb_TempDisableSelected, &QPushButton::released, this,
40  &CAircraftModelValidationComponent::onTempDisabledButtonClicked, Qt::QueuedConnection);
41  connect(ui->pb_RemoveInvalid, &QPushButton::released, this,
42  &CAircraftModelValidationComponent::onRemoveButtonClicked, Qt::QueuedConnection);
43  connect(ui->pb_RemoveSelected, &QPushButton::released, this,
44  &CAircraftModelValidationComponent::onRemoveButtonClicked, Qt::QueuedConnection);
45 
46  connect(ui->pb_TriggerValidation, &QPushButton::released, this,
47  &CAircraftModelValidationComponent::triggerValidation, Qt::QueuedConnection);
48  connect(ui->pb_Help, &QPushButton::released, this, &CAircraftModelValidationComponent::showHelp,
49  Qt::QueuedConnection);
50 
51  // 1st init when running in distributed environment
52  QPointer<CAircraftModelValidationComponent> myself(this);
53  const qint64 lastResults = m_lastResults;
54  QTimer::singleShot(2500, this, [=] {
55  if (!myself || !sGui || sGui->isShuttingDown()) { return; }
56  if (m_lastResults > lastResults) { return; } // values received in meantime
57  myself->requestLastResults();
58  });
59  }
60 
62 
64  const CAircraftModelList &valid,
65  const CAircraftModelList &invalid, bool stopped,
66  const CStatusMessageList &msgs)
67  {
68  // swift::misc::simulation::CBackgroundValidation
69  Q_UNUSED(simulator)
70  Q_UNUSED(valid)
71 
72  constexpr std::chrono::seconds MsgTimeout { 15000 };
73  m_lastResults = QDateTime::currentMSecsSinceEpoch();
74  ui->tvp_InvalidModels->updateContainerMaybeAsync(invalid);
75  ui->comp_Simulator->setValue(simulator);
76  ui->comp_Messages->clear();
77  if (!msgs.isEmpty()) { ui->comp_Messages->appendStatusMessagesToList(msgs); }
78 
79  // pre-select tab
80  if (invalid.isEmpty() && !msgs.isEmpty())
81  {
82  // messages but no invalid models
83  ui->tw_CAircraftModelValidationComponent->setCurrentWidget(ui->tb_Messages);
84  }
85  else { ui->tw_CAircraftModelValidationComponent->setCurrentWidget(ui->tb_InvalidModels); }
86 
87  const CAircraftMatcherSetup setup = m_matchingSettings.get();
88  ui->cb_EnableStartupCheck->setChecked(setup.doVerificationAtStartup());
89  ui->pb_TempDisableInvalid->setEnabled(!invalid.isEmpty());
90  ui->pb_TempDisableSelected->setEnabled(!invalid.isEmpty());
91  ui->pb_RemoveInvalid->setEnabled(!invalid.isEmpty());
92  ui->pb_RemoveSelected->setEnabled(!invalid.isEmpty());
93 
94  const QString msg =
95  stopped ?
96  QStringLiteral("Validation for '%1' stopped, maybe your models are not accessible or too many issues")
97  .arg(simulator.toQString(true)) :
98  QStringLiteral("Validated for '%1'. Valid: %2 Invalid: %3")
99  .arg(simulator.toQString(true))
100  .arg(valid.size())
101  .arg(invalid.size());
102  ui->lbl_Summay->setText(msg);
103  if (stopped) { this->showOverlayHTMLMessage(msg, MsgTimeout); }
104  else if (msgs.hasWarningOrErrorMessages() || !invalid.isEmpty())
105  {
106  this->showOverlayHTMLMessage(u"There are warnings or errors, please check the messages and invalid models.",
107  MsgTimeout);
108  }
109  else { this->showOverlayHTMLMessage(u"There are NO warnings or errors, your set looks good.", MsgTimeout); }
110  }
111 
112  void CAircraftModelValidationComponent::tempDisableModels(const CAircraftModelList &models)
113  {
114  if (models.isEmpty()) { return; }
115  if (!sGui || sGui->isShuttingDown() || !sGui->supportsContexts()) { return; }
116  if (!sGui->getIContextSimulator()) { return; }
118  this->saveInvalidModels(models);
119  }
120 
121  void CAircraftModelValidationComponent::onCheckAtStartupChanged(bool checked)
122  {
123  CAircraftMatcherSetup setup = m_matchingSettings.get();
124  if (setup.doVerificationAtStartup() == checked) { return; }
125  setup.setVerificationAtStartup(checked);
126  const CStatusMessage msg = m_matchingSettings.setAndSave(setup);
127  Q_UNUSED(msg)
128  }
129 
130  void CAircraftModelValidationComponent::onOnlyErrorWarningChanged(bool checked)
131  {
132  CAircraftMatcherSetup setup = m_matchingSettings.get();
133  if (setup.onlyShowVerificationWarningsAndErrors() == checked) { return; }
135  const CStatusMessage msg = m_matchingSettings.setAndSave(setup);
136  Q_UNUSED(msg)
137  }
138 
139  void CAircraftModelValidationComponent::triggerValidation()
140  {
141  using namespace std::chrono_literals;
142  if (!sGui || sGui->isShuttingDown() || !sGui->supportsContexts()) { return; }
143  if (!sGui->getIContextSimulator()) { return; }
145  {
146  this->showOverlayHTMLMessage("Validation in progress", 5s);
147  return;
148  }
149 
150  const CSimulatorInfo simulator = ui->comp_Simulator->getValue();
152  {
153  this->showOverlayHTMLMessage(QStringLiteral("Triggered validation for '%1'").arg(simulator.toQString(true)),
154  5s);
155  }
156  else
157  {
159  QStringLiteral("Cannot trigger validation for '%1'").arg(simulator.toQString(true)), 5s);
160  }
161  }
162 
163  void CAircraftModelValidationComponent::requestLastResults()
164  {
165  using namespace std::chrono_literals;
166 
167  if (!sGui || sGui->isShuttingDown() || !sGui->supportsContexts()) { return; }
168  if (!sGui->getIContextSimulator()) { return; }
170  {
171  this->showOverlayHTMLMessage("Validation in progress", 5s);
172  return;
173  }
175  }
176 
177  void CAircraftModelValidationComponent::onTempDisabledButtonClicked()
178  {
179  using namespace std::chrono_literals;
180 
181  if (!sGui || sGui->isShuttingDown()) { return; }
182 
183  CAircraftModelList disableModels;
184  const QObject *sender = QObject::sender();
185  if (sender == ui->pb_TempDisableInvalid) { disableModels = ui->tvp_InvalidModels->container(); }
186  else if (sender == ui->pb_TempDisableSelected) { disableModels = ui->tvp_InvalidModels->selectedObjects(); }
187 
188  if (disableModels.isEmpty()) { this->showOverlayHTMLMessage("No models disabled", 4s); }
189  else
190  {
191  this->tempDisableModels(disableModels);
192  this->showOverlayHTMLMessage(QStringLiteral("%1 models disabled").arg(disableModels.size()));
193  }
194  }
195 
196  void CAircraftModelValidationComponent::onRemoveButtonClicked()
197  {
198  using namespace std::chrono_literals;
199 
200  if (!sGui || sGui->isShuttingDown()) { return; }
201  if (!sGui->getIContextSimulator()) { return; }
202 
203  CAircraftModelList removeModels;
204  const QObject *sender = QObject::sender();
205  if (sender == ui->pb_RemoveInvalid) { removeModels = ui->tvp_InvalidModels->container(); }
206  else if (sender == ui->pb_RemoveSelected) { removeModels = ui->tvp_InvalidModels->selectedObjects(); }
207 
208  if (removeModels.isEmpty()) { this->showOverlayHTMLMessage("No models removed", 4s); }
209  else
210  {
211  const QMessageBox::StandardButton ret = QMessageBox::question(
212  this, tr("Model validation"),
213  tr("Do you really want to delete %1 models from model set?").arg(removeModels.sizeInt()),
214  QMessageBox::Ok | QMessageBox::Cancel);
215  if (ret != QMessageBox::Ok) { return; }
216 
217  const int r = sGui->getIContextSimulator()->removeModelsFromSet(removeModels);
218  this->showOverlayHTMLMessage(QStringLiteral("%1 models removed").arg(r));
219  }
220  }
221 
222  void CAircraftModelValidationComponent::showHelp()
223  {
224  if (!sGui || sGui->isShuttingDown()) { return; }
225  sGui->showHelp(this);
226  }
227 
228  void CAircraftModelValidationComponent::saveInvalidModels(const CAircraftModelList &models) const
229  {
230  const CStatusMessage m = models.saveInvalidModels();
231  Q_UNUSED(m)
232  }
233 } // namespace swift::gui::components
bool isShuttingDown() const
Is application shutting down?
const context::IContextSimulator * getIContextSimulator() const
Direct access to contexts if a CCoreFacade has been initialized.
bool supportsContexts(bool ignoreShutdownTest=false) const
Supports contexts.
virtual void disableModelsForMatching(const swift::misc::simulation::CAircraftModelList &removedModels, bool incremental)=0
Remove a model for matching.
virtual bool isValidationInProgress() const =0
Validation in progress.
virtual int removeModelsFromSet(const swift::misc::simulation::CAircraftModelList &removeModels)=0
Remove models from set.
virtual bool triggerModelSetValidation(const swift::misc::simulation::CSimulatorInfo &simulator)=0
Trigger model set validation.
void showHelp(const QString &context={}) const
Show help page (online help)
bool showOverlayHTMLMessage(const QString &htmlMessage, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
HTML message.
Using this class provides a QFrame with the overlay functionality already integrated.
void validatedModelSet(const swift::misc::simulation::CSimulatorInfo &simulator, const swift::misc::simulation::CAircraftModelList &valid, const swift::misc::simulation::CAircraftModelList &invalid, bool stopped, const swift::misc::CStatusMessageList &msgs)
Validated a model set.
CStatusMessage setAndSave(const T &value, qint64 timestamp=0)
Write and save in the same step. Must be called from the thread in which the owner lives.
Definition: valuecache.h:417
T get() const
Get a copy of the current value.
Definition: valuecache.h:408
size_type size() const
Returns number of elements in the sequence.
Definition: sequence.h:273
bool isEmpty() const
Synonym for empty.
Definition: sequence.h:285
int sizeInt() const
Avoid compiler warnings when using with int.
Definition: sequence.h:276
Streamable status message, e.g.
Status messages, e.g. from Core -> GUI.
bool hasWarningOrErrorMessages() const
Warning or error messages.
const CONTAINER & container() const
Container.
QString toQString(bool i18n=false) const
Cast as QString.
Definition: mixinstring.h:76
bool onlyShowVerificationWarningsAndErrors() const
Verification only shown for warning/errors?
void setOnlyShowVerificationWarningsAndErrors(bool only)
Set the "show only errors" mode.
bool doVerificationAtStartup() const
Verification at startup?
void setVerificationAtStartup(bool verify)
Set startup verification.
Value object encapsulating a list of aircraft models.
CStatusMessage saveInvalidModels() const
Save/load invalid models.
Simple hardcoded info about the corresponding simulator.
Definition: simulatorinfo.h:41
SWIFT_GUI_EXPORT swift::gui::CGuiApplication * sGui
Single instance of GUI application object.
High level reusable GUI components.
Definition: aboutdialog.cpp:13
Free functions in swift::misc.
auto singleShot(int msec, QObject *target, F &&task)
Starts a single-shot timer which will call a task in the thread of the given object when it times out...
Definition: threadutils.h:30