diff --git a/src/blackmisc/simulation/aircraftmodellist.cpp b/src/blackmisc/simulation/aircraftmodellist.cpp index 457a34578..9f6af1f9d 100644 --- a/src/blackmisc/simulation/aircraftmodellist.cpp +++ b/src/blackmisc/simulation/aircraftmodellist.cpp @@ -657,7 +657,7 @@ namespace BlackMisc return Private::isLikelyImpl(this->countPerSimulator().getCountForFsxFamilySimulators(), this->size()); } - bool CAircraftModelList::isLikelyXplaneModelList() const + bool CAircraftModelList::isLikelyXPlaneModelList() const { if (this->isEmpty()) { return false; } // avoid DIV 0 return Private::isLikelyImpl(this->countPerSimulator().getCount(CSimulatorInfo::xplane()), this->size()); @@ -1309,7 +1309,7 @@ namespace BlackMisc return msgs; } - CStatusMessageList CAircraftModelList::validateFiles(CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmpty, int stopAtFailedFiles, bool &stopped, bool alreadySorted) const + CStatusMessageList CAircraftModelList::validateFiles(CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmpty, int stopAtFailedFiles, bool &stopped, const QString &rootDirectory, bool alreadySortedByFn) const { invalidModels.clear(); validModels.clear(); @@ -1322,9 +1322,11 @@ namespace BlackMisc // sorting allows to skip multiple files as once when a file fails CAircraftModelList sorted(*this); - if (!alreadySorted) { sorted.sortByFileName(); } + if (!alreadySortedByFn) { sorted.sortByFileName(); } const bool caseSensitive = CFileUtils::isFileNameCaseSensitive(); + const QString rDir = caseSensitive ? rootDirectory : rootDirectory.toLower(); + for (const CAircraftModel &model : as_const(sorted)) { bool ok = false; @@ -1352,10 +1354,20 @@ namespace BlackMisc if (workingFiles.contains(fn) || model.hasExistingCorrespondingFile()) { - ok = true; - workingFiles.insert(fn); - // msgs.push_back(CStatusMessage(this).validationInfo(u"'%1', file '%2' existing") << model.getModelStringAndDbKey() << model.getFileName()); - break; + if (!rootDirectory.isEmpty() && !fn.contains(rDir)) + { + msgs.push_back(CStatusMessage(this).validationError(u"'%1', not in root directory '%2', '%3' skipped") << model.getModelStringAndDbKey() << rDir << model.getFileName()); + failedFiles.insert(fn); + failedFilesCount++; + break; + } + else + { + ok = true; + workingFiles.insert(fn); + // msgs.push_back(CStatusMessage(this).validationInfo(u"'%1', file '%2' existing") << model.getModelStringAndDbKey() << model.getFileName()); + break; + } } failedFiles.insert(fn); diff --git a/src/blackmisc/simulation/aircraftmodellist.h b/src/blackmisc/simulation/aircraftmodellist.h index f9ab0ccff..1b6813928 100644 --- a/src/blackmisc/simulation/aircraftmodellist.h +++ b/src/blackmisc/simulation/aircraftmodellist.h @@ -270,7 +270,7 @@ namespace BlackMisc bool isLikelyFsxFamilyModelList() const; //! Is this here a XPlane model list? - bool isLikelyXplaneModelList() const; + bool isLikelyXPlaneModelList() const; //! Set mode for all elements int setModelMode(CAircraftModel::ModelMode mode); @@ -453,8 +453,8 @@ namespace BlackMisc //! Validate distributors CStatusMessageList validateDistributors(const CDistributorList &distributors, CAircraftModelList &validModels, CAircraftModelList &invalidModels) const; - //! Validate distributors - CStatusMessageList validateFiles(CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmpty, int stopAtFailedFiles, bool &stopped, bool alreadySorted = false) const; + //! Validate files (file exists etc.) + CStatusMessageList validateFiles(CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmpty, int stopAtFailedFiles, bool &stopped, const QString &rootDirectory, bool alreadySortedByFn = false) const; //! To compact JSON format QJsonObject toMemoizedJson() const; diff --git a/src/blackmisc/simulation/aircraftmodelutils.cpp b/src/blackmisc/simulation/aircraftmodelutils.cpp index b0e8c00f3..ba4613f67 100644 --- a/src/blackmisc/simulation/aircraftmodelutils.cpp +++ b/src/blackmisc/simulation/aircraftmodelutils.cpp @@ -140,12 +140,45 @@ namespace BlackMisc return ok ? dir.absoluteFilePath(fn) : ""; } - CStatusMessageList CAircraftModelUtilities::validateModelFiles(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmpty, int stopAtFailedFiles, bool &stopped) + CStatusMessageList CAircraftModelUtilities::validateModelFiles(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmpty, int stopAtFailedFiles, bool &stopped, const QString &simulatorDir) { - // specifi checks for XPlane/FG would go here - return models.isLikelyFsFamilyModelList() ? - FsCommon::CFsCommonUtil::validateConfigFiles(models, validModels, invalidModels, ignoreEmpty, stopAtFailedFiles, stopped) : - models.validateFiles(validModels, invalidModels, ignoreEmpty, stopAtFailedFiles, stopped); + // some generic tests + CStatusMessageList msgs; + if (models.isEmpty()) + { + msgs.push_back(CStatusMessage(CLogCategory::matching(), CStatusMessage::SeverityError, u"No models", true)); + return msgs; + } + + const int noDb = models.size() - models.countWithValidDbKey(); + if (noDb > 0) + { + msgs.push_back(CStatusMessage(CLogCategory::matching(), CStatusMessage::SeverityWarning, QStringLiteral("%1 models without DB data, is this intended?").arg(noDb), true)); + } + + const int noExcluded = models.countByMode(CAircraftModel::Exclude); + if (noExcluded > 0) + { + msgs.push_back(CStatusMessage(CLogCategory::matching(), CStatusMessage::SeverityWarning, QStringLiteral("%1 models marked as excluded, is this intended?").arg(noExcluded), true)); + } + + // specific checks for FSX/XPlane/FG + CStatusMessageList specificTests; + if (models.isLikelyFsFamilyModelList()) + { + specificTests = FsCommon::CFsCommonUtil::validateConfigFiles(models, validModels, invalidModels, ignoreEmpty, stopAtFailedFiles, stopped); + } + else if (models.isLikelyXPlaneModelList()) + { + specificTests = models.validateFiles(validModels, invalidModels, ignoreEmpty, stopAtFailedFiles, stopped, simulatorDir); + } + else + { + specificTests = models.validateFiles(validModels, invalidModels, ignoreEmpty, stopAtFailedFiles, stopped, {}); + } + + msgs.push_back(specificTests); + return msgs; } } // ns } // ns diff --git a/src/blackmisc/simulation/aircraftmodelutils.h b/src/blackmisc/simulation/aircraftmodelutils.h index 3e057be08..da6ad1864 100644 --- a/src/blackmisc/simulation/aircraftmodelutils.h +++ b/src/blackmisc/simulation/aircraftmodelutils.h @@ -26,6 +26,7 @@ namespace BlackMisc CAircraftModelUtilities() = delete; //! Merge with vPilot data if possible + //! \deprecated vPilot parts might be removed static bool mergeWithVPilotData(BlackMisc::Simulation::CAircraftModelList &modelToBeModified, const BlackMisc::Simulation::CAircraftModelList &vPilotModels, bool force = false); //! Matrix airlines/aircraft ICAOs @@ -35,7 +36,7 @@ namespace BlackMisc static QString createIcaoAirlineAircraftHtmlMatrixFile(const BlackMisc::Simulation::CAircraftModelList &models, const QString &tempDir); //! Validate aircraft.cfg entries - static CStatusMessageList validateModelFiles(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmpty, int stopAtFailedFiles, bool &stopped); + static CStatusMessageList validateModelFiles(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmpty, int stopAtFailedFiles, bool &stopped, const QString &simulatorDir); }; } //namespace } // namespace