From 6f97e7290b1978e8dfe848c5e653090c73a4a2bf Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Tue, 28 Jun 2016 21:23:16 +0200 Subject: [PATCH] refs #681, FSD UI at login screen * plus completers for login GUI (ICAO, ...) * some utility functions in related value object classed --- src/blackgui/components/logincomponent.cpp | 114 ++++++++-- src/blackgui/components/logincomponent.h | 7 +- src/blackgui/components/logincomponent.ui | 200 ++++++++++-------- src/blackmisc/aviation/aircrafticaocode.cpp | 3 +- src/blackmisc/aviation/aircrafticaocode.h | 2 +- src/blackmisc/aviation/airlineicaocode.cpp | 12 ++ src/blackmisc/aviation/airlineicaocode.h | 3 + .../aviation/airlineicaocodelist.cpp | 14 ++ src/blackmisc/aviation/airlineicaocodelist.h | 3 + 9 files changed, 244 insertions(+), 114 deletions(-) diff --git a/src/blackgui/components/logincomponent.cpp b/src/blackgui/components/logincomponent.cpp index 53918c75d..89eb8e271 100644 --- a/src/blackgui/components/logincomponent.cpp +++ b/src/blackgui/components/logincomponent.cpp @@ -12,6 +12,7 @@ #include "blackcore/contextnetwork.h" #include "blackcore/contextownaircraft.h" #include "blackcore/contextsimulator.h" +#include "blackcore/webdataservices.h" #include "blackcore/data/globalsetup.h" #include "blackcore/network.h" #include "blackcore/simulator.h" @@ -43,6 +44,8 @@ #include #include #include +#include +#include #include using namespace BlackConfig; @@ -58,6 +61,12 @@ namespace BlackGui { namespace Components { + const CLogCategoryList &CLoginComponent::getLogCategories() + { + static const BlackMisc::CLogCategoryList cats { BlackMisc::CLogCategory::guiComponent() }; + return cats; + } + CLoginComponent::CLoginComponent(QWidget *parent) : QFrame(parent), ui(new Ui::CLoginComponent) @@ -74,6 +83,9 @@ namespace BlackGui connect(this->ui->bb_OkCancel, &QDialogButtonBox::accepted, this, &CLoginComponent::ps_toggleNetworkConnection); connect(this->ui->pb_OtherServersGotoSettings, &QPushButton::pressed, this, &CLoginComponent::requestNetworkSettings); + this->ui->comp_FsdDetails->showEnableInfo(true); + this->ui->comp_FsdDetails->setFsdSetupEnabled(false); + this->ui->lblp_SimulatorModel->setToolTips("available", "unavailable"); this->ui->lblp_SimulatorModel->setPixmapUnticked(CIcons::empty()); this->ui->lblp_AircraftCombinedType->setToolTips("ok", "wrong"); @@ -110,9 +122,9 @@ namespace BlackGui this->ui->le_AircraftCombinedType->setValidator(new CUpperCaseValidator(this)); connect(ui->le_AircraftCombinedType, &QLineEdit::editingFinished, this, &CLoginComponent::ps_validateAircraftValues); - this->ui->le_AircraftIcaoAirline->setMaxLength(5); - this->ui->le_AircraftIcaoAirline->setValidator(new CUpperCaseValidator(this)); - connect(ui->le_AircraftIcaoAirline, &QLineEdit::editingFinished, this, &CLoginComponent::ps_validateAircraftValues); + this->ui->le_AirlineIcaoDesignator->setMaxLength(5); + this->ui->le_AirlineIcaoDesignator->setValidator(new CUpperCaseValidator(this)); + connect(ui->le_AirlineIcaoDesignator, &QLineEdit::editingFinished, this, &CLoginComponent::ps_validateAircraftValues); this->ui->le_AircraftIcaoDesignator->setMaxLength(5); this->ui->le_AircraftIcaoDesignator->setValidator(new CUpperCaseValidator(this)); @@ -126,9 +138,9 @@ namespace BlackGui connect(sGui->getIContextNetwork(), &IContextNetwork::webServiceDataRead, this, &CLoginComponent::ps_onWebServiceDataRead); // inital setup, if data already available - ps_validateAircraftValues(); - ps_validateVatsimValues(); - ps_onWebServiceDataRead(CEntityFlags::VatsimDataFile, CEntityFlags::ReadFinished, -1); + this->ps_validateAircraftValues(); + this->ps_validateVatsimValues(); + this->ps_onWebServiceDataRead(CEntityFlags::VatsimDataFile, CEntityFlags::ReadFinished, -1); CServerList otherServers(this->m_otherTrafficNetworkServers.getThreadLocal()); // add a testserver when no servers can be loaded @@ -180,6 +192,11 @@ namespace BlackGui void CLoginComponent::ps_toggleNetworkConnection() { + if (this->ui->tw_Network->currentWidget() == this->ui->pg_FsdDetails) + { + CLogMessage(this).validationError("No login possible from this very tab, use VATSIM or other servers"); + return; + } const bool isConnected = sGui->getIContextNetwork()->isConnected(); const bool vatsimLogin = (this->ui->tw_Network->currentWidget() == this->ui->pg_NetworkVatsim); CServer currentServer; // used for login @@ -190,13 +207,13 @@ namespace BlackGui if (!this->ps_validateAircraftValues()) { - CLogMessage(this).warning("Invalid aircraft data, login not possible"); + CLogMessage(this).validationWarning("Invalid aircraft data, login not possible"); return; } if (vatsimLogin && !this->ps_validateVatsimValues()) { - CLogMessage(this).warning("Invalid VATSIM data, login not possible"); + CLogMessage(this).validationWarning("Invalid VATSIM data, login not possible"); return; } @@ -256,6 +273,14 @@ namespace BlackGui { currentServer = this->getCurrentOtherServer(); } + + // FSD setup, then override + if (ui->comp_FsdDetails->isFsdSetuoEnabled()) + { + const CFsdSetup fsd = ui->comp_FsdDetails->getValue(); + currentServer.setFsdSetup(fsd); + } + this->ui->frp_CurrentServer->setServer(currentServer); sGui->getIContextOwnAircraft()->updateOwnAircraftPilot(currentServer.getUser()); @@ -287,25 +312,33 @@ namespace BlackGui } } - void CLoginComponent::ps_onWebServiceDataRead(int entityInt, int stateI, int number) + void CLoginComponent::ps_onWebServiceDataRead(int entityInt, int stateInt, int number) { const CEntityFlags::EntityFlag entity = static_cast(entityInt); - const CEntityFlags::ReadState state = static_cast(stateI); - if (entity != CEntityFlags::VatsimDataFile || state != CEntityFlags::ReadFinished) { return; } + const CEntityFlags::ReadState state = static_cast(stateInt); + if (state != CEntityFlags::ReadFinished) { return; } Q_UNUSED(number); - const CServerList vatsimFsdServers = sGui->getIContextNetwork()->getVatsimFsdServers(); - if (vatsimFsdServers.isEmpty()) { return; } - const CServer currentServer = this->m_currentVatsimServer.get(); - this->ui->comp_VatsimServer->setServers(vatsimFsdServers); - this->ui->comp_VatsimServer->preSelect(currentServer.getName()); + + if (entity == CEntityFlags::VatsimDataFile) + { + const CServerList vatsimFsdServers = sGui->getIContextNetwork()->getVatsimFsdServers(); + if (vatsimFsdServers.isEmpty()) { return; } + const CServer currentServer = this->m_currentVatsimServer.get(); + this->ui->comp_VatsimServer->setServers(vatsimFsdServers); + this->ui->comp_VatsimServer->preSelect(currentServer.getName()); + } + else + { + this->initCompleters(entity); + } } void CLoginComponent::setGuiValuesFromAircraft(const CSimulatedAircraft &ownAircraft) { - CAircraftIcaoCode aircraftIcao = ownAircraft.getAircraftIcaoCode(); + const CAircraftIcaoCode aircraftIcao = ownAircraft.getAircraftIcaoCode(); this->ui->le_Callsign->setText(ownAircraft.getCallsignAsString()); this->ui->le_AircraftIcaoDesignator->setText(aircraftIcao.getDesignator()); - this->ui->le_AircraftIcaoAirline->setText(ownAircraft.getAirlineIcaoCodeDesignator()); + this->ui->le_AirlineIcaoDesignator->setText(ownAircraft.getAirlineIcaoCodeDesignator()); this->ui->le_AircraftCombinedType->setText(aircraftIcao.getCombinedType()); } @@ -336,8 +369,8 @@ namespace BlackGui { CGuiAircraftValues values; values.ownCallsign = this->ui->le_Callsign->text().trimmed().toUpper(); - values.ownAircraftIcaoTypeDesignator = this->ui->le_AircraftIcaoDesignator->text().trimmed().toUpper(); - values.ownAircraftIcaoAirline = this->ui->le_AircraftIcaoAirline->text().trimmed().toUpper(); + values.ownAircraftIcaoTypeDesignator = CAircraftIcaoCode::normalizeDesignator(this->ui->le_AircraftIcaoDesignator->text()); + values.ownAircraftIcaoAirline = CAirlineIcaoCode::normalizeDesignator(this->ui->le_AirlineIcaoDesignator->text()); values.ownAircraftCombinedType = this->ui->le_AircraftCombinedType->text().trimmed().toUpper(); values.ownAircraftSimulatorModel = this->ui->le_SimulatorModel->text().trimmed().toUpper(); return values; @@ -434,9 +467,9 @@ namespace BlackGui { this->ui->le_AircraftIcaoDesignator->setText(model.getAircraftIcaoCode().getDesignator()); } - if (!onlyIfEmpty || this->ui->le_AircraftIcaoAirline->text().trimmed().isEmpty()) + if (!onlyIfEmpty || this->ui->le_AirlineIcaoDesignator->text().trimmed().isEmpty()) { - this->ui->le_AircraftIcaoAirline->setText(model.getAirlineIcaoCode().getDesignator()); + this->ui->le_AirlineIcaoDesignator->setText(model.getAirlineIcaoCode().getDesignator()); } if (!onlyIfEmpty || this->ui->le_AircraftCombinedType->text().trimmed().isEmpty()) { @@ -523,5 +556,42 @@ namespace BlackGui CLogMessage(this).validationInfo("Reverse lookup for %1 failed, set data manually") << modelStr; } } + + void CLoginComponent::initCompleters(CEntityFlags::Entity entity) + { + // completers where possible + if (sGui && sGui->getWebDataServices()) + { + //! \todo fill in when airports are ready + + if (entity.testFlag(CEntityFlags::AircraftIcaoEntity) && !ui->le_AircraftIcaoDesignator->completer()) + { + const QStringList aircraftDesignators = sGui->getWebDataServices()->getAircraftIcaoCodes().toCompleterStrings(); + if (!aircraftDesignators.isEmpty()) + { + QCompleter *completer = new QCompleter(aircraftDesignators, this); + QStyledItemDelegate *itemDelegate = new QStyledItemDelegate(completer); + completer->popup()->setItemDelegate(itemDelegate); + ui->le_AircraftIcaoDesignator->setCompleter(completer); + completer->popup()->setObjectName("AircraftCompleter"); + completer->popup()->setMinimumWidth(175); + } + } + + if (entity.testFlag(CEntityFlags::AirlineIcaoEntity) && !ui->le_AirlineIcaoDesignator->completer()) + { + const QStringList airlineDesignators = sGui->getWebDataServices()->getAirlineIcaoCodes().toIcaoDesignatorNameCountryCompleterStrings(); + if (!airlineDesignators.isEmpty()) + { + QCompleter *completer = new QCompleter(airlineDesignators, this); + QStyledItemDelegate *itemDelegate = new QStyledItemDelegate(completer); + completer->popup()->setItemDelegate(itemDelegate); + ui->le_AirlineIcaoDesignator->setCompleter(completer); + completer->popup()->setObjectName("AirlineCompleter"); + completer->popup()->setMinimumWidth(175); + } + } + } + } } // namespace } // namespace diff --git a/src/blackgui/components/logincomponent.h b/src/blackgui/components/logincomponent.h index 2d6102b35..1c2480094 100644 --- a/src/blackgui/components/logincomponent.h +++ b/src/blackgui/components/logincomponent.h @@ -52,6 +52,9 @@ namespace BlackGui Q_OBJECT public: + //! Log categories + static const BlackMisc::CLogCategoryList &getLogCategories(); + //! Constructor explicit CLoginComponent(QWidget *parent = nullptr); @@ -80,7 +83,7 @@ namespace BlackGui void ps_toggleNetworkConnection(); //! VATSIM data file was loaded - void ps_onWebServiceDataRead(int entity, int state, int number); + void ps_onWebServiceDataRead(int entity, int stateInt, int number); //! Validate aircaft bool ps_validateAircraftValues(); @@ -156,6 +159,8 @@ namespace BlackGui //! Set ICAO values void setGuiIcaoValues(const BlackMisc::Simulation::CAircraftModel &model, bool onlyIfEmpty); + void initCompleters(BlackMisc::Network::CEntityFlags::Entity entity); + QScopedPointer ui; bool m_visible = false; //!< is this component selected? const int LogoffIntervalSeconds = 10; diff --git a/src/blackgui/components/logincomponent.ui b/src/blackgui/components/logincomponent.ui index 6b7ca04f6..fcb7b42e8 100644 --- a/src/blackgui/components/logincomponent.ui +++ b/src/blackgui/components/logincomponent.ui @@ -6,8 +6,8 @@ 0 0 - 463 - 443 + 384 + 576 @@ -93,6 +93,30 @@ 6 + + 4 + + + + + + + + + + + + + + + + + + + Id: + + + @@ -100,16 +124,39 @@ - - + + + + + + + + + + + QLineEdit::PasswordEchoOnEdit + + 4 + + e.g. "KLAX" + + + + + + + + + + @@ -131,23 +178,6 @@ - - - - QLineEdit::PasswordEchoOnEdit - - - - - - - Id: - - - - - - @@ -155,30 +185,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - @@ -196,7 +202,7 @@ 3 - 3 + 10 3 @@ -214,14 +220,14 @@ - + Edit - + goto settings @@ -230,6 +236,38 @@ + + + FSD details + + + + 3 + + + 6 + + + 3 + + + 3 + + + + + QFrame::NoFrame + + + QFrame::Plain + + + 0 + + + + + @@ -286,21 +324,15 @@ - + e.g. DLH - - - - - - - 6 + 128 - + e.g. "DLH" @@ -319,7 +351,7 @@ 3 - + e.g. "L2J" @@ -348,18 +380,9 @@ Qt::ImhUppercaseOnly - - - - - - 10 - - - @@ -367,17 +390,11 @@ e.g. B737 - - - - - - - 6 + 128 - + e.g. "B737" @@ -502,6 +519,12 @@ + + + 0 + 80 + + QFrame::StyledPanel @@ -529,21 +552,14 @@ - - - - Qt::Vertical - - - - 20 - 40 - - - - + + + 0 + 0 + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok @@ -577,6 +593,12 @@
blackgui/editors/serverform.h
1 + + BlackGui::Editors::CFsdSetupForm + QFrame +
blackgui/editors/fsdsetupform.h
+ 1 +
tw_Network @@ -588,7 +610,7 @@ le_SimulatorModel le_Callsign le_AircraftIcaoDesignator - le_AircraftIcaoAirline + le_AirlineIcaoDesignator le_AircraftCombinedType comp_OtherServers pb_OtherServersGotoSettings diff --git a/src/blackmisc/aviation/aircrafticaocode.cpp b/src/blackmisc/aviation/aircrafticaocode.cpp index e63c76735..9c35c3016 100644 --- a/src/blackmisc/aviation/aircrafticaocode.cpp +++ b/src/blackmisc/aviation/aircrafticaocode.cpp @@ -490,9 +490,10 @@ namespace BlackMisc return s; } - const QString CAircraftIcaoCode::normalizeDesignator(const QString candidate) + QString CAircraftIcaoCode::normalizeDesignator(const QString candidate) { QString n(candidate.trimmed().toUpper()); + if (n.contains(' ')) { n = n.left(n.indexOf(' ')); } // cutoff as first space if (n.isEmpty()) { return n; } static QThreadStorage tsRegex; diff --git a/src/blackmisc/aviation/aircrafticaocode.h b/src/blackmisc/aviation/aircrafticaocode.h index ec6f78bb9..05af2a611 100644 --- a/src/blackmisc/aviation/aircrafticaocode.h +++ b/src/blackmisc/aviation/aircrafticaocode.h @@ -259,7 +259,7 @@ namespace BlackMisc static const QStringList &getSpecialDesignators(); //! Normalize designator, remove illegal characters - static const QString normalizeDesignator(const QString candidate); + static QString normalizeDesignator(const QString candidate); //! Create relaxed combined codes, e.g "L2J" -> "L3J", ... static QStringList alternativeCombinedCodes(const QString &combinedCode); diff --git a/src/blackmisc/aviation/airlineicaocode.cpp b/src/blackmisc/aviation/airlineicaocode.cpp index 603f1cb2d..9bcc772ea 100644 --- a/src/blackmisc/aviation/airlineicaocode.cpp +++ b/src/blackmisc/aviation/airlineicaocode.cpp @@ -263,6 +263,18 @@ namespace BlackMisc return (regexp.match(airline).hasMatch()); } + QString CAirlineIcaoCode::normalizeDesignator(const QString candidate) + { + QString n(candidate.trimmed().toUpper()); + if (n.contains(' ')) { n = n.left(n.indexOf(' ')); } // cutoff as first space + if (n.isEmpty()) { return n; } + + static QThreadStorage tsRegex; + if (! tsRegex.hasLocalData()) { tsRegex.setLocalData(QRegularExpression("[^a-zA-Z\\d\\s]")); } + const QRegularExpression ®exp = tsRegex.localData(); + return n.remove(regexp); + } + QString CAirlineIcaoCode::getCombinedStringWithKey() const { QString s(getVDesignator()); diff --git a/src/blackmisc/aviation/airlineicaocode.h b/src/blackmisc/aviation/airlineicaocode.h index be0dde74a..0f2c3898a 100644 --- a/src/blackmisc/aviation/airlineicaocode.h +++ b/src/blackmisc/aviation/airlineicaocode.h @@ -180,6 +180,9 @@ namespace BlackMisc //! Valid designator? static bool isValidAirlineDesignator(const QString &airline); + //! Normalize string as airline designator + static QString normalizeDesignator(const QString candidate); + //! From our DB JSON static CAirlineIcaoCode fromDatabaseJson(const QJsonObject &json, const QString &prefix = QString()); diff --git a/src/blackmisc/aviation/airlineicaocodelist.cpp b/src/blackmisc/aviation/airlineicaocodelist.cpp index e0e7c7de6..770e7b7ae 100644 --- a/src/blackmisc/aviation/airlineicaocodelist.cpp +++ b/src/blackmisc/aviation/airlineicaocodelist.cpp @@ -154,6 +154,20 @@ namespace BlackMisc return c; } + QStringList CAirlineIcaoCodeList::toIcaoDesignatorNameCountryCompleterStrings(bool sort) const + { + QStringList c; + for (const CAirlineIcaoCode &icao : *this) + { + if (!icao.hasValidDesignator()) { continue; } + const QString cs(icao.getDesignatorNameCountry()); + if (cs.isEmpty()) { continue; } + c.append(cs); + } + if (sort) { c.sort(); } + return c; + } + QStringList CAirlineIcaoCodeList::toNameCompleterStrings(bool sort) const { QStringList c; diff --git a/src/blackmisc/aviation/airlineicaocodelist.h b/src/blackmisc/aviation/airlineicaocodelist.h index f8d57d7e3..a2756e83c 100644 --- a/src/blackmisc/aviation/airlineicaocodelist.h +++ b/src/blackmisc/aviation/airlineicaocodelist.h @@ -75,6 +75,9 @@ namespace BlackMisc //! String list for completion by ICAO designator QStringList toIcaoDesignatorCompleterStrings(bool combinedString = true, bool sort = true) const; + //! String list for completion by ICAO designator plus Name + QStringList toIcaoDesignatorNameCountryCompleterStrings(bool sort = true) const; + //! String list for completion by name QStringList toNameCompleterStrings(bool sort = true) const;