swift
atcstationcomponent.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2013 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #include <QAbstractItemModel>
7 #include <QCompleter>
8 #include <QGroupBox>
9 #include <QLineEdit>
10 #include <QModelIndex>
11 #include <QPointer>
12 #include <QPushButton>
13 #include <QStandardItemModel>
14 #include <QStringBuilder>
15 #include <QTabBar>
16 #include <QTableView>
17 #include <QTextEdit>
18 #include <QTimer>
19 #include <QTreeView>
20 
21 #include "ui_atcstationcomponent.h"
22 
25 #include "core/webdataservices.h"
26 #include "gui/dockwidgetinfoarea.h"
27 #include "gui/guiapplication.h"
28 #include "gui/guiutility.h"
29 #include "gui/infoarea.h"
32 #include "gui/uppercasevalidator.h"
34 #include "gui/views/viewbase.h"
37 #include "misc/icons.h"
38 #include "misc/logmessage.h"
40 #include "misc/weather/metar.h"
41 
42 using namespace swift::gui::models;
43 using namespace swift::gui::views;
44 using namespace swift::gui::settings;
45 using namespace swift::misc;
46 using namespace swift::misc::aviation;
47 using namespace swift::misc::network;
48 using namespace swift::misc::physical_quantities;
49 using namespace swift::misc::weather;
50 using namespace swift::core;
51 using namespace swift::core::context;
52 
53 namespace swift::gui::components
54 {
55  CAtcStationComponent::CAtcStationComponent(QWidget *parent)
57  ui(new Ui::CAtcStationComponent)
58  {
59  Q_ASSERT_X(sGui, Q_FUNC_INFO, "Need sGui");
60  ui->setupUi(this);
61  ui->tw_Atc->setCurrentIndex(0);
62  ui->tw_Atc->tabBar()->setExpanding(false);
63  ui->tw_Atc->tabBar()->setUsesScrollButtons(true);
64  auto *ucv = new CUpperCaseValidator(ui->le_AtcStationsOnlineMetar);
65  ui->le_AtcStationsOnlineMetar->setValidator(ucv);
66 
67  // some icons
68  ui->tb_AtcStationsAtisReload->setIcon(CIcons::atis());
69  ui->tb_AtcStationsAtisReload->setText("ATIS");
70  ui->tb_AtcStationsAtisReload->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
71  ui->tb_AtcStationsLoadMetar->setIcon(CIcons::metar());
72  ui->tb_AtcStationsLoadMetar->setText("METAR");
73  ui->tb_AtcStationsLoadMetar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
74  ui->tb_Audio->setIcon(CIcons::appAudio16());
75  ui->tb_Audio->setText("Audio");
76  ui->tb_Audio->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
77  ui->tb_TextMessageOverlay->setIcon(CIcons::appTextMessages16());
78  ui->tb_TextMessageOverlay->setText("Text");
79  ui->tb_TextMessageOverlay->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
80 
81  // set station mode
82  ui->tvp_AtcStationsOnline->setStationMode(CAtcStationListModel::StationsOnline);
83  ui->tvp_AtcStationsOnlineTree->setColumns(ui->tvp_AtcStationsOnline->getColumns());
84 
85  // menus
86  ui->tvp_AtcStationsOnline->menuRemoveItems(CAtcStationView::MenuClear);
87 
88  // Signal / Slots
89  connect(ui->le_AtcStationsOnlineMetar, &QLineEdit::returnPressed, this,
90  &CAtcStationComponent::getMetarAsEntered);
91  connect(ui->tb_AtcStationsLoadMetar, &QPushButton::clicked, this, &CAtcStationComponent::getMetarAsEntered);
93  connect(ui->tb_TextMessageOverlay, &QPushButton::clicked, this,
94  &CAtcStationComponent::showOverlayInlineTextMessage);
95 
96  connect(ui->tvp_AtcStationsOnline, &CAtcStationView::objectClicked, this,
97  &CAtcStationComponent::onOnlineAtcStationVariantSelected, Qt::QueuedConnection);
98  connect(ui->tvp_AtcStationsOnline, &CAtcStationView::objectSelected, this,
99  &CAtcStationComponent::onOnlineAtcStationVariantSelected, Qt::QueuedConnection);
100  connect(ui->tvp_AtcStationsOnline, &CAtcStationView::testRequestDummyAtcOnlineStations, this,
101  &CAtcStationComponent::testCreateDummyOnlineAtcStations);
102  connect(ui->tvp_AtcStationsOnline, &CAtcStationView::requestUpdate, this,
103  &CAtcStationComponent::requestOnlineStationsUpdate);
104  connect(ui->tvp_AtcStationsOnline, &CAtcStationView::requestNewBackendData, this,
105  &CAtcStationComponent::requestOnlineStationsUpdate);
106  connect(ui->tvp_AtcStationsOnline, &CAtcStationView::requestComFrequency, this,
107  &CAtcStationComponent::setComFrequency);
108  connect(ui->tvp_AtcStationsOnline, &CAtcStationView::requestTextMessageWidget, this,
110 
111  connect(ui->tvp_AtcStationsOnlineTree, &CAtcStationTreeView::requestComFrequency, this,
112  &CAtcStationComponent::setComFrequency);
113  connect(ui->tvp_AtcStationsOnlineTree, &CAtcStationTreeView::objectSelected, this,
114  &CAtcStationComponent::onOnlineAtcStationSelected, Qt::QueuedConnection);
115  connect(ui->tvp_AtcStationsOnlineTree, &CAtcStationTreeView::requestTextMessageWidget, this,
117 
118  connect(ui->tb_AtcStationsAtisReload, &QPushButton::clicked, this, &CAtcStationComponent::requestAtisUpdates);
119  connect(&m_updateTimer, &QTimer::timeout, this, &CAtcStationComponent::update);
120 
121  // Group box
122  connect(ui->gb_Details, &QGroupBox::toggled, this, &CAtcStationComponent::onDetailsToggled,
124 
125  // runtime based connects
126  if (sGui)
127  {
128  connect(sGui->getIContextNetwork(), &IContextNetwork::changedAtcStationsOnlineDigest, this,
129  &CAtcStationComponent::changedAtcStationsOnline, Qt::QueuedConnection);
130  connect(sGui->getIContextNetwork(), &IContextNetwork::atcStationDisconnected, this,
131  &CAtcStationComponent::atcStationDisconnected, Qt::QueuedConnection);
132  connect(sGui->getIContextNetwork(), &IContextNetwork::connectionStatusChanged, this,
133  &CAtcStationComponent::connectionStatusChanged, Qt::QueuedConnection);
134  }
135 
136  // selection
137  ui->tvp_AtcStationsOnline->acceptClickSelection(true);
138  ui->tvp_AtcStationsOnline->acceptRowSelection(true);
139 
140  // before splitter
141  // QVBoxLayout *layout = this->vLayout();
142  // m_stretch.push_back(layout->stretch(0));
143  // m_stretch.push_back(layout->stretch(1));
144 
145  // no effect
146  ui->sp_AtcSplitter->setStretchFactor(0, 3);
147  ui->sp_AtcSplitter->setStretchFactor(1, 1);
148 
149  // web readers
150  if (sGui && sGui->hasWebDataServices())
151  {
152  connect(sGui->getWebDataServices(), &CWebDataServices::swiftDbAirportsRead, this,
153  &CAtcStationComponent::airportsRead);
154  this->airportsRead();
155  }
156 
157  // init settings
158  this->settingsChanged();
159  }
160 
162 
164  {
165  const int t = static_cast<int>(tab);
166  ui->tw_Atc->setCurrentIndex(t);
167  }
168 
169  int CAtcStationComponent::countOnlineStations() const { return ui->tvp_AtcStationsOnline->rowCount(); }
170 
172  {
174  const bool c = connect(this->getParentInfoArea(), &CInfoArea::changedInfoAreaTabBarIndex, this,
175  &CAtcStationComponent::infoAreaTabBarChanged, Qt::QueuedConnection);
176  Q_ASSERT_X(c, Q_FUNC_INFO, "failed connect");
177  Q_ASSERT_X(parentDockableWidget, Q_FUNC_INFO, "missing parent");
178  return c && parentDockableWidget;
179  }
180 
182  {
183  using namespace std::chrono_literals;
184  if (!this->canAccessContext()) { return; }
185  Q_ASSERT(ui->tvp_AtcStationsOnline);
186 
187  // check if component is visible, if we have already data then skip update
188  const bool hasData = this->countOnlineStations() > 0;
189  if (hasData && !this->isVisibleWidget())
190  {
191  // Update skipped, as not visible
192  ui->tvp_AtcStationsOnline->hideLoadIndicator();
193  return;
194  }
195 
196  // online stations, only when connected
198  {
199  // update
200  if (m_timestampOnlineStationsChanged > m_timestampLastReadOnlineStations)
201  {
202  CAtcStationList onlineStations = sGui->getIContextNetwork()->getAtcStationsOnline(true);
203  const int stationsCount = onlineStations.sizeInt();
204  ui->tvp_AtcStationsOnline->updateContainerMaybeAsync(onlineStations);
205  m_timestampLastReadOnlineStations = QDateTime::currentDateTimeUtc();
206  m_timestampOnlineStationsChanged = m_timestampLastReadOnlineStations;
207  this->updateTreeView();
208  this->setOnlineTabs(stationsCount);
209 
210  if (stationsCount < 1) { m_selectedCallsign.clear(); }
211  else if (!m_selectedCallsign.isEmpty() && onlineStations.containsCallsign(m_selectedCallsign))
212  {
213  const CAtcStation lastSelected = onlineStations.findFirstByCallsign(m_selectedCallsign);
214  if (lastSelected.hasCallsign())
215  {
216  // avoid override of manually entered METAR callsigns
217  const CCallsign currentCs(ui->le_AtcStationsOnlineMetar->text());
218  if (currentCs.isEmpty() || currentCs == lastSelected.getCallsign())
219  {
220  this->triggerOnlineAtcStationSelected(lastSelected);
221  }
222  }
223  } // stations
224  }
225  }
226  else
227  {
228  m_selectedCallsign.clear();
229  ui->tvp_AtcStationsOnline->clear();
230  this->updateTreeView();
231  this->setOnlineTabs(0);
232  }
233  }
234 
235  void CAtcStationComponent::atcStationDisconnected(const CAtcStation &station)
236  {
237  // trick here is, we want to display a station ASAP
238  ui->tvp_AtcStationsOnline->changedAtcStationConnectionStatus(station, false);
239  }
240 
241  void CAtcStationComponent::getMetarAsEntered() { this->getMetar(""); }
242 
243  void CAtcStationComponent::getMetar(const QString &airportIcaoCode)
244  {
245  if (!this->canAccessContext()) { return; }
246  const CAirportIcaoCode icao(airportIcaoCode.isEmpty() ?
247  ui->le_AtcStationsOnlineMetar->text().trimmed().toUpper() :
248  airportIcaoCode.trimmed().toUpper());
249  ui->le_AtcStationsOnlineMetar->setText(icao.asString());
250  if (!icao.hasValidIcaoCode(true)) { return; }
251  const CMetar metar(sGui->getIContextNetwork()->getMetarForAirport(icao));
252  if (metar.hasMessage())
253  {
254  const QString metarText = metar.getMessage() % u"\n\n" % metar.getMetarText();
255  ui->te_AtcStationsOnlineInfo->setText(metarText);
256  }
257  else { ui->te_AtcStationsOnlineInfo->clear(); }
258  }
259 
260  void CAtcStationComponent::changedAtcStationsOnline()
261  {
262  // just update timestamp, data will be pulled by timer
263  // the timestamp will tell if there are any newer data
264  m_timestampOnlineStationsChanged = QDateTime::currentDateTimeUtc();
265  }
266 
267  void CAtcStationComponent::connectionStatusChanged(const CConnectionStatus &from, const CConnectionStatus &to)
268  {
269  Q_UNUSED(from)
270  if (to.isConnected())
271  {
272  ui->tvp_AtcStationsOnline->clear();
273  this->updateTreeView();
274  m_updateTimer.start();
275  }
276  else if (to.isDisconnected())
277  {
278  m_updateTimer.stop();
279  this->clearOnlineViews();
280  this->update();
281  }
282  }
283 
284  void CAtcStationComponent::testCreateDummyOnlineAtcStations(int number)
285  {
286  if (!sGui || !sGui->getIContextNetwork()) { return; }
287  if (this->canAccessContext()) { sGui->getIContextNetwork()->testCreateDummyOnlineAtcStations(number); }
288  }
289 
290  void CAtcStationComponent::requestOnlineStationsUpdate()
291  {
292  m_timestampLastReadOnlineStations.setMSecsSinceEpoch(0); // mark as outdated
293  this->update();
294  }
295 
296  void CAtcStationComponent::infoAreaTabBarChanged(int index)
297  {
298  // ignore in those cases
299  if (!this->isVisibleWidget()) { return; }
300  if (this->isParentDockWidgetFloating()) { return; }
301 
302  // here I know I am the selected widget, update, but keep GUI responsive (-> timer)
303  const QPointer<CAtcStationComponent> myself(this);
304  QTimer::singleShot(1000, this, [=, this] {
305  if (!sApp || sApp->isShuttingDown() || !myself) { return; }
306  this->update();
307  });
308  Q_UNUSED(index)
309  }
310 
311  void CAtcStationComponent::setOnlineTabs(int count)
312  {
313  const int io = ui->tw_Atc->indexOf(ui->tb_AtcStationsOnline);
314  const int it = ui->tw_Atc->indexOf(ui->tb_AtcStationsOnlineTree);
315  static const QString o = ui->tw_Atc->tabBar()->tabText(io);
316  static const QString t = ui->tw_Atc->tabBar()->tabText(it);
317  const QString info = QStringLiteral(" (%1)").arg(count);
318  ui->tw_Atc->tabBar()->setTabText(io, o % info);
319  ui->tw_Atc->tabBar()->setTabText(it, t % info);
320  }
321 
322  void CAtcStationComponent::setComFrequency(const physical_quantities::CFrequency &frequency,
323  CComSystem::ComUnit unit, bool active)
324  {
325  if (unit != CComSystem::Com1 && unit != CComSystem::Com2) { return; }
326  if (!CComSystem::isValidComFrequency(frequency)) { return; }
327  if (active) { sGui->getIContextOwnAircraft()->updateActiveComFrequency(frequency, unit, identifier()); }
328  else { sGui->getIContextOwnAircraft()->updateStandbyComFrequency(frequency, unit, identifier()); }
329  }
330 
331  void CAtcStationComponent::settingsChanged()
332  {
333  if (!this->canAccessContext()) { return; }
334  const CViewUpdateSettings settings = m_settingsView.get();
335  const int ms = settings.getAtcUpdateTime().toMs();
336  const bool connected = sGui->getIContextNetwork()->isConnected();
337  m_updateTimer.setInterval(ms);
338  if (connected)
339  {
340  m_timestampOnlineStationsChanged = QDateTime::currentDateTimeUtc();
341  m_updateTimer.start(ms); // restart
342  this->update();
343  }
344  else { m_updateTimer.stop(); }
345  }
346 
347  void CAtcStationComponent::airportsRead() { this->initCompleters(); }
348 
349  void CAtcStationComponent::updateTreeView()
350  {
351  ui->tvp_AtcStationsOnlineTree->updateContainer(ui->tvp_AtcStationsOnline->container());
352  ui->tvp_AtcStationsOnlineTree->fullResizeToContents();
353  }
354 
355  void CAtcStationComponent::initCompleters()
356  {
357  if (!sGui || !sGui->getWebDataServices()) { return; }
358  const QStringList airports = sGui->getWebDataServices()->getAirports().allIcaoCodes(true);
359  if (!airports.isEmpty())
360  {
361  auto *airportCompleter = new QCompleter(airports, this);
362  const int w5chars = airportCompleter->popup()->fontMetrics().size(Qt::TextSingleLine, "FooBa").width();
363  airportCompleter->popup()->setMinimumWidth(w5chars * 5);
364  ui->le_AtcStationsOnlineMetar->setCompleter(airportCompleter);
365  }
366  }
367 
368  void CAtcStationComponent::onOnlineAtcStationVariantSelected(const CVariant &object)
369  {
370  ui->te_AtcStationsOnlineInfo->setText(""); // reset
371  if (!object.isValid() || !object.canConvert<CAtcStation>()) { return; }
372  const CAtcStation station = object.valueOrDefault(CAtcStation());
373  this->onOnlineAtcStationSelected(station);
374  }
375 
376  void CAtcStationComponent::triggerOnlineAtcStationSelected(const CAtcStation &station)
377  {
378  // pass copy, not reference -> can crash
379  QPointer<CAtcStationComponent> myself(this);
380  QTimer::singleShot(500, this, [=] {
381  if (myself) { myself->onOnlineAtcStationSelected(station); }
382  });
383  }
384 
385  void CAtcStationComponent::onOnlineAtcStationSelected(const CAtcStation &station)
386  {
387  if (!station.hasCallsign()) { return; }
388  const QString infoMessage =
389  station.getCallsignAsString() % u": " %
390  station.getFrequency().valueRoundedWithUnit(CFrequencyUnit::MHz(), 3) %
391  (station.hasAtis() ? u"\n\n" % station.getAtis().getMessage() : QStringLiteral("")) %
392  (station.hasMetar() ? u"\n\n" % station.getMetar().getMessage() : QStringLiteral(""));
393  ui->te_AtcStationsOnlineInfo->setText(infoMessage);
394  ui->le_AtcStationsOnlineMetar->setText(station.getCallsign().asString());
395  m_selectedCallsign = station.getCallsign();
396  }
397 
398  void CAtcStationComponent::requestAtisUpdates()
399  {
400  using namespace std::chrono_literals;
401 
402  if (!this->canAccessContext()) { return; }
404  if (ui->tw_Atc->currentIndex() == TabAtcOnline)
405  {
406  ui->tvp_AtcStationsOnline->showOverlayHTMLMessage("Requested ATIS update", 5s);
407  }
408  else { ui->tvp_AtcStationsOnlineTree->showOverlayHTMLMessage("Requested ATIS update", 5s); }
409  }
410 
411  bool CAtcStationComponent::canAccessContext() const
412  {
413  return sGui && !sGui->isShuttingDown() && sGui->getIContextNetwork();
414  }
415 
416  void CAtcStationComponent::clearOnlineViews()
417  {
418  ui->tvp_AtcStationsOnline->clear();
419  ui->tvp_AtcStationsOnlineTree->clear();
420  m_selectedCallsign.clear();
421  }
422 
423  void CAtcStationComponent::showOverlayInlineTextMessage()
424  {
425  // COverlayMessagesFrame::showOverlayInlineTextMessage(TextMessagesCom1);
426  emit requestTextMessageEntryTab(TextMessagesCom1);
427  }
428 
429  void CAtcStationComponent::onDetailsToggled(bool checked)
430  {
431  QVBoxLayout *layout = this->vLayout();
432  if (layout)
433  {
434  if (checked)
435  {
436  if (!m_splitterSizes.isEmpty()) { ui->sp_AtcSplitter->setSizes(m_splitterSizes); }
437  }
438  else
439  {
440  m_splitterSizes = ui->sp_AtcSplitter->sizes();
441  if (m_splitterSizes.size() > 1)
442  {
443  int min {};
444  int max {};
445  ui->sp_AtcSplitter->getRange(1, &min, &max);
446  QList<int> newSizes;
447  newSizes.push_back(qMax(0, m_splitterSizes.first() + m_splitterSizes.last() - min));
448  newSizes.push_back(min);
449  ui->sp_AtcSplitter->setSizes(newSizes);
450  }
451  }
452  }
453 
454  ui->te_AtcStationsOnlineInfo->setVisible(checked);
455  ui->le_AtcStationsOnlineMetar->setVisible(checked);
456  ui->tb_AtcStationsAtisReload->setVisible(checked);
457  ui->tb_AtcStationsLoadMetar->setVisible(checked);
458  ui->tb_TextMessageOverlay->setVisible(checked);
459  ui->tb_Audio->setVisible(checked);
460  }
461 
462  QVBoxLayout *CAtcStationComponent::vLayout() const
463  {
464  auto *layout = qobject_cast<QVBoxLayout *>(this->layout());
465  return layout;
466  }
467 } // namespace swift::gui::components
SWIFT_CORE_EXPORT swift::core::CApplication * sApp
Single instance of application object.
Definition: application.cpp:71
const context::IContextOwnAircraft * getIContextOwnAircraft() const
Direct access to contexts if a CCoreFacade has been initialized.
bool hasWebDataServices() const
Web data services available?
const context::IContextNetwork * getIContextNetwork() const
Direct access to contexts if a CCoreFacade has been initialized.
bool isShuttingDown() const
Is application shutting down?
CWebDataServices * getWebDataServices() const
Get the web data services.
swift::misc::aviation::CAirportList getAirports() const
Get airports.
virtual void testCreateDummyOnlineAtcStations(int number)=0
Create dummy ATC stations for performance tests etc.
virtual void requestAtisUpdates()=0
Request ATIS updates (for all stations)
virtual swift::misc::weather::CMetar getMetarForAirport(const swift::misc::aviation::CAirportIcaoCode &airportIcaoCode) const =0
Get METAR, if not available request it (code such as EDDF, KLAX)
virtual swift::misc::aviation::CAtcStationList getAtcStationsOnline(bool recalculateDistance) const =0
The ATC list with online ATC controllers.
virtual bool isConnected() const =0
Network connected?
virtual bool updateActiveComFrequency(const swift::misc::physical_quantities::CFrequency &frequency, swift::misc::aviation::CComSystem::ComUnit comUnit, const swift::misc::CIdentifier &originator)=0
Tune in a COM frequency (active)
virtual bool updateStandbyComFrequency(const swift::misc::physical_quantities::CFrequency &frequency, swift::misc::aviation::CComSystem::ComUnit comUnit, const swift::misc::CIdentifier &originator)=0
Tune in a COM frequency (standby)
Specialized class for dock widgets serving as info area.
CInfoArea * getParentInfoArea() const
The parent info area.
bool isParentDockWidgetFloating() const
Is the parent dockable widget floating?
virtual bool setParentDockWidgetInfoArea(CDockWidgetInfoArea *parentDockableWidget)
Corresponding dockable widget in info area.
void changedInfoAreaTabBarIndex(int index)
Tab bar changed.
Using this class provides a QFrame with the overlay and dock widget functionality already integrated.
void requestTextMessageWidget(const swift::misc::aviation::CCallsign &callsign)
Request a text message widget.
void requestTextMessageEntryTab(components::TextMessageTab tab)
Request an text message entry.
int countOnlineStations() const
Number of online stations.
void getMetar(const QString &airportIcaoCode)
Get METAR for given ICAO airport code.
bool setParentDockWidgetInfoArea(swift::gui::CDockWidgetInfoArea *parentDockableWidget)
Corresponding dockable widget in info area.
void requestAudioWidget()
Request audio widget.
Settings about view update rates.
const swift::misc::physical_quantities::CTime & getAtcUpdateTime() const
Get time.
T get() const
Get a copy of the current value.
Definition: valuecache.h:408
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
int sizeInt() const
Avoid compiler warnings when using with int.
Definition: sequence.h:276
Wrapper around QVariant which provides transparent access to CValueObject methods of the contained ob...
Definition: variant.h:66
Value object encapsulating information of airport ICAO data.
bool hasValidIcaoCode(bool strict) const
Has valid code?
const QString & asString() const
Get code.
QStringList allIcaoCodes(bool sorted) const
All ICAO codes.
Definition: airportlist.cpp:63
Value object encapsulating information about an ATC station.
Definition: atcstation.h:38
const CCallsign & getCallsign() const
Get callsign.
Definition: atcstation.h:84
bool hasAtis() const
Has ATIS?
Definition: atcstation.h:78
const CInformationMessage & getMetar() const
Get METAR.
Definition: atcstation.h:187
QString getCallsignAsString() const
Get callsign as string.
Definition: atcstation.h:90
const CInformationMessage & getAtis() const
Get ATIS.
Definition: atcstation.h:178
const physical_quantities::CFrequency & getFrequency() const
Get frequency.
Definition: atcstation.h:135
bool hasMetar() const
Has METAR?
Definition: atcstation.cpp:44
bool hasCallsign() const
Has callsign?
Definition: atcstation.h:87
Value object for a list of ATC stations.
Value object encapsulating information of a callsign.
Definition: callsign.h:30
void clear()
Clear this callsign.
Definition: callsign.cpp:45
const QString & asString() const
Get callsign (normalized)
Definition: callsign.h:96
bool isEmpty() const
Is empty?
Definition: callsign.h:63
const QString & getMessage() const
Get message.
OBJ findFirstByCallsign(const CCallsign &callsign, const OBJ &ifNotFound={}) const
Find the first aircraft by callsign, if none return given one.
bool containsCallsign(const CCallsign &callsign) const
Contains callsign?
Value object encapsulating information about a connection status.
bool isConnected() const
Query status.
bool isDisconnected() const
Query status.
QString valueRoundedWithUnit(const MU &unit, int digits=-1, bool withGroupSeparator=false, bool i18n=false) const
Value to QString with the given unit, e.g. "5.00m".
int toMs() const
Convenience functions when used with timers etc.
Definition: time.cpp:117
Value object encapsulating information about METAR FIXME: runway visibilities FIXME: runway wind shea...
Definition: metar.h:38
QString getMetarText() const
Returns the METAR in a descriptive text.
Definition: metar.cpp:65
bool hasMessage() const
Has METAR message.
Definition: metar.cpp:23
const QString & getMessage() const
Get METAR message.
Definition: metar.h:54
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
Models to be used with views, mainly QTableView.
Views, mainly QTableView.
Free functions in swift::misc.
void clicked(bool checked)
QDateTime currentDateTimeUtc()
void setMSecsSinceEpoch(qint64 msecs)
void toggled(bool on)
void returnPressed()
T & first()
bool isEmpty() const const
T & last()
void push_back(QList< T >::parameter_type value)
qsizetype size() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QString arg(Args &&... args) const const
bool isEmpty() const const
QString toUpper() const const
QString trimmed() const const
QueuedConnection
TextSingleLine
ToolButtonTextBesideIcon
void setInterval(int msec)
void start()
void stop()
void timeout()
QLayout * layout() const const