diff --git a/src/blackmisc/aviation/aircrafticaocode.cpp b/src/blackmisc/aviation/aircrafticaocode.cpp index 366b2128e..707c71617 100644 --- a/src/blackmisc/aviation/aircrafticaocode.cpp +++ b/src/blackmisc/aviation/aircrafticaocode.cpp @@ -149,6 +149,31 @@ namespace BlackMisc return c; } + bool CAircraftIcaoCode::matchesCombinedCode(const QString &combinedCode) const + { + const QString cc(combinedCode.toUpper().trimmed().replace(' ', '*').replace('-', '*')); + if (combinedCode.length() != 3) { return false; } + if (cc == this->getCombinedType()) { return true; } + + const bool wildcard = cc.contains('*'); + if (!wildcard) { return false; } + QChar at = cc.at(0); + QChar c = cc.at(1); + QChar et = cc.at(2); + if (at != '*') + { + const QString cat = getAircraftType(); + if (cat.isEmpty() || cat.at(0) != at) { return false; } + } + if (c != '*') + { + if (getEngineCount() != c.digitValue()) { return false; } + } + if (et == '*') { return true; } + const QString cet = getEngineType(); + return cet.length() == 1 && cet.at(0) == et; + } + QString CAircraftIcaoCode::getDesignatorManufacturer() const { QString d(getDesignator()); diff --git a/src/blackmisc/aviation/aircrafticaocode.h b/src/blackmisc/aviation/aircrafticaocode.h index 6048dda3c..67a936e43 100644 --- a/src/blackmisc/aviation/aircrafticaocode.h +++ b/src/blackmisc/aviation/aircrafticaocode.h @@ -128,6 +128,10 @@ namespace BlackMisc //! Get model description, e.g. "A-330-200" const QString &getModelDescription() const { return m_modelDescription; } + //! Matches given combined code + //! \remark * can be used as wildcard, e.g. L*J, L** + bool matchesCombinedCode(const QString &combinedCode) const; + //! Designator + Manufacturer QString getDesignatorManufacturer() const; diff --git a/src/blackmisc/aviation/aircrafticaocodelist.cpp b/src/blackmisc/aviation/aircrafticaocodelist.cpp index 2983a5548..5ae029ae0 100644 --- a/src/blackmisc/aviation/aircrafticaocodelist.cpp +++ b/src/blackmisc/aviation/aircrafticaocodelist.cpp @@ -96,21 +96,42 @@ namespace BlackMisc this->sortBy(&CAircraftIcaoCode::getRank); } - QStringList CAircraftIcaoCodeList::toCompleterStrings(bool withIataCodes, bool withFamily) const + void CAircraftIcaoCodeList::sortByDesignatorAndRank() + { + this->sortBy(&CAircraftIcaoCode::getDesignator, &CAircraftIcaoCode::getRank); + } + + QStringList CAircraftIcaoCodeList::toCompleterStrings(bool withIataCodes, bool withFamily, bool sort) const { QStringList c; - for (const CAircraftIcaoCode &icao : *this) + CAircraftIcaoCodeList icaos(*this); + if (sort) { icaos.sortByDesignatorAndRank(); } + + // 3 steps to get a proper sort order + for (const CAircraftIcaoCode &icao : as_const(icaos)) { c.append(icao.getCombinedIcaoStringWithKey()); - if (withIataCodes && icao.hasIataCode() && !icao.isIataSameAsDesignator()) - { - c.append(icao.getCombinedIataStringWithKey()); - } - if (withFamily && icao.hasFamily() && !icao.isFamilySameAsDesignator()) + } + + if (withFamily) + { + icaos = this->findWithFamily(true); + for (const CAircraftIcaoCode &icao : as_const(icaos)) { c.append(icao.getCombinedFamilyStringWithKey()); } } + + if (withIataCodes) + { + icaos = icaos.findWithIataCode(true); + if (sort) { icaos.sortBy(&CAircraftIcaoCode::getIataCode, &CAircraftIcaoCode::getRank); } + for (const CAircraftIcaoCode &icao : as_const(icaos)) + { + c.append(icao.getCombinedIataStringWithKey()); + } + } + return c; } diff --git a/src/blackmisc/aviation/aircrafticaocodelist.h b/src/blackmisc/aviation/aircrafticaocodelist.h index 90b419f2e..f7349c22b 100644 --- a/src/blackmisc/aviation/aircrafticaocodelist.h +++ b/src/blackmisc/aviation/aircrafticaocodelist.h @@ -69,7 +69,7 @@ namespace BlackMisc void sortByRank(); //! For selection completion - QStringList toCompleterStrings(bool withIataCodes = false, bool withFamily = false) const; + QStringList toCompleterStrings(bool withIataCodes = false, bool withFamily = false, bool sort = true) const; //! All ICAO codes, no duplicates QStringList allIcaoCodes(bool noUnspecified = true) const; diff --git a/src/blackmisc/aviation/airlineicaocodelist.cpp b/src/blackmisc/aviation/airlineicaocodelist.cpp index ef03f5521..473154597 100644 --- a/src/blackmisc/aviation/airlineicaocodelist.cpp +++ b/src/blackmisc/aviation/airlineicaocodelist.cpp @@ -123,20 +123,30 @@ namespace BlackMisc return codes; } - QStringList CAirlineIcaoCodeList::toIcaoDesignatorCompleterStrings() const + QStringList CAirlineIcaoCodeList::toIcaoDesignatorCompleterStrings(bool combinedString, bool sort) const { QStringList c; for (const CAirlineIcaoCode &icao : *this) { - if (!icao.hasValidDbKey()) { continue; } - const QString cs(icao.getCombinedStringWithKey()); - if (cs.isEmpty()) { continue; } - c.append(cs); + if (combinedString) + { + if (!icao.hasValidDbKey()) { continue; } + const QString cs(icao.getCombinedStringWithKey()); + if (cs.isEmpty()) { continue; } + c.append(cs); + } + else + { + const QString d(icao.getDesignator()); + if (c.contains(d)) { continue; } + c.append(d); + } } + if (sort) { c.sort(); } return c; } - QStringList CAirlineIcaoCodeList::toNameCompleterStrings() const + QStringList CAirlineIcaoCodeList::toNameCompleterStrings(bool sort) const { QStringList c; for (const CAirlineIcaoCode &icao : *this) @@ -146,6 +156,7 @@ namespace BlackMisc if (cs.isEmpty()) { continue; } c.append(cs); } + if (sort) { c.sort(); } return c; } } // namespace diff --git a/src/blackmisc/aviation/airlineicaocodelist.h b/src/blackmisc/aviation/airlineicaocodelist.h index 15cf5ba66..a591a8f7b 100644 --- a/src/blackmisc/aviation/airlineicaocodelist.h +++ b/src/blackmisc/aviation/airlineicaocodelist.h @@ -66,10 +66,10 @@ namespace BlackMisc CAirlineIcaoCode smartAirlineIcaoSelector(const CAirlineIcaoCode &icaoPattern) const; //! String list for completion by ICAO designator - QStringList toIcaoDesignatorCompleterStrings() const; + QStringList toIcaoDesignatorCompleterStrings(bool combinedString = true, bool sort = true) const; //! String list for completion by name - QStringList toNameCompleterStrings() const; + QStringList toNameCompleterStrings(bool sort = true) const; //! From our DB JSON static CAirlineIcaoCodeList fromDatabaseJson(const QJsonArray &array, bool ignoreIncomplete = true); diff --git a/src/blackmisc/aviation/livery.h b/src/blackmisc/aviation/livery.h index 359692aff..376d0a84f 100644 --- a/src/blackmisc/aviation/livery.h +++ b/src/blackmisc/aviation/livery.h @@ -151,19 +151,19 @@ namespace BlackMisc //! Valid combined code string? static bool isValidCombinedCode(const QString &candidate); - //! Standard livery marker + //! Standard livery marker string static const QString &standardLiveryMarker(); //! Color livery marker static const QString &colorLiveryMarker(); private: - CAirlineIcaoCode m_airline; //!< corresponding airline, if any - QString m_combinedCode; //!< livery code and pseudo airline ICAO code - QString m_description; //!< describes the livery + CAirlineIcaoCode m_airline; //!< corresponding airline, if any + QString m_combinedCode; //!< livery code and pseudo airline ICAO code + QString m_description; //!< describes the livery BlackMisc::CRgbColor m_colorFuselage; //! color of fuselage BlackMisc::CRgbColor m_colorTail; //! color of tail - bool m_military = false; //! Military livery? + bool m_military = false; //! Military livery? BLACK_METACLASS( CLivery, diff --git a/src/blackmisc/simulation/aircraftmodellist.cpp b/src/blackmisc/simulation/aircraftmodellist.cpp index f236da087..5d522ab53 100644 --- a/src/blackmisc/simulation/aircraftmodellist.cpp +++ b/src/blackmisc/simulation/aircraftmodellist.cpp @@ -52,6 +52,7 @@ namespace BlackMisc CAircraftModel CAircraftModelList::findFirstByModelStringOrDefault(const QString &modelString, Qt::CaseSensitivity sensitivity) const { + if (modelString.isEmpty()) { return CAircraftModel(); } return this->findFirstByOrDefault([ = ](const CAircraftModel & model) { return model.matchesModelString(modelString, sensitivity); @@ -94,6 +95,17 @@ namespace BlackMisc }); } + CAircraftModelList CAircraftModelList::findByLiveryCode(const CLivery &livery) const + { + if (!livery.hasCombinedCode()) { return CAircraftModelList(); } + const QString code(livery.getCombinedCode()); + return this->findBy([ = ](const CAircraftModel & model) + { + if (!model.getLivery().hasCombinedCode()) return false; + return model.getLivery().getCombinedCode() == code; + }); + } + CAircraftModelList CAircraftModelList::findWithFileName() const { return this->findBy([ = ](const CAircraftModel & model) @@ -127,9 +139,65 @@ namespace BlackMisc }); } + CAircraftModelList CAircraftModelList::findByManunfacturer(const QString &manufacturer) const + { + if (manufacturer.isEmpty()) { return CAircraftModelList(); } + const QString m(manufacturer.toUpper().trimmed()); + return this->findBy([ = ](const CAircraftModel & model) + { + return model.getAircraftIcaoCode().getManufacturer() == m; + }); + } + + CAircraftModelList CAircraftModelList::findByFamily(const QString &family) const + { + if (family.isEmpty()) { return CAircraftModelList(); } + const QString f(family.toUpper().trimmed()); + return this->findBy([ = ](const CAircraftModel & model) + { + const CAircraftIcaoCode icao(model.getAircraftIcaoCode()); + if (!icao.hasFamily()) { return false; } + return icao.getFamily() == f; + }); + } + + CAircraftModelList CAircraftModelList::findByCombinedCode(const QString &combinedCode) const + { + const QString cc(combinedCode.trimmed().toUpper()); + if (combinedCode.length() != 3) { return CAircraftModelList(); } + return this->findBy([ = ](const CAircraftModel & model) + { + const CAircraftIcaoCode icao(model.getAircraftIcaoCode()); + return icao.matchesCombinedCode(cc); + }); + } + + CAircraftModelList CAircraftModelList::findByMilitaryFlag(bool military) const + { + return this->findBy([ = ](const CAircraftModel & model) + { + return (model.isMilitary() == military); + }); + } + + QString CAircraftModelList::designatorToFamily(const CAircraftIcaoCode &aircraftIcaoCode) const + { + if (aircraftIcaoCode.hasFamily()) { return aircraftIcaoCode.getFamily(); } + for (const CAircraftModel &model : (*this)) + { + const CAircraftIcaoCode icao(model.getAircraftIcaoCode()); + if (!icao.hasFamily()) continue; + if (icao.matchesDesignator(aircraftIcaoCode.getDesignator())) + { + return icao.getFamily(); + } + } + return QString(); + } + CAircraftModelList CAircraftModelList::matchesSimulator(const CSimulatorInfo &simulator) const { - return this->findBy([ = ](const CAircraftModel &model) + return this->findBy([ = ](const CAircraftModel & model) { return model.matchesSimulator(simulator); }); @@ -364,6 +432,17 @@ namespace BlackMisc } } + QStringList CAircraftModelList::toCompleterStrings(bool sorted) const + { + QStringList c; + for (const CAircraftModel &model : *this) + { + c.append(model.getModelString()); + } + if (sorted) { c.sort(); } + return c; + } + CStatusMessageList CAircraftModelList::validateForPublishing() const { CAircraftModelList invalidModels; diff --git a/src/blackmisc/simulation/aircraftmodellist.h b/src/blackmisc/simulation/aircraftmodellist.h index 0105f2744..80d9bdef2 100644 --- a/src/blackmisc/simulation/aircraftmodellist.h +++ b/src/blackmisc/simulation/aircraftmodellist.h @@ -66,6 +66,9 @@ namespace BlackMisc //! Find by model string CAircraftModelList findByAircraftDesignatorAndLiveryCombinedCode(const QString &aircraftDesignator, const QString &combinedCode) const; + //! Find by livery code + CAircraftModelList findByLiveryCode(const BlackMisc::Aviation::CLivery &livery) const; + //! With file name CAircraftModelList findWithFileName() const; @@ -81,6 +84,21 @@ namespace BlackMisc //! Models with a known aircraft ICAO code set CAircraftModelList findWithKnownAircraftDesignator() const; + //! Find by manufacturer + CAircraftModelList findByManunfacturer(const QString &manufacturer) const; + + //! Models with aircraft family + CAircraftModelList findByFamily(const QString &family) const; + + //! Find by combined code, wildcards possible e.g. L*P, *2J + CAircraftModelList findByCombinedCode(const QString &combinedCode) const; + + //! Find by military flag + CAircraftModelList findByMilitaryFlag(bool military) const; + + //! Take a designator and find its family + QString designatorToFamily(const BlackMisc::Aviation::CAircraftIcaoCode &aircraftIcaoCode) const; + //! Find for given simulator CAircraftModelList matchesSimulator(const BlackMisc::Simulation::CSimulatorInfo &simulator) const; @@ -135,6 +153,9 @@ namespace BlackMisc //! Update livery void updateLivery(const BlackMisc::Aviation::CLivery &livery); + //! Completer strings + QStringList toCompleterStrings(bool sorted = true) const; + //! Validate for publishing CStatusMessageList validateForPublishing() const; diff --git a/src/blackmisc/simulation/distributorlist.cpp b/src/blackmisc/simulation/distributorlist.cpp index c6ce43b46..3c864820c 100644 --- a/src/blackmisc/simulation/distributorlist.cpp +++ b/src/blackmisc/simulation/distributorlist.cpp @@ -53,7 +53,7 @@ namespace BlackMisc return false; } - QStringList CDistributorList::getDbKeysAndAliases() const + QStringList CDistributorList::getDbKeysAndAliases(bool sort) const { if (this->isEmpty()) { return QStringList(); } QStringList sl; @@ -70,6 +70,7 @@ namespace BlackMisc sl.append(d.getAlias2()); } } + if (sort) { sl.sort(); } return sl; } diff --git a/src/blackmisc/simulation/distributorlist.h b/src/blackmisc/simulation/distributorlist.h index 54d643397..608003f44 100644 --- a/src/blackmisc/simulation/distributorlist.h +++ b/src/blackmisc/simulation/distributorlist.h @@ -50,7 +50,7 @@ namespace BlackMisc bool matchesAnyKeyOrAlias(const QString &keyOrAlias) const; //! All DB keys and aliases - QStringList getDbKeysAndAliases() const; + QStringList getDbKeysAndAliases(bool sort) const; }; } //namespace } // namespace