diff --git a/src/blackmisc/simulation/aircraftmodellist.cpp b/src/blackmisc/simulation/aircraftmodellist.cpp index f2cd143f7..8633ef091 100644 --- a/src/blackmisc/simulation/aircraftmodellist.cpp +++ b/src/blackmisc/simulation/aircraftmodellist.cpp @@ -1420,7 +1420,7 @@ namespace BlackMisc return msgs; } - CStatusMessageList CAircraftModelList::validateFiles(CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, bool &stopped, const QString &rootDirectory, bool alreadySortedByFn) const + CStatusMessageList CAircraftModelList::validateFiles(CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, bool &stopped, const QString &simRootDirectory, bool alreadySortedByFn) const { stopped = false; @@ -1434,11 +1434,11 @@ namespace BlackMisc if (!alreadySortedByFn) { sorted.sortByFileName(); } const bool caseSensitive = CFileUtils::isFileNameCaseSensitive(); - const QString rDir = CFileUtils::normalizeFilePathToQtStandard( - CFileUtils::stripLeadingSlashOrDriveLetter( - caseSensitive ? rootDirectory : rootDirectory.toLower() - ) - ); + const QString simRootDir = CFileUtils::normalizeFilePathToQtStandard( + CFileUtils::stripLeadingSlashOrDriveLetter( + caseSensitive ? simRootDirectory : simRootDirectory.toLower() + ) + ); for (const CAircraftModel &model : as_const(sorted)) { @@ -1467,9 +1467,10 @@ namespace BlackMisc if (workingFiles.contains(fn) || model.hasExistingCorrespondingFile()) { - if (!rootDirectory.isEmpty() && !fn.contains(rDir)) + if (!simRootDirectory.isEmpty() && !fn.contains(simRootDir)) { - msgs.push_back(CStatusMessage(this).validationError(u"'%1', not in root directory '%2', '%3' skipped") << model.getModelStringAndDbKey() << rDir << model.getFileName()); + // check if in root directory + msgs.push_back(CStatusMessage(this).validationError(u"'%1', not in root directory '%2', '%3' skipped") << model.getModelStringAndDbKey() << simRootDir << model.getFileName()); failedFiles.insert(fn); failedFilesCount++; break; diff --git a/src/blackmisc/simulation/aircraftmodellist.h b/src/blackmisc/simulation/aircraftmodellist.h index 34e3cbba5..b44e55d89 100644 --- a/src/blackmisc/simulation/aircraftmodellist.h +++ b/src/blackmisc/simulation/aircraftmodellist.h @@ -484,7 +484,7 @@ namespace BlackMisc CStatusMessageList validateDistributors(const CDistributorList &distributors, CAircraftModelList &validModels, CAircraftModelList &invalidModels) const; //! Validate files (file exists etc.) - CStatusMessageList validateFiles(CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, bool &stopped, const QString &rootDirectory, bool alreadySortedByFn = false) const; + CStatusMessageList validateFiles(CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, bool &stopped, const QString &simRootDirectory, 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 82a086dc7..0c92dfd32 100644 --- a/src/blackmisc/simulation/aircraftmodelutils.cpp +++ b/src/blackmisc/simulation/aircraftmodelutils.cpp @@ -166,7 +166,7 @@ namespace BlackMisc CStatusMessageList specificTests; if (simulator.isMicrosoftOrPrepare3DSimulator() || models.isLikelyFsFamilyModelList()) { - const CStatusMessageList specificTests1 = FsCommon::CFsCommonUtil::validateConfigFiles(models, validModels, invalidModels, ignoreEmpty, stopAtFailedFiles, stopped); + const CStatusMessageList specificTests1 = FsCommon::CFsCommonUtil::validateAircraftConfigFiles(models, validModels, invalidModels, ignoreEmpty, stopAtFailedFiles, stopped); specificTests.push_back(specificTests1); if (simulator.isP3D()) @@ -176,7 +176,7 @@ namespace BlackMisc } else if (simulator.isFSX()) { - const CStatusMessageList specificTests2 = FsCommon::CFsCommonUtil::validateFSXSimObjectsPath(models, validModels, invalidModels, ignoreEmpty, stopAtFailedFiles, stopped); + const CStatusMessageList specificTests2 = FsCommon::CFsCommonUtil::validateFSXSimObjectsPath(models, validModels, invalidModels, ignoreEmpty, stopAtFailedFiles, stopped, simulatorDir); specificTests.push_back(specificTests2); } } diff --git a/src/blackmisc/simulation/fscommon/fscommonutil.cpp b/src/blackmisc/simulation/fscommon/fscommonutil.cpp index 47ea736fd..7bfd38a27 100644 --- a/src/blackmisc/simulation/fscommon/fscommonutil.cpp +++ b/src/blackmisc/simulation/fscommon/fscommonutil.cpp @@ -216,14 +216,38 @@ namespace BlackMisc return dir; } - QStringList CFsCommonUtil::p3dSimObjectsDirPlusAddOnSimObjectsDirs(const QString &simObjectsDir, const QString &versionHint) + QStringList CFsCommonUtil::fsxSimObjectsDirPlusAddOnXmlSimObjectsPaths(const QString &simObjectsDir) { // finding the user settings only works on P3D machine - const QSet allP3dAddOnSimObjectPaths = CFsCommonUtil::allP3dAddOnSimObjectPaths(versionHint); - QStringList all(allP3dAddOnSimObjectPaths.toList()); - all.push_front(simObjectsDir.isEmpty() ? p3dSimObjectsDir() : simObjectsDir); - all.sort(Qt::CaseInsensitive); - return all; + QStringList allPaths = CFsCommonUtil::allFsxSimObjectPaths().toList(); + const QString sod = simObjectsDir.isEmpty() ? CFsCommonUtil::fsxSimObjectsDir() : simObjectsDir; + if (!sod.isEmpty() && !allPaths.contains(sod, Qt::CaseInsensitive)) + { + // case insensitive is important here + allPaths.push_front(sod); + } + + allPaths.removeAll({}); // remove all empty + allPaths.removeDuplicates(); + allPaths.sort(Qt::CaseInsensitive); + return allPaths; + } + + QStringList CFsCommonUtil::p3dSimObjectsDirPlusAddOnXmlSimObjectsPaths(const QString &simObjectsDir, const QString &versionHint) + { + // finding the user settings only works on P3D machine + QStringList allPaths = CFsCommonUtil::allP3dAddOnXmlSimObjectPaths(versionHint).toList(); + const QString sod = simObjectsDir.isEmpty() ? CFsCommonUtil::p3dSimObjectsDir() : simObjectsDir; + if (!sod.isEmpty() && !allPaths.contains(sod, Qt::CaseInsensitive)) + { + // case insensitive is important here + allPaths.push_front(sod); + } + + allPaths.removeAll({}); // remove all empty + allPaths.removeDuplicates(); + allPaths.sort(Qt::CaseInsensitive); + return allPaths; } QString CFsCommonUtil::p3dSimObjectsDirFromSimDir(const QString &simDir) @@ -472,7 +496,7 @@ namespace BlackMisc return paths; } - QSet CFsCommonUtil::allP3dAddOnSimObjectPaths(const QStringList &addOnPaths, bool checked) + QSet CFsCommonUtil::allP3dAddOnXmlSimObjectPaths(const QStringList &addOnPaths, bool checked) { if (addOnPaths.isEmpty()) { return QSet(); } QSet simObjectPaths; @@ -513,7 +537,7 @@ namespace BlackMisc return simObjectPaths; } - QSet CFsCommonUtil::allP3dAddOnSimObjectPaths(const QString &versionHint) + QSet CFsCommonUtil::allP3dAddOnXmlSimObjectPaths(const QString &versionHint) { // all add-ons.cfg files const QStringList addOnConfigFiles = CFsCommonUtil::findP3dAddOnConfigFiles(versionHint).toList(); @@ -521,23 +545,14 @@ namespace BlackMisc // all PATH values in those files const QStringList addOnPaths = CFsCommonUtil::allConfigFilesPathValues(addOnConfigFiles, true, {}).toList(); - // based on all paths of all config - const QSet all = CFsCommonUtil::allP3dAddOnSimObjectPaths(addOnPaths, true); + // based on all paths of all config files search the XML files + const QSet all = CFsCommonUtil::allP3dAddOnXmlSimObjectPaths(addOnPaths, true); return all; } - QSet CFsCommonUtil::allP3dSimObjectsConfigPaths(const QString &simulatorDir, const QString &versionHint) + QSet CFsCommonUtil::allFsxSimObjectPaths() { - const QStringList configFiles = CFsCommonUtil::findP3dSimObjectsConfigFiles(versionHint).toList(); - return CFsCommonUtil::allConfigFilesPathValues(configFiles, true, simulatorDir); - } - - QSet CFsCommonUtil::allP3dSimObjectPaths(const QString &simulatorDir, const QString &versionHint) - { - const QSet configFiles = CFsCommonUtil::allP3dSimObjectsConfigPaths(simulatorDir, versionHint); - const QSet addOnFiles = CFsCommonUtil::allP3dAddOnSimObjectPaths(versionHint); - QSet all(configFiles); - return all.unite(addOnFiles); + return CFsCommonUtil::fsxSimObjectsPaths(CFsCommonUtil::findFsxConfigFiles(), true); } QStringList CFsCommonUtil::findFsxConfigFiles() @@ -594,13 +609,13 @@ namespace BlackMisc return paths; } - CStatusMessageList CFsCommonUtil::validateConfigFiles(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, bool &stopped) + CStatusMessageList CFsCommonUtil::validateAircraftConfigFiles(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, bool &stopped) { CStatusMessage m; CAircraftModelList sorted(models); sorted.sortByFileName(); stopped = false; - CStatusMessageList msgs = sorted.validateFiles(validModels, invalidModels, ignoreEmptyFileNames, stopAtFailedFiles, stopped, "", true); + CStatusMessageList msgs = sorted.validateFiles(validModels, invalidModels, ignoreEmptyFileNames, stopAtFailedFiles, stopped, QString(), true); if (stopped || validModels.isEmpty()) { return msgs; } const CAircraftModelList nonFsModels = validModels.findNonFsFamilyModels(); @@ -658,14 +673,16 @@ namespace BlackMisc CStatusMessageList CFsCommonUtil::validateP3DSimObjectsPath(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, bool &stopped, const QString &simulatorDir) { - const QSet simObjectDirs = CFsCommonUtil::allP3dSimObjectPaths(simulatorDir, "v4"); - return CFsCommonUtil::validateSimObjectsPath(simObjectDirs, models, validModels, invalidModels, ignoreEmptyFileNames, stopAtFailedFiles, stopped); + const QString simObjectsDir = simulatorDir.isEmpty() ? CFsCommonUtil::p3dSimObjectsDir() : CFsCommonUtil::p3dSimObjectsDirFromSimDir(simulatorDir); + const QSet simObjectPaths = CFsCommonUtil::p3dSimObjectsDirPlusAddOnXmlSimObjectsPaths(simObjectsDir, "v4").toSet(); + return CFsCommonUtil::validateSimObjectsPath(simObjectPaths, models, validModels, invalidModels, ignoreEmptyFileNames, stopAtFailedFiles, stopped); } - CStatusMessageList CFsCommonUtil::validateFSXSimObjectsPath(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, bool &stopped) + CStatusMessageList CFsCommonUtil::validateFSXSimObjectsPath(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, bool &stopped, const QString &simulatorDir) { - const QSet simObjectDirs = CFsCommonUtil::fsxSimObjectsPaths(CFsCommonUtil::findFsxConfigFiles(), true); - return CFsCommonUtil::validateSimObjectsPath(simObjectDirs, models, validModels, invalidModels, ignoreEmptyFileNames, stopAtFailedFiles, stopped); + Q_UNUSED(simulatorDir); + const QSet simObjectPaths = CFsCommonUtil::fsxSimObjectsDirPlusAddOnXmlSimObjectsPaths().toSet(); + return CFsCommonUtil::validateSimObjectsPath(simObjectPaths, models, validModels, invalidModels, ignoreEmptyFileNames, stopAtFailedFiles, stopped); } CStatusMessageList CFsCommonUtil::validateSimObjectsPath( @@ -673,22 +690,24 @@ namespace BlackMisc CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, bool &stopped) { - CAircraftModelList sorted(models); - sorted.sortByFileName(); CStatusMessageList msgs; - if (sorted.isEmpty()) - { - msgs.push_back(CStatusMessage(getLogCategories()).validationInfo(u"No models to validate")); - return msgs; - } if (simObjectDirs.isEmpty()) { msgs.push_back(CStatusMessage(getLogCategories()).validationInfo(u"No SimObject directories from cfg files, skipping validation")); return msgs; } + CAircraftModelList sortedModels(models); + sortedModels.sortByFileName(); + if (sortedModels.isEmpty()) + { + msgs.push_back(CStatusMessage(getLogCategories()).validationInfo(u"No models to validate")); + return msgs; + } + // info - msgs.push_back(CStatusMessage(getLogCategories()).validationInfo(u"Validating %1 models against %2 SimObject paths: %3") << models.size() << simObjectDirs.size() << joinStringSet(simObjectDirs, ", ")); + const QString simObjDirs = joinStringSet(simObjectDirs, ", "); + msgs.push_back(CStatusMessage(getLogCategories()).validationInfo(u"Validating %1 models against %2 SimObject paths: '%3'") << models.size() << simObjectDirs.size() << simObjDirs); // validate int failed = 0; diff --git a/src/blackmisc/simulation/fscommon/fscommonutil.h b/src/blackmisc/simulation/fscommon/fscommonutil.h index 1522cb2a2..c8b1ed4f7 100644 --- a/src/blackmisc/simulation/fscommon/fscommonutil.h +++ b/src/blackmisc/simulation/fscommon/fscommonutil.h @@ -52,6 +52,12 @@ namespace BlackMisc //! Exclude directories for simObjects static const QStringList &fsxSimObjectsExcludeDirectoryPatterns(); + //! FSX's simObject dir and the add on dirs + static QStringList fsxSimObjectsDirPlusAddOnXmlSimObjectsPaths(const QString &simObjectsDir = ""); + + //! P3D's simObject dir and the add on dirs + static QStringList p3dSimObjectsDirPlusAddOnXmlSimObjectsPaths(const QString &simObjectsDir = "", const QString &versionHint = "v4"); + //! P3D directory obtained from registry static const QString &p3dDirFromRegistry(); @@ -64,9 +70,6 @@ namespace BlackMisc //! P3D's simObject dir, resolved from multiple sources static const QString &p3dSimObjectsDir(); - //! P3D's simObject dir and the add on dirs - static QStringList p3dSimObjectsDirPlusAddOnSimObjectsDirs(const QString &simObjectsDir = "", const QString &versionHint = "v4"); - //! P3D aircraft dir, relative to simulator directory static QString p3dSimObjectsDirFromSimDir(const QString &simDir); @@ -113,20 +116,17 @@ namespace BlackMisc //! All PATH values from the config files static QSet allConfigFilesPathValues(const QStringList &configFiles, bool checked, const QString &pathPrefix); - //! All add-on paths from the config files - static QSet allP3dAddOnSimObjectPaths(const QStringList &addOnPaths, bool checked); + //! All add-on paths from the XML add-on files "add-on.xml" + static QSet allP3dAddOnXmlSimObjectPaths(const QStringList &addOnPaths, bool checked); - //! All add-on paths from the config files - static QSet allP3dAddOnSimObjectPaths(const QString &versionHint = "v4"); + //! All add-on paths from the XML add-on files "add-on.xml" files, use CFsCommonUtil::findP3dAddOnConfigFiles to find config files + static QSet allP3dAddOnXmlSimObjectPaths(const QString &versionHint = "v4"); - //! All paths from the simobjects.cfg files - static QSet allP3dSimObjectsConfigPaths(const QString &simulatorDir, const QString &versionHint = "v4"); - - //! All add-on paths from the config files and the simobjects.cfg files - static QSet allP3dSimObjectPaths(const QString &simulatorDir, const QString &versionHint = "v4"); + //! Get all the SimObjects paths from all config files + static QSet allFsxSimObjectPaths(); //! Find the config files (fsx.cfg) - // C:/Users/Joe Doe/AppData/Roaming/Lockheed Martin/Prepar3D v4 + // C:/Users/Joe Doe/AppData/Roaming/Microsoft/FSX/fsx.cfg static QStringList findFsxConfigFiles(); //! Get all the SimObjects paths from fsx.cfg @@ -137,9 +137,9 @@ namespace BlackMisc // SimObjectPaths.0=SimObjects\Airplanes static QSet fsxSimObjectsPaths(const QString &fsxFile, bool checked); - //! Validate aircraft.cfg entries + //! Validate aircraft.cfg entries (sometimes also sim.cfg) //! \remark only for FSX/P3D/FS9 models - static CStatusMessageList validateConfigFiles(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, bool &stopped); + static CStatusMessageList validateAircraftConfigFiles(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, bool &stopped); //! Validate if known SimObjects path are used //! \remark only for P3D @@ -147,7 +147,7 @@ namespace BlackMisc //! Validate if known SimObjects path are used //! \remark only for FSX - static CStatusMessageList validateFSXSimObjectsPath(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, bool &stopped); + static CStatusMessageList validateFSXSimObjectsPath(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, bool &stopped, const QString &simulatorDir); private: //! Utility functions @{ @@ -155,7 +155,7 @@ namespace BlackMisc //! @} //! Validate if known SimObjects path are used - //! \remark only for P3D + //! \remark only for P3D/FSX static CStatusMessageList validateSimObjectsPath(const QSet &simObjectDirs, const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, bool &stopped); //! Log the reading of config files diff --git a/src/blackmisc/simulation/settings/simulatorsettings.cpp b/src/blackmisc/simulation/settings/simulatorsettings.cpp index 8dea9b177..0ae61deeb 100644 --- a/src/blackmisc/simulation/settings/simulatorsettings.cpp +++ b/src/blackmisc/simulation/settings/simulatorsettings.cpp @@ -561,11 +561,13 @@ namespace BlackMisc QStringList dirs; switch (m_simulator.getSimulator()) { - case CSimulatorInfo::FG: dirs = QStringList(CFlightgearUtil::modelDirectoriesFromSimDir(s)); break; + case CSimulatorInfo::FG: dirs = QStringList(CFlightgearUtil::modelDirectoriesFromSimDir(s)); break; case CSimulatorInfo::FS9: dirs = QStringList({CFsCommonUtil::fs9AircraftDirFromSimDir(s)}); break; - case CSimulatorInfo::FSX: dirs = QStringList({CFsCommonUtil::fsxSimObjectsDirFromSimDir(s)}); break; + case CSimulatorInfo::FSX: + dirs = CFsCommonUtil::fsxSimObjectsDirPlusAddOnXmlSimObjectsPaths(CFsCommonUtil::fsxSimObjectsDirFromSimDir(s)); + break; case CSimulatorInfo::P3D: - dirs = QStringList(CFsCommonUtil::p3dSimObjectsDirPlusAddOnSimObjectsDirs(CFsCommonUtil::p3dSimObjectsDirFromSimDir(s))); + dirs = CFsCommonUtil::p3dSimObjectsDirPlusAddOnXmlSimObjectsPaths(CFsCommonUtil::p3dSimObjectsDirFromSimDir(s)); break; case CSimulatorInfo::XPLANE: dirs = QStringList({CXPlaneUtil::modelDirectoriesFromSimDir(s)}); break; default: break; @@ -645,13 +647,13 @@ namespace BlackMisc case CSimulatorInfo::FSX: { if (CFsCommonUtil::fsxSimObjectsDir().isEmpty()) { return e; } - static const QStringList md({ CFsCommonUtil::fsxSimObjectsDir() }); + static const QStringList md = CFsCommonUtil::fsxSimObjectsDirPlusAddOnXmlSimObjectsPaths(); return md; } case CSimulatorInfo::P3D: { if (CFsCommonUtil::p3dSimObjectsDir().isEmpty()) { return e; } - static const QStringList md = CFsCommonUtil::p3dSimObjectsDirPlusAddOnSimObjectsDirs(); + static const QStringList md = CFsCommonUtil::p3dSimObjectsDirPlusAddOnXmlSimObjectsPaths(); return md; } case CSimulatorInfo::XPLANE: