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"
51 using namespace swift::config;
53 using namespace swift::misc::aviation;
54 using namespace swift::misc::audio;
55 using namespace swift::misc::network;
56 using namespace swift::misc::simulation;
59 using namespace swift::core::context;
66 static const QStringList cats { CLogCategories::guiComponent() };
73 m_logoffCountdownTimer.
setObjectName(
"CLoginComponent:m_logoffCountdownTimer");
91 this->loadRememberedUserData();
115 ui->frp_CurrentServer->setReadOnly(
true);
116 ui->frp_CurrentServer->showPasswordField(
false);
117 ui->tb_Timeout->setIcon(m_iconPause);
121 ui->form_Pilot->validate();
128 this->updateUiConnectState();
132 if (!myself) {
return; }
142 if (currentWidget !=
this && currentWidget != this->
parentWidget())
148 ui->comp_OwnAircraft->setOwnModelAndIcaoValues();
150 this->updateUiConnectState();
151 this->blinkConnectButton();
157 ui->pb_LogoffTimeout->setMaximum(timeout.count());
158 ui->pb_LogoffTimeout->setValue(timeout.count());
159 m_logoffIntervalSeconds = timeout;
162 void CLoginComponent::loginCancelled()
164 m_logoffCountdownTimer.
stop();
165 ui->fr_TimeoutConnected->hide();
177 const bool vatsimLogin = this->isVatsimNetworkTabSelected();
179 ui->form_Pilot->setVatsimValidation(vatsimLogin);
180 this->updateUiConnectState();
188 if (!m_networkConnected)
194 CStatusMessage(
this).validationWarning(u
"Invalid aircraft data, login not possible"),
203 CStatusMessage(
this).validationWarning(u
"Invalid pilot data, login not possible"),
210 this->updateOwnAircraftCallsignAndPilotFromGuiValues();
211 ui->comp_OwnAircraft->updateOwnAircaftIcaoValuesFromGuiValues();
214 const CLoginMode mode = ui->comp_NetworkDetails->getLoginMode();
218 currentServer = this->getCurrentServer();
219 const CUser user = this->getUserFromPilotGuiValues();
222 ui->frp_CurrentServer->setServer(currentServer);
230 if (ui->comp_NetworkDetails->hasPartnerCallsign())
232 partnerCs = ui->comp_NetworkDetails->getPartnerCallsign();
246 "Callsign and the pilot/copilot callsign appear not to be synchronized", OverlayMessageMs);
257 Q_ASSERT_X(currentServer.
isValidForLogin(), Q_FUNC_INFO,
"invalid server");
260 CCrashHandler::instance()->crashAndLogInfoFlightNetwork(currentServer.
getEcosystem().
toQString(
true));
261 CCrashHandler::instance()->crashAndLogAppendInfo(currentServer.
getServerSessionId(
false));
265 m_lastAircraftModel.
set(ownModel);
281 CLogMessage::preformatted(msg);
284 this->setGuiLoginAsValues(ownAircraft);
290 void CLoginComponent::loadRememberedUserData()
294 ui->form_Pilot->setUser(lastUser);
295 ui->comp_OwnAircraft->setUser(lastUser);
298 void CLoginComponent::onSelectedServerChanged(
const CServer &server)
300 if (!m_updatePilotOnServerChanges) {
return; }
301 const bool vatsim = this->isVatsimNetworkTabSelected();
304 if ((vatsim && server.
getServerType() != CServer::FSDServer) ||
306 ui->form_Pilot->setUser(user);
309 void CLoginComponent::onSimulatorStatusChanged(
int status)
311 auto s =
static_cast<ISimulator::SimulatorStatus
>(status);
312 if (!this->hasValidContexts()) {
return; }
313 m_simulatorConnected = s.testFlag(ISimulator::Connected);
314 this->updateUiConnectState();
317 if (!m_simulatorConnected)
320 this->autoLogoffDetection();
328 if (to != CConnectionStatus::Connected) {
return; }
330 m_networkConnected =
true;
331 this->updateUiConnectState();
335 void CLoginComponent::onServerTabWidgetChanged(
int index)
338 if (!m_updatePilotOnServerChanges) {
return; }
339 const bool vatsim = this->isVatsimNetworkTabSelected();
340 const CServer server = vatsim ? this->getCurrentVatsimServer() : this->getCurrentOtherServer();
341 ui->form_Pilot->setUser(server.
getUser());
344 bool CLoginComponent::hasValidContexts()
const
354 CUser CLoginComponent::getUserFromPilotGuiValues()
const
356 CUser user = ui->form_Pilot->getUser();
357 user.
setCallsign(ui->comp_OwnAircraft->getCallsignFromGui());
361 CServer CLoginComponent::getCurrentVatsimServer()
const
363 CServer server = ui->comp_NetworkDetails->getCurrentVatsimServer();
373 CServer CLoginComponent::getCurrentOtherServer()
const {
return ui->comp_NetworkDetails->getCurrentOtherServer(); }
375 CServer CLoginComponent::getCurrentServer()
const
377 return this->isVatsimNetworkTabSelected() ? this->getCurrentVatsimServer() : this->getCurrentOtherServer();
380 void CLoginComponent::startLogoffTimerCountdown()
382 ui->pb_LogoffTimeout->setValue(m_logoffIntervalSeconds.count());
384 m_logoffCountdownTimer.
start();
385 ui->fr_TimeoutConnected->show();
396 ui->le_LoginAsAircaft->setText(ac);
397 ui->le_LoginAsAircaft->home(
false);
398 ui->le_LoginCallsign->setText(cs);
401 void CLoginComponent::logoffCountdown()
403 int v = ui->pb_LogoffTimeout->value();
405 if (v < 0) { v = 0; }
406 ui->pb_LogoffTimeout->setValue(v);
409 m_logoffCountdownTimer.
stop();
414 void CLoginComponent::autoLogoffDetection()
416 using namespace std::chrono_literals;
417 if (!this->hasValidContexts()) {
return; }
422 u
"Auto logoff in progress (could be simulator shutdown, crash, closing simulator)");
423 const auto delay = 20s;
426 this->startLogoffTimerCountdown();
431 void CLoginComponent::autoLogoffFrameRate(
bool fatal)
433 using namespace std::chrono_literals;
435 if (!this->hasValidContexts()) {
return; }
438 const auto msg = fatal ?
CStatusMessage(
this, CStatusMessage::SeverityError,
439 u
"Sim frame rate too low to maintain constant simulation rate. "
440 u
"Disconnecting to avoid disrupting the network.") :
442 u
"Sim frame rate too low to maintain constant simulation rate. Reduce "
443 u
"graphics quality to avoid disconnection.");
444 const auto delay = 20s;
449 this->startLogoffTimerCountdown();
455 void CLoginComponent::onSimulatorModelChanged(
const CAircraftModel &model)
459 if (isNetworkConnected) {
return; }
466 if (!reverseModel.isLoadedFromDb()) { reverseModel = model; }
469 const QString modelStr(reverseModel.hasModelString() ? reverseModel.getModelString() :
"<unknown>");
470 if (!reverseModel.hasModelString())
473 << modelStr << reverseModel.toQString();
477 ui->comp_OwnAircraft->setOwnModelAndIcaoValues(reverseModel);
480 this->updateOwnAircraftCallsignAndPilotFromGuiValues();
486 void CLoginComponent::toggleTimeout()
488 if (m_logoffCountdownTimer.
isActive())
490 m_logoffCountdownTimer.
stop();
491 ui->tb_Timeout->setIcon(m_iconPlay);
495 m_logoffCountdownTimer.
start();
496 ui->tb_Timeout->setIcon(m_iconPause);
500 void CLoginComponent::updateUiConnectState()
502 ui->fr_LoginDisconnected->setVisible(!m_networkConnected);
503 ui->fr_LogoffConfirmationConnected->setVisible(m_networkConnected);
505 const QString s = m_networkConnected ? QStringLiteral(
"disconnect") : QStringLiteral(
"connect");
506 ui->pb_Ok->setText(s);
508 if (m_networkConnected) { ui->pb_Ok->setDisabled(
false); }
509 else { ui->pb_Ok->setDisabled(!m_simulatorConnected); }
512 void CLoginComponent::blinkConnectButton()
514 if (!ui->pb_Ok->isEnabled()) {
return; }
515 ui->pb_Ok->setProperty(
"blinkOn",
true);
516 static constexpr
int blinkLength = 100;
517 static constexpr
int blinkTimes = 10;
519 auto timer =
new QTimer(
this);
521 if (++*count <= blinkTimes) { ui->pb_Ok->setProperty(
"blinkOn", !ui->pb_Ok->property(
"blinkOn").toBool()); }
524 ui->pb_Ok->setProperty(
"blinkOn",
false);
526 timer->deleteLater();
528 ui->pb_Ok->style()->unpolish(ui->pb_Ok);
529 ui->pb_Ok->style()->polish(ui->pb_Ok);
531 timer->setObjectName(
"blinker");
532 timer->start(blinkLength);
535 bool CLoginComponent::isVatsimNetworkTabSelected()
const
537 return ui->comp_NetworkDetails->isVatsimServerSelected();
544 return IContextOwnAircraft::getDefaultOwnAircraftModel();
547 bool CLoginComponent::updateOwnAircraftCallsignAndPilotFromGuiValues()
549 if (!this->hasValidContexts()) {
return false; }
551 const CCallsign cs = ui->comp_OwnAircraft->getCallsignFromGui();
552 bool changedCallsign =
false;
557 changedCallsign =
true;
560 const CUser uiUser = ui->form_Pilot->getUser();
565 bool changedPilot =
false;
566 if (ownAircraft.
getPilot() != pilot)
571 return changedCallsign || changedPilot;
574 void CLoginComponent::updateGui()
576 if (!m_networkConnected) {
return; }
577 if (!this->hasValidContexts()) {
return; }
581 this->setGuiLoginAsValues(ownAircraft);
582 this->updateUiConnectState();
583 ui->comp_OwnAircraft->setOwnModelAndIcaoValues();
586 ui->frp_CurrentServer->setServer(server);
587 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.
~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.
ServerType getServerType() const
Get server type.
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.
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
char * toString(QSizePolicy sp)
void setInterval(int msec)
bool isActive() const const
GUI aircraft values, formatted.
QString ownLiverySend
send livery
QString ownAircraftModelStringSend
send model string
bool useModelString
use model string