6 #include <QDialogButtonBox>
8 #include <QIntValidator>
10 #include <QMessageBox>
12 #include <QProgressBar>
13 #include <QPushButton>
14 #include <QStringBuilder>
17 #include <QToolButton>
20 #include "ui_logincomponent.h"
50 using namespace swift::config;
52 using namespace swift::misc::aviation;
53 using namespace swift::misc::audio;
54 using namespace swift::misc::network;
55 using namespace swift::misc::simulation;
58 using namespace swift::core::context;
63 const QStringList &CLoginComponent::getLogCategories()
65 static const QStringList cats { CLogCategories::guiComponent() };
72 m_logoffCountdownTimer.setObjectName(
"CLoginComponent:m_logoffCountdownTimer");
75 connect(&m_logoffCountdownTimer, &QTimer::timeout,
this, &CLoginComponent::logoffCountdown);
76 connect(ui->pb_Cancel, &QPushButton::clicked,
this, &CLoginComponent::loginCancelled, Qt::QueuedConnection);
78 Qt::QueuedConnection);
82 &CLoginComponent::onSelectedServerChanged, Qt::QueuedConnection);
90 this->loadRememberedUserData();
98 &CLoginComponent::onSimulatorModelChanged, Qt::QueuedConnection);
100 &CLoginComponent::autoLogoffDetection, Qt::QueuedConnection);
102 &CLoginComponent::onSimulatorStatusChanged, Qt::QueuedConnection);
104 &CLoginComponent::autoLogoffFrameRate, Qt::QueuedConnection);
110 &CLoginComponent::onNetworkStatusChanged, Qt::QueuedConnection);
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);
120 ui->form_Pilot->validate();
127 this->updateUiConnectState();
129 QPointer<CLoginComponent> myself(
this);
131 if (!myself) {
return; }
141 if (currentWidget !=
this && currentWidget != this->parentWidget())
147 ui->comp_OwnAircraft->setOwnModelAndIcaoValues();
149 this->updateUiConnectState();
150 this->blinkConnectButton();
156 ui->pb_LogoffTimeout->setMaximum(timeout.count());
157 ui->pb_LogoffTimeout->setValue(timeout.count());
158 m_logoffIntervalSeconds = timeout;
161 void CLoginComponent::loginCancelled()
163 m_logoffCountdownTimer.stop();
164 ui->fr_TimeoutConnected->hide();
176 const bool vatsimLogin = this->isVatsimNetworkTabSelected();
178 ui->form_Pilot->setVatsimValidation(vatsimLogin);
179 this->updateUiConnectState();
187 if (!m_networkConnected)
193 CStatusMessage(
this).validationWarning(u
"Invalid aircraft data, login not possible"),
202 CStatusMessage(
this).validationWarning(u
"Invalid pilot data, login not possible"),
209 this->updateOwnAircraftCallsignAndPilotFromGuiValues();
210 ui->comp_OwnAircraft->updateOwnAircaftIcaoValuesFromGuiValues();
213 const CLoginMode mode = ui->comp_NetworkDetails->getLoginMode();
217 currentServer = this->getCurrentServer();
218 const CUser user = this->getUserFromPilotGuiValues();
221 ui->frp_CurrentServer->setServer(currentServer);
229 if (ui->comp_NetworkDetails->hasPartnerCallsign())
231 partnerCs = ui->comp_NetworkDetails->getPartnerCallsign();
245 "Callsign and the pilot/copilot callsign appear not to be synchronized", OverlayMessageMs);
256 Q_ASSERT_X(currentServer.
isValidForLogin(), Q_FUNC_INFO,
"invalid server");
259 CCrashHandler::instance()->crashAndLogInfoFlightNetwork(currentServer.
getEcosystem().
toQString(
true));
260 CCrashHandler::instance()->crashAndLogAppendInfo(currentServer.
getServerSessionId(
false));
264 m_lastAircraftModel.
set(ownModel);
280 CLogMessage::preformatted(msg);
283 this->setGuiLoginAsValues(ownAircraft);
289 void CLoginComponent::loadRememberedUserData()
293 ui->form_Pilot->setUser(lastUser);
294 ui->comp_OwnAircraft->setUser(lastUser);
297 void CLoginComponent::onSelectedServerChanged(
const CServer &server)
299 if (!m_updatePilotOnServerChanges) {
return; }
300 const bool vatsim = this->isVatsimNetworkTabSelected();
302 ui->form_Pilot->setUser(user);
305 void CLoginComponent::onSimulatorStatusChanged(
int status)
307 ISimulator::SimulatorStatus s =
static_cast<ISimulator::SimulatorStatus
>(status);
308 if (!this->hasValidContexts()) {
return; }
309 m_simulatorConnected = s.testFlag(ISimulator::Connected);
310 this->updateUiConnectState();
313 if (!m_simulatorConnected)
316 this->autoLogoffDetection();
324 if (to != CConnectionStatus::Connected) {
return; }
326 m_networkConnected =
true;
327 this->updateUiConnectState();
331 void CLoginComponent::onServerTabWidgetChanged(
int 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());
340 bool CLoginComponent::hasValidContexts()
const
350 CUser CLoginComponent::getUserFromPilotGuiValues()
const
352 CUser user = ui->form_Pilot->getUser();
353 user.
setCallsign(ui->comp_OwnAircraft->getCallsignFromGui());
357 CServer CLoginComponent::getCurrentVatsimServer()
const
359 CServer server = ui->comp_NetworkDetails->getCurrentVatsimServer();
369 CServer CLoginComponent::getCurrentOtherServer()
const {
return ui->comp_NetworkDetails->getCurrentOtherServer(); }
371 CServer CLoginComponent::getCurrentServer()
const
373 return this->isVatsimNetworkTabSelected() ? this->getCurrentVatsimServer() : this->getCurrentOtherServer();
376 void CLoginComponent::startLogoffTimerCountdown()
378 ui->pb_LogoffTimeout->setValue(m_logoffIntervalSeconds.count());
379 m_logoffCountdownTimer.setInterval(1000);
380 m_logoffCountdownTimer.start();
381 ui->fr_TimeoutConnected->show();
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);
397 void CLoginComponent::logoffCountdown()
399 int v = ui->pb_LogoffTimeout->value();
401 if (v < 0) { v = 0; }
402 ui->pb_LogoffTimeout->setValue(v);
405 m_logoffCountdownTimer.stop();
410 void CLoginComponent::autoLogoffDetection()
412 using namespace std::chrono_literals;
413 if (!this->hasValidContexts()) {
return; }
418 u
"Auto logoff in progress (could be simulator shutdown, crash, closing simulator)");
419 const auto delay = 20s;
422 this->startLogoffTimerCountdown();
427 void CLoginComponent::autoLogoffFrameRate(
bool fatal)
429 using namespace std::chrono_literals;
431 if (!this->hasValidContexts()) {
return; }
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.") :
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;
445 this->startLogoffTimerCountdown();
451 void CLoginComponent::onSimulatorModelChanged(
const CAircraftModel &model)
455 if (isNetworkConnected) {
return; }
462 if (!reverseModel.isLoadedFromDb()) { reverseModel = model; }
465 const QString modelStr(reverseModel.hasModelString() ? reverseModel.getModelString() :
"<unknown>");
466 if (!reverseModel.hasModelString())
469 << modelStr << reverseModel.toQString();
473 ui->comp_OwnAircraft->setOwnModelAndIcaoValues(reverseModel);
476 this->updateOwnAircraftCallsignAndPilotFromGuiValues();
482 void CLoginComponent::toggleTimeout()
484 if (m_logoffCountdownTimer.isActive())
486 m_logoffCountdownTimer.stop();
487 ui->tb_Timeout->setIcon(m_iconPlay);
491 m_logoffCountdownTimer.start();
492 ui->tb_Timeout->setIcon(m_iconPause);
496 void CLoginComponent::updateUiConnectState()
498 ui->fr_LoginDisconnected->setVisible(!m_networkConnected);
499 ui->fr_LogoffConfirmationConnected->setVisible(m_networkConnected);
501 const QString s = m_networkConnected ? QStringLiteral(
"disconnect") : QStringLiteral(
"connect");
502 ui->pb_Ok->setText(s);
504 if (m_networkConnected) { ui->pb_Ok->setDisabled(
false); }
505 else { ui->pb_Ok->setDisabled(!m_simulatorConnected); }
508 void CLoginComponent::blinkConnectButton()
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;
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()); }
520 ui->pb_Ok->setProperty(
"blinkOn",
false);
522 timer->deleteLater();
524 ui->pb_Ok->style()->unpolish(ui->pb_Ok);
525 ui->pb_Ok->style()->polish(ui->pb_Ok);
527 timer->setObjectName(
"blinker");
528 timer->start(blinkLength);
531 bool CLoginComponent::isVatsimNetworkTabSelected()
const
533 return ui->comp_NetworkDetails->isVatsimServerSelected();
540 return IContextOwnAircraft::getDefaultOwnAircraftModel();
543 bool CLoginComponent::updateOwnAircraftCallsignAndPilotFromGuiValues()
545 if (!this->hasValidContexts()) {
return false; }
547 const CCallsign cs = ui->comp_OwnAircraft->getCallsignFromGui();
548 bool changedCallsign =
false;
553 changedCallsign =
true;
556 const CUser uiUser = ui->form_Pilot->getUser();
561 bool changedPilot =
false;
562 if (ownAircraft.
getPilot() != pilot)
567 return changedCallsign || changedPilot;
570 void CLoginComponent::updateGui()
572 if (!m_networkConnected) {
return; }
573 if (!this->hasValidContexts()) {
return; }
577 this->setGuiLoginAsValues(ownAircraft);
578 this->updateUiConnectState();
579 ui->comp_OwnAircraft->setOwnModelAndIcaoValues();
582 ui->frp_CurrentServer->setServer(server);
583 ui->comp_NetworkDetails->setLoginMode(nwc->
getLoginMode());
SWIFT_CORE_EXPORT swift::core::CApplication * sApp
Single instance of application object.
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.
void closeOverlay()
Close button clicked.
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.
virtual ~CLoginComponent()
Destructor.
void loginOrLogoffCancelled()
Cancelled.
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 loginOrLogoffSuccessful()
Login.
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.
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.
void inputSignal()
Received input signal, or manually trigger.
Class for emitting a log message.
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.
const QString & asString() const
Get callsign (normalized)
bool isEmpty() const
Is empty?
QString toQString(bool i18n=false) const
Cast as QString.
Value object encapsulating information about a connection status.
Value object encapsulating information about login mode.
bool isObserver() const
Is login as observer?
Value object encapsulating information of a server.
bool isValidForLogin() const
Is valid for login?
void setUser(const CUser &user)
Set user.
const CEcosystem & getEcosystem() const
Get the ecosystem.
const CUser & getUser() const
Get user.
QString getServerSessionId(bool onlyConnected) const
Identifying a session, if not connected empty.
Value object encapsulating information of a user.
const aviation::CAirportIcaoCode & getHomeBase() const
Homebase.
const QString & getRealName() const
Get full name.
void setRealName(const QString &realname)
Set real name.
QString getRealNameAndId() const
Real name and id.
void setId(const QString &id)
Set id.
const QString & getId() const
Get id.
void setHomeBase(const aviation::CAirportIcaoCode &homebase)
Set homebase.
bool setCallsign(const aviation::CCallsign &callsign)
Set associated callsign.
bool hasValidVatsimId() const
Has a valid VATSIM id?
Aircraft model (used by another pilot, my models on disk)
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.
High level reusable GUI components.
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...
GUI aircraft values, formatted.
QString ownLiverySend
send livery
QString ownAircraftModelStringSend
send model string
bool useModelString
use model string