swift
swiftguistd.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 
4 #include "ui_swiftguistd.h"
5 
6 #include "config/buildconfig.h"
11 #include "core/corefacadeconfig.h"
12 #include "core/webdataservices.h"
20 #include "gui/guiapplication.h"
21 #include "gui/guiutility.h"
24 #include "misc/icons.h"
25 #include "misc/logcategories.h"
26 #include "misc/logmessage.h"
27 #include "misc/threadutils.h"
28 
29 #if defined(Q_OS_MACOS)
31 #endif
32 
33 #include <QAction>
34 #include <QDateTime>
35 #include <QIcon>
36 #include <QMessageBox>
37 #include <QPointer>
38 #include <QSize>
39 #include <QStackedWidget>
40 #include <QStyle>
41 #include <QWidget>
42 #include <Qt>
43 #include <QtGlobal>
44 
45 #include "swiftguistd.h"
46 
47 class QCloseEvent;
48 class QEvent;
49 class QMouseEvent;
50 class QWidget;
51 
52 namespace swift::gui
53 {
55  class IMainWindowAccess;
56 } // namespace swift::gui
57 namespace swift::misc
58 {
59  class CIdentifiable;
60 }
61 
62 using namespace swift::core;
63 using namespace swift::core::context;
64 using namespace swift::gui;
65 using namespace swift::gui::components;
66 using namespace swift::misc;
67 using namespace swift::misc::network;
68 using namespace swift::misc::aviation;
69 using namespace swift::misc::physical_quantities;
70 using namespace swift::misc::geo;
71 using namespace swift::misc::audio;
72 using namespace swift::misc::input;
73 using namespace swift::misc::simulation;
74 using namespace swift::config;
75 
76 // Constructor
78  : QMainWindow(parent, CEnableForFramelessWindow::modeToWindowFlags(windowMode)), CIdentifiable(this),
79  CEnableForFramelessWindow(windowMode, true, "framelessMainWindow", this), ui(new Ui::SwiftGuiStd)
80 {
81  // GUI
82  Q_ASSERT_X(sGui, Q_FUNC_INFO, "Need sGui");
84  ui->setupUi(this);
85  this->setDynamicProperties(windowMode == CEnableForFramelessWindow::WindowFrameless);
86  this->init();
87 }
88 
90 
91 void SwiftGuiStd::mouseMoveEvent(QMouseEvent *event)
92 {
93  if (!handleMouseMoveEvent(event)) { QMainWindow::mouseMoveEvent(event); }
94 }
95 
96 void SwiftGuiStd::mousePressEvent(QMouseEvent *event)
97 {
98  if (!handleMousePressEvent(event)) { QMainWindow::mousePressEvent(event); }
99 }
100 
101 void SwiftGuiStd::mouseReleaseEvent(QMouseEvent *event)
102 {
103  m_framelessDragPosition = QPoint();
104  QMainWindow::mouseReleaseEvent(event);
105 }
106 
107 void SwiftGuiStd::performGracefulShutdown()
108 {
109  if (!m_init) { return; }
110  m_init = false;
111 
112  Q_ASSERT_X(CThreadUtils::thisIsMainThread(), Q_FUNC_INFO, "Should shutdown in main thread");
113 
114  // shut down all timers
115  this->stopAllTimers(true);
116 
117  // if we have a context, we shut some things down
118  if (m_contextNetworkAvailable)
119  {
121  {
122  if (m_contextAudioAvailable)
123  {
124  sGui->getIContextAudio()->disconnect(this); // break down signal / slots
125  }
127  sGui->getIContextNetwork()->disconnect(this); // avoid any status update signals, etc.
128  }
129  }
130 
131  // clean up GUI
132  ui->comp_MainInfoArea->dockAllWidgets();
133 
134  // allow some other parts to react
135  const QPointer<SwiftGuiStd> myself(this);
136  if (sGui) { sGui->processEventsToRefreshGui(); }
137  if (!sGui || !myself) { return; } // killed in meantime?
138 
139  // tell context GUI is going down
141 
142  // allow some other parts to react
143  if (sGui) { sGui->processEventsToRefreshGui(); }
144 }
145 
146 void SwiftGuiStd::closeEvent(QCloseEvent *event)
147 {
148  if (sGui)
149  {
151  {
152  // we do not just logoff, but give the user a chance to respond
153  event->ignore();
154  QPointer<SwiftGuiStd> myself(this);
155  QTimer::singleShot(500, this, [=] {
156  if (!myself) { return; }
157  myself->loginRequested();
158  });
159  return;
160  }
161 
162  if (this->triggerAutoPublishDialog())
163  {
164  event->ignore();
165  return;
166  }
167 
168  // save settings
169  if (sGui->showCloseDialog(this, event) == QDialog::Rejected)
170  {
171  // already ignored
172  return;
173  }
174  }
175  this->performGracefulShutdown();
176 }
177 
178 void SwiftGuiStd::changeEvent(QEvent *event)
179 {
180  if (!CEnableForFramelessWindow::handleChangeEvent(event)) { QMainWindow::changeEvent(event); }
181 }
182 
183 QAction *SwiftGuiStd::getWindowMinimizeAction(QObject *parent)
184 {
185  const QIcon i(CIcons::changeIconBackgroundColor(this->style()->standardIcon(QStyle::SP_TitleBarMinButton),
186  Qt::white, QSize(16, 16)));
187  QAction *a = new QAction(i, "Window minimized", parent);
188  connect(a, &QAction::triggered, this, &SwiftGuiStd::showMinimized);
189  return a;
190 }
191 
192 QAction *SwiftGuiStd::getWindowNormalAction(QObject *parent)
193 {
194  const QIcon i(CIcons::changeIconBackgroundColor(this->style()->standardIcon(QStyle::SP_TitleBarNormalButton),
195  Qt::white, QSize(16, 16)));
196  QAction *a = new QAction(i, "Window normal", parent);
197  connect(a, &QAction::triggered, this, &SwiftGuiStd::showNormal);
198  return a;
199 }
200 
202 {
203  const QIcon i(CIcons::changeIconBackgroundColor(this->style()->standardIcon(QStyle::SP_TitleBarShadeButton),
204  Qt::white, QSize(16, 16)));
205  QAction *a = new QAction(i, "Toogle main window visibility", parent);
206  connect(a, &QAction::triggered, this, &SwiftGuiStd::toggleWindowVisibility);
207  return a;
208 }
209 
210 QAction *SwiftGuiStd::getToggleStayOnTopAction(QObject *parent)
211 {
212  const QIcon i(CIcons::changeIconBackgroundColor(this->style()->standardIcon(QStyle::SP_TitleBarUnshadeButton),
213  Qt::white, QSize(16, 16)));
214  QAction *a = new QAction(i, "Toogle main window on top", parent);
215  connect(a, &QAction::triggered, this, &SwiftGuiStd::toggleWindowStayOnTop);
216  return a;
217 }
218 
219 void SwiftGuiStd::setMainPage(SwiftGuiStd::MainPageIndex mainPage) { ui->sw_MainMiddle->setCurrentIndex(mainPage); }
220 
221 void SwiftGuiStd::setMainPageInfoArea(CMainInfoAreaComponent::InfoArea infoArea)
222 {
223  this->setMainPageToInfoArea();
224  ui->comp_MainInfoArea->selectArea(infoArea);
225 }
226 
227 void SwiftGuiStd::setSettingsPage(int settingsTabIndex)
228 {
229  this->setMainPageInfoArea(CMainInfoAreaComponent::InfoAreaSettings);
230  if (settingsTabIndex < 0) { return; }
231  ui->comp_MainInfoArea->getSettingsComponent()->setCurrentIndex(settingsTabIndex);
232 }
233 
234 bool SwiftGuiStd::isMainPageSelected(SwiftGuiStd::MainPageIndex mainPage) const
235 {
236  return ui->sw_MainMiddle->currentIndex() == static_cast<int>(mainPage);
237 }
238 
239 void SwiftGuiStd::loginRequested()
240 {
241  if (!sGui || sGui->isShuttingDown() || !sGui->getIContextNetwork()) { return; }
242 
243  const bool changed = MainPageLogin != ui->sw_MainMiddle->currentIndex();
244  this->setMainPage(MainPageLogin);
245  if (!changed)
246  {
247  // fake changed signal to trigger blinking disconnect button (issue #115)
248  emit this->currentMainInfoAreaChanged(ui->sw_MainMiddle->currentWidget());
249  }
250 }
251 
252 void SwiftGuiStd::onKickedFromNetwork(const QString &kickMessage)
253 {
254  this->updateGuiStatusInformation();
255 
256  const QString msgText = kickMessage.isEmpty() ? QStringLiteral("You have been kicked from the network") :
257  QStringLiteral("You have been kicked: '%1'").arg(kickMessage);
258  CLogMessage(this).error(msgText);
259  // this->displayInOverlayWindow(CStatusMessage(this, CStatusMessage::SeverityError, msgText));
260 }
261 
262 void SwiftGuiStd::onConnectionStatusChanged(const CConnectionStatus &from, const CConnectionStatus &to)
263 {
264  Q_UNUSED(from)
265  this->updateGuiStatusInformation();
266 
267  // sounds
268  switch (to.getConnectionStatus())
269  {
270  case CConnectionStatus::Connected: this->playNotifcationSound(CNotificationSounds::NotificationLogin); break;
271  case CConnectionStatus::Disconnected: this->playNotifcationSound(CNotificationSounds::NotificationLogoff); break;
272  default: break;
273  }
274 }
275 
276 void SwiftGuiStd::handleTimerBasedUpdates()
277 {
278  this->setContextAvailability();
279  this->updateGuiStatusInformation();
280 
281  // own aircraft
282  this->reloadOwnAircraft();
283 }
284 
285 void SwiftGuiStd::setContextAvailability()
286 {
287  const bool corePreviouslyAvailable = m_coreAvailable;
288  const bool isShuttingDown = !sGui || sGui->isShuttingDown();
289  if (!isShuttingDown && sGui->getIContextApplication() && !sGui->getIContextApplication()->isEmptyObject())
290  {
291  // ping to check if core is still alive
293  }
294  else { m_coreAvailable = false; }
295  if (isShuttingDown) { return; }
296  if (m_coreAvailable && m_coreFailures > 0) { m_coreFailures--; }
297  else if (!m_coreAvailable && m_coreFailures < MaxCoreFailures) { m_coreFailures++; }
298  else if (!m_coreAvailable && !m_displayingDBusReconnect) { this->displayDBusReconnectDialog(); }
299  m_contextNetworkAvailable =
300  m_coreAvailable && sGui->getIContextNetwork() && !sGui->getIContextNetwork()->isEmptyObject();
301  m_contextAudioAvailable = m_coreAvailable && sGui->getIContextAudio() && !sGui->getIContextAudio()->isEmptyObject();
302 
303  // react to a change in core's availability
304  if (m_coreAvailable != corePreviouslyAvailable)
305  {
306  if (m_coreAvailable)
307  {
308  // core has just become available (startup)
309  // this HERE is called with and without DBus
311  }
312  }
313 }
314 
315 void SwiftGuiStd::updateGuiStatusInformation()
316 {
317  if (m_coreAvailable)
318  {
319  static const QString dBusTimestamp("%1 %2");
320  static const QString local("local");
321  const QString now = QDateTime::currentDateTimeUtc().toString("yyyy-MM-dd HH:mm:ss");
322  const bool dBus = sGui->getCoreFacadeConfig().requiresDBusConnection();
323  ui->comp_InfoBarStatus->setDBusStatus(dBus && m_coreAvailable);
324  ui->comp_InfoBarStatus->setDBusTooltip(
325  dBus ? dBusTimestamp.arg(now, sGui->getCoreFacadeConfig().getDBusAddress()) : local);
326  }
327  else
328  {
329  static const QString unavailable("unavailable");
330  ui->comp_InfoBarStatus->setDBusStatus(false);
331  ui->comp_InfoBarStatus->setDBusTooltip(unavailable);
332  }
333 }
334 
335 void SwiftGuiStd::onChangedWindowOpacity(int opacity)
336 {
337  qreal o = opacity / 100.0;
338  o = o < 0.3 ? 0.3 : o;
339  o = o > 1.0 ? 1.0 : o;
340  QWidget::setWindowOpacity(o);
341  ui->comp_MainInfoArea->getSettingsComponent()->setGuiOpacity(o * 100.0);
342 }
343 
344 void SwiftGuiStd::toggleWindowStayOnTop()
345 {
346  if (sGui) { sGui->toggleStayOnTop(); }
347 }
348 
349 void SwiftGuiStd::toggleWindowVisibility()
350 {
351  if (this->isVisible())
352  {
353  this->hide();
354  return;
355  }
356  this->show();
357 }
358 
359 void SwiftGuiStd::onStyleSheetsChanged() { this->initStyleSheet(); }
360 
361 void SwiftGuiStd::onToggledWindowsOnTop(bool onTop)
362 {
363  if (onTop)
364  {
365  // here we could automatically display the navigator
366  // if (m_navigator) { m_navigator->showNavigator(true); }
367  ui->comp_MainInfoArea->allFloatingOnTop();
368  }
369 }
370 
371 void SwiftGuiStd::onCurrentMainWidgetChanged(int currentIndex)
372 {
373  emit this->currentMainInfoAreaChanged(ui->sw_MainMiddle->currentWidget());
374  Q_UNUSED(currentIndex)
375 }
376 
377 void SwiftGuiStd::onChangedMainInfoAreaFloating(bool floating)
378 {
379  // code for whole floating area goes here
380  Q_UNUSED(floating)
381 }
382 
383 void SwiftGuiStd::onAudioClientFailure(const CStatusMessage &msg)
384 {
385  if (msg.isEmpty()) { return; }
386  if (!sGui || sGui->isShuttingDown()) { return; }
387 
388  ui->fr_CentralFrameInside->showOverlayHTMLMessage(msg);
389 }
390 
391 void SwiftGuiStd::focusInMainEntryField() { ui->comp_MainKeypadArea->focusInEntryField(); }
392 
393 void SwiftGuiStd::focusInTextMessageEntryField()
394 {
395  if (!ui->comp_MainInfoArea->getTextMessageComponent()) { return; }
396  if (ui->comp_MainInfoArea->getTextMessageComponent()->isParentDockWidgetFloating())
397  {
398  ui->comp_MainInfoArea->getTextMessageComponent()->activateWindow();
399  ui->comp_MainInfoArea->getTextMessageComponent()->focusTextEntry();
400  }
401  else { this->focusInMainEntryField(); }
402 }
403 
404 void SwiftGuiStd::showMinimized() { this->showMinimizedModeChecked(); }
405 
406 void SwiftGuiStd::showNormal() { this->showNormalModeChecked(); }
407 
408 void SwiftGuiStd::onNavigatorClosed()
409 {
410  if (!sGui || sGui->isShuttingDown()) { return; }
411  this->show();
412 }
413 
414 void SwiftGuiStd::verifyPrerequisites()
415 {
416  if (!sGui || sGui->isShuttingDown()) { return; }
417 
418  CStatusMessageList msgs;
420  {
421  msgs.push_back(CStatusMessage(this).error(u"No simulator context"));
422  }
424 
425 #if defined(Q_OS_MACOS)
427  {
428  // A log message about missing permissions is already emitted when initializing the keyboard.
429  // But this happens way before initializing the GUI. Hence do the check here again to show an error message
430  // to the user
431  msgs.push_back(
432  CLogMessage(this).error(u"Cannot access the keyboard. Is \"Input Monitoring\" for swift enabled?"));
433  }
434 #endif
435 
436  if (msgs.hasWarningOrErrorMessages())
437  {
438  if (msgs.size() > 1) { this->displayInOverlayWindow(msgs); }
439  else { this->displayInOverlayWindow(msgs.front()); }
440  }
441 }
442 
443 void SwiftGuiStd::onValidatedModelSet(const CSimulatorInfo &simulator, const CAircraftModelList &valid,
444  const CAircraftModelList &invalid, bool stopped, const CStatusMessageList &msgs)
445 {
446  using namespace std::chrono_literals;
447  // will NOT be called if no errors and setting is "only on errors"
448  if (!sGui || sGui->isShuttingDown()) { return; }
449  if (QApplication::activeModalWidget())
450  {
451  // avoid too many "deadlocking" dialogs, display warning instead
452  if (invalid.isEmpty()) { return; }
453  const CStatusMessage m =
455  u"Model set validation has found %1 invalid models for '%2', check the model validation")
456  << invalid.size() << simulator.toQString(true);
457  this->displayInOverlayWindow(m, 5s);
458  return;
459  }
460 
461  this->displayValidationDialog();
462  m_validationDialog->validatedModelSet(simulator, valid, invalid, stopped, msgs);
463 }
464 
465 void SwiftGuiStd::displayValidationDialog()
466 {
467  if (!sGui || sGui->isShuttingDown()) { return; }
468  if (!m_validationDialog) { m_validationDialog.reset(new CAircraftModelSetValidationDialog(this)); }
469  m_validationDialog->show();
470 }
471 
472 void SwiftGuiStd::checkDbDataLoaded()
473 {
474  if (!sGui || sGui->isShuttingDown()) { return; }
475  Q_ASSERT_X(sGui->hasWebDataServices(), Q_FUNC_INFO, "Missing web services");
476  Q_ASSERT_X(CThreadUtils::thisIsMainThread(), Q_FUNC_INFO, "Wrong thread, needs to run in main thread");
477  const CEntityFlags::Entity loadEntities =
479  if (loadEntities == CEntityFlags::NoEntity)
480  {
481  m_dbDataLoading = false;
482  return;
483  }
484 
485  if (!m_dbLoadDialog) { m_dbLoadDialog.reset(new CDbLoadDataDialog(this)); }
486  m_dbLoadDialog->newerOrEmptyEntitiesDetected(loadEntities);
487 }
488 
489 void SwiftGuiStd::playNotifcationSound(CNotificationSounds::NotificationFlag notification) const
490 {
491  if (!m_contextAudioAvailable) { return; }
492  if (!m_audioSettings.get().isNotificationFlagSet(notification)) { return; }
493  if (!sGui || sGui->isShuttingDown()) { return; }
494  sGui->getCContextAudioBase()->playNotification(notification, true);
495 }
496 
497 void SwiftGuiStd::displayLog() { ui->comp_MainInfoArea->displayLog(); }
498 
499 void SwiftGuiStd::displayNetworkSettings()
500 {
501  if (!sApp || sApp->isShuttingDown()) { return; }
502  this->setMainPageInfoArea(CMainInfoAreaComponent::InfoAreaSettings);
503  ui->comp_MainInfoArea->getSettingsComponent()->setTab(CSettingsComponent::SettingTabServers);
504 }
505 
506 void SwiftGuiStd::onPttChanged(bool enabled)
507 {
508  Q_UNUSED(enabled)
509  if (!sGui || !sGui->getCContextAudioBase()) { return; }
510 
511  // based on user request still play with AFV
513  enabled ? CNotificationSounds::PTTClickKeyDown : CNotificationSounds::PTTClickKeyUp, true);
514 }
515 
516 void SwiftGuiStd::displayDBusReconnectDialog()
517 {
518  if (m_displayingDBusReconnect) { return; }
519  if (!sGui || sGui->isShuttingDown()) { return; }
520  if (!sGui->getCoreFacade()) { return; }
521  if (!sGui->getCoreFacadeConfig().requiresDBusConnection()) { return; }
522  m_displayingDBusReconnect = true;
523  const QString dBusAddress = sGui->getCoreFacade()->getDBusAddress();
524  static const QString informativeText("Do you want to try to reconnect? 'Abort' will close the GUI.\n\nDBus: '%1'");
525  QMessageBox msgBox(this);
526  msgBox.setIcon(QMessageBox::Critical);
527  msgBox.setText("swift core not reachable!");
528  msgBox.setInformativeText(informativeText.arg(dBusAddress));
529  msgBox.setStandardButtons(QMessageBox::Retry | QMessageBox::Abort);
530  msgBox.setDefaultButton(QMessageBox::Retry);
531  const int ret = msgBox.exec();
532  if (ret == QMessageBox::Abort)
533  {
534  m_coreFailures = 0;
536  CGuiApplication::exit(EXIT_FAILURE);
537  return;
538  }
539 
540  m_displayingDBusReconnect = false;
542  if (msg.isSuccess()) { m_coreFailures = 0; }
543  msg.clampSeverity(CStatusMessage::SeverityWarning);
544  CLogMessage::preformatted(msg);
545 }
546 
547 void SwiftGuiStd::onShowOverlayVariant(const CVariant &variant, std::chrono::milliseconds duration)
548 {
549  if (!sGui || sGui->isShuttingDown()) { return; }
550  ui->fr_CentralFrameInside->showOverlayVariant(variant, duration);
551 }
552 
553 void SwiftGuiStd::onShowOverlayInlineTextMessageTab(components::TextMessageTab tab)
554 {
555  if (!sGui || sGui->isShuttingDown()) { return; }
556  ui->fr_CentralFrameInside->showOverlayInlineTextMessage(tab);
557 }
558 
559 void SwiftGuiStd::onShowOverlayInlineTextMessageCallsign(const CCallsign &callsign)
560 {
561  if (!sGui || sGui->isShuttingDown()) { return; }
562  ui->fr_CentralFrameInside->showOverlayInlineTextMessage(callsign);
563 }
564 
565 bool SwiftGuiStd::triggerAutoPublishDialog()
566 {
567  if (!CAutoPublishData::existAutoPublishFiles()) { return false; }
568 
569  constexpr qint64 deltaT = 48 * 60 * 60 * 1000;
570  const qint64 lastDialogTs = m_lastAutoPublish.get();
571  bool showAutoPublish = lastDialogTs < 0 || (QDateTime::currentMSecsSinceEpoch() - lastDialogTs) > deltaT;
572  if (!showAutoPublish) { return false; }
573 
574  const QMessageBox::StandardButton reply =
575  QMessageBox::question(this, QStringLiteral("Upload data?"),
576  QStringLiteral("Do you want to help improving swift by uploading anonymized data?"),
577  QMessageBox::Yes | QMessageBox::No);
578 
579  if (reply != QMessageBox::Yes)
580  {
581  m_lastAutoPublish.set(QDateTime::currentMSecsSinceEpoch());
582  return false;
583  }
584 
585  this->autoPublishDialog(); // updates m_lastAutoPublish
586  return true;
587 }
588 
589 bool SwiftGuiStd::startModelBrowser()
590 {
591  if (!m_modelBrower) { m_modelBrower.reset(new CModelBrowserDialog(this)); }
592  m_modelBrower->exec();
593  return true;
594 }
595 
596 bool SwiftGuiStd::startAFVMap()
597 {
599 
600  return true;
601 }
SWIFT_CORE_EXPORT swift::core::CApplication * sApp
Single instance of application object.
Definition: application.cpp:71
swift GUI
Definition: swiftguistd.h:63
virtual void mousePressEvent(QMouseEvent *event)
Definition: swiftguistd.cpp:96
virtual void mouseMoveEvent(QMouseEvent *event)
Definition: swiftguistd.cpp:91
void currentMainInfoAreaChanged(const QWidget *currentWidget)
Main info area has changed.
QAction * getToggleStayOnTopAction(QObject *parent)
Get a minimize action which minimizes the window.
SwiftGuiStd(WindowMode windowMode, QWidget *parent=nullptr)
Constructor.
Definition: swiftguistd.cpp:77
virtual ~SwiftGuiStd()
Destructor.
Definition: swiftguistd.cpp:89
QAction * getToggleWindowVisibilityAction(QObject *parent)
Get a minimize action which minimizes the window.
virtual void closeEvent(QCloseEvent *event)
MainPageIndex
Main page indexes.
Definition: swiftguistd.h:71
QAction * getWindowNormalAction(QObject *parent)
Get a minimize action which minimizes the window.
QAction * getWindowMinimizeAction(QObject *parent)
Get a minimize action which minimizes the window.
virtual void changeEvent(QEvent *event)
virtual void mouseReleaseEvent(QMouseEvent *event)
const context::IContextAudio * getIContextAudio() const
Direct access to contexts if a CCoreFacade has been initialized.
data::CGlobalSetup getGlobalSetup() const
Global setup.
const context::IContextApplication * getIContextApplication() const
Direct access to contexts if a CCoreFacade has been initialized.
CCoreFacade * getCoreFacade()
Get the facade.
Definition: application.h:346
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?
const context::IContextSimulator * getIContextSimulator() const
Direct access to contexts if a CCoreFacade has been initialized.
const CCoreFacadeConfig & getCoreFacadeConfig() const
The core facade config.
Definition: application.h:326
const context::CContextAudioBase * getCContextAudioBase() const
Direct access to contexts if a CCoreFacade has been initialized.
bool supportsContexts(bool ignoreShutdownTest=false) const
Supports contexts.
CWebDataServices * getWebDataServices() const
Get the web data services.
bool requiresDBusConnection() const
Requires DBus connection (at least one remote)?
QString getDBusAddress() const
DBus address.
QString getDBusAddress() const
DBus address if any.
Definition: corefacade.cpp:323
swift::misc::CStatusMessage tryToReconnectWithDBus()
In case connection between DBus parties is lost, try to reconnect.
Definition: corefacade.cpp:52
swift::misc::network::CEntityFlags::Entity getSynchronizedEntitiesWithNewerSharedFileOrEmpty(bool syncData=true, swift::misc::network::CEntityFlags::Entity entities=swift::misc::network::CEntityFlags::AllDbEntities)
Synchronized entities either empty or with newer shared file.
void playNotification(swift::misc::audio::CNotificationSounds::NotificationFlag notification, bool considerSettings, int volume=-1)
Notification sounds.
virtual void unregisterApplication(const misc::CIdentifier &application)=0
Unregister application.
virtual void synchronizeLocalSettings()=0
Update local settings with settings from core.
virtual misc::CIdentifier registerApplication(const misc::CIdentifier &application)=0
Register application, can also be used for ping.
bool isEmptyObject() const
Empty object?
Definition: context.h:54
virtual swift::misc::CStatusMessage disconnectFromNetwork()=0
Disconnect from network.
virtual bool isConnected() const =0
Network connected?
virtual swift::misc::CStatusMessageList verifyPrerequisites() const =0
Verify prerequisites for simulation like an existing model set.
swift::misc::network::CUrl getAfvMapUrl() const
AFV map URL.
Definition: globalsetup.h:140
Main window which can be frameless.
bool handleMousePressEvent(QMouseEvent *event)
Mouse press, required for frameless window.
void showMinimizedModeChecked()
Check mode and then show minimized.
QPoint m_framelessDragPosition
position, if moving is handled with frameless window
void showNormalModeChecked()
Check mode and then show normal.
bool handleMouseMoveEvent(QMouseEvent *event)
Mouse moving, required for frameless window.
void setDynamicProperties(bool frameless)
Set dynamic properties such as frameless.
void registerMainApplicationWidget(QWidget *mainWidget)
Register main application window widget if this is known.
void processEventsToRefreshGui() const
Allow the GUI to refresh by processing events, call the event loop.
QDialog::DialogCode showCloseDialog(QMainWindow *mainWindow, QCloseEvent *closeEvent)
Show close dialog.
void gracefulShutdown()
Graceful shutdown.
bool toggleStayOnTop()
Toggle stay on top.
void openUrl(const swift::misc::network::CUrl &url)
Open a given URL.
Direct acccess to main window`s status bar, info bar and such.
virtual bool displayInOverlayWindow(const swift::misc::CStatusMessage &message, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Display in overlay window.
static bool hasAccess()
Check OS permission for input monitoring access.
T get() const
Get a copy of the current value.
Definition: valuecache.h:408
CStatusMessage set(const typename Trait::type &value, qint64 timestamp=0)
Write a new value. Must be called from the thread in which the owner lives.
Definition: datacache.h:350
Base class with a member CIdentifier to be inherited by a class which has an identity in the environm...
Definition: identifiable.h:24
bool isMyIdentifier(const CIdentifier &otherIdentifier) const
My identifier?
Definition: identifiable.h:33
const CIdentifier & identifier() const
Get identifier.
Definition: identifiable.h:27
Class for emitting a log message.
Definition: logmessage.h:27
bool isEmpty() const
Message empty.
Derived & validationWarning(const char16_t(&format)[N])
Set the severity to warning, providing a format string, and adding the validation category.
Derived & error(const char16_t(&format)[N])
Set the severity to error, providing a format string.
size_type size() const
Returns number of elements in the sequence.
Definition: sequence.h:273
void push_back(const T &value)
Appends an element at the end of the sequence.
Definition: sequence.h:305
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 isSuccess() const
Operation considered successful.
bool clampSeverity(StatusSeverity severity)
Clip/reduce severity if higher (more critical)
Status messages, e.g. from Core -> GUI.
bool hasWarningOrErrorMessages() const
Warning or error messages.
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
QString toQString(bool i18n=false) const
Cast as QString.
Definition: mixinstring.h:76
Value object encapsulating information about a connection status.
ConnectionStatus getConnectionStatus() const
Get status.
Value object encapsulating a list of aircraft 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.
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:13
GUI related classes.
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