diff --git a/src/blackmisc/simulation/aircraftmodel.cpp b/src/blackmisc/simulation/aircraftmodel.cpp index a82eaa277..2aa9b6b31 100644 --- a/src/blackmisc/simulation/aircraftmodel.cpp +++ b/src/blackmisc/simulation/aircraftmodel.cpp @@ -132,10 +132,12 @@ namespace BlackMisc }); } - QString CAircraftModel::asHtmlSummary() const + QString CAircraftModel::asHtmlSummary(const QString &separator) const { - const QString html = "Model: %1
Aircraft ICAO: %2
Livery: %3"; - return html.arg(this->getModelStringAndDbKey(), this->getAircraftIcaoCode().asHtmlSummary(), this->getLivery().asHtmlSummary()); + const QString html = "Model: %1%2Aircraft ICAO: %3%4Livery: %5"; + return html.arg(this->getModelStringAndDbKey(), separator, + this->getAircraftIcaoCode().asHtmlSummary(), separator, + this->getLivery().asHtmlSummary()); } bool CAircraftModel::canInitializeFromFsd() const diff --git a/src/blackmisc/simulation/aircraftmodel.h b/src/blackmisc/simulation/aircraftmodel.h index b43554fd9..69ed381bf 100644 --- a/src/blackmisc/simulation/aircraftmodel.h +++ b/src/blackmisc/simulation/aircraftmodel.h @@ -180,6 +180,9 @@ namespace BlackMisc //! Airline ICAO code designator const QString &getAirlineIcaoCodeDesignator() const { return this->m_livery.getAirlineIcaoCode().getDesignator(); } + //! Airline ICAO code designator + const QString getAirlineIcaoCodeVDesignator() const { return this->m_livery.getAirlineIcaoCode().getVDesignator(); } + //! Set aircraft ICAO code bool setAircraftIcaoCode(const BlackMisc::Aviation::CAircraftIcaoCode &aircraftIcaoCode); @@ -377,7 +380,7 @@ namespace BlackMisc QString toDatabaseJsonString(QJsonDocument::JsonFormat format = QJsonDocument::Compact) const; //! As a brief HTML summary (e.g. used in tooltips) - QString asHtmlSummary() const; + QString asHtmlSummary(const QString &separator = "
") const; //! Model type static QString modelTypeToString(ModelType type); diff --git a/src/blackmisc/simulation/aircraftmodellist.cpp b/src/blackmisc/simulation/aircraftmodellist.cpp index 78d129247..549d6390c 100644 --- a/src/blackmisc/simulation/aircraftmodellist.cpp +++ b/src/blackmisc/simulation/aircraftmodellist.cpp @@ -503,6 +503,39 @@ namespace BlackMisc return distributors; } + QSet CAircraftModelList::getAircraftDesignators() const + { + QSet designators; + for (const CAircraftModel &model : *this) + { + if (!model.hasAircraftDesignator()) { continue; } + designators.insert(model.getAircraftIcaoCodeDesignator()); + } + return designators; + } + + QSet CAircraftModelList::getAirlineDesignators() const + { + QSet designators; + for (const CAircraftModel &model : *this) + { + if (!model.hasAirlineDesignator()) { continue; } + designators.insert(model.getAirlineIcaoCodeDesignator()); + } + return designators; + } + + QSet CAircraftModelList::getAirlineVDesignators() const + { + QSet designators; + for (const CAircraftModel &model : *this) + { + if (!model.hasAirlineDesignator()) { continue; } + designators.insert(model.getAirlineIcaoCodeVDesignator()); + } + return designators; + } + void CAircraftModelList::updateAircraftIcao(const CAircraftIcaoCode &icao) { for (CAircraftModel &model : *this) @@ -687,5 +720,17 @@ namespace BlackMisc { return QJsonDocument(toDatabaseJson()).toJson(format); } + + QString CAircraftModelList::asHtmlSummary() const + { + if (this->isEmpty()) { return ""; } + QString html; + for (const CAircraftModel &model : *this) + { + if (!html.isEmpty()) { html += "
"; } + html += model.asHtmlSummary(" "); + } + return html; + } } // namespace } // namespace diff --git a/src/blackmisc/simulation/aircraftmodellist.h b/src/blackmisc/simulation/aircraftmodellist.h index 630b6cae0..02dff1dd2 100644 --- a/src/blackmisc/simulation/aircraftmodellist.h +++ b/src/blackmisc/simulation/aircraftmodellist.h @@ -198,6 +198,15 @@ namespace BlackMisc //! All distributors used with models of this list CDistributorList getDistributors(bool onlyDbDistributors = true) const; + //! Aircraft designators + QSet getAircraftDesignators() const; + + //! Airline designators + QSet getAirlineDesignators() const; + + //! Airline virtual designators + QSet getAirlineVDesignators() const; + //! Update aircraft ICAO void updateAircraftIcao(const BlackMisc::Aviation::CAircraftIcaoCode &icao); @@ -236,6 +245,9 @@ namespace BlackMisc //! To database JSON QString toDatabaseJsonString(QJsonDocument::JsonFormat format = QJsonDocument::Compact) const; + + //! As HTML summary + QString asHtmlSummary() const; }; } // ns } // ns diff --git a/src/blackmisc/simulation/aircraftmodelutils.cpp b/src/blackmisc/simulation/aircraftmodelutils.cpp index f2b40809c..22547b27b 100644 --- a/src/blackmisc/simulation/aircraftmodelutils.cpp +++ b/src/blackmisc/simulation/aircraftmodelutils.cpp @@ -7,9 +7,12 @@ * contained in the LICENSE file. */ -#include "blackmisc/simulation/aircraftmodel.h" +#include "blackconfig/buildconfig.h" +#include "blackmisc/simulation/aircraftmodellist.h" #include "blackmisc/simulation/aircraftmodelutils.h" +#include "blackmisc/verify.h" +using namespace BlackConfig; namespace BlackMisc { namespace Simulation @@ -29,5 +32,111 @@ namespace BlackMisc } return true; } + + QString CAircraftModelUtilities::createIcaoAirlineAircraftHtmlMatrix(const CAircraftModelList &models) + { + if (models.isEmpty()) { return ""; } + static const QString emptyDesignator = "----"; + static const QString colorLiveryDesignator = "-C-"; + + QMap> modelsByDesignator; + + // create an empty map of all airlines + const QMap emptyAirlineDesignatorMap; + CAircraftModelList sortedByAircraft(models); + sortedByAircraft.sortBy(&CAircraftModel::getAircraftIcaoCodeDesignator); + + for (const CAircraftModel &model : as_const(sortedByAircraft)) + { + const QString aircraftIcao(model.hasAircraftDesignator() ? model.getAircraftIcaoCodeDesignator() : emptyDesignator); + if (!modelsByDesignator.contains(aircraftIcao)) + { + modelsByDesignator.insert(aircraftIcao, emptyAirlineDesignatorMap); + } + QMap &airlineModels = modelsByDesignator[aircraftIcao]; + const QString airlineIcao( + model.getLivery().isColorLivery() ? colorLiveryDesignator : + model.hasAirlineDesignator() ? model.getAirlineIcaoCodeDesignator() : emptyDesignator); + if (airlineModels.contains(airlineIcao)) + { + airlineModels[airlineIcao].push_back(model); + } + else + { + airlineModels.insert(airlineIcao, CAircraftModelList({model})); + } + } + + // to HTML + QString html("\n"); + QStringList airlineIcaos = models.getAirlineVDesignators().toList(); + qSort(airlineIcaos); + airlineIcaos.push_front(colorLiveryDesignator); + airlineIcaos.push_back(emptyDesignator); + QStringList aircraftIcaos = modelsByDesignator.keys(); + qSort(aircraftIcaos); + + // header + html += "\n"; + html += ""; + for (const QString &airline : as_const(airlineIcaos)) + { + html += ""; + } + html += "\n\n"; + + // fill data + html += "\n"; + for (const QString &aircraftIcao : as_const(aircraftIcaos)) + { + html += "\n"; + html += " \n"; + + const QMap &airlineModels = modelsByDesignator[aircraftIcao]; + for (const QString &airline : as_const(airlineIcaos)) + { + if (airlineModels.contains(airline)) + { + html += " \n"; + } + else + { + html += " \n"; + } + } + html += "\n"; + } + html += "\n"; + html += "
"; + html += airline; + html += "
"; + html += aircraftIcao; + html += ""; + const CAircraftModelList &models(airlineModels[airline]); + html += ""; + html += QString::number(models.size()); + html += "
"; + html += models.asHtmlSummary(); + html += "
"; + html += "
\n"; + return html; + } + + QString CAircraftModelUtilities::createIcaoAirlineAircraftHtmlMatrixFile(const CAircraftModelList &models, const QString &tempDir) + { + Q_ASSERT_X(!tempDir.isEmpty(), Q_FUNC_INFO, "Need directory"); + if (models.isEmpty()) { return ""; } + const QString html = createIcaoAirlineAircraftHtmlMatrix(models); + if (html.isEmpty()) { return ""; } + + QDir dir(tempDir); + BLACK_VERIFY_X(dir.exists(), Q_FUNC_INFO, "Directory does not exist"); + if (!dir.exists()) { return ""; } + + const QString htmlTemplate = CFileUtils::readFileToString(CBuildConfig::getHtmlTemplateFileName()); + const QString fn("airlineAircraftMatrix.html"); + const bool ok = CFileUtils::writeStringToFile(htmlTemplate.arg(html), dir.absoluteFilePath(fn)); + return ok ? dir.absoluteFilePath(fn) : ""; + } } // ns } // ns diff --git a/src/blackmisc/simulation/aircraftmodelutils.h b/src/blackmisc/simulation/aircraftmodelutils.h index fadace3a8..9a59fa473 100644 --- a/src/blackmisc/simulation/aircraftmodelutils.h +++ b/src/blackmisc/simulation/aircraftmodelutils.h @@ -28,6 +28,13 @@ namespace BlackMisc //! Merge with vPilot data if possible static bool mergeWithVPilotData(BlackMisc::Simulation::CAircraftModelList &modelToBeModified, const BlackMisc::Simulation::CAircraftModelList &vPilotModels, bool force = false); + + //! Matrix airlines/aircraft ICAOs + static QString createIcaoAirlineAircraftHtmlMatrix(const BlackMisc::Simulation::CAircraftModelList &models); + + //! Matrix airlines/aircraft ICAOs + static QString createIcaoAirlineAircraftHtmlMatrixFile(const BlackMisc::Simulation::CAircraftModelList &models, const QString &tempDir); + }; } //namespace } // namespace