Ref T365, find add-on SimObjects

* utility function to compare directories
* parse "add-on.xml"
* use add-on SimObject paths for P3D as default
This commit is contained in:
Klaus Basan
2018-12-07 13:02:08 +01:00
parent a1bea413f4
commit 50cc9c32d6
5 changed files with 77 additions and 13 deletions

View File

@@ -223,6 +223,27 @@ namespace BlackMisc
return relativeDirectories;
}
bool CFileUtils::sameDirectories(const QStringList &dirs1, const QStringList &dirs2, Qt::CaseSensitivity cs)
{
// clean up
QStringList dirs1Cleaned(dirs1);
QStringList dirs2Cleaned(dirs2);
dirs1Cleaned.removeAll("");
dirs1Cleaned.removeDuplicates();
dirs2Cleaned.removeAll("");
dirs2Cleaned.removeDuplicates();
if (dirs1Cleaned.size() != dirs2Cleaned.size()) { return false; }
int d2 = 0;
dirs1Cleaned.sort(cs);
dirs2Cleaned.sort(cs);
for (const QString &d1 : dirs1)
{
if (!stringCompare(d1, dirs2.at(d2), cs)) { return false; }
}
return true;
}
Qt::CaseSensitivity CFileUtils::osFileNameCaseSensitivity()
{
return CBuildConfig::isRunningOnWindowsNtPlatform() ? Qt::CaseInsensitive : Qt::CaseSensitive;

View File

@@ -107,6 +107,9 @@ namespace BlackMisc
//! \remark unlike QDir::relativePath here reltive paths are only created when a directory is a subdir of rootDirectory
static QStringList makeDirectoriesRelative(const QStringList &directories, const QString &rootDirectory, Qt::CaseSensitivity cs = osFileNameCaseSensitivity());
//! Same directories, order in list does not matter and lists are cleaned up
static bool sameDirectories(const QStringList &dirs1, const QStringList &dirs2, Qt::CaseSensitivity cs = osFileNameCaseSensitivity());
//! Case sensitivity for current OS
static Qt::CaseSensitivity osFileNameCaseSensitivity();

View File

@@ -22,6 +22,8 @@
#include <QVariant>
#include <QFileInfo>
#include <QStandardPaths>
#include <QDomDocument>
#include <QDomNodeList>
#include <QSettings>
#include <QStringBuilder>
@@ -207,6 +209,16 @@ namespace BlackMisc
return dir;
}
QStringList CFsCommonUtil::p3dSimObjectsDirPlusAddOnSimObjectsDirs(const QString &simObjectsDir)
{
// finding the user settings only works on P3D machine
const QSet<QString> allP3dAddOnSimObjectPaths = CFsCommonUtil::allP3dAddOnSimObjectPaths("v4");
QStringList all(allP3dAddOnSimObjectPaths.toList());
all.push_front(simObjectsDir.isEmpty() ? p3dSimObjectsDir() : simObjectsDir);
all.sort(Qt::CaseInsensitive);
return all;
}
QString CFsCommonUtil::p3dSimObjectsDirFromSimDir(const QString &simDir)
{
if (simDir.isEmpty()) { return QStringLiteral(""); }
@@ -402,6 +414,7 @@ namespace BlackMisc
const QStringList entries = d.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
for (const QString &entry : entries)
{
// right version or just one file
if (entry.contains(versionHint, Qt::CaseInsensitive))
{
const QString f = CFileUtils::appendFilePaths(d.absolutePath(), entry, cfgFile);
@@ -442,13 +455,34 @@ namespace BlackMisc
QSet<QString> simObjectPaths;
for (const QString &addOnPath : addOnPaths)
{
const QString so = CFileUtils::appendFilePaths(addOnPath, "SimObjects");
const QFileInfo fi(so);
if (!checked || fi.exists()) { simObjectPaths.insert(fi.absolutePath()); }
const QString filename = CFileUtils::appendFilePaths(addOnPath, "add-on.xml");
QDomDocument doc;
QFile file(filename);
if (!file.open(QIODevice::ReadOnly) || !doc.setContent(&file)) { continue; }
const QDomNodeList components = doc.elementsByTagName("AddOn.Component");
for (int i = 0; i < components.size(); i++)
{
const QDomNode component = components.item(i);
const QDomElement category = component.firstChildElement("Category");
const QString categoryValue = category.text();
if (!caseInsensitiveStringCompare(categoryValue, QStringLiteral("SimObjects"))) { continue; }
const QDomElement path = component.firstChildElement("Path");
const QString pathValue = path.text();
if (pathValue.isEmpty()) { continue; }
if (!checked || QDir(pathValue).exists()) { simObjectPaths.insert(CFileUtils::normalizeFilePathToQtStandard(pathValue)); }
}
}
return simObjectPaths;
}
QSet<QString> CFsCommonUtil::allP3dAddOnSimObjectPaths(const QString &versionHint)
{
const QStringList configFiles = CFsCommonUtil::findP3dAddOnConfigFiles(versionHint).toList();
const QStringList addOnPaths = CFsCommonUtil::allP3dAddOnPaths(configFiles, true).toList();
const QSet<QString> all = CFsCommonUtil::allP3dAddOnSimObjectPaths(addOnPaths, true);
return all;
}
QStringList CFsCommonUtil::findFsxConfigFiles()
{
const QStringList locations = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation);

View File

@@ -57,9 +57,12 @@ namespace BlackMisc
//! P3D's simObject directory from registry
static const QString &p3dSimObjectsDirFromRegistry();
//! P3D's sim object dir, resolved from multiple sources
//! 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 = "");
//! P3D aircraft dir, relative to simulator directory
static QString p3dSimObjectsDirFromSimDir(const QString &simDir);
@@ -93,10 +96,10 @@ namespace BlackMisc
//! Copy the terrain probe
static int copyFsxTerrainProbeFiles(const QString &simObjectDir, CStatusMessageList &messages);
//! Find the config files
//! Find the config files (add-ons.cfg)
//! \note C:/Users/Joe Doe/AppData/Roaming/Lockheed Martin/Prepar3D v4
//! \param versionHint like "v4"
static QSet<QString> findP3dAddOnConfigFiles(const QString &versionHint);
static QSet<QString> findP3dAddOnConfigFiles(const QString &versionHint = "v4");
//! All add-on paths from the config files
static QSet<QString> allP3dAddOnPaths(const QStringList &addOnConfigsFiles, bool checked);
@@ -104,7 +107,10 @@ namespace BlackMisc
//! All add-on paths from the config files
static QSet<QString> allP3dAddOnSimObjectPaths(const QStringList &addOnPaths, bool checked);
//! Find the config files
//! All add-on paths from the config files
static QSet<QString> allP3dAddOnSimObjectPaths(const QString &versionHint = "v4");
//! Find the config files (fsx.cfg)
// C:/Users/Joe Doe/AppData/Roaming/Lockheed Martin/Prepar3D v4
static QStringList findFsxConfigFiles();

View File

@@ -501,7 +501,9 @@ namespace BlackMisc
case CSimulatorInfo::FG: break;
case CSimulatorInfo::FS9: dirs = QStringList({CFsCommonUtil::fs9AircraftDirFromSimDir(s)}); break;
case CSimulatorInfo::FSX: dirs = QStringList({CFsCommonUtil::fsxSimObjectsDirFromSimDir(s)}); break;
case CSimulatorInfo::P3D: dirs = QStringList({CFsCommonUtil::p3dSimObjectsDirFromSimDir(s)}); break;
case CSimulatorInfo::P3D:
dirs = QStringList(CFsCommonUtil::p3dSimObjectsDirPlusAddOnSimObjectsDirs(CFsCommonUtil::p3dSimObjectsDirFromSimDir(s)));
break;
case CSimulatorInfo::XPLANE: dirs = QStringList({CXPlaneUtil::modelDirectoriesFromSimDir(s)}); break;
default: break;
}
@@ -521,10 +523,8 @@ namespace BlackMisc
{
static const QStringList empty;
if (!m_genericSettings.hasModelDirectories()) { return empty; }
if (m_genericSettings.getModelDirectories() == CSpecializedSimulatorSettings::defaultModelDirectories(m_simulator))
{
return empty;
}
const QStringList defaultDirectories = CSpecializedSimulatorSettings::defaultModelDirectories(m_simulator);
if (CFileUtils::sameDirectories(m_genericSettings.getModelDirectories(), defaultDirectories)) { return empty; }
return m_genericSettings.getModelDirectories();
}
@@ -588,7 +588,7 @@ namespace BlackMisc
case CSimulatorInfo::P3D:
{
if (CFsCommonUtil::p3dSimObjectsDir().isEmpty()) { return e; }
static const QStringList md({ CFsCommonUtil::p3dSimObjectsDir() });
static const QStringList md = CFsCommonUtil::p3dSimObjectsDirPlusAddOnSimObjectsDirs();
return md;
}
case CSimulatorInfo::XPLANE: