From 23cd247bd829a291bf88a6986acc0040e4ef3c78 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Tue, 6 Feb 2018 00:15:11 +0100 Subject: [PATCH] Ref T247, utility functions to validate model set --- src/blackmisc/simulation/aircraftmodel.cpp | 30 ++++- src/blackmisc/simulation/aircraftmodel.h | 121 ++++++++++-------- .../simulation/aircraftmodellist.cpp | 16 +++ src/blackmisc/simulation/aircraftmodellist.h | 10 +- 4 files changed, 118 insertions(+), 59 deletions(-) diff --git a/src/blackmisc/simulation/aircraftmodel.cpp b/src/blackmisc/simulation/aircraftmodel.cpp index 4fa354320..2aceeb03d 100644 --- a/src/blackmisc/simulation/aircraftmodel.cpp +++ b/src/blackmisc/simulation/aircraftmodel.cpp @@ -25,8 +25,8 @@ #include #include #include +#include -using namespace BlackMisc; using namespace BlackMisc::Aviation; using namespace BlackMisc::Db; @@ -553,7 +553,7 @@ namespace BlackMisc { if (this->getModelType() == CAircraftModel::TypeOwnSimulatorModel) { - // this is local model, ignore + // this is already a local model, ignore return; } @@ -570,6 +570,32 @@ namespace BlackMisc if (m_iconPath.isEmpty()) { this->setIconPath(model.getIconPath()); } } + bool CAircraftModel::adjustLocalFileNames(const QString &newModelDir, const QString &stripModelDirIndicator) + { + if (!this->hasFileName()) { return false; } + const QString md = CFileUtils::normalizeFilePathToQtStandard(newModelDir); + int i = -1; + if (stripModelDirIndicator.isEmpty()) + { + QString strip = md.mid(md.lastIndexOf('/')); + i = m_fileName.lastIndexOf(strip); + } + else + { + i = m_fileName.lastIndexOf(stripModelDirIndicator); + } + if (i < 0) { return false; } + m_fileName = CFileUtils::appendFilePaths(newModelDir, m_fileName.mid(i)); + return true; + } + + bool CAircraftModel::existsCorrespondingFile() const + { + if (!this->hasFileName()) { return false; } + const QFileInfo fi(this->getFileName()); + return (fi.exists() && fi.isReadable()); + } + bool CAircraftModel::matchesModelString(const QString &modelString, Qt::CaseSensitivity sensitivity) const { return m_modelString.length() == modelString.length() && diff --git a/src/blackmisc/simulation/aircraftmodel.h b/src/blackmisc/simulation/aircraftmodel.h index 2cca66232..f7f379d11 100644 --- a/src/blackmisc/simulation/aircraftmodel.h +++ b/src/blackmisc/simulation/aircraftmodel.h @@ -50,8 +50,8 @@ namespace BlackMisc //! \remarks Simulator independent class, supposed to be common denominator class BLACKMISC_EXPORT CAircraftModel : public CValueObject, - public BlackMisc::Db::IDatastoreObjectWithIntegerKey, - public BlackMisc::IOrderable + public Db::IDatastoreObjectWithIntegerKey, // also ITimestampBased + public IOrderable { public: //! Model type @@ -295,6 +295,63 @@ namespace BlackMisc //! Matches given simulator? bool matchesSimulatorFlag(CSimulatorInfo::Simulator simulator) const; + //! swift livery string (to be sent via network), "liveryCode [modelString]"; + //! \sa splitNetworkLiveryString + QString getSwiftLiveryString() const; + + //! Update missing parts from another model + void updateMissingParts(const CAircraftModel &otherModel, bool dbModelPriority = true); + + //! Queried model string? + bool hasQueriedModelString() const; + + //! Model string which was manually set + bool hasManuallySetString() const; + + //! Non empty model string + bool hasModelString() const { return !m_modelString.isEmpty(); } + + //! Description + bool hasDescription(bool ignoreAutoGenerated = false) const; + + //! Valid simulator + bool hasValidSimulator() const; + + //! Info, which members (Livery, Aircraft ICAO, ...) are already based on DB data + QString getMembersDbStatus() const; + + //! Matches model string? + bool matchesModelString(const QString &modelString, Qt::CaseSensitivity sensitivity) const; + + //! Calculate score + int calculateScore(const CAircraftModel &compareModel, bool preferColorLiveries, CStatusMessageList *log = nullptr) const; + + //! Validate + CStatusMessageList validate(bool withNestedObjects) const; + + //! Considered equal for publishing, compares if livery etc. are the same DB values + bool isEqualForPublishing(const CAircraftModel &dbModel, CStatusMessageList *details = nullptr) const; + + //! Helper class used by implementation. + using MemoHelper = CMemoHelper; + + //! To JSON with memoized members (used by CAircraftModelList) + QJsonObject toMemoizedJson(MemoHelper::CMemoizer &) const; + + //! From JSON with memoized members (used by CAircraftModelList) + void convertFromMemoizedJson(const QJsonObject &json, const MemoHelper::CUnmemoizer &); + + //! To database JSON + QJsonObject toDatabaseJson() const; + + //! To database JSON + QString toDatabaseJsonString(QJsonDocument::JsonFormat format = QJsonDocument::Compact) const; + + //! As a brief HTML summary (e.g. used in tooltips) + QString asHtmlSummary(const QString &separator = "
") const; + + // ---------------- simulator file related functions ------------------- + //! File name (corresponding data for simulator, only available if representing simulator model QString getFileName() const { return m_fileName; } @@ -328,66 +385,20 @@ namespace BlackMisc //! Load icon from disk CPixmap loadIcon(CStatusMessage &success) const; - //! swift livery string (to be sent via network), "liveryCode [modelString]"; - //! \sa splitNetworkLiveryString - QString getSwiftLiveryString() const; - - //! Update missing parts from another model - void updateMissingParts(const CAircraftModel &otherModel, bool dbModelPriority = true); - - //! Queried model string? - bool hasQueriedModelString() const; - - //! Model string which was manually set - bool hasManuallySetString() const; - - //! Non empty model string - bool hasModelString() const { return !m_modelString.isEmpty(); } - - //! Description - bool hasDescription(bool ignoreAutoGenerated = false) const; - - //! Valid simulator - bool hasValidSimulator() const; - - //! Info, which members (Livery, Aircraft ICAO, ...) are already based on DB data - QString getMembersDbStatus() const; - //! File path for DB (absolute paths make no sense in DB) void normalizeFileNameForDb(); - //! If we have local file names, we use those namesx + //! Update file names from local model + //! \remark if we have local file names, we use those names void updateLocalFileNames(const CAircraftModel &model); - //! Matches model string? - bool matchesModelString(const QString &modelString, Qt::CaseSensitivity sensitivity) const; + //! Adjust file names to a new directory + bool adjustLocalFileNames(const QString &newModelDir, const QString &stripModelDirIndicator = {}); - //! Calculate score - int calculateScore(const CAircraftModel &compareModel, bool preferColorLiveries, CStatusMessageList *log = nullptr) const; + //! Does the corresponding file exist? + bool existsCorrespondingFile() const; - //! Validate - CStatusMessageList validate(bool withNestedObjects) const; - - //! Considered equal for publishing, compares if livery etc. are the same DB values - bool isEqualForPublishing(const CAircraftModel &dbModel, CStatusMessageList *details = nullptr) const; - - //! Helper class used by implementation. - using MemoHelper = CMemoHelper; - - //! To JSON with memoized members (used by CAircraftModelList) - QJsonObject toMemoizedJson(MemoHelper::CMemoizer &) const; - - //! From JSON with memoized members (used by CAircraftModelList) - void convertFromMemoizedJson(const QJsonObject &json, const MemoHelper::CUnmemoizer &); - - //! To database JSON - QJsonObject toDatabaseJson() const; - - //! To database JSON - QString toDatabaseJsonString(QJsonDocument::JsonFormat format = QJsonDocument::Compact) const; - - //! As a brief HTML summary (e.g. used in tooltips) - QString asHtmlSummary(const QString &separator = "
") const; + // ---------------- end file related functions -------------- //! Model type static QString modelTypeToString(ModelType type); diff --git a/src/blackmisc/simulation/aircraftmodellist.cpp b/src/blackmisc/simulation/aircraftmodellist.cpp index db9052458..a8f04be4f 100644 --- a/src/blackmisc/simulation/aircraftmodellist.cpp +++ b/src/blackmisc/simulation/aircraftmodellist.cpp @@ -321,6 +321,22 @@ namespace BlackMisc return m.getIconPath(); } + CAircraftModelList CAircraftModelList::findModelsWithoutExistingFile() const + { + return this->findBy([](const CAircraftModel & model) + { + return !model.existsCorrespondingFile(); + }); + } + + CAircraftModelList CAircraftModelList::findModelsWithExistingFile() const + { + return this->findBy([](const CAircraftModel & model) + { + return model.existsCorrespondingFile(); + }); + } + QString CAircraftModelList::designatorToFamily(const CAircraftIcaoCode &aircraftIcaoCode) const { if (aircraftIcaoCode.hasFamily()) { return aircraftIcaoCode.getFamily(); } diff --git a/src/blackmisc/simulation/aircraftmodellist.h b/src/blackmisc/simulation/aircraftmodellist.h index fbb28ec78..76040b896 100644 --- a/src/blackmisc/simulation/aircraftmodellist.h +++ b/src/blackmisc/simulation/aircraftmodellist.h @@ -124,7 +124,7 @@ namespace BlackMisc //! Find by livery code CAircraftModelList findByLiveryCode(const Aviation::CLivery &livery) const; - //! With file name + //! Models with file name CAircraftModelList findWithFileName() const; //! All models from given distributors @@ -178,6 +178,12 @@ namespace BlackMisc //! Model icon path QString findModelIconPathByCallsign(const Aviation::CCallsign &callsign) const; + //! Find models where the filename is not set or the file no longer exists + CAircraftModelList findModelsWithoutExistingFile() const; + + //! Find models where the filename is set and the file exists + CAircraftModelList findModelsWithExistingFile() const; + //! All models of the FS (FSX, P3D, FS9) family CAircraftModelList getAllFsFamilyModels() const; @@ -290,7 +296,7 @@ namespace BlackMisc //! From given CDistributorList update the model`s distributor order int updateDistributorOrder(const CDistributorList &distributors); - //! File name normalized for DB + //! All file names normalized for DB void normalizeFileNamesForDb(); //! Score by aircraft ICAO code