swift
logincomponent.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 "logincomponent.h"
5 
6 #include <QDialogButtonBox>
7 #include <QGroupBox>
8 #include <QIntValidator>
9 #include <QLineEdit>
10 #include <QMessageBox>
11 #include <QPointer>
12 #include <QProgressBar>
13 #include <QPushButton>
14 #include <QStringBuilder>
15 #include <QTabWidget>
16 #include <QTimer>
17 #include <QToolButton>
18 #include <QtGlobal>
19 
20 #include "ui_logincomponent.h"
21 
22 #include "config/buildconfig.h"
27 #include "core/data/globalsetup.h"
28 #include "core/simulator.h"
29 #include "core/webdataservices.h"
31 #include "gui/editors/pilotform.h"
32 #include "gui/editors/serverform.h"
33 #include "gui/guiapplication.h"
34 #include "gui/ticklabel.h"
35 #include "gui/uppercasevalidator.h"
39 #include "misc/crashhandler.h"
40 #include "misc/icons.h"
41 #include "misc/logmessage.h"
48 #include "misc/statusmessage.h"
49 
50 using namespace swift::config;
51 using namespace swift::misc;
52 using namespace swift::misc::aviation;
53 using namespace swift::misc::audio;
54 using namespace swift::misc::network;
55 using namespace swift::misc::simulation;
56 using namespace swift::core;
57 using namespace swift::core::data;
58 using namespace swift::core::context;
59 using namespace swift::gui;
60 
61 namespace swift::gui::components
62 {
63  const QStringList &CLoginComponent::getLogCategories()
64  {
65  static const QStringList cats { CLogCategories::guiComponent() };
66  return cats;
67  }
68 
69  CLoginComponent::CLoginComponent(QWidget *parent) : COverlayMessagesFrame(parent), ui(new Ui::CLoginComponent)
70  {
71  ui->setupUi(this);
72  m_logoffCountdownTimer.setObjectName("CLoginComponent:m_logoffCountdownTimer");
73 
74  this->setLogoffCountdown();
75  connect(&m_logoffCountdownTimer, &QTimer::timeout, this, &CLoginComponent::logoffCountdown);
76  connect(ui->pb_Cancel, &QPushButton::clicked, this, &CLoginComponent::loginCancelled, Qt::QueuedConnection);
77  connect(ui->pb_Ok, &QPushButton::clicked, this, &CLoginComponent::toggleNetworkConnection,
78  Qt::QueuedConnection);
79  connect(ui->comp_NetworkDetails, &CNetworkDetailsComponent::requestNetworkSettings, this,
80  &CLoginComponent::requestNetworkSettings, Qt::QueuedConnection);
81  connect(ui->comp_NetworkDetails, &CNetworkDetailsComponent::currentServerChanged, this,
82  &CLoginComponent::onSelectedServerChanged, Qt::QueuedConnection);
83 
84  // overlay
85  this->setOverlaySizeFactors(0.8, 0.5);
86  this->setReducedInfo(true);
87  this->setForceSmall(true);
88 
89  // Stored data
90  this->loadRememberedUserData();
91 
92  // Remark: The validators affect the signals such as returnPressed, editingFinished
93  // So I use no ranges in the CUpperCaseValidators, as this disables the signals for invalid values
94 
95  if (sGui && sGui->getIContextSimulator())
96  {
97  connect(sGui->getIContextSimulator(), &IContextSimulator::ownAircraftModelChanged, this,
98  &CLoginComponent::onSimulatorModelChanged, Qt::QueuedConnection);
99  connect(sGui->getIContextSimulator(), &IContextSimulator::vitalityLost, this,
100  &CLoginComponent::autoLogoffDetection, Qt::QueuedConnection);
101  connect(sGui->getIContextSimulator(), &IContextSimulator::simulatorStatusChanged, this,
102  &CLoginComponent::onSimulatorStatusChanged, Qt::QueuedConnection);
103  connect(sGui->getIContextSimulator(), &IContextSimulator::insufficientFrameRateDetected, this,
104  &CLoginComponent::autoLogoffFrameRate, Qt::QueuedConnection);
105  }
106 
107  if (sGui && sGui->getIContextNetwork())
108  {
109  connect(sGui->getIContextNetwork(), &IContextNetwork::connectionStatusChanged, this,
110  &CLoginComponent::onNetworkStatusChanged, Qt::QueuedConnection);
111  }
112 
113  // server and UI elements when in disconnect state
114  ui->frp_CurrentServer->setReadOnly(true);
115  ui->frp_CurrentServer->showPasswordField(false);
116  ui->tb_Timeout->setIcon(m_iconPause);
117  connect(ui->tb_Timeout, &QToolButton::clicked, this, &CLoginComponent::toggleTimeout);
118 
119  // inital setup, if data already available
120  ui->form_Pilot->validate();
121 
122  if (sGui && sGui->getIContextSimulator())
123  {
124  this->onSimulatorStatusChanged(sGui->getIContextSimulator()->getSimulatorStatus());
125  }
126 
127  this->updateUiConnectState();
128 
129  QPointer<CLoginComponent> myself(this);
130  QTimer::singleShot(5000, this, [=] {
131  if (!myself) { return; }
132  this->updateGui();
133  });
134  }
135 
137 
138  void CLoginComponent::mainInfoAreaChanged(const QWidget *currentWidget)
139  {
140  if (!sGui || sGui->isShuttingDown()) { return; }
141  if (currentWidget != this && currentWidget != this->parentWidget())
142  {
143  // m_logoffCountdownTimer.stop();
144  }
145  else
146  {
147  ui->comp_OwnAircraft->setOwnModelAndIcaoValues();
148  m_networkConnected = sGui->getIContextNetwork()->isConnected();
149  this->updateUiConnectState();
150  this->blinkConnectButton();
151  }
152  }
153 
154  void CLoginComponent::setLogoffCountdown(std::chrono::seconds timeout)
155  {
156  ui->pb_LogoffTimeout->setMaximum(timeout.count());
157  ui->pb_LogoffTimeout->setValue(timeout.count());
158  m_logoffIntervalSeconds = timeout;
159  }
160 
161  void CLoginComponent::loginCancelled()
162  {
163  m_logoffCountdownTimer.stop();
164  ui->fr_TimeoutConnected->hide();
165  this->setLogoffCountdown(); // reset time
166  this->closeOverlay();
167  emit this->loginOrLogoffCancelled();
168  }
169 
171  {
172  if (!sGui || sGui->isShuttingDown()) { return; }
173  if (!sGui->getIContextNetwork() || !sGui->getIContextAudio()) { return; }
174 
175  m_networkConnected = sGui && sGui->getIContextNetwork()->isConnected();
176  const bool vatsimLogin = this->isVatsimNetworkTabSelected();
177 
178  ui->form_Pilot->setVatsimValidation(vatsimLogin);
179  this->updateUiConnectState();
180 
181  // reset time
182  this->setLogoffCountdown();
183 
184  CServer currentServer; // used for login
185  CSimulatedAircraft ownAircraft; // used own aircraft
186  CStatusMessage msg;
187  if (!m_networkConnected)
188  {
189  const CStatusMessageList aircraftMsgs = ui->comp_OwnAircraft->validate();
190  if (aircraftMsgs.isFailure())
191  {
193  CStatusMessage(this).validationWarning(u"Invalid aircraft data, login not possible"),
194  OverlayMessageMs);
195  return;
196  }
197 
198  const CStatusMessageList pilotMsgs = ui->form_Pilot->validate();
199  if (pilotMsgs.isFailure())
200  {
202  CStatusMessage(this).validationWarning(u"Invalid pilot data, login not possible"),
203  OverlayMessageMs);
204  return;
205  }
206 
207  // sync values with GUI values
208  const COwnAircraftComponent::CGuiAircraftValues values = ui->comp_OwnAircraft->getAircraftValuesFromGui();
209  this->updateOwnAircraftCallsignAndPilotFromGuiValues();
210  ui->comp_OwnAircraft->updateOwnAircaftIcaoValuesFromGuiValues();
211 
212  // Login mode
213  const CLoginMode mode = ui->comp_NetworkDetails->getLoginMode();
214  if (mode.isObserver()) { CLogMessage(this).info(u"Login in observer mode"); }
215 
216  // Server
217  currentServer = this->getCurrentServer();
218  const CUser user = this->getUserFromPilotGuiValues();
219  currentServer.setUser(user);
220 
221  ui->frp_CurrentServer->setServer(currentServer);
223 
224  // set own aircraft from all values
225  ownAircraft = sGui->getIContextOwnAircraft()->getOwnAircraft();
226 
227  // check the copilot stuff
228  CCallsign partnerCs;
229  if (ui->comp_NetworkDetails->hasPartnerCallsign())
230  {
231  partnerCs = ui->comp_NetworkDetails->getPartnerCallsign();
232  if (partnerCs == ownAircraft.getCallsign())
233  {
234  this->showOverlayHTMLMessage("Your callsign and the pilot/copilot callsign must be NOT the same",
235  OverlayMessageMs);
236  return;
237  }
238 
239  const bool ok =
240  (partnerCs.asString().startsWith(ownAircraft.getCallsignAsString(), Qt::CaseInsensitive) ||
241  ownAircraft.getCallsignAsString().startsWith(partnerCs.asString(), Qt::CaseInsensitive));
242  if (!ok)
243  {
245  "Callsign and the pilot/copilot callsign appear not to be synchronized", OverlayMessageMs);
246  return;
247  }
248  }
249 
250  // Login
251  msg = sGui->getIContextNetwork()->connectToNetwork(currentServer, values.ownLiverySend, values.useLivery,
253  partnerCs, mode);
254  if (msg.isSuccess())
255  {
256  Q_ASSERT_X(currentServer.isValidForLogin(), Q_FUNC_INFO, "invalid server");
257  sGui->setExtraWindowTitle(QStringLiteral("[%1]").arg(ownAircraft.getCallsignAsString()));
258  CCrashHandler::instance()->crashAndLogInfoUserName(currentServer.getUser().getRealNameAndId());
259  CCrashHandler::instance()->crashAndLogInfoFlightNetwork(currentServer.getEcosystem().toQString(true));
260  CCrashHandler::instance()->crashAndLogAppendInfo(currentServer.getServerSessionId(false));
261  m_networkSetup.setLastServer(currentServer);
262 
263  const CAircraftModel ownModel = ownAircraft.getModel();
264  m_lastAircraftModel.set(ownModel);
265  ui->le_LoginCallsign->setText(ownAircraft.getCallsignAsString());
266  ui->le_LoginHomeBase->setText(currentServer.getUser().getHomeBase().asString());
267  if (vatsimLogin) { m_networkSetup.setLastVatsimServer(currentServer); }
268  }
269  else { sGui->setExtraWindowTitle(""); }
270  }
271  else
272  {
273  // disconnect from network
276  }
277 
278  // log message and trigger events
279  msg.addCategories(this);
280  CLogMessage::preformatted(msg);
281  if (msg.isSuccess())
282  {
283  this->setGuiLoginAsValues(ownAircraft);
284  emit this->loginOrLogoffSuccessful();
285  }
286  else { emit this->loginOrLogoffCancelled(); }
287  }
288 
289  void CLoginComponent::loadRememberedUserData()
290  {
291  const CServer lastServer = m_networkSetup.getLastServer();
292  const CUser lastUser = lastServer.getUser();
293  ui->form_Pilot->setUser(lastUser);
294  ui->comp_OwnAircraft->setUser(lastUser);
295  }
296 
297  void CLoginComponent::onSelectedServerChanged(const CServer &server)
298  {
299  if (!m_updatePilotOnServerChanges) { return; }
300  const bool vatsim = this->isVatsimNetworkTabSelected();
301  const CUser user = vatsim ? this->getCurrentVatsimServer().getUser() : server.getUser();
302  ui->form_Pilot->setUser(user);
303  }
304 
305  void CLoginComponent::onSimulatorStatusChanged(int status)
306  {
307  ISimulator::SimulatorStatus s = static_cast<ISimulator::SimulatorStatus>(status);
308  if (!this->hasValidContexts()) { return; }
309  m_simulatorConnected = s.testFlag(ISimulator::Connected);
310  this->updateUiConnectState();
312  {
313  if (!m_simulatorConnected)
314  {
315  // sim NOT connected but network connected
316  this->autoLogoffDetection();
317  }
318  }
319  }
320 
321  void CLoginComponent::onNetworkStatusChanged(const CConnectionStatus &from, const CConnectionStatus &to)
322  {
323  Q_UNUSED(from)
324  if (to != CConnectionStatus::Connected) { return; }
325 
326  m_networkConnected = true;
327  this->updateUiConnectState();
328  this->updateGui();
329  }
330 
331  void CLoginComponent::onServerTabWidgetChanged(int index)
332  {
333  Q_UNUSED(index)
334  if (!m_updatePilotOnServerChanges) { return; }
335  const bool vatsim = this->isVatsimNetworkTabSelected();
336  const CServer server = vatsim ? this->getCurrentVatsimServer() : this->getCurrentOtherServer();
337  ui->form_Pilot->setUser(server.getUser());
338  }
339 
340  bool CLoginComponent::hasValidContexts() const
341  {
342  if (!sGui || !sGui->supportsContexts()) { return false; }
343  if (sGui->isShuttingDown()) { return false; }
344  if (!sGui->getIContextSimulator()) { return false; }
345  if (!sGui->getIContextNetwork()) { return false; }
346  if (!sGui->getIContextOwnAircraft()) { return false; }
347  return true;
348  }
349 
350  CUser CLoginComponent::getUserFromPilotGuiValues() const
351  {
352  CUser user = ui->form_Pilot->getUser();
353  user.setCallsign(ui->comp_OwnAircraft->getCallsignFromGui());
354  return user;
355  }
356 
357  CServer CLoginComponent::getCurrentVatsimServer() const
358  {
359  CServer server = ui->comp_NetworkDetails->getCurrentVatsimServer();
360  if (!server.getUser().hasValidVatsimId())
361  {
362  // normally VATSIM server have no valid user associated
363  const CUser user = m_networkSetup.getLastVatsimServer().getUser();
364  server.setUser(user);
365  }
366  return server;
367  }
368 
369  CServer CLoginComponent::getCurrentOtherServer() const { return ui->comp_NetworkDetails->getCurrentOtherServer(); }
370 
371  CServer CLoginComponent::getCurrentServer() const
372  {
373  return this->isVatsimNetworkTabSelected() ? this->getCurrentVatsimServer() : this->getCurrentOtherServer();
374  }
375 
376  void CLoginComponent::startLogoffTimerCountdown()
377  {
378  ui->pb_LogoffTimeout->setValue(m_logoffIntervalSeconds.count());
379  m_logoffCountdownTimer.setInterval(1000);
380  m_logoffCountdownTimer.start();
381  ui->fr_TimeoutConnected->show();
382  }
383 
384  void CLoginComponent::setGuiLoginAsValues(const CSimulatedAircraft &ownAircraft)
385  {
386  const QString ac(
387  ownAircraft.getAircraftIcaoCodeDesignator() %
388  (ownAircraft.hasAirlineDesignator() ? (u' ' % ownAircraft.getAirlineIcaoCodeDesignator()) : QString()) %
389  (ownAircraft.hasModelString() ? (u' ' % ownAircraft.getModelString()) : QString()));
390  const QString cs = ownAircraft.getCallsignAsString();
391  ui->le_LoginSince->setText(QDateTime::currentDateTimeUtc().toString());
392  ui->le_LoginAsAircaft->setText(ac);
393  ui->le_LoginAsAircaft->home(false);
394  ui->le_LoginCallsign->setText(cs);
395  }
396 
397  void CLoginComponent::logoffCountdown()
398  {
399  int v = ui->pb_LogoffTimeout->value();
400  v -= 1;
401  if (v < 0) { v = 0; }
402  ui->pb_LogoffTimeout->setValue(v);
403  if (v <= 0)
404  {
405  m_logoffCountdownTimer.stop();
406  this->toggleNetworkConnection();
407  }
408  }
409 
410  void CLoginComponent::autoLogoffDetection()
411  {
412  using namespace std::chrono_literals;
413  if (!this->hasValidContexts()) { return; }
414  if (!sGui->getIContextNetwork()->isConnected()) { return; } // nothing to logoff
415 
416  const CStatusMessage m =
417  CStatusMessage(this, CStatusMessage::SeverityInfo,
418  u"Auto logoff in progress (could be simulator shutdown, crash, closing simulator)");
419  const auto delay = 20s;
420  this->showOverlayHTMLMessage(m, 800 * delay);
421  this->setLogoffCountdown(delay);
422  this->startLogoffTimerCountdown();
423 
424  emit this->requestLoginPage();
425  }
426 
427  void CLoginComponent::autoLogoffFrameRate(bool fatal)
428  {
429  using namespace std::chrono_literals;
431  if (!this->hasValidContexts()) { return; }
432  if (!sGui->getIContextNetwork()->isConnected()) { return; }
433 
434  const auto msg = fatal ? CStatusMessage(this, CStatusMessage::SeverityError,
435  u"Sim frame rate too low to maintain constant simulation rate. "
436  u"Disconnecting to avoid disrupting the network.") :
437  CStatusMessage(this, CStatusMessage::SeverityWarning,
438  u"Sim frame rate too low to maintain constant simulation rate. Reduce "
439  u"graphics quality to avoid disconnection.");
440  const auto delay = 20s;
441  this->showOverlayHTMLMessage(msg, 800 * delay);
442  if (fatal)
443  {
444  this->setLogoffCountdown(delay);
445  this->startLogoffTimerCountdown();
446  }
447 
448  emit this->requestLoginPage();
449  }
450 
451  void CLoginComponent::onSimulatorModelChanged(const CAircraftModel &model)
452  {
453  if (!sGui || !sGui->getIContextNetwork() || sApp->isShuttingDown()) { return; }
454  const bool isNetworkConnected = sGui && sGui->getIContextNetwork()->isConnected();
455  if (isNetworkConnected) { return; }
456 
457  // update with latest DB data
458  CAircraftModel reverseModel(model);
459  if (sGui->hasWebDataServices())
460  {
461  reverseModel = sGui->getWebDataServices()->getModelForModelString(model.getModelString());
462  if (!reverseModel.isLoadedFromDb()) { reverseModel = model; } // reset if not found
463  }
464 
465  const QString modelStr(reverseModel.hasModelString() ? reverseModel.getModelString() : "<unknown>");
466  if (!reverseModel.hasModelString())
467  {
468  CLogMessage(this).validationInfo(u"Invalid lookup for '%1' successful: %2")
469  << modelStr << reverseModel.toQString();
470  CLogMessage(this).validationInfo(u"Hint: Are you using the emulated driver? Set a model if so!");
471  return;
472  }
473  ui->comp_OwnAircraft->setOwnModelAndIcaoValues(reverseModel);
474 
475  // check state of own aircraft
476  this->updateOwnAircraftCallsignAndPilotFromGuiValues();
477 
478  // let others know data changed
479  m_changedLoginDataDigestSignal.inputSignal();
480  }
481 
482  void CLoginComponent::toggleTimeout()
483  {
484  if (m_logoffCountdownTimer.isActive())
485  {
486  m_logoffCountdownTimer.stop();
487  ui->tb_Timeout->setIcon(m_iconPlay);
488  }
489  else
490  {
491  m_logoffCountdownTimer.start();
492  ui->tb_Timeout->setIcon(m_iconPause);
493  }
494  }
495 
496  void CLoginComponent::updateUiConnectState()
497  {
498  ui->fr_LoginDisconnected->setVisible(!m_networkConnected);
499  ui->fr_LogoffConfirmationConnected->setVisible(m_networkConnected);
500 
501  const QString s = m_networkConnected ? QStringLiteral("disconnect") : QStringLiteral("connect");
502  ui->pb_Ok->setText(s);
503 
504  if (m_networkConnected) { ui->pb_Ok->setDisabled(false); }
505  else { ui->pb_Ok->setDisabled(!m_simulatorConnected); }
506  }
507 
508  void CLoginComponent::blinkConnectButton()
509  {
510  if (!ui->pb_Ok->isEnabled()) { return; }
511  ui->pb_Ok->setProperty("blinkOn", true);
512  static constexpr int blinkLength = 100;
513  static constexpr int blinkTimes = 10;
514 
515  auto timer = new QTimer(this);
516  connect(timer, &QTimer::timeout, this, [this, timer, count = std::make_shared<int>(0)] {
517  if (++*count <= blinkTimes) { ui->pb_Ok->setProperty("blinkOn", !ui->pb_Ok->property("blinkOn").toBool()); }
518  else
519  {
520  ui->pb_Ok->setProperty("blinkOn", false);
521  timer->stop();
522  timer->deleteLater();
523  }
524  ui->pb_Ok->style()->unpolish(ui->pb_Ok);
525  ui->pb_Ok->style()->polish(ui->pb_Ok);
526  });
527  timer->setObjectName("blinker");
528  timer->start(blinkLength);
529  }
530 
531  bool CLoginComponent::isVatsimNetworkTabSelected() const
532  {
533  return ui->comp_NetworkDetails->isVatsimServerSelected();
534  }
535 
536  CAircraftModel CLoginComponent::getPrefillModel() const
537  {
538  const CAircraftModel model = m_lastAircraftModel.get();
539  if (model.hasAircraftDesignator()) { return model; }
540  return IContextOwnAircraft::getDefaultOwnAircraftModel();
541  }
542 
543  bool CLoginComponent::updateOwnAircraftCallsignAndPilotFromGuiValues()
544  {
545  if (!this->hasValidContexts()) { return false; }
547  const CCallsign cs = ui->comp_OwnAircraft->getCallsignFromGui();
548  bool changedCallsign = false;
549  if (!cs.isEmpty() && ownAircraft.getCallsignAsString() != cs)
550  {
552  ownAircraft.setCallsign(cs); // also update
553  changedCallsign = true;
554  }
555  CUser pilot = ownAircraft.getPilot();
556  const CUser uiUser = ui->form_Pilot->getUser();
557  pilot.setRealName(uiUser.getRealName());
558  pilot.setHomeBase(uiUser.getHomeBase());
559  pilot.setId(uiUser.getId());
560  pilot.setCallsign(CCallsign(cs));
561  bool changedPilot = false;
562  if (ownAircraft.getPilot() != pilot)
563  {
564  // it can be that the callsign was changed and this results in unchanged here
565  changedPilot = sGui->getIContextOwnAircraft()->updateOwnAircraftPilot(pilot);
566  }
567  return changedCallsign || changedPilot;
568  }
569 
570  void CLoginComponent::updateGui()
571  {
572  if (!m_networkConnected) { return; }
573  if (!this->hasValidContexts()) { return; }
574  if (!sGui->getIContextNetwork()) { return; }
575  const IContextNetwork *nwc = sGui->getIContextNetwork();
577  this->setGuiLoginAsValues(ownAircraft);
578  this->updateUiConnectState();
579  ui->comp_OwnAircraft->setOwnModelAndIcaoValues();
580  const CServer server = nwc->getConnectedServer();
581  ui->le_LoginHomeBase->setText(server.getUser().getHomeBase().asString());
582  ui->frp_CurrentServer->setServer(server);
583  ui->comp_NetworkDetails->setLoginMode(nwc->getLoginMode());
584  }
585 } // namespace swift::gui::components
SWIFT_CORE_EXPORT swift::core::CApplication * sApp
Single instance of application object.
Definition: application.cpp:71
const context::IContextAudio * getIContextAudio() const
Direct access to contexts if a CCoreFacade has been initialized.
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?
const context::IContextSimulator * getIContextSimulator() 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.
swift::misc::simulation::CAircraftModel getModelForModelString(const QString &modelString) const
Model for model string if any.
virtual swift::misc::CStatusMessage disconnectFromNetwork()=0
Disconnect from network.
virtual swift::misc::CStatusMessage connectToNetwork(const swift::misc::network::CServer &server, const QString &extraLiveryString, bool sendLivery, const QString &extraModelString, bool sendModelString, const swift::misc::aviation::CCallsign &partnerCallsign, swift::misc::network::CLoginMode loginMode)=0
Connect to Network.
virtual swift::misc::network::CLoginMode getLoginMode() const =0
Login mode.
virtual swift::misc::network::CServer getConnectedServer() const =0
Server which is connected, if not connected empty default object.
virtual bool isConnected() const =0
Network connected?
virtual bool updateOwnAircraftPilot(const swift::misc::network::CUser &pilot)=0
Set current pilot.
virtual bool updateOwnCallsign(const swift::misc::aviation::CCallsign &callsign)=0
Set callsign.
virtual swift::misc::simulation::CSimulatedAircraft getOwnAircraft() const =0
Get own aircraft.
virtual ISimulator::SimulatorStatus getSimulatorStatus() const =0
Simulator combined status.
swift::misc::CStatusMessage setLastVatsimServer(const swift::misc::network::CServer &server)
Set value of last VATSIM server.
swift::misc::CStatusMessage setLastServer(const swift::misc::network::CServer &server)
Set value of last server.
swift::misc::network::CServer getLastVatsimServer() const
Last VATSIM server (VATSIM only)
swift::misc::network::CServer getLastServer() const
Last server (all networks)
QString setExtraWindowTitle(const QString &extraInfo, QWidget *mainWindowWidget=mainApplicationWidget()) const
Set window title.
bool showOverlayHTMLMessage(const QString &htmlMessage, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
HTML message.
void setForceSmall(bool force)
Force small (smaller layout)
void setOverlaySizeFactors(double widthFactor, double heightFactor, double middleFactor=2)
Set the size factors.
void setReducedInfo(bool reduced)
Display reduced information.
Using this class provides a QFrame with the overlay functionality already integrated.
Login component to flight network.
void toggleNetworkConnection()
Login requested.
void mainInfoAreaChanged(const QWidget *currentWidget)
Main info area changed.
void setLogoffCountdown(std::chrono::seconds timeout=LogoffIntervalSeconds)
Set a logoff time.
void requestNetworkSettings()
Request network settings.
void requestLoginPage()
Request to be shown.
void requestNetworkSettings()
Request network settings.
void currentServerChanged(const misc::network::CServer &server)
Current selected server changed.
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
void inputSignal()
Received input signal, or manually trigger.
Class for emitting a log message.
Definition: logmessage.h:27
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.
Streamable status message, e.g.
bool isSuccess() const
Operation considered successful.
void addCategories(const CLogCategoryList &categories)
Add categories, avoids duplicates.
Status messages, e.g. from Core -> GUI.
bool isFailure() const
Any message is marked as failure.
const QString & asString() const
Get code.
Value object encapsulating information of a callsign.
Definition: callsign.h:30
const QString & asString() const
Get callsign (normalized)
Definition: callsign.h:96
bool isEmpty() const
Is empty?
Definition: callsign.h:63
QString toQString(bool i18n=false) const
Cast as QString.
Definition: mixinstring.h:76
Value object encapsulating information about a connection status.
Value object encapsulating information about login mode.
Definition: loginmode.h:18
bool isObserver() const
Is login as observer?
Definition: loginmode.h:37
Value object encapsulating information of a server.
Definition: server.h:28
bool isValidForLogin() const
Is valid for login?
Definition: server.cpp:98
void setUser(const CUser &user)
Set user.
Definition: server.h:89
const CEcosystem & getEcosystem() const
Get the ecosystem.
Definition: server.h:122
const CUser & getUser() const
Get user.
Definition: server.h:86
QString getServerSessionId(bool onlyConnected) const
Identifying a session, if not connected empty.
Definition: server.cpp:153
Value object encapsulating information of a user.
Definition: user.h:28
const aviation::CAirportIcaoCode & getHomeBase() const
Homebase.
Definition: user.h:134
const QString & getRealName() const
Get full name.
Definition: user.h:59
void setRealName(const QString &realname)
Set real name.
Definition: user.cpp:98
QString getRealNameAndId() const
Real name and id.
Definition: user.cpp:52
void setId(const QString &id)
Set id.
Definition: user.cpp:307
const QString & getId() const
Get id.
Definition: user.h:119
void setHomeBase(const aviation::CAirportIcaoCode &homebase)
Set homebase.
Definition: user.h:137
bool setCallsign(const aviation::CCallsign &callsign)
Set associated callsign.
Definition: user.cpp:62
bool hasValidVatsimId() const
Has a valid VATSIM id?
Definition: user.h:86
Aircraft model (used by another pilot, my models on disk)
Definition: aircraftmodel.h:71
const QString & getModelString() const
Model key, either queried or loaded from simulator model.
bool hasAircraftDesignator() const
Has aircraft designator?
Comprehensive information of an aircraft.
void setCallsign(const aviation::CCallsign &callsign)
Set callsign.
const QString & getAirlineIcaoCodeDesignator() const
Airline ICAO code designator.
bool hasAirlineDesignator() const
Valid airline designator.
bool hasModelString() const
Has model string?
const network::CUser & getPilot() const
Get user.
const aviation::CCallsign & getCallsign() const
Get callsign.
const QString & getAircraftIcaoCodeDesignator() const
Aircraft ICAO code designator.
const simulation::CAircraftModel & getModel() const
Get model (model used for mapping)
QString getCallsignAsString() const
Get callsign.
const QString & getModelString() const
Get model string.
SWIFT_GUI_EXPORT swift::gui::CGuiApplication * sGui
Single instance of GUI application object.
Core data traits (aka cached values) and classes.
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