swift
simulatoremulatedmonitordialog.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2017 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #include <QIntValidator>
7 
8 #include "simulatoremulated.h"
9 #include "ui_simulatoremulatedmonitordialog.h"
10 
13 #include "gui/guiapplication.h"
14 #include "misc/logmessage.h"
15 
16 using namespace swift::config;
17 using namespace swift::misc;
18 using namespace swift::misc::aviation;
19 using namespace swift::misc::simulation;
20 using namespace swift::gui;
21 using namespace swift::gui::components;
22 using namespace swift::gui::editors;
23 
24 namespace swift::simplugin::emulated
25 {
26  const QStringList &CSimulatorEmulatedMonitorDialog::getLogCategories()
27  {
28  static const QStringList cats { CLogCategories::driver(), CLogCategories::plugin() };
29  return cats;
30  }
31 
32  CSimulatorEmulatedMonitorDialog::CSimulatorEmulatedMonitorDialog(CSimulatorEmulated *simulator, QWidget *parent)
33  : QDialog(parent), CIdentifiable("Emulated driver dialog"), ui(new Ui::CSimulatorEmulatedMonitorDialog)
34  {
35  Q_ASSERT_X(simulator, Q_FUNC_INFO, "Need simulator");
36 
37  ui->setupUi(this);
38  ui->tw_SwiftMonitorDialog->setCurrentIndex(0);
39  ui->comp_LogComponent->setMaxLogMessages(500);
40  this->setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
41 
42  m_simulator = simulator;
43  m_uiUpdateTimer.setObjectName(this->objectName() + ":uiUpdateTimer");
44  m_uiUpdateTimer.start(2500);
45 
46  connect(m_simulator, &CSimulatorEmulated::internalAircraftChanged, this,
47  &CSimulatorEmulatedMonitorDialog::setInternalAircraftUiValues, Qt::QueuedConnection);
48  connect(&m_uiUpdateTimer, &QTimer::timeout, this, &CSimulatorEmulatedMonitorDialog::timerBasedUiUpdates);
49 
50  connect(ui->cb_Connected, &QCheckBox::released, this,
51  &CSimulatorEmulatedMonitorDialog::onSimulatorValuesChanged);
52  connect(ui->cb_Paused, &QCheckBox::released, this, &CSimulatorEmulatedMonitorDialog::onSimulatorValuesChanged);
53  connect(ui->cb_Simulating, &QCheckBox::released, this,
54  &CSimulatorEmulatedMonitorDialog::onSimulatorValuesChanged);
55 
56  connect(ui->editor_Situation, &CSituationForm::changeAircraftSituation, this,
57  &CSimulatorEmulatedMonitorDialog::changeSituationFromUi, Qt::QueuedConnection);
58  connect(ui->editor_AircraftParts, &CAircraftPartsForm::changeAircraftParts, this,
59  &CSimulatorEmulatedMonitorDialog::changePartsFromUi, Qt::QueuedConnection);
60  connect(ui->editor_Com, &CCockpitComForm::changedCockpitValues, this,
61  &CSimulatorEmulatedMonitorDialog::changeComFromUi, Qt::QueuedConnection);
62  connect(ui->editor_Com, &CCockpitComForm::changedSelcal, this,
63  &CSimulatorEmulatedMonitorDialog::changeSelcalFromUi, Qt::QueuedConnection);
64  connect(ui->comp_ComTransmissions, &CCockpitComTransmissionComponent::changedValues, this,
65  &CSimulatorEmulatedMonitorDialog::onSavedComTransmissionValues, Qt::QueuedConnection);
66 
67  connect(ui->pb_ResetStatistics, &QPushButton::clicked, this, &CSimulatorEmulatedMonitorDialog::resetStatistics);
68  connect(ui->pb_InterpolatorStopLog, &QPushButton::clicked, this,
69  &CSimulatorEmulatedMonitorDialog::interpolatorLogButton);
70  connect(ui->pb_InterpolatorWriteLog, &QPushButton::clicked, this,
71  &CSimulatorEmulatedMonitorDialog::interpolatorLogButton);
72  connect(ui->pb_InterpolatorClearLog, &QPushButton::clicked, this,
73  &CSimulatorEmulatedMonitorDialog::interpolatorLogButton);
74  connect(ui->pb_InterpolatorShowLogs, &QPushButton::clicked, this,
75  &CSimulatorEmulatedMonitorDialog::interpolatorLogButton);
76  connect(ui->pb_InterpolatorStartLog, &QPushButton::clicked, this,
77  &CSimulatorEmulatedMonitorDialog::interpolatorLogButton);
78  connect(ui->pb_InterpolatorFetch, &QPushButton::clicked, this,
79  &CSimulatorEmulatedMonitorDialog::interpolatorLogButton);
80  connect(ui->pb_EmitAddedFailed, &QPushButton::clicked, this, &CSimulatorEmulatedMonitorDialog::emitSignal);
81  connect(ui->pb_AddAutoPublishData, &QPushButton::clicked, this,
82  &CSimulatorEmulatedMonitorDialog::addAutoPublishTestData);
83 
84  ui->led_Receiving->setToolTips("receiving", "idle");
85  ui->led_Receiving->setShape(CLedWidget::Rounded);
86  ui->led_Sending->setToolTips("sending", "idle");
87  ui->led_Sending->setShape(CLedWidget::Rounded);
88  ui->led_Fetching->setToolTips("fetching interpolated", "not fetching interpolated");
89  ui->led_Fetching->setShape(CLedWidget::Rounded);
90 
91  ui->le_InterpolatorTimeMs->setValidator(new QIntValidator(10, 20000, ui->le_InterpolatorTimeMs));
92 
93  this->enableInterpolationLogButtons(false);
94  this->setSimulatorUiValues();
95  this->setInternalAircraftUiValues();
97  }
98 
100 
102  {
103  ui->comp_LogComponent->appendStatusMessagesToList(statusMessage);
104  }
105 
106  void
108  {
109  ui->comp_LogComponent->appendStatusMessagesToList(statusMessages);
110  }
111 
112  void CSimulatorEmulatedMonitorDialog::appendReceivingCall(const QString &function, const QString &p1,
113  const QString &p2, const QString &p3)
114  {
115  ui->led_Receiving->blink();
116  this->appendFunctionCall(function, p1, p2, p3);
117  }
118 
119  void CSimulatorEmulatedMonitorDialog::appendSendingCall(const QString &function, const QString &p1,
120  const QString &p2, const QString &p3)
121  {
122  ui->led_Sending->blink();
123  this->appendFunctionCall(function, p1, p2, p3);
124  }
125 
126  void CSimulatorEmulatedMonitorDialog::appendFunctionCall(const QString &function, const QString &p1,
127  const QString &p2, const QString &p3)
128  {
129  static const QString c1("%1 %2");
130  static const QString c2("%1 %2 %3");
131  static const QString c3("%1 %2 %3 %4");
132 
133  CStatusMessage msg;
134  if (!p3.isEmpty()) { msg = CStatusMessage(this, CStatusMessage::SeverityInfo, c3.arg(function, p1, p2, p3)); }
135  else if (!p2.isEmpty()) { msg = CStatusMessage(this, CStatusMessage::SeverityInfo, c2.arg(function, p1, p2)); }
136  else if (!p1.isEmpty()) { msg = CStatusMessage(this, CStatusMessage::SeverityInfo, c1.arg(function, p1)); }
137  else { msg = CStatusMessage(this, CStatusMessage::SeverityInfo, function); }
138  this->appendStatusMessageToList(msg);
139  }
140 
142  {
143  ui->pte_StatusMessages->setPlainText(message.toQString(true));
144  }
145 
147  {
148  ui->pte_TextMessages->setPlainText(message.toQString(true));
149  }
150 
152  {
153  if (!info.isSingleSimulator()) { return; }
154  this->setWindowTitle("Emulated driver : " + info.toQString());
155  this->setSimulatorUiValues();
156  }
157 
158  void CSimulatorEmulatedMonitorDialog::onSimulatorValuesChanged()
159  {
160  m_simulator->setCombinedStatus(ui->cb_Connected->isChecked(), ui->cb_Simulating->isChecked(),
161  ui->cb_Paused->isChecked());
162  }
163 
164  void CSimulatorEmulatedMonitorDialog::onSavedComTransmissionValues(CComSystem::ComUnit unit)
165  {
166  if (!this->canUseSimulator()) { return; }
167  const CSimulatedAircraft ownAircraft = m_simulator->getOwnAircraft();
168  CComSystem com = ownAircraft.getComSystem(unit);
169  ui->comp_ComTransmissions->updateComSystem(com, unit);
170  m_simulator->changeInternalCom(com, unit);
171  }
172 
173  void CSimulatorEmulatedMonitorDialog::changeComFromUi(const CSimulatedAircraft &aircraft)
174  {
175  if (!this->canUseSimulator()) { return; }
176  m_simulator->changeInternalCom(aircraft);
177  }
178 
179  void CSimulatorEmulatedMonitorDialog::changeSelcalFromUi(const CSelcal &selcal)
180  {
181  if (!this->canUseSimulator()) { return; }
182  m_simulator->changeInternalSelcal(selcal);
183  }
184 
185  void CSimulatorEmulatedMonitorDialog::changeSituationFromUi()
186  {
187  if (!this->canUseSimulator()) { return; }
188  const CAircraftSituation s(ui->editor_Situation->getSituation());
189  m_simulator->changeInternalSituation(s);
190  }
191 
192  void CSimulatorEmulatedMonitorDialog::changePartsFromUi()
193  {
194  if (!this->canUseSimulator()) { return; }
195  const CAircraftParts p(ui->editor_AircraftParts->getAircraftPartsFromGui());
196  m_simulator->changeInternalParts(p);
197  }
198 
199  void CSimulatorEmulatedMonitorDialog::setSimulatorUiValues()
200  {
201  ui->cb_Connected->setChecked(m_simulator->isConnected());
202  ui->cb_Paused->setChecked(m_simulator->isPaused());
203  ui->cb_Simulating->setChecked(m_simulator->isSimulating());
204 
205  ui->le_Simulator->setText(m_simulator->getSimulatorInfo().toQString(true));
206  ui->le_SimulatorPlugin->setText(m_simulator->getSimulatorPluginInfo().toQString(true));
207  }
208 
209  void CSimulatorEmulatedMonitorDialog::setInternalAircraftUiValues()
210  {
211  const CSimulatedAircraft internal(m_simulator->getInternalOwnAircraft());
212  ui->editor_Situation->setSituation(internal.getSituation());
213  ui->editor_AircraftParts->setAircraftParts(internal.getParts());
214  ui->editor_Com->setValue(internal);
215  ui->comp_ComTransmissions->setComSystems(internal);
216  }
217 
218  void CSimulatorEmulatedMonitorDialog::timerBasedUiUpdates()
219  {
220  if (!this->canUseSimulator()) { return; }
221 
222  ui->le_PhysicallyAddedAircraft->setText(QString::number(m_simulator->getStatisticsPhysicallyAddedAircraft()));
223  ui->le_PhysicallyRemovedAircraft->setText(QString::number(m_simulator->aircraftSituationsAdded()));
224  ui->le_SituationAdded->setText(QString::number(m_simulator->aircraftSituationsAdded()));
225  ui->le_PartsAdded->setText(QString::number(m_simulator->aircraftPartsAdded()));
226  ui->le_AircraftRendered->setText(QString::number(m_simulator->m_renderedAircraft.size()));
227  ui->le_PartsEnabledAircraft->setText(QString::number(m_simulator->getRemoteAircraftSupportingPartsCount()));
228  }
229 
230  void CSimulatorEmulatedMonitorDialog::resetStatistics()
231  {
232  if (!this->canUseSimulator()) { return; }
233 
234  m_simulator->resetAircraftStatistics();
235  ui->le_PhysicallyAddedAircraft->clear();
236  ui->le_PhysicallyRemovedAircraft->clear();
237  ui->le_SituationAdded->clear();
238  ui->le_PartsAdded->clear();
239  }
240 
241  void CSimulatorEmulatedMonitorDialog::interpolatorLogButton()
242  {
243  const QObject *sender = QObject::sender();
244  bool ok = false;
245  if (sender == ui->pb_InterpolatorStopLog)
246  {
247  ok = m_simulator->parseCommandLine(".drv logint off", this->identifier());
248  }
249  else if (sender == ui->pb_InterpolatorWriteLog)
250  {
251  ok = m_simulator->parseCommandLine(".drv logint write", this->identifier());
252  }
253  else if (sender == ui->pb_InterpolatorClearLog)
254  {
255  ok = m_simulator->parseCommandLine(".drv logint clear", this->identifier());
256  }
257  else if (sender == ui->pb_InterpolatorShowLogs)
258  {
259  ok = m_simulator->parseCommandLine(".drv logint show", this->identifier());
260  }
261  else if (sender == ui->pb_InterpolatorStartLog)
262  {
263  const CCallsign cs = ui->comp_LogInterpolatorCallsign->getCallsign();
264  if (cs.isValid())
265  {
266  ok = m_simulator->parseCommandLine(".drv logint " + cs.asString(), this->identifier());
267  }
268  else
269  {
270  CLogMessage(this).warning(u"Need a (valid) callsign to write a log");
271  ok = true; // already a warning
272  }
273  }
274  else if (sender == ui->pb_InterpolatorFetch)
275  {
276  // toggle fetching
277  const int timeMs = m_simulator->isInterpolatorFetching() ? -1 : ui->le_InterpolatorTimeMs->text().toInt();
278  const bool fetching = m_simulator->setInterpolatorFetchTime(timeMs);
279  ui->led_Fetching->setOn(fetching);
280  ui->pb_InterpolatorFetch->setText(fetching ? "Stop" : "Fetch");
281  this->enableInterpolationLogButtons(fetching);
282  ok = true;
283  }
284  else { Q_ASSERT_X(false, Q_FUNC_INFO, "Unhandled button"); }
285  if (!ok) { CLogMessage(this).warning(u"Cannot parse command for button: %1") << sender->objectName(); }
286  }
287 
288  void CSimulatorEmulatedMonitorDialog::enableInterpolationLogButtons(bool enable)
289  {
290  ui->pb_InterpolatorClearLog->setEnabled(enable);
291  ui->pb_InterpolatorShowLogs->setEnabled(enable);
292  ui->pb_InterpolatorStartLog->setEnabled(enable);
293  ui->pb_InterpolatorStopLog->setEnabled(enable);
294  ui->pb_InterpolatorWriteLog->setEnabled(enable);
295  }
296 
297  void CSimulatorEmulatedMonitorDialog::emitSignal()
298  {
299  if (!this->canUseSimulator()) { return; }
300 
301  const CCallsign cs = ui->comp_CallsignCompleter->getCallsign();
302  const QObject *sender = QObject::sender();
303  if (sender == ui->pb_EmitAddedFailed && cs.isValid())
304  {
305  const CSimulatedAircraft aircraft = m_simulator->getAircraftInRangeForCallsign(cs);
306  const CStatusMessage msg(this, CStatusMessage::SeverityError,
307  "Simulated driver driver failed for " + cs.asString());
308  emit m_simulator->physicallyAddingRemoteModelFailed(aircraft, true, ui->cb_Failover->isChecked(), msg);
309  }
310  }
311 
312  void CSimulatorEmulatedMonitorDialog::addAutoPublishTestData()
313  {
314  if (!this->canUseSimulator()) { return; }
315  m_simulator->m_autoPublishing.testData();
316  }
317 
318  bool CSimulatorEmulatedMonitorDialog::canUseSimulator() const
319  {
320  return (m_simulator && sGui && !sGui->isShuttingDown());
321  }
322 } // namespace swift::simplugin::emulated
bool isShuttingDown() const
Is application shutting down?
int getStatisticsPhysicallyAddedAircraft() const
Counter added aircraft.
Definition: simulator.h:296
void physicallyAddingRemoteModelFailed(const swift::misc::simulation::CSimulatedAircraft &remoteAircraft, bool disabled, bool requestFailover, const swift::misc::CStatusMessage &message)
Adding the remote model failed.
swift::misc::simulation::CAutoPublishData m_autoPublishing
for the DB
Definition: simulator.h:580
virtual void resetAircraftStatistics()
Reset the statistics.
Definition: simulator.cpp:277
Base class with a member CIdentifier to be inherited by a class which has an identity in the environm...
Definition: identifiable.h:24
const CIdentifier & identifier() const
Get identifier.
Definition: identifiable.h:27
Class for emitting a log message.
Definition: logmessage.h:27
Derived & warning(const char16_t(&format)[N])
Set the severity to warning, providing a format string.
size_type size() const
Returns number of elements in the sequence.
Definition: sequence.h:273
Streamable status message, e.g.
Status messages, e.g. from Core -> GUI.
Value object encapsulating information of aircraft's parts.
Definition: aircraftparts.h:26
Value object encapsulating information of an aircraft's situation.
Value object encapsulating information of a callsign.
Definition: callsign.h:30
const QString & asString() const
Get callsign (normalized)
Definition: callsign.h:96
bool isValid() const
Valid callsign?
Definition: callsign.cpp:359
COM system (aka "radio")
Definition: comsystem.h:37
Value object for SELCAL.
Definition: selcal.h:31
QString toQString(bool i18n=false) const
Cast as QString.
Definition: mixinstring.h:76
Value object encapsulating information of a text message.
Definition: textmessage.h:31
CSimulatedAircraft getOwnAircraft() const
Own aircraft.
int aircraftSituationsAdded() const
Number of situations added.
CSimulatedAircraft getAircraftInRangeForCallsign(const aviation::CCallsign &callsign) const
Aircraft for callsign.
int aircraftPartsAdded() const
Number of parts added.
int getRemoteAircraftSupportingPartsCount() const
Number of aircraft supporting parts.
Comprehensive information of an aircraft.
aviation::CComSystem getComSystem(aviation::CComSystem::ComUnit unit) const
Get COM unit.
Simple hardcoded info about the corresponding simulator.
Definition: simulatorinfo.h:41
bool isSingleSimulator() const
Single simulator selected.
CSimulatorPluginInfo getSimulatorPluginInfo() const
Get the represented plugin.
CSimulatorInfo getSimulatorInfo() const
Get the represented simulator.
bool isInterpolatorFetching() const
Is fetching from interpolator.
void internalAircraftChanged()
Internal aircraft changed.
const swift::misc::simulation::CSimulatedAircraft & getInternalOwnAircraft() const
Internal own aircraft.
bool changeInternalSituation(const swift::misc::aviation::CAircraftSituation &situation)
Simulator internal change of situation.
bool changeInternalCom(const swift::misc::simulation::CSimulatedAircraft &aircraft)
Simulator internal change of COM values.
virtual bool isSimulating() const
Simulator running?
bool setInterpolatorFetchTime(int timeMs)
Interpolator fetch time, <=0 stops.
bool changeInternalParts(const swift::misc::aviation::CAircraftParts &parts)
Simulator internal change of parts.
bool changeInternalSelcal(const swift::misc::aviation::CSelcal &selcal)
Simulator internal change of SELCAL.
virtual bool isConnected() const
Are we connected to the simulator?
virtual bool isPaused() const
Simulator paused?
void setCombinedStatus(bool connected, bool simulating, bool paused)
UI setter.
void appendStatusMessageToList(const swift::misc::CStatusMessage &statusMessage)
Append status message.
void appendReceivingCall(const QString &function, const QString &p1={}, const QString &p2={}, const QString &p3={})
Receiving call to be written in log widget.
void displayStatusMessage(const swift::misc::CStatusMessage &message)
Display status message.
void updateWindowTitleAndUiValues(const swift::misc::simulation::CSimulatorInfo &info)
The title.
void appendStatusMessagesToList(const swift::misc::CStatusMessageList &statusMessages)
Append status messages.
void appendSendingCall(const QString &function, const QString &p1={}, const QString &p2={}, const QString &p3={})
Sending call to be written in log widget.
void displayTextMessage(const swift::misc::network::CTextMessage &message)
Display text message.
virtual bool parseCommandLine(const QString &commandLine, const swift::misc::CIdentifier &originator)
SWIFT_GUI_EXPORT swift::gui::CGuiApplication * sGui
Single instance of GUI application object.
High level reusable GUI components.
Definition: aboutdialog.cpp:13
GUI related classes.
Free functions in swift::misc.