swift
mappingcomponent.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2015 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #include <QCheckBox>
7 #include <QCompleter>
8 #include <QLabel>
9 #include <QLineEdit>
10 #include <QPixmap>
11 #include <QPointer>
12 #include <QPushButton>
13 #include <QStringListModel>
14 #include <QtGlobal>
15 
16 #include "mappingcomponent.h"
17 #include "ui_mappingcomponent.h"
18 
21 #include "gui/guiapplication.h"
22 #include "gui/guiutility.h"
28 #include "gui/views/viewbase.h"
29 #include "misc/aviation/callsign.h"
30 #include "misc/icons.h"
31 #include "misc/logmessage.h"
33 #include "misc/network/server.h"
34 #include "misc/pixmap.h"
38 #include "misc/statusmessage.h"
39 
40 using namespace swift::misc;
41 using namespace swift::misc::simulation;
42 using namespace swift::misc::network;
43 using namespace swift::misc::aviation;
44 using namespace swift::misc::physical_quantities;
45 using namespace swift::core;
46 using namespace swift::core::context;
47 using namespace swift::gui::views;
48 using namespace swift::gui::models;
49 using namespace swift::gui::filters;
50 using namespace swift::gui::settings;
51 
52 namespace swift::gui::components
53 {
54  const QStringList &CMappingComponent::getLogCategories()
55  {
57  return cats;
58  }
59 
60  CMappingComponent::CMappingComponent(QWidget *parent)
61  : COverlayMessagesFrame(parent), CIdentifiable(this), ui(new Ui::CMappingComponent)
62  {
63  Q_ASSERT_X(sGui, Q_FUNC_INFO, "need sGui");
64  Q_ASSERT_X(sGui->getIContextSimulator(), Q_FUNC_INFO, "need simulator context");
65  Q_ASSERT_X(sGui->getIContextNetwork(), Q_FUNC_INFO, "need network context");
66 
67  ui->setupUi(this);
68  ui->tw_SpecializedViews->setCurrentIndex(0);
69 
70  ui->tvp_AircraftModels->setAircraftModelMode(CAircraftModelListModel::OwnAircraftModelClient);
71  ui->tvp_AircraftModels->setResizeMode(CAircraftModelView::ResizingOff);
72  ui->tvp_AircraftModels->addFilterDialog();
73  ui->tvp_AircraftModels->menuRemoveItems(CAircraftModelView::MenuBackend);
74  ui->tvp_AircraftModels->menuAddItems(CAircraftModelView::MenuDisableModelsTemp);
75 
76  ui->tvp_RenderedAircraft->setAircraftMode(CSimulatedAircraftListModel::RenderedMode);
77  ui->tvp_RenderedAircraft->setResizeMode(CAircraftModelView::ResizingOnce);
78  ui->tvp_RenderedAircraft->menuAddItems(CAircraftModelView::MenuDisableModelsTemp);
79 
80  connect(sGui->getIContextNetwork(), &IContextNetwork::connectionStatusChanged, this,
81  &CMappingComponent::onNetworkConnectionStatusChanged);
82 
83  connect(ui->tvp_AircraftModels, &CAircraftModelView::requestUpdate, this,
84  &CMappingComponent::onModelsUpdateRequested);
85  connect(ui->tvp_AircraftModels, &CAircraftModelView::modelDataChanged, this,
86  &CMappingComponent::onRowCountChanged);
87  connect(ui->tvp_AircraftModels, &CAircraftModelView::clicked, this, &CMappingComponent::onModelSelectedInView);
88  connect(ui->tvp_AircraftModels, &CAircraftModelView::requestTempDisableModelsForMatching, this,
89  &CMappingComponent::onTempDisableModelsForMatchingRequested);
90 
91  connect(ui->tvp_RenderedAircraft, &CSimulatedAircraftView::modelDataChanged, this,
92  &CMappingComponent::onRowCountChanged);
93  connect(ui->tvp_RenderedAircraft, &CSimulatedAircraftView::clicked, this,
94  &CMappingComponent::onAircraftSelectedInView);
95  connect(ui->tvp_RenderedAircraft, &CSimulatedAircraftView::requestUpdate, this,
96  &CMappingComponent::tokenBucketUpdate);
97  connect(ui->tvp_RenderedAircraft, &CSimulatedAircraftView::requestTextMessageWidget, this,
99  connect(ui->tvp_RenderedAircraft, &CSimulatedAircraftView::requestTempDisableModelsForMatching, this,
100  &CMappingComponent::onTempDisableModelsForMatchingRequested);
101 
102  connect(ui->pb_SaveAircraft, &QPushButton::clicked, this, &CMappingComponent::onSaveAircraft);
103  connect(ui->pb_ResetAircraft, &QPushButton::clicked, this, &CMappingComponent::onResetAircraft);
104  connect(ui->pb_LoadModels, &QPushButton::clicked, this, &CMappingComponent::onModelsUpdateRequested);
105  connect(ui->pb_DoMatchingAgain, &QPushButton::clicked, this, &CMappingComponent::doMatchingsAgain);
107 
108  m_currentMappingsViewDelegate = new CCheckBoxDelegate(":/diagona/icons/diagona/icons/tick.png",
109  ":/diagona/icons/diagona/icons/cross.png", this);
110  ui->tvp_RenderedAircraft->setItemDelegateForColumn(0, m_currentMappingsViewDelegate);
111 
112  // overlay
113  this->setReducedInfo(true);
114  this->setForceSmall(true);
115 
116  // Aircraft previews
117  connect(ui->cb_AircraftIconDisplayed, &QCheckBox::checkStateChanged, this,
118  &CMappingComponent::onModelPreviewChanged);
119 
120  // model string completer
121  ui->completer_ModelStrings->setSourceVisible(CAircraftModelStringCompleter::OwnModels, false);
122  ui->completer_ModelStrings->selectSource(CAircraftModelStringCompleter::ModelSet);
123 
124  // Updates
125  connect(&m_updateTimer, &QTimer::timeout, this, &CMappingComponent::timerUpdate);
126  m_updateTimer.setObjectName(this->objectName() + "::updateTimer");
127  ui->tvp_AircraftModels->setDisplayAutomatically(false);
128  this->settingsChanged();
129 
130  // selector
131  ui->comp_SimulatorSelector->setRememberSelection(false); // pilot client UI
132  ui->comp_SimulatorSelector->setMode(CSimulatorSelector::ComboBox);
133  ui->comp_SimulatorSelector->setToConnectedSimulator();
134  connect(ui->comp_SimulatorSelector, &CSimulatorSelector::changed, this,
135  &CMappingComponent::onModelSetSimulatorChanged);
136 
137  // connect
138  connect(sGui->getIContextSimulator(), &IContextSimulator::modelSetChanged, this,
139  &CMappingComponent::onModelSetChanged, Qt::QueuedConnection);
140  connect(sGui->getIContextSimulator(), &IContextSimulator::modelMatchingCompleted, this,
141  &CMappingComponent::tokenBucketUpdateAircraft, Qt::QueuedConnection);
142  connect(sGui->getIContextSimulator(), &IContextSimulator::aircraftRenderingChanged, this,
143  &CMappingComponent::tokenBucketUpdateAircraft, Qt::QueuedConnection);
144  connect(sGui->getIContextSimulator(), &IContextSimulator::airspaceSnapshotHandled, this,
145  &CMappingComponent::tokenBucketUpdate, Qt::QueuedConnection);
146  connect(sGui->getIContextSimulator(), &IContextSimulator::addingRemoteModelFailed, this,
147  &CMappingComponent::onAddingRemoteAircraftFailed, Qt::QueuedConnection);
148  connect(sGui->getIContextSimulator(), &IContextSimulator::simulatorPluginChanged, this,
149  &CMappingComponent::onSimulatorPluginChanged, Qt::QueuedConnection);
150  connect(sGui->getIContextSimulator(), &IContextSimulator::simulatorStatusChanged, this,
151  &CMappingComponent::onSimulatorStatusChanged, Qt::QueuedConnection);
152  connect(sGui->getIContextNetwork(), &IContextNetwork::changedRemoteAircraftModel, this,
153  &CMappingComponent::onRemoteAircraftModelChanged, Qt::QueuedConnection);
154  connect(sGui->getIContextNetwork(), &IContextNetwork::changedRemoteAircraftEnabled, this,
155  &CMappingComponent::tokenBucketUpdateAircraft, Qt::QueuedConnection);
156  connect(sGui->getIContextNetwork(), &IContextNetwork::changedFastPositionUpdates, this,
157  &CMappingComponent::tokenBucketUpdateAircraft, Qt::QueuedConnection);
158  connect(sGui->getIContextNetwork(), &IContextNetwork::changedGndFlagCapability, this,
159  &CMappingComponent::tokenBucketUpdateAircraft, Qt::QueuedConnection);
160  connect(sGui->getIContextNetwork(), &IContextNetwork::removedAircraft, this,
161  &CMappingComponent::tokenBucketUpdate, Qt::QueuedConnection);
162  connect(sGui->getIContextNetwork(), &IContextNetwork::connectionStatusChanged, this,
163  &CMappingComponent::onConnectionStatusChanged, Qt::QueuedConnection);
164 
165  connect(ui->tw_SpecializedViews, &QTabWidget::currentChanged, this, &CMappingComponent::onTabWidgetChanged);
166 
167  // requires simulator context
168  connect(ui->tvp_RenderedAircraft, &CAircraftModelView::objectChanged, this,
169  &CMappingComponent::onChangedSimulatedAircraftInView, Qt::QueuedConnection);
170 
171  // with external core models might be already available
172  // nevertheless, wait some time to allow to init
173  QPointer<CMappingComponent> myself(this);
174  QTimer::singleShot(10000, this, [=] {
175  if (!myself || !sGui || sGui->isShuttingDown()) { return; }
176  const CSimulatorInfo simulator(myself->getConnectedOrSelectedSimulator());
177  myself->onModelSetSimulatorChanged(simulator);
178  myself->onModelSetChanged(simulator);
179  });
180  }
181 
183 
185  {
186  Q_ASSERT(ui->tvp_RenderedAircraft);
187  return ui->tvp_RenderedAircraft->rowCount();
188  }
189 
191  {
192  Q_ASSERT(ui->tvp_AircraftModels);
193  return ui->tvp_AircraftModels->rowCount();
194  }
195 
197  {
198  const int tabIndex = static_cast<int>(tab);
199  ui->tw_SpecializedViews->setCurrentIndex(tabIndex);
200  }
201 
203  {
204  Q_ASSERT(ui->tvp_AircraftModels);
205  return ui->tvp_AircraftModels->container().findModelsStartingWith(modelName, cs);
206  }
207 
208  void CMappingComponent::onModelSetChanged(const CSimulatorInfo &dummy)
209  {
210  // changed model set, which can be any model set
211  Q_UNUSED(dummy); // we do not use the passed simulator
212 
213  const CSimulatorInfo simulator(ui->comp_SimulatorSelector->getValue()); // UI value
214  const bool changed = ui->completer_ModelStrings->setSimulator(simulator);
215  if (!changed) { return; }
216 
217  if (ui->tvp_AircraftModels->displayAutomatically()) { this->onModelsUpdateRequested(); }
218  else
219  {
220  CLogMessage(this).info(u"Model set loaded ('%1'), you can update the model view")
221  << simulator.toQString(true);
222  }
223  }
224 
225  void CMappingComponent::onRowCountChanged(int count, bool withFilter)
226  {
227  Q_UNUSED(count);
228  Q_UNUSED(withFilter);
229  const int am = ui->tw_SpecializedViews->indexOf(ui->tb_AircraftModels);
230  const int cm = ui->tw_SpecializedViews->indexOf(ui->tb_CurrentMappings);
231  const QString amf = ui->tvp_AircraftModels->derivedModel()->hasFilter() ? "F" : "";
232  QString a = ui->tw_SpecializedViews->tabBar()->tabText(am);
233  QString c = ui->tw_SpecializedViews->tabBar()->tabText(cm);
236  ui->tw_SpecializedViews->tabBar()->setTabText(am, a);
237  ui->tw_SpecializedViews->tabBar()->setTabText(cm, c);
238  }
239 
240  void CMappingComponent::onChangedSimulatedAircraftInView(const CVariant &object, const CPropertyIndex &index)
241  {
242  if (!index.contains(CSimulatedAircraft::IndexEnabled)) { return; } // we only deal with enabled/disabled here
243  const auto sa = object.to<CSimulatedAircraft>(); // changed in GUI
244  const CSimulatedAircraft saFromBackend =
246  if (!saFromBackend.hasValidCallsign()) { return; } // obviously deleted
247  const bool nowEnabled = sa.isEnabled();
248  if (saFromBackend.isEnabled() == nowEnabled) { return; } // already same value
249  CLogMessage(this).info(u"Request to %1 aircraft '%2'")
250  << (nowEnabled ? "enable" : "disable") << saFromBackend.getCallsign().toQString();
251  sGui->getIContextNetwork()->updateAircraftEnabled(saFromBackend.getCallsign(), nowEnabled);
252  }
253 
254  void CMappingComponent::onAircraftSelectedInView(const QModelIndex &index)
255  {
256  const CSimulatedAircraft simAircraft = ui->tvp_RenderedAircraft->at(index);
257  ui->cb_AircraftEnabled->setChecked(simAircraft.isEnabled());
258  ui->le_Callsign->setText(simAircraft.getCallsign().asString());
259  ui->completer_ModelStrings->setModel(simAircraft.getModel());
260  }
261 
262  void CMappingComponent::onModelSelectedInView(const QModelIndex &index)
263  {
264  const CAircraftModel model = ui->tvp_AircraftModels->at(index);
265  ui->completer_ModelStrings->setModel(model);
266  }
267 
268  CCallsign CMappingComponent::validateRenderedCallsign()
269  {
270  const QString cs = ui->le_Callsign->text().trimmed();
271  if (!CCallsign::isValidAircraftCallsign(cs))
272  {
273  this->showOverlayMessage(CStatusMessage(this).validationError(u"Invalid callsign for mapping"),
274  OverlayMessageMs);
275  return {};
276  }
277 
278  const CCallsign callsign(cs);
279  const bool hasCallsign = ui->tvp_RenderedAircraft->container().containsCallsign(callsign);
280  if (!hasCallsign)
281  {
282  const CStatusMessage msg = CStatusMessage(this).validationError(u"Unmapped callsign '%1' for mapping")
283  << callsign.asString();
284  this->showOverlayMessage(msg);
285  return {};
286  }
287  return callsign;
288  }
289 
290  void CMappingComponent::onModelSetSimulatorChanged(const CSimulatorInfo &simulator)
291  {
292  if (!sGui || this->isSimulatorAvailable()) { return; }
294 
295  // completer will be changed in onModelSetChanged
296  }
297 
298  void CMappingComponent::onSimulatorPluginChanged(const CSimulatorPluginInfo &pluginInfo)
299  {
300  Q_UNUSED(pluginInfo);
301  ui->comp_SimulatorSelector->setToConnectedSimulator(50);
302  }
303 
304  void CMappingComponent::onSimulatorStatusChanged(int status)
305  {
306  const ISimulator::SimulatorStatus simStatus = static_cast<ISimulator::SimulatorStatus>(status);
307 
308  // make sure the selector represents connected simulator
309  if (simStatus.testFlag(ISimulator::Connected) && sGui && sGui->getIContextSimulator())
310  {
311  ui->comp_SimulatorSelector->setToConnectedSimulator(50);
312  }
313  }
314 
315  void CMappingComponent::doMatchingsAgain()
316  {
317  using namespace std::chrono_literals;
318 
319  if (!sGui || sGui->isShuttingDown() || !sGui->getIContextSimulator()) { return; }
320  if (!sGui->getIContextSimulator()->isSimulatorAvailable()) { return; }
321  const int rematchedNumber = sGui->getIContextSimulator()->doMatchingsAgain();
322 
323  const QString info = QStringLiteral("Triggered re-matching of %1 aircraft").arg(rematchedNumber);
324  this->showOverlayHTMLMessage(info, 5s);
325  CLogMessage(this).info(info);
326  }
327 
328  void CMappingComponent::onSaveAircraft()
329  {
331  {
332  return;
333  }
334  const CCallsign callsign(this->validateRenderedCallsign());
335  if (callsign.isEmpty()) { return; }
336  const QString modelString = ui->completer_ModelStrings->getModelString();
337  if (modelString.isEmpty())
338  {
339  this->showOverlayHTMLMessage(CStatusMessage(this).validationError(u"Missing model for mapping"),
340  OverlayMessageMs);
341  return;
342  }
343 
344  // model in current view (data already in UI)
345  bool hasModel = ui->tvp_AircraftModels->container().containsModelString(modelString);
346  if (!hasModel && sGui && sGui->getIContextSimulator())
347  {
348  hasModel = sGui->getIContextSimulator()->isKnownModelInSet(modelString);
349  }
350 
351  if (!hasModel)
352  {
353  this->showOverlayMessage(
354  CStatusMessage(this).validationError(u"Invalid model for mapping, reloading model set"),
355  OverlayMessageMs);
356  if (ui->tvp_AircraftModels->isEmpty()) { this->onModelsUpdateRequested(); }
357  return;
358  }
359 
360  const CSimulatedAircraft aircraftFromBackend =
362  const bool enabled = ui->cb_AircraftEnabled->isChecked();
363  bool changed = false;
364 
365  // changed model?
366  if (aircraftFromBackend.getModelString() != modelString)
367  {
369  if (models.isEmpty())
370  {
371  const CStatusMessage msg = CStatusMessage(this).validationError(u"No model for title: '%1'")
372  << modelString;
373  this->showOverlayMessage(msg, OverlayMessageMs);
374  return;
375  }
376 
377  CAircraftModel model(models.front());
378  if (models.size() > 1)
379  {
380  if (models.containsModelString(modelString))
381  {
382  model = models.findByModelString(modelString).front(); // exact match
383  }
384  else
385  {
386  const CStatusMessage msg = CStatusMessage(this).validationInfo(u"Ambigious title: '%1', using '%2'")
387  << modelString << model.getModelString();
388  this->showOverlayMessage(msg, OverlayMessageMs);
389  }
390  }
391  model.setModelType(CAircraftModel::TypeManuallySet);
392  CLogMessage(this).info(u"Requesting changes for '%1'") << callsign.asString();
393 
394  // enable in any case
395  sGui->getIContextNetwork()->updateAircraftEnabled(aircraftFromBackend.getCallsign(), true);
396  changed =
397  sGui->getIContextNetwork()->updateAircraftModel(aircraftFromBackend.getCallsign(), model, identifier());
398  }
399  if (aircraftFromBackend.isEnabled() != enabled)
400  {
401  changed = sGui->getIContextNetwork()->updateAircraftEnabled(aircraftFromBackend.getCallsign(), enabled);
402  }
403 
404  if (!changed)
405  {
406  this->showOverlayHTMLMessage(CLogMessage(this).info(u"Model mapping, nothing to change"), OverlayMessageMs);
407  }
408  }
409 
410  void CMappingComponent::onResetAircraft()
411  {
412  using namespace std::chrono_literals;
413 
415  {
416  return;
417  }
418  const CCallsign callsign(this->validateRenderedCallsign());
419  if (callsign.isEmpty()) { return; }
420  const bool reset = sGui->getIContextSimulator()->resetToModelMatchingAircraft(callsign);
421  const CStatusMessage msg = reset ? CStatusMessage(this).info(u"Model reset for '%1'") << callsign.toQString() :
422  CStatusMessage(this).info(u"Reset failed for '%1'") << callsign.toQString();
423  this->showOverlayHTMLMessage(msg, 3s);
424  }
425 
426  void CMappingComponent::onModelPreviewChanged(Qt::CheckState state)
427  {
428  Q_UNUSED(state);
429  this->closeOverlay();
430  }
431 
432  void CMappingComponent::onModelsUpdateRequested()
433  {
434  if (!sGui || sGui->isShuttingDown() || !sGui->getIContextSimulator()) { return; }
436 
438  const bool hasDisabledModels = !disabledModels.isEmpty();
439 
440  ui->tvp_AircraftModels->setHighlightColor(Qt::red);
441  ui->tvp_AircraftModels->setHighlight(hasDisabledModels);
442  ui->tvp_AircraftModels->setHighlightModels(disabledModels);
443  ui->tvp_AircraftModels->updateContainerMaybeAsync(modelSet);
444  ui->tw_SpecializedViews->setCurrentIndex(TabAircraftModels);
445  }
446 
447  void CMappingComponent::onTempDisableModelsForMatchingRequested(const CAircraftModelList &models)
448  {
449  if (models.isEmpty()) { return; }
450  if (sGui && sGui->getIContextSimulator())
451  {
453  const CStatusMessage m = CLogMessage(this).info(u"Disabled %1 model(s): %2")
454  << models.size() << models.getCallsignsAsString(", ", true);
455  this->showOverlayHTMLMessage(m, OverlayMessageMs);
456  this->onModelsUpdateRequested();
457  }
458  }
459 
460  void CMappingComponent::onRemoteAircraftModelChanged(const CSimulatedAircraft &aircraft,
461  const CIdentifier &originator)
462  {
463  if (CIdentifiable::isMyIdentifier(originator)) { return; }
464  this->tokenBucketUpdateAircraft(aircraft);
465  }
466 
467  void CMappingComponent::onConnectionStatusChanged(const CConnectionStatus &from, const CConnectionStatus &to)
468  {
469  Q_UNUSED(from);
470  if (to.isDisconnected())
471  {
472  this->tokenBucketUpdate();
473  ui->tvp_RenderedAircraft->clear();
474  }
475  else if (to.isConnected())
476  {
477  if (sGui && sGui->getIContextNetwork())
478  {
479  const CServer server = sGui->getIContextNetwork()->getConnectedServer();
480  const bool sendFast = server.getFsdSetup().sendInterimPositions();
481  ui->tvp_RenderedAircraft->configureMenuFastPositionUpdates(sendFast);
482  }
483  }
484  }
485 
486  CSimulatorInfo CMappingComponent::getConnectedOrSelectedSimulator() const
487  {
488  if (this->isSimulatorAvailable()) { return sGui->getIContextSimulator()->isSimulatorAvailable(); }
489  return ui->comp_SimulatorSelector->getValue();
490  }
491 
492  bool CMappingComponent::isSimulatorAvailable() const
493  {
494  if (!sGui || !sGui->getIContextSimulator()) { return false; }
496  }
497 
498  void CMappingComponent::showAircraftModelDetails(bool show)
499  {
500  QList<int> sizes = ui->sp_MappingComponentSplitter->sizes();
501  Q_ASSERT_X(sizes.size() == 2, Q_FUNC_INFO, "Wrong splitter sizes");
502  const int total = sizes[0] + sizes[1];
503  QList<int> newSizes({ 0, 0 });
504  if (show)
505  {
506  newSizes[0] = qRound(total * 0.8);
507  newSizes[1] = qRound(total * 0.2);
508  }
509  else
510  {
511  newSizes[0] = total;
512  newSizes[1] = 0;
513  }
514  ui->sp_MappingComponentSplitter->setSizes(newSizes);
515  }
516 
517  void CMappingComponent::onAddingRemoteAircraftFailed(const CSimulatedAircraft &aircraft, bool disabled,
518  bool failover, const CStatusMessage &message)
519  {
520  this->tokenBucketUpdate();
521  Q_UNUSED(failover);
522  Q_UNUSED(aircraft);
523  Q_UNUSED(message);
524  Q_UNUSED(disabled);
525  }
526 
527  void CMappingComponent::onTabWidgetChanged(int index)
528  {
529  Q_UNUSED(index);
530  const auto w = static_cast<TabWidget>(index);
531  const bool show = (w == TabAircraftModels) || (w == TabRenderedAircraft);
532  this->showAircraftModelDetails(show);
533  }
534 
535  void CMappingComponent::updateRenderedAircraftView(bool forceUpdate)
536  {
537  if (!sGui || sGui->isShuttingDown()) { return; }
538  m_updateTimer.start(); // restart
539  if (!forceUpdate && !this->isVisibleWidget())
540  {
541  m_missedRenderedAircraftUpdate = true;
542  return;
543  }
544 
545  m_missedRenderedAircraftUpdate = false;
546  m_updateTimer.start(); // restart
548  {
550  ui->tvp_RenderedAircraft->updateContainerMaybeAsync(aircraft);
551  }
552  else { ui->tvp_RenderedAircraft->clear(); }
553  }
554 
555  void CMappingComponent::timerUpdate()
556  {
557  // timer update to update position, speed ...
558  this->updateRenderedAircraftView(false); // unforced
559  }
560 
561  void CMappingComponent::tokenBucketUpdateAircraft(const CSimulatedAircraft &aircraft)
562  {
563  Q_UNUSED(aircraft);
564  this->tokenBucketUpdate();
565  }
566 
567  void CMappingComponent::tokenBucketUpdate()
568  {
569  if (!m_bucket.tryConsume()) { return; }
570  this->updateRenderedAircraftView(true); // forced update
571  }
572 
573  void CMappingComponent::settingsChanged()
574  {
575  const CViewUpdateSettings settings = m_settings.get();
576  const int ms = settings.getRenderingUpdateTime().toMs();
577  m_updateTimer.setInterval(ms);
578  }
579 
580  void CMappingComponent::onNetworkConnectionStatusChanged(const CConnectionStatus &from, const CConnectionStatus &to)
581  {
582  Q_UNUSED(from);
583  if (to.isDisconnected())
584  {
585  ui->tvp_RenderedAircraft->clear();
586  m_updateTimer.stop();
587  }
588  else if (to.isConnected())
589  {
590  ui->comp_SimulatorSelector->setReadOnly(true);
591  m_updateTimer.start();
592  }
593  }
594 } // namespace swift::gui::components
const context::IContextNetwork * getIContextNetwork() const
Direct access to contexts if a CCoreFacade has been initialized.
bool isShuttingDown() const
Is application shutting down?
const context::IContextSimulator * getIContextSimulator() const
Direct access to contexts if a CCoreFacade has been initialized.
virtual swift::misc::simulation::CSimulatedAircraft getAircraftInRangeForCallsign(const swift::misc::aviation::CCallsign &callsign) const =0
Aircraft for given callsign.
virtual bool updateAircraftModel(const swift::misc::aviation::CCallsign &callsign, const swift::misc::simulation::CAircraftModel &model, const swift::misc::CIdentifier &originator)=0
Change model (for remote aircraft)
virtual bool updateAircraftEnabled(const swift::misc::aviation::CCallsign &callsign, bool enabledForRendering)=0
Enable/disable rendering.
virtual swift::misc::simulation::CSimulatedAircraftList getAircraftInRange() const =0
Aircraft list.
virtual swift::misc::network::CServer getConnectedServer() const =0
Server which is connected, if not connected empty default object.
virtual bool resetToModelMatchingAircraft(const swift::misc::aviation::CCallsign &callsign)=0
Reset model by matching it again.
virtual bool isKnownModelInSet(const QString &modelstring) const =0
Known model?
virtual void disableModelsForMatching(const swift::misc::simulation::CAircraftModelList &removedModels, bool incremental)=0
Remove a model for matching.
virtual swift::misc::simulation::CAircraftModelList getDisabledModelsForMatching() const =0
The disabled models for matching.
bool isSimulatorAvailable() const
Simulator avialable (driver available)?
virtual int doMatchingsAgain()=0
Repeat all matchings.
virtual swift::misc::simulation::CAircraftModelList getModelSetModelsStartingWith(const QString &modelString) const =0
Models for model string.
virtual swift::misc::simulation::CAircraftModelList getModelSet() const =0
Installed models in simulator eco system.
bool isSimulatorSimulating() const
Is available simulator simulating? Returns false if no simulator is available.
virtual ISimulator::SimulatorStatus getSimulatorStatus() const =0
Simulator combined status.
virtual void setModelSetLoaderSimulator(const swift::misc::simulation::CSimulatorInfo &simulator)=0
Set the model set loader simulator directly.
static QString replaceTabCountValue(const QString &oldName, int count)
Replace count in name such as "stations (4)".
Definition: guiutility.cpp:522
bool showOverlayHTMLMessage(const QString &htmlMessage, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
HTML message.
bool showOverlayMessage(const swift::misc::CStatusMessage &message, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Show single message.
void setForceSmall(bool force)
Force small (smaller layout)
void setReducedInfo(bool reduced)
Display reduced information.
Using this class provides a QFrame with the overlay functionality already integrated.
void requestTextMessageWidget(const swift::misc::aviation::CCallsign &callsign)
Request a text message widget.
int countAircraftModels() const
Numer of models.
int countCurrentMappings() const
Number of current mappings.
void requestValidationDialog()
Request the validation dialog.
swift::misc::simulation::CAircraftModelList findModelsStartingWith(const QString &modelName, Qt::CaseSensitivity cs)
Find models starting with.
void changed(const swift::misc::simulation::CSimulatorInfo &simulator)
Value has been changed.
Settings about view update rates.
const swift::misc::physical_quantities::CTime & getRenderingUpdateTime() const
Get time.
CheckBox for single column.
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
Value object encapsulating information identifying a component of a modular distributed swift process...
Definition: identifier.h:29
static const QString & guiComponent()
GUI components.
Definition: logcategories.h:94
static const QString & mapping()
Mapping.
Class for emitting a log message.
Definition: logmessage.h:27
Derived & validationError(const char16_t(&format)[N])
Set the severity to error, providing a format string, and adding the validation category.
Derived & validationInfo(const char16_t(&format)[N])
Set the severity to info, providing a format string, and adding the validation category.
Derived & info(const char16_t(&format)[N])
Set the severity to info, providing a format string.
bool contains(int index) const
Contains index?
size_type size() const
Returns number of elements in the sequence.
Definition: sequence.h:273
reference front()
Access the first element.
Definition: sequence.h:225
bool isEmpty() const
Synonym for empty.
Definition: sequence.h:285
Streamable status message, e.g.
bool tryConsume(int numTokens=1, qint64 msSinceEpoch=-1)
Try to consume a number of tokens.
Definition: tokenbucket.cpp:14
Wrapper around QVariant which provides transparent access to CValueObject methods of the contained ob...
Definition: variant.h:66
Value object encapsulating information of a callsign.
Definition: callsign.h:30
const QString & asString() const
Get callsign (normalized)
Definition: callsign.h:96
QString getCallsignsAsString(const QString &separator, bool sorted=false) const
Get callsigns as strings.
QString toQString(bool i18n=false) const
Cast as QString.
Definition: mixinstring.h:74
Value object encapsulating information about a connection status.
bool isConnected() const
Query status.
bool isDisconnected() const
Query status.
bool sendInterimPositions() const
FSD setup flags.
Definition: fsdsetup.h:103
Value object encapsulating information of a server.
Definition: server.h:28
const CFsdSetup & getFsdSetup() const
Get FSD setup.
Definition: server.h:140
int toMs() const
Convenience functions when used with timers etc.
Definition: time.cpp:117
Aircraft model (used by another pilot, my models on disk)
Definition: aircraftmodel.h:71
void setModelType(ModelType type)
Set type.
const QString & getModelString() const
Model key, either queried or loaded from simulator model.
Value object encapsulating a list of aircraft models.
CAircraftModelList findByModelString(const QString &modelString, Qt::CaseSensitivity sensitivity=Qt::CaseInsensitive) const
Find by model string.
bool containsModelString(const QString &modelString, Qt::CaseSensitivity sensitivity=Qt::CaseInsensitive) const
Contains model string?
Comprehensive information of an aircraft.
const aviation::CCallsign & getCallsign() const
Get callsign.
const simulation::CAircraftModel & getModel() const
Get model (model used for mapping)
bool isEnabled() const
Enabled? Enable means it shall be displayed in the simulator.
const QString & getModelString() const
Get model string.
Value object encapsulating a list of aircraft.
Simple hardcoded info about the corresponding simulator.
Definition: simulatorinfo.h:41
SWIFT_GUI_EXPORT swift::gui::CGuiApplication * sGui
Single instance of GUI application object.
Backend services of the swift project, like dealing with the network or the simulators.
Definition: actionbind.cpp:7
High level reusable GUI components.
Definition: aboutdialog.cpp:14
Filter to search data sets.
Models to be used with views, mainly QTableView.
Views, mainly QTableView.
Free functions in swift::misc.
void clicked(bool checked)
void checkStateChanged(Qt::CheckState state)
qsizetype size() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void setObjectName(QAnyStringView name)
QString arg(Args &&... args) const const
bool isEmpty() const const
CaseSensitivity
CheckState
QueuedConnection
QTextStream & reset(QTextStream &stream)
void currentChanged(int index)
void setInterval(int msec)
void start()
void stop()
void timeout()
void show()