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"
44 #include "misc/network/server.h"
49 #include "misc/statusmessage.h"
50 
51 using namespace swift::config;
52 using namespace swift::misc;
53 using namespace swift::misc::aviation;
54 using namespace swift::misc::audio;
55 using namespace swift::misc::network;
56 using namespace swift::misc::simulation;
57 using namespace swift::core;
58 using namespace swift::core::data;
59 using namespace swift::core::context;
60 using namespace swift::gui;
61 
62 namespace swift::gui::components
63 {
64  const QStringList &CLoginComponent::getLogCategories()
65  {
66  static const QStringList cats { CLogCategories::guiComponent() };
67  return cats;
68  }
69 
70  CLoginComponent::CLoginComponent(QWidget *parent) : COverlayMessagesFrame(parent), ui(new Ui::CLoginComponent)
71  {
72  ui->setupUi(this);
73  m_logoffCountdownTimer.setObjectName("CLoginComponent:m_logoffCountdownTimer");
74 
75  this->setLogoffCountdown();
76  connect(&m_logoffCountdownTimer, &QTimer::timeout, this, &CLoginComponent::logoffCountdown);
77  connect(ui->pb_Cancel, &QPushButton::clicked, this, &CLoginComponent::loginCancelled, Qt::QueuedConnection);
80  connect(ui->comp_NetworkDetails, &CNetworkDetailsComponent::requestNetworkSettings, this,
82  connect(ui->comp_NetworkDetails, &CNetworkDetailsComponent::currentServerChanged, this,
83  &CLoginComponent::onSelectedServerChanged, Qt::QueuedConnection);
84 
85  // overlay
86  this->setOverlaySizeFactors(0.8, 0.5);
87  this->setReducedInfo(true);
88  this->setForceSmall(true);
89 
90  // Stored data
91  this->loadRememberedUserData();
92 
93  // Remark: The validators affect the signals such as returnPressed, editingFinished
94  // So I use no ranges in the CUpperCaseValidators, as this disables the signals for invalid values
95 
96  if (sGui && sGui->getIContextSimulator())
97  {
98  connect(sGui->getIContextSimulator(), &IContextSimulator::ownAircraftModelChanged, this,
99  &CLoginComponent::onSimulatorModelChanged, Qt::QueuedConnection);
100  connect(sGui->getIContextSimulator(), &IContextSimulator::vitalityLost, this,
101  &CLoginComponent::autoLogoffDetection, Qt::QueuedConnection);
102  connect(sGui->getIContextSimulator(), &IContextSimulator::simulatorStatusChanged, this,
103  &CLoginComponent::onSimulatorStatusChanged, Qt::QueuedConnection);
104  connect(sGui->getIContextSimulator(), &IContextSimulator::insufficientFrameRateDetected, this,
105  &CLoginComponent::autoLogoffFrameRate, Qt::QueuedConnection);
106  }
107 
108  if (sGui && sGui->getIContextNetwork())
109  {
110  connect(sGui->getIContextNetwork(), &IContextNetwork::connectionStatusChanged, this,
111  &CLoginComponent::onNetworkStatusChanged, Qt::QueuedConnection);
112  }
113 
114  // server and UI elements when in disconnect state
115  ui->frp_CurrentServer->setReadOnly(true);
116  ui->frp_CurrentServer->showPasswordField(false);
117  ui->tb_Timeout->setIcon(m_iconPause);
118  connect(ui->tb_Timeout, &QToolButton::clicked, this, &CLoginComponent::toggleTimeout);
119 
120  // inital setup, if data already available
121  ui->form_Pilot->validate();
122 
123  if (sGui && sGui->getIContextSimulator())
124  {
125  this->onSimulatorStatusChanged(sGui->getIContextSimulator()->getSimulatorStatus());
126  }
127 
128  this->updateUiConnectState();
129 
130  QPointer<CLoginComponent> myself(this);
131  QTimer::singleShot(5000, this, [=] {
132  if (!myself) { return; }
133  this->updateGui();
134  });
135  }
136 
138 
140  {
141  if (!sGui || sGui->isShuttingDown()) { return; }
142  if (currentWidget != this && currentWidget != this->parentWidget())
143  {
144  // m_logoffCountdownTimer.stop();
145  }
146  else
147  {
148  ui->comp_OwnAircraft->setOwnModelAndIcaoValues();
149  m_networkConnected = sGui->getIContextNetwork()->isConnected();
150  this->updateUiConnectState();
151  this->blinkConnectButton();
152  }
153  }
154 
155  void CLoginComponent::setLogoffCountdown(std::chrono::seconds timeout)
156  {
157  ui->pb_LogoffTimeout->setMaximum(timeout.count());
158  ui->pb_LogoffTimeout->setValue(timeout.count());
159  m_logoffIntervalSeconds = timeout;
160  }
161 
162  void CLoginComponent::loginCancelled()
163  {
164  m_logoffCountdownTimer.stop();
165  ui->fr_TimeoutConnected->hide();
166  this->setLogoffCountdown(); // reset time
167  this->closeOverlay();
168  emit this->loginOrLogoffCancelled();
169  }
170 
172  {
173  if (!sGui || sGui->isShuttingDown()) { return; }
174  if (!sGui->getIContextNetwork() || !sGui->getIContextAudio()) { return; }
175 
176  m_networkConnected = sGui && sGui->getIContextNetwork()->isConnected();
177  const bool vatsimLogin = this->isVatsimNetworkTabSelected();
178 
179  ui->form_Pilot->setVatsimValidation(vatsimLogin);
180  this->updateUiConnectState();
181 
182  // reset time
183  this->setLogoffCountdown();
184 
185  CServer currentServer; // used for login
186  CSimulatedAircraft ownAircraft; // used own aircraft
187  CStatusMessage msg;
188  if (!m_networkConnected)
189  {
190  const CStatusMessageList aircraftMsgs = ui->comp_OwnAircraft->validate();
191  if (aircraftMsgs.isFailure())
192  {
194  CStatusMessage(this).validationWarning(u"Invalid aircraft data, login not possible"),
195  OverlayMessageMs);
196  return;
197  }
198 
199  const CStatusMessageList pilotMsgs = ui->form_Pilot->validate();
200  if (pilotMsgs.isFailure())
201  {
203  CStatusMessage(this).validationWarning(u"Invalid pilot data, login not possible"),
204  OverlayMessageMs);
205  return;
206  }
207 
208  // sync values with GUI values
209  const COwnAircraftComponent::CGuiAircraftValues values = ui->comp_OwnAircraft->getAircraftValuesFromGui();
210  this->updateOwnAircraftCallsignAndPilotFromGuiValues();
211  ui->comp_OwnAircraft->updateOwnAircaftIcaoValuesFromGuiValues();
212 
213  // Login mode
214  const CLoginMode mode = ui->comp_NetworkDetails->getLoginMode();
215  if (mode.isObserver()) { CLogMessage(this).info(u"Login in observer mode"); }
216 
217  // Server
218  currentServer = this->getCurrentServer();
219  const CUser user = this->getUserFromPilotGuiValues();
220  currentServer.setUser(user);
221 
222  ui->frp_CurrentServer->setServer(currentServer);
224 
225  // set own aircraft from all values
226  ownAircraft = sGui->getIContextOwnAircraft()->getOwnAircraft();
227 
228  // check the copilot stuff
229  CCallsign partnerCs;
230  if (ui->comp_NetworkDetails->hasPartnerCallsign())
231  {
232  partnerCs = ui->comp_NetworkDetails->getPartnerCallsign();
233  if (partnerCs == ownAircraft.getCallsign())
234  {
235  this->showOverlayHTMLMessage("Your callsign and the pilot/copilot callsign must be NOT the same",
236  OverlayMessageMs);
237  return;
238  }
239 
240  const bool ok =
241  (partnerCs.asString().startsWith(ownAircraft.getCallsignAsString(), Qt::CaseInsensitive) ||
242  ownAircraft.getCallsignAsString().startsWith(partnerCs.asString(), Qt::CaseInsensitive));
243  if (!ok)
244  {
246  "Callsign and the pilot/copilot callsign appear not to be synchronized", OverlayMessageMs);
247  return;
248  }
249  }
250 
251  // Login
252  msg = sGui->getIContextNetwork()->connectToNetwork(currentServer, values.ownLiverySend, values.useLivery,
254  partnerCs, mode);
255  if (msg.isSuccess())
256  {
257  Q_ASSERT_X(currentServer.isValidForLogin(), Q_FUNC_INFO, "invalid server");
258  sGui->setExtraWindowTitle(QStringLiteral("[%1]").arg(ownAircraft.getCallsignAsString()));
259  CCrashHandler::instance()->crashAndLogInfoUserName(currentServer.getUser().getRealNameAndId());
260  CCrashHandler::instance()->crashAndLogInfoFlightNetwork(currentServer.getEcosystem().toQString(true));
261  CCrashHandler::instance()->crashAndLogAppendInfo(currentServer.getServerSessionId(false));
262  m_networkSetup.setLastServer(currentServer);
263 
264  const CAircraftModel ownModel = ownAircraft.getModel();
265  m_lastAircraftModel.set(ownModel);
266  ui->le_LoginCallsign->setText(ownAircraft.getCallsignAsString());
267  ui->le_LoginHomeBase->setText(currentServer.getUser().getHomeBase().asString());
268  if (vatsimLogin) { m_networkSetup.setLastVatsimServer(currentServer); }
269  }
270  else { sGui->setExtraWindowTitle(""); }
271  }
272  else
273  {
274  // disconnect from network
277  }
278 
279  // log message and trigger events
280  msg.addCategories(this);
281  CLogMessage::preformatted(msg);
282  if (msg.isSuccess())
283  {
284  this->setGuiLoginAsValues(ownAircraft);
285  emit this->loginOrLogoffSuccessful();
286  }
287  else { emit this->loginOrLogoffCancelled(); }
288  }
289 
290  void CLoginComponent::loadRememberedUserData()
291  {
292  const CServer lastServer = m_networkSetup.getLastServer();
293  const CUser lastUser = lastServer.getUser();
294  ui->form_Pilot->setUser(lastUser);
295  ui->comp_OwnAircraft->setUser(lastUser);
296  }
297 
298  void CLoginComponent::onSelectedServerChanged(const CServer &server)
299  {
300  if (!m_updatePilotOnServerChanges) { return; }
301  const bool vatsim = this->isVatsimNetworkTabSelected();
302  // const CUser user = vatsim ? this->getCurrentVatsimServer().getUser() : server.getUser();
303  const CUser user =
304  server.getServerType() != CServer::FSDServer ? this->getCurrentVatsimServer().getUser() : server.getUser();
305  if ((vatsim && server.getServerType() != CServer::FSDServer) ||
306  (!vatsim && server.getServerType() == CServer::FSDServer))
307  ui->form_Pilot->setUser(user);
308  }
309 
310  void CLoginComponent::onSimulatorStatusChanged(int status)
311  {
312  auto s = static_cast<ISimulator::SimulatorStatus>(status);
313  if (!this->hasValidContexts()) { return; }
314  m_simulatorConnected = s.testFlag(ISimulator::Connected);
315  this->updateUiConnectState();
317  {
318  if (!m_simulatorConnected)
319  {
320  // sim NOT connected but network connected
321  this->autoLogoffDetection();
322  }
323  }
324  }
325 
326  void CLoginComponent::onNetworkStatusChanged(const CConnectionStatus &from, const CConnectionStatus &to)
327  {
328  Q_UNUSED(from)
329  if (to != CConnectionStatus::Connected) { return; }
330 
331  m_networkConnected = true;
332  this->updateUiConnectState();
333  this->updateGui();
334  }
335 
336  void CLoginComponent::onServerTabWidgetChanged(int index)
337  {
338  Q_UNUSED(index)
339  if (!m_updatePilotOnServerChanges) { return; }
340  const bool vatsim = this->isVatsimNetworkTabSelected();
341  const CServer server = vatsim ? this->getCurrentVatsimServer() : this->getCurrentOtherServer();
342  ui->form_Pilot->setUser(server.getUser());
343  }
344 
345  bool CLoginComponent::hasValidContexts() const
346  {
347  if (!sGui || !sGui->supportsContexts()) { return false; }
348  if (sGui->isShuttingDown()) { return false; }
349  if (!sGui->getIContextSimulator()) { return false; }
350  if (!sGui->getIContextNetwork()) { return false; }
351  if (!sGui->getIContextOwnAircraft()) { return false; }
352  return true;
353  }
354 
355  CUser CLoginComponent::getUserFromPilotGuiValues() const
356  {
357  CUser user = ui->form_Pilot->getUser();
358  user.setCallsign(ui->comp_OwnAircraft->getCallsignFromGui());
359  return user;
360  }
361 
362  CServer CLoginComponent::getCurrentVatsimServer() const
363  {
364  CServer server = ui->comp_NetworkDetails->getCurrentVatsimServer();
365  if (!server.getUser().hasValidVatsimId())
366  {
367  // normally VATSIM server have no valid user associated
368  const CUser user = m_networkSetup.getLastVatsimServer().getUser();
369  server.setUser(user);
370  }
371  return server;
372  }
373 
374  CServer CLoginComponent::getCurrentOtherServer() const { return ui->comp_NetworkDetails->getCurrentOtherServer(); }
375 
376  CServer CLoginComponent::getCurrentServer() const
377  {
378  return this->isVatsimNetworkTabSelected() ? this->getCurrentVatsimServer() : this->getCurrentOtherServer();
379  }
380 
381  void CLoginComponent::startLogoffTimerCountdown()
382  {
383  ui->pb_LogoffTimeout->setValue(m_logoffIntervalSeconds.count());
384  m_logoffCountdownTimer.setInterval(1000);
385  m_logoffCountdownTimer.start();
386  ui->fr_TimeoutConnected->show();
387  }
388 
389  void CLoginComponent::setGuiLoginAsValues(const CSimulatedAircraft &ownAircraft)
390  {
391  const QString ac(
392  ownAircraft.getAircraftIcaoCodeDesignator() %
393  (ownAircraft.hasAirlineDesignator() ? (u' ' % ownAircraft.getAirlineIcaoCodeDesignator()) : QString()) %
394  (ownAircraft.hasModelString() ? (u' ' % ownAircraft.getModelString()) : QString()));
395  const QString cs = ownAircraft.getCallsignAsString();
396  ui->le_LoginSince->setText(QDateTime::currentDateTimeUtc().toString());
397  ui->le_LoginAsAircaft->setText(ac);
398  ui->le_LoginAsAircaft->home(false);
399  ui->le_LoginCallsign->setText(cs);
400  }
401 
402  void CLoginComponent::logoffCountdown()
403  {
404  int v = ui->pb_LogoffTimeout->value();
405  v -= 1;
406  v = std::max(v, 0);
407  ui->pb_LogoffTimeout->setValue(v);
408  if (v <= 0)
409  {
410  m_logoffCountdownTimer.stop();
411  this->toggleNetworkConnection();
412  }
413  }
414 
415  void CLoginComponent::autoLogoffDetection()
416  {
417  using namespace std::chrono_literals;
418  if (!this->hasValidContexts()) { return; }
419  if (!sGui->getIContextNetwork()->isConnected()) { return; } // nothing to logoff
420 
421  const CStatusMessage m =
422  CStatusMessage(this, CStatusMessage::SeverityInfo,
423  u"Auto logoff in progress (could be simulator shutdown, crash, closing simulator)");
424  const auto delay = 20s;
425  this->showOverlayHTMLMessage(m, 800 * delay);
426  this->setLogoffCountdown(delay);
427  this->startLogoffTimerCountdown();
428 
429  emit this->requestLoginPage();
430  }
431 
432  void CLoginComponent::autoLogoffFrameRate(bool fatal)
433  {
434  using namespace std::chrono_literals;
436  if (!this->hasValidContexts()) { return; }
437  if (!sGui->getIContextNetwork()->isConnected()) { return; }
438 
439  const auto msg = fatal ? CStatusMessage(this, CStatusMessage::SeverityError,
440  u"Sim frame rate too low to maintain constant simulation rate. "
441  u"Disconnecting to avoid disrupting the network.") :
442  CStatusMessage(this, CStatusMessage::SeverityWarning,
443  u"Sim frame rate too low to maintain constant simulation rate. Reduce "
444  u"graphics quality to avoid disconnection.");
445  const auto delay = 20s;
446  this->showOverlayHTMLMessage(msg, 800 * delay);
447  if (fatal)
448  {
449  this->setLogoffCountdown(delay);
450  this->startLogoffTimerCountdown();
451  }
452 
453  emit this->requestLoginPage();
454  }
455 
456  void CLoginComponent::onSimulatorModelChanged(const CAircraftModel &model)
457  {
458  if (!sGui || !sGui->getIContextNetwork() || sApp->isShuttingDown()) { return; }
459  const bool isNetworkConnected = sGui && sGui->getIContextNetwork()->isConnected();
460  if (isNetworkConnected) { return; }
461 
462  // update with latest DB data
463  CAircraftModel reverseModel(model);
464  if (sGui->hasWebDataServices())
465  {
466  reverseModel = sGui->getWebDataServices()->getModelForModelString(model.getModelString());
467  if (!reverseModel.isLoadedFromDb()) { reverseModel = model; } // reset if not found
468  }
469 
470  const QString modelStr(reverseModel.hasModelString() ? reverseModel.getModelString() : "<unknown>");
471  if (!reverseModel.hasModelString())
472  {
473  CLogMessage(this).validationInfo(u"Invalid lookup for '%1' successful: %2")
474  << modelStr << reverseModel.toQString();
475  CLogMessage(this).validationInfo(u"Hint: Are you using the emulated driver? Set a model if so!");
476  return;
477  }
478  ui->comp_OwnAircraft->setOwnModelAndIcaoValues(reverseModel);
479 
480  // check state of own aircraft
481  this->updateOwnAircraftCallsignAndPilotFromGuiValues();
482 
483  // let others know data changed
484  m_changedLoginDataDigestSignal.inputSignal();
485  }
486 
487  void CLoginComponent::toggleTimeout()
488  {
489  if (m_logoffCountdownTimer.isActive())
490  {
491  m_logoffCountdownTimer.stop();
492  ui->tb_Timeout->setIcon(m_iconPlay);
493  }
494  else
495  {
496  m_logoffCountdownTimer.start();
497  ui->tb_Timeout->setIcon(m_iconPause);
498  }
499  }
500 
501  void CLoginComponent::updateUiConnectState()
502  {
503  ui->fr_LoginDisconnected->setVisible(!m_networkConnected);
504  ui->fr_LogoffConfirmationConnected->setVisible(m_networkConnected);
505 
506  const QString s = m_networkConnected ? QStringLiteral("disconnect") : QStringLiteral("connect");
507  ui->pb_Ok->setText(s);
508 
509  if (m_networkConnected) { ui->pb_Ok->setDisabled(false); }
510  else { ui->pb_Ok->setDisabled(!m_simulatorConnected); }
511  }
512 
513  void CLoginComponent::blinkConnectButton()
514  {
515  if (!ui->pb_Ok->isEnabled()) { return; }
516  ui->pb_Ok->setProperty("blinkOn", true);
517  static constexpr int blinkLength = 100;
518  static constexpr int blinkTimes = 10;
519 
520  auto timer = new QTimer(this);
521  connect(timer, &QTimer::timeout, this, [this, timer, count = std::make_shared<int>(0)] {
522  if (++*count <= blinkTimes) { ui->pb_Ok->setProperty("blinkOn", !ui->pb_Ok->property("blinkOn").toBool()); }
523  else
524  {
525  ui->pb_Ok->setProperty("blinkOn", false);
526  timer->stop();
527  timer->deleteLater();
528  }
529  ui->pb_Ok->style()->unpolish(ui->pb_Ok);
530  ui->pb_Ok->style()->polish(ui->pb_Ok);
531  });
532  timer->setObjectName("blinker");
533  timer->start(blinkLength);
534  }
535 
536  bool CLoginComponent::isVatsimNetworkTabSelected() const
537  {
538  return ui->comp_NetworkDetails->isVatsimServerSelected();
539  }
540 
541  CAircraftModel CLoginComponent::getPrefillModel() const
542  {
543  const CAircraftModel model = m_lastAircraftModel.get();
544  if (model.hasAircraftDesignator()) { return model; }
545  return IContextOwnAircraft::getDefaultOwnAircraftModel();
546  }
547 
548  bool CLoginComponent::updateOwnAircraftCallsignAndPilotFromGuiValues()
549  {
550  if (!this->hasValidContexts()) { return false; }
552  const CCallsign cs = ui->comp_OwnAircraft->getCallsignFromGui();
553  bool changedCallsign = false;
554  if (!cs.isEmpty() && ownAircraft.getCallsignAsString() != cs)
555  {
557  ownAircraft.setCallsign(cs); // also update
558  changedCallsign = true;
559  }
560  CUser pilot = ownAircraft.getPilot();
561  const CUser uiUser = ui->form_Pilot->getUser();
562  pilot.setRealName(uiUser.getRealName());
563  pilot.setHomeBase(uiUser.getHomeBase());
564  pilot.setId(uiUser.getId());
565  pilot.setCallsign(CCallsign(cs));
566  bool changedPilot = false;
567  if (ownAircraft.getPilot() != pilot)
568  {
569  // it can be that the callsign was changed and this results in unchanged here
570  changedPilot = sGui->getIContextOwnAircraft()->updateOwnAircraftPilot(pilot);
571  }
572  return changedCallsign || changedPilot;
573  }
574 
575  void CLoginComponent::updateGui()
576  {
577  if (!m_networkConnected) { return; }
578  if (!this->hasValidContexts()) { return; }
579  if (!sGui->getIContextNetwork()) { return; }
580  const IContextNetwork *nwc = sGui->getIContextNetwork();
582  this->setGuiLoginAsValues(ownAircraft);
583  this->updateUiConnectState();
584  ui->comp_OwnAircraft->setOwnModelAndIcaoValues();
585  const CServer server = nwc->getConnectedServer();
586  ui->le_LoginHomeBase->setText(server.getUser().getHomeBase().asString());
587  ui->frp_CurrentServer->setServer(server);
588  ui->comp_NetworkDetails->setLoginMode(nwc->getLoginMode());
589  }
590 } // 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:74
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
ServerType getServerType() const
Get server type.
Definition: server.h:164
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:14
GUI related classes.
Free functions in swift::misc.
void clicked(bool checked)
QDateTime currentDateTimeUtc()
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void setObjectName(QAnyStringView name)
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
CaseInsensitive
QueuedConnection
char * toString(QSizePolicy sp)
void setInterval(int msec)
bool isActive() const const
void start()
void stop()
void timeout()
QWidget * parentWidget() const const