diff --git a/src/blackmisc/aviation/airlineicaocode.cpp b/src/blackmisc/aviation/airlineicaocode.cpp index 5b5bb3093..10737e0a1 100644 --- a/src/blackmisc/aviation/airlineicaocode.cpp +++ b/src/blackmisc/aviation/airlineicaocode.cpp @@ -9,8 +9,8 @@ #include "airlineicaocode.h" #include "callsign.h" -#include "blackmisc/comparefunctions.h" #include "blackmisc/db/datastoreutility.h" +#include "blackmisc/comparefunctions.h" #include "blackmisc/icons.h" #include "blackmisc/logcategory.h" #include "blackmisc/logcategorylist.h" @@ -75,6 +75,11 @@ namespace BlackMisc return s.trimmed(); } + QString CAirlineIcaoCode::getSimplifiedName() const + { + return BlackMisc::simplifyNameForSearch(this->getName()); + } + bool CAirlineIcaoCode::hasValidCountry() const { return this->m_country.isValid(); @@ -120,6 +125,14 @@ namespace BlackMisc return this->matchesVDesignator(candidate) || this->matchesIataCode(candidate); } + bool CAirlineIcaoCode::isContainedInSimplifiedName(const QString &candidate) const + { + if (candidate.isEmpty() || !this->hasName()) { return false; } + // try unaltered name first (should be faster) + if (this->getName().contains(candidate, Qt::CaseInsensitive)) { return true; } + return this->getSimplifiedName().contains(candidate, Qt::CaseInsensitive); + } + bool CAirlineIcaoCode::hasCompleteData() const { return this->hasValidDesignator() && this->hasValidCountry() && this->hasName(); @@ -361,15 +374,15 @@ namespace BlackMisc return CAirlineIcaoCode(); } - QString designator(json.value(prefix + "designator").toString()); - QString iata(json.value(prefix + "iata").toString()); - QString telephony(json.value(prefix + "callsign").toString()); - QString name(json.value(prefix + "name").toString()); - QString countryIso(json.value(prefix + "country").toString()); - QString countryName(json.value(prefix + "countryname").toString()); - bool va = CDatastoreUtility::dbBoolStringToBool(json.value(prefix + "va").toString()); - bool operating = CDatastoreUtility::dbBoolStringToBool(json.value(prefix + "operating").toString()); - bool military = CDatastoreUtility::dbBoolStringToBool(json.value(prefix + "military").toString()); + const QString designator(json.value(prefix + "designator").toString()); + const QString iata(json.value(prefix + "iata").toString()); + const QString telephony(json.value(prefix + "callsign").toString()); + const QString name(json.value(prefix + "name").toString()); + const QString countryIso(json.value(prefix + "country").toString()); + const QString countryName(json.value(prefix + "countryname").toString()); + const bool va = CDatastoreUtility::dbBoolStringToBool(json.value(prefix + "va").toString()); + const bool operating = CDatastoreUtility::dbBoolStringToBool(json.value(prefix + "operating").toString()); + const bool military = CDatastoreUtility::dbBoolStringToBool(json.value(prefix + "military").toString()); CAirlineIcaoCode code( designator, name, diff --git a/src/blackmisc/aviation/airlineicaocode.h b/src/blackmisc/aviation/airlineicaocode.h index 2f2ad186b..f553cf367 100644 --- a/src/blackmisc/aviation/airlineicaocode.h +++ b/src/blackmisc/aviation/airlineicaocode.h @@ -92,6 +92,9 @@ namespace BlackMisc //! Get name, e.g. "Lufthansa" const QString &getName() const { return this->m_name; } + //! \copydoc BlackMisc::simplifyNameForSearch + QString getSimplifiedName() const; + //! Name plus key, e.g. "Lufthansa (3421)" QString getNameWithKey() const; @@ -146,6 +149,9 @@ namespace BlackMisc //! Matches IATA code or v-designator? bool matchesVDesignatorOrIataCode(const QString &candidate) const; + //! Does simplified name contain the candidate + bool isContainedInSimplifiedName(const QString &candidate) const; + //! Telephony designator? bool hasTelephonyDesignator() const { return !this->m_telephonyDesignator.isEmpty(); } @@ -158,7 +164,7 @@ namespace BlackMisc //! Comined string with key QString getCombinedStringWithKey() const; - //! What is better, the callsign airline code or this code + //! What is better, the callsign airline code or this code. Return the better one. CAirlineIcaoCode thisOrCallsignCode(const CCallsign &callsign) const; //! \copydoc BlackMisc::Mixin::Icon::toIcon diff --git a/src/blackmisc/aviation/airlineicaocodelist.cpp b/src/blackmisc/aviation/airlineicaocodelist.cpp index c0a6f8c37..6b8fd0256 100644 --- a/src/blackmisc/aviation/airlineicaocodelist.cpp +++ b/src/blackmisc/aviation/airlineicaocodelist.cpp @@ -80,6 +80,15 @@ namespace BlackMisc }); } + CAirlineIcaoCodeList CAirlineIcaoCodeList::findBySimplifiedNameContaining(const QString &containedString) const + { + if (containedString.isEmpty()) { return CAirlineIcaoCodeList(); } + return this->findBy([&](const CAirlineIcaoCode & code) + { + return code.isContainedInSimplifiedName(containedString); + }); + } + CAirlineIcaoCodeList CAirlineIcaoCodeList::findByMilitary(bool military) const { return this->findBy([&](const CAirlineIcaoCode & code) diff --git a/src/blackmisc/aviation/airlineicaocodelist.h b/src/blackmisc/aviation/airlineicaocodelist.h index 2b523d882..2f3051742 100644 --- a/src/blackmisc/aviation/airlineicaocodelist.h +++ b/src/blackmisc/aviation/airlineicaocodelist.h @@ -66,6 +66,9 @@ namespace BlackMisc //! Find by country code CAirlineIcaoCodeList findByCountryIsoCode(const QString &isoCode) const; + //! Find if simplified name contains search string + CAirlineIcaoCodeList findBySimplifiedNameContaining(const QString &containedString) const; + //! Find by military flag CAirlineIcaoCodeList findByMilitary(bool military) const; @@ -87,7 +90,6 @@ namespace BlackMisc //! From our DB JSON static CAirlineIcaoCodeList fromDatabaseJson(const QJsonArray &array, bool ignoreIncomplete = true); }; - } //namespace } // namespace diff --git a/src/blackmisc/aviation/livery.cpp b/src/blackmisc/aviation/livery.cpp index 6d916990b..77b0c44fd 100644 --- a/src/blackmisc/aviation/livery.cpp +++ b/src/blackmisc/aviation/livery.cpp @@ -74,6 +74,11 @@ namespace BlackMisc return s; } + bool CLivery::isContainedInSimplifiedAirlineName(const QString &candidate) const + { + return this->getAirlineIcaoCode().isContainedInSimplifiedName(candidate); + } + bool CLivery::setAirlineIcaoCode(const CAirlineIcaoCode &airlineIcao) { if (m_airline == airlineIcao) { return false; } diff --git a/src/blackmisc/aviation/livery.h b/src/blackmisc/aviation/livery.h index ebb2d9d39..969bbefb3 100644 --- a/src/blackmisc/aviation/livery.h +++ b/src/blackmisc/aviation/livery.h @@ -80,6 +80,12 @@ namespace BlackMisc //! Get description. const QString &getDescription() const { return m_description; } + //! Get corresponding airline name + const QString &getAirlineName() const { return this->getAirlineIcaoCode().getName(); } + + //! Does simplified airline name contain the candidate + bool isContainedInSimplifiedAirlineName(const QString &candidate) const; + //! Get fuselage color. const BlackMisc::CRgbColor &getColorFuselage() const { return m_colorFuselage; } diff --git a/src/blackmisc/aviation/liverylist.cpp b/src/blackmisc/aviation/liverylist.cpp index a5e376987..71d9686df 100644 --- a/src/blackmisc/aviation/liverylist.cpp +++ b/src/blackmisc/aviation/liverylist.cpp @@ -37,21 +37,31 @@ namespace BlackMisc return this->findBy(&CLivery::getAirlineIcaoCodeDesignator, i); } - CLivery CLiveryList::findStdLiveryByAirlineIcaoDesignator(const QString &icao) const + CLivery CLiveryList::findStdLiveryByAirlineIcaoVDesignator(const QString &icao) const { QString i(icao.trimmed().toUpper()); if (i.isEmpty()) { return CLivery(); } return this->findFirstByOrDefault([&](const CLivery & livery) { - return livery.getAirlineIcaoCodeDesignator() == icao && - livery.isAirlineStandardLivery(); - + if (!livery.isAirlineStandardLivery()) { return false; } + return livery.getAirlineIcaoCode().matchesVDesignator(i); }); } - CLivery CLiveryList::findStdLiveryByAirlineIcaoDesignator(const CAirlineIcaoCode &icao) const + CLiveryList CLiveryList::findStdLiveriesBySimplifiedAirlineName(const QString &containedString) const { - return this->findStdLiveryByAirlineIcaoDesignator(icao.getDesignator()); + if (containedString.isEmpty()) { return CLiveryList(); } + return this->findBy([&](const CLivery & livery) + { + // keep isAirlineStandardLivery first (faster) + return livery.isAirlineStandardLivery() && + livery.isContainedInSimplifiedAirlineName(containedString); + }); + } + + CLivery CLiveryList::findStdLiveryByAirlineIcaoVDesignator(const CAirlineIcaoCode &icao) const + { + return this->findStdLiveryByAirlineIcaoVDesignator(icao.getVDesignator()); } CLivery CLiveryList::findByCombinedCode(const QString &combinedCode) const @@ -81,6 +91,9 @@ namespace BlackMisc CLivery CLiveryList::smartLiverySelector(const CLivery &liveryPattern) const { + // multiple searches are slow, maybe we can performance optimize this + // in the futuew + // first try on id, that would be perfect if (liveryPattern.hasValidDbKey()) { @@ -97,14 +110,25 @@ namespace BlackMisc if (l.hasCompleteData()) { return l; } } + // by airline if (liveryPattern.hasValidAirlineDesignator()) { const QString icao(liveryPattern.getAirlineIcaoCodeDesignator()); - const CLivery l(this->findStdLiveryByAirlineIcaoDesignator(icao)); + const CLivery l(this->findStdLiveryByAirlineIcaoVDesignator(icao)); if (l.hasCompleteData()) { return l; } } + + // lenient search by name contained (slow) + if (liveryPattern.getAirlineIcaoCode().hasName()) + { + const QString search(liveryPattern.getAirlineIcaoCode().getSimplifiedName()); + const CLiveryList liveries(this->findStdLiveriesBySimplifiedAirlineName(search)); + if (!liveries.isEmpty()) + { + return liveries.front(); + } + } return CLivery(); } - } // namespace } // namespace diff --git a/src/blackmisc/aviation/liverylist.h b/src/blackmisc/aviation/liverylist.h index f25fe7aaa..77b669469 100644 --- a/src/blackmisc/aviation/liverylist.h +++ b/src/blackmisc/aviation/liverylist.h @@ -47,10 +47,13 @@ namespace BlackMisc CLiveryList findByAirlineIcaoDesignator(const QString &icao) const; //! Find livery by airline - CLivery findStdLiveryByAirlineIcaoDesignator(const QString &icao) const; + CLivery findStdLiveryByAirlineIcaoVDesignator(const QString &icao) const; //! Find livery by airline - CLivery findStdLiveryByAirlineIcaoDesignator(const CAirlineIcaoCode &icao) const; + CLivery findStdLiveryByAirlineIcaoVDesignator(const CAirlineIcaoCode &icao) const; + + //! By simplified name + CLiveryList findStdLiveriesBySimplifiedAirlineName(const QString &containedString) const; //! Find livery by combined code CLivery findByCombinedCode(const QString &combinedCode) const; @@ -63,7 +66,6 @@ namespace BlackMisc //! Find CLivery smartLiverySelector(const CLivery &liveryPattern) const; - }; } //namespace } // namespace diff --git a/src/blackmisc/country.cpp b/src/blackmisc/country.cpp index 6ab339362..8436cb6cf 100644 --- a/src/blackmisc/country.cpp +++ b/src/blackmisc/country.cpp @@ -218,6 +218,7 @@ namespace BlackMisc const QString iso3(json.value(prefix + "iso3").toString()); const QString historic(json.value(prefix + "historic").toString()); CCountry country(iso, name); + country.setLoadedFromDb(true); country.setAlias1(alias1); country.setAlias2(alias2); country.setIso3Code(iso3); diff --git a/src/blackmisc/country.h b/src/blackmisc/country.h index 81bb627c8..5f1dd9a1a 100644 --- a/src/blackmisc/country.h +++ b/src/blackmisc/country.h @@ -149,7 +149,8 @@ namespace BlackMisc BLACK_METACLASS( CCountry, - BLACK_METAMEMBER(dbKey), + BLACK_METAMEMBER(dbKey, 0, CaseInsensitiveComparison), + BLACK_METAMEMBER(loadedFromDb), BLACK_METAMEMBER(timestampMSecsSinceEpoch), BLACK_METAMEMBER(iso3), BLACK_METAMEMBER(name), diff --git a/src/blackmisc/db/datastore.cpp b/src/blackmisc/db/datastore.cpp index 41d85e0ce..18b5219f3 100644 --- a/src/blackmisc/db/datastore.cpp +++ b/src/blackmisc/db/datastore.cpp @@ -41,6 +41,18 @@ namespace BlackMisc this->m_dbKey = k; } + bool IDatastoreObjectWithIntegerKey::isLoadedFromDb() const + { + return this->hasValidDbKey(); + } + + bool IDatastoreObjectWithIntegerKey::matchesDbKeyState(Db::DbKeyStateFilter filter) const + { + if (filter == All) { return true; } + const bool validKey = this->hasValidDbKey(); + return (validKey && filter.testFlag(Valid)) || (!validKey && filter.testFlag(Invalid)); + } + const CIcon &IDatastoreObjectWithIntegerKey::toDatabaseIcon() const { static const CIcon empty; @@ -131,6 +143,12 @@ namespace BlackMisc return null; } + bool IDatastoreObjectWithStringKey::matchesDbKeyState(Db::DbKeyStateFilter filter) const + { + if (filter == All) { return true; } + return this->hasValidDbKey() && filter.testFlag(Valid); + } + const CIcon &IDatastoreObjectWithStringKey::toDatabaseIcon() const { static const CIcon empty; @@ -159,6 +177,7 @@ namespace BlackMisc { case IndexDbStringKey: return CVariant::from(this->m_dbKey); case IndexDatabaseIcon: return CVariant::from(this->toDatabaseIcon()); + case IndexIsLoadedFromDb: return CVariant::from(this->m_loadedFromDb); default: break; } @@ -174,6 +193,9 @@ namespace BlackMisc case IndexDbStringKey: this->m_dbKey = variant.value(); break; + case IndexIsLoadedFromDb: + this->m_loadedFromDb = variant.toBool(); + break; default: break; } diff --git a/src/blackmisc/db/datastore.h b/src/blackmisc/db/datastore.h index 5c9649548..2c0ea63e6 100644 --- a/src/blackmisc/db/datastore.h +++ b/src/blackmisc/db/datastore.h @@ -25,9 +25,20 @@ namespace BlackMisc { class CIcon; - namespace Db { + //! State of key (in DB, ...?) + enum DbKeyState + { + Undefined = 0, + Valid = 1 << 0, + Invalid = 1 << 1, + All = Valid | Invalid + }; + + //! Supposed to be used only in filter operations + Q_DECLARE_FLAGS(DbKeyStateFilter, DbKeyState) + /*! * Class from which a derived class can inherit datastore-related functions. */ @@ -62,6 +73,13 @@ namespace BlackMisc //! Has valid DB key bool hasValidDbKey() const { return m_dbKey >= 0; } + //! Loaded from DB + //! \remarks here not really needed, but added to have similar signature as IDatastoreObjectWithStringKey + bool isLoadedFromDb() const; + + //! Matches filter? + bool matchesDbKeyState(Db::DbKeyStateFilter filter) const; + //! Database icon if this has valid key, otherwise empty const CIcon &toDatabaseIcon() const; @@ -109,6 +127,7 @@ namespace BlackMisc enum ColumnIndex { IndexDbStringKey = CPropertyIndex::GlobalIndexIDatastoreString, + IndexIsLoadedFromDb, IndexDatabaseIcon }; @@ -124,6 +143,15 @@ namespace BlackMisc //! Has valid DB key bool hasValidDbKey() const { return !m_dbKey.isEmpty(); } + //! Loaded from DB + bool isLoadedFromDb() const { return m_loadedFromDb; } + + //! Mark as loaded from DB + void setLoadedFromDb(bool loaded) { m_loadedFromDb = loaded; } + + //! Matches filter? + bool matchesDbKeyState(Db::DbKeyStateFilter filter) const; + //! Database icon if this has valid key, otherwise empty const CIcon &toDatabaseIcon() const; @@ -155,11 +183,15 @@ namespace BlackMisc //! Can given index be handled static bool canHandleIndex(const BlackMisc::CPropertyIndex &index); - QString m_dbKey; //!< key + QString m_dbKey; //!< key + bool m_loadedFromDb = false; //!< as we have no artificial key, it can happen key is set, but not loaded from DB }; } // ns } // ns +Q_DECLARE_METATYPE(BlackMisc::Db::DbKeyState) +Q_DECLARE_METATYPE(BlackMisc::Db::DbKeyStateFilter) +Q_DECLARE_OPERATORS_FOR_FLAGS(BlackMisc::Db::DbKeyStateFilter) Q_DECLARE_INTERFACE(BlackMisc::Db::IDatastoreObjectWithIntegerKey, "org.swift-project.blackmisc.db.idatastoreobjectwithintegerkey") Q_DECLARE_INTERFACE(BlackMisc::Db::IDatastoreObjectWithStringKey, "org.swift-project.blackmisc.db.idatastoreobjectwithstringkey") diff --git a/src/blackmisc/simulation/aircraftmodel.cpp b/src/blackmisc/simulation/aircraftmodel.cpp index 7976660ad..befd9dc97 100644 --- a/src/blackmisc/simulation/aircraftmodel.cpp +++ b/src/blackmisc/simulation/aircraftmodel.cpp @@ -372,6 +372,7 @@ namespace BlackMisc bool CAircraftModel::matchesMode(ModelModeFilter mode) const { + if (mode == All) { return true; } return (mode & this->m_modelMode) > 0; } diff --git a/src/blackmisc/simulation/aircraftmodellist.cpp b/src/blackmisc/simulation/aircraftmodellist.cpp index 4d03d3751..9ad12a7c5 100644 --- a/src/blackmisc/simulation/aircraftmodellist.cpp +++ b/src/blackmisc/simulation/aircraftmodellist.cpp @@ -365,7 +365,7 @@ namespace BlackMisc return addOrReplaceList.size(); } CAircraftModelList newModels(*this); - const QStringList keys(addOrReplaceList.getModelStrings(false)); + const QStringList keys(addOrReplaceList.getModelStringList(false)); newModels.removeModelsWithString(keys, sensitivity); int removed = newModels.size(); // size after removing newModels.push_back(addOrReplaceList); @@ -398,7 +398,7 @@ namespace BlackMisc }); } - QStringList CAircraftModelList::getModelStrings(bool sort) const + QStringList CAircraftModelList::getModelStringList(bool sort) const { QStringList ms; for (const CAircraftModel &model : (*this)) @@ -410,6 +410,17 @@ namespace BlackMisc return ms; } + QSet CAircraftModelList::getModelStringSet() const + { + QSet ms; + for (const CAircraftModel &model : (*this)) + { + if (!model.hasModelString()) { continue; } + ms.insert(model.getModelString()); + } + return ms; + } + CCountPerSimulator CAircraftModelList::countPerSimulator() const { CCountPerSimulator count; diff --git a/src/blackmisc/simulation/aircraftmodellist.h b/src/blackmisc/simulation/aircraftmodellist.h index 6f60d918b..1b3fcdcba 100644 --- a/src/blackmisc/simulation/aircraftmodellist.h +++ b/src/blackmisc/simulation/aircraftmodellist.h @@ -166,7 +166,10 @@ namespace BlackMisc int replaceOrAddModelsWithString(const CAircraftModelList &addOrReplaceList, Qt::CaseSensitivity sensitivity); //! Model strings - QStringList getModelStrings(bool sort = true) const; + QStringList getModelStringList(bool sort = true) const; + + //! Model strings as set + QSet getModelStringSet() const; //! Simulator counts CCountPerSimulator countPerSimulator() const; @@ -204,9 +207,8 @@ namespace BlackMisc //! To database JSON QString toDatabaseJsonString(QJsonDocument::JsonFormat format = QJsonDocument::Compact) const; }; - - } //namespace -} // namespace + } // ns +} // ns Q_DECLARE_METATYPE(BlackMisc::Simulation::CAircraftModelList) Q_DECLARE_METATYPE(BlackMisc::CCollection) diff --git a/src/blackmisc/simulation/distributor.cpp b/src/blackmisc/simulation/distributor.cpp index e5525ed46..734474fde 100644 --- a/src/blackmisc/simulation/distributor.cpp +++ b/src/blackmisc/simulation/distributor.cpp @@ -178,6 +178,7 @@ namespace BlackMisc Q_ASSERT_X(!description.isEmpty(), Q_FUNC_INFO, "Missing description"); CDistributor distributor("", description, alias1, alias2, simulator); distributor.setKeyAndTimestampFromDatabaseJson(json, prefix); + distributor.setLoadedFromDb(true); return distributor; } } // namespace diff --git a/src/blackmisc/simulation/distributor.h b/src/blackmisc/simulation/distributor.h index eb7615ba0..89e9ffb31 100644 --- a/src/blackmisc/simulation/distributor.h +++ b/src/blackmisc/simulation/distributor.h @@ -130,6 +130,7 @@ namespace BlackMisc BLACK_METACLASS( CDistributor, BLACK_METAMEMBER(dbKey, 0, CaseInsensitiveComparison), + BLACK_METAMEMBER(loadedFromDb), BLACK_METAMEMBER(timestampMSecsSinceEpoch), BLACK_METAMEMBER(order), BLACK_METAMEMBER(description), diff --git a/src/blackmisc/simulation/distributorlist.cpp b/src/blackmisc/simulation/distributorlist.cpp index 232038414..dc47b1b81 100644 --- a/src/blackmisc/simulation/distributorlist.cpp +++ b/src/blackmisc/simulation/distributorlist.cpp @@ -7,7 +7,9 @@ * contained in the LICENSE file. */ -#include "blackmisc/simulation/distributorlist.h" +#include "distributorlist.h" +#include "simulatorinfo.h" +#include "aircraftmodel.h" #include "blackmisc/metaclassprivate.h" #include @@ -32,20 +34,40 @@ namespace BlackMisc return CDistributor(); } - CDistributor CDistributorList::smartDistributorSelector(const CDistributor &distributorPattern) const + CDistributor CDistributorList::findByModelData(const CAircraftModel &model) const { - if (distributorPattern.hasValidDbKey()) + // some stuipd hardcoded resolutions + if (model.getDistributor().hasValidDbKey()) { return model.getDistributor(); } + if (model.getModelString().startsWith("WOA", Qt::CaseInsensitive)) { return this->findByKeyOrAlias("WOAI"); } + if (model.getDescription().contains("WOA", Qt::CaseInsensitive)) { return this->findByKeyOrAlias("WOAI"); } + if (model.getDescription().contains("IVAO", Qt::CaseInsensitive)) { return this->findByKeyOrAlias("IVAO"); } + return CDistributor(); + } + + CDistributor CDistributorList::smartDistributorSelector(const CDistributor &distributor) const + { + // key is not necessarily a DB key, so use complete data, happens when key is set from raw data + if (distributor.isLoadedFromDb()) { return distributor; } + if (distributor.hasValidDbKey()) { - QString k(distributorPattern.getDbKey()); - CDistributor d(this->findByKey(k)); + const QString key(distributor.getDbKey()); + CDistributor d(this->findByKey(key)); if (d.hasCompleteData()) { return d; } // more lenient search - return this->findByKeyOrAlias(k); + return this->findByKeyOrAlias(key); } return CDistributor(); } + CDistributor CDistributorList::smartDistributorSelector(const CDistributor &distributorPattern, const CAircraftModel &model) const + { + const CDistributor d = this->smartDistributorSelector(distributorPattern); + // key is not necessarily a DB key, so use complete data, happens when key is set from raw data + if (d.hasCompleteData()) { return d; } + return this->findByModelData(model); + } + bool CDistributorList::matchesAnyKeyOrAlias(const QString &keyOrAlias) const { for (const CDistributor &distributor : (*this)) diff --git a/src/blackmisc/simulation/distributorlist.h b/src/blackmisc/simulation/distributorlist.h index f20b8ac04..c7110b063 100644 --- a/src/blackmisc/simulation/distributorlist.h +++ b/src/blackmisc/simulation/distributorlist.h @@ -18,7 +18,6 @@ #include "blackmisc/orderablelist.h" #include "blackmisc/sequence.h" #include "blackmisc/simulation/distributor.h" -#include "blackmisc/simulation/simulatorinfo.h" #include "blackmisc/variant.h" #include @@ -29,6 +28,8 @@ namespace BlackMisc { namespace Simulation { + class CSimulatorModel; + //! Value object encapsulating a list of distributors. class BLACKMISC_EXPORT CDistributorList : public BlackMisc::CSequence, @@ -48,9 +49,16 @@ namespace BlackMisc //! Find by id or alias CDistributor findByKeyOrAlias(const QString &keyOrAlias) const; + //! Find by model string + //! \remark model strings may have a pattern which makes it impossible to find the distributor + CDistributor findByModelData(const CAircraftModel &model) const; + //! Best match by given pattern CDistributor smartDistributorSelector(const CDistributor &distributorPattern) const; + //! Best match by given pattern + CDistributor smartDistributorSelector(const CDistributor &distributorPattern, const CAircraftModel &model) const; + //! At least is matching key or alias bool matchesAnyKeyOrAlias(const QString &keyOrAlias) const; @@ -58,7 +66,7 @@ namespace BlackMisc QStringList getDbKeysAndAliases(bool sort) const; //! Find for given simulator - CDistributorList matchesSimulator(const BlackMisc::Simulation::CSimulatorInfo &simulator) const; + CDistributorList matchesSimulator(const CSimulatorInfo &simulator) const; }; } //namespace } // namespace diff --git a/src/blackmisc/stringutils.cpp b/src/blackmisc/stringutils.cpp index a4cccf2ac..0e362c6e9 100644 --- a/src/blackmisc/stringutils.cpp +++ b/src/blackmisc/stringutils.cpp @@ -12,6 +12,7 @@ #include "stringutils.h" #include #include +#include namespace BlackMisc { @@ -162,6 +163,13 @@ namespace BlackMisc { return c1.length() == c2.length() && c1.startsWith(c2, Qt::CaseInsensitive); } + + QString simplifyNameForSearch(const QString &name) + { + static const QRegularExpression reg("[^A-Z]"); + const QString r = name.toUpper().remove(reg); + return r; + } } //! \endcond diff --git a/src/blackmisc/stringutils.h b/src/blackmisc/stringutils.h index 12f9c6f9b..5423b8d12 100644 --- a/src/blackmisc/stringutils.h +++ b/src/blackmisc/stringutils.h @@ -78,6 +78,9 @@ namespace BlackMisc //! Case insensitive string compare BLACKMISC_EXPORT bool caseInsensitiveStringCompare(const QString &c1, const QString &c2); + //! Get a simplified upper case name for searching by removing all characters except A-Z + BLACKMISC_EXPORT QString simplifyNameForSearch(const QString &name); + namespace Mixin { /*!