Issue #77 Factor out parts of CDirectoryUtils into CSwiftDirectories

CDirectoryUtils is utilities for manipulating directories.
CSwiftDirectories is getters that return directories used by swift.
This commit is contained in:
Mat Sutcliffe
2020-08-24 22:04:10 +01:00
parent 802576eda9
commit 8e065a8fef
61 changed files with 880 additions and 803 deletions

View File

@@ -7,6 +7,7 @@
*/
#include "blackmisc/applicationinfolist.h"
#include "blackmisc/swiftdirectories.h"
#include "blackmisc/directoryutils.h"
#include "blackconfig/buildconfig.h"
@@ -45,8 +46,8 @@ namespace BlackMisc
{
this->clear();
const QMap<QString, CApplicationInfo> otherVersions = reinit ?
CDirectoryUtils::currentApplicationDataDirectoryMapWithoutCurrentVersion() :
CDirectoryUtils::applicationDataDirectoryMapWithoutCurrentVersion();
CSwiftDirectories::currentApplicationDataDirectoryMapWithoutCurrentVersion() :
CSwiftDirectories::applicationDataDirectoryMapWithoutCurrentVersion();
for (const CApplicationInfo &info : otherVersions)
{

View File

@@ -7,7 +7,7 @@
*/
#include "blackmisc/audio/audiosettings.h"
#include "blackmisc/directoryutils.h"
#include "blackmisc/swiftdirectories.h"
#include "blackmisc/fileutils.h"
#include <QChar>
#include <QtGlobal>
@@ -76,13 +76,13 @@ namespace BlackMisc
const QDir d(m_notificationSoundDir);
if (d.exists()) { return m_notificationSoundDir; }
}
return CDirectoryUtils::soundFilesDirectory();
return CSwiftDirectories::soundFilesDirectory();
}
QString CSettings::getNotificationFilePath(const QString &fileName) const
{
if (fileName.isEmpty()) { return {}; }
return CFileUtils::soundFilePathOrDefaultPath(m_notificationSoundDir, fileName);
return CSwiftDirectories::soundFilePathOrDefaultPath(m_notificationSoundDir, fileName);
}
void CSettings::setNotificationVolume(int volume)

View File

@@ -17,6 +17,7 @@
#include "blackmisc/propertyindex.h"
#include "blackmisc/statusmessage.h"
#include "blackmisc/stringutils.h"
#include "blackmisc/swiftdirectories.h"
#include "blackmisc/directoryutils.h"
#include "blackmisc/variant.h"
#include "blackmisc/verify.h"
@@ -191,7 +192,7 @@ namespace BlackMisc
{
static const QString p("airlines/%1_%2.png");
const QString n(p.arg(this->getDbKey(), 5, 10, QChar('0')).arg(this->getDesignator()));
return CFileUtils::appendFilePaths(CDirectoryUtils::imagesDirectory(), n);
return CFileUtils::appendFilePaths(CSwiftDirectories::imagesDirectory(), n);
}
return {};
}
@@ -489,7 +490,7 @@ namespace BlackMisc
//! \private
QSet<int> iconIdsImpl()
{
QDir dir(CDirectoryUtils::imagesAirlinesDirectory());
QDir dir(CSwiftDirectories::imagesAirlinesDirectory());
Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "image directory missing");
QSet<int> ids;

View File

@@ -12,6 +12,7 @@
#include "blackmisc/pq/pqstring.h"
#include "blackmisc/math/mathutils.h"
#include "blackmisc/fileutils.h"
#include "blackmisc/swiftdirectories.h"
#include "blackmisc/directoryutils.h"
#include "blackmisc/stringutils.h"
#include "blackmisc/comparefunctions.h"
@@ -35,7 +36,7 @@ namespace BlackMisc
QVector<CAltitude::MetricTuple> initMetricValues()
{
QVector<CAltitude::MetricTuple> v;
const QString f = CFileUtils::appendFilePaths(CDirectoryUtils::shareMiscDirectory(), "Metric Altitudes.csv");
const QString f = CFileUtils::appendFilePaths(CSwiftDirectories::shareMiscDirectory(), "Metric Altitudes.csv");
const QString ma = CFileUtils::readFileToString(f);
const QStringList values = splitLines(ma);
for (const QString &value : values)

View File

@@ -8,6 +8,7 @@
#include "blackmisc/compressutils.h"
#include "blackmisc/fileutils.h"
#include "blackmisc/swiftdirectories.h"
#include "blackmisc/directoryutils.h"
#include "blackmisc/stringutils.h"
#include "blackconfig/buildconfig.h"
@@ -36,7 +37,7 @@ namespace BlackMisc
QString executable;
if (CBuildConfig::isRunningOnMacOSPlatform())
{
executable += CDirectoryUtils::binDirectory();
executable += CSwiftDirectories::binDirectory();
executable += '/';
}
executable += QStringLiteral("7za");

View File

@@ -7,6 +7,7 @@
*/
#include "blackmisc/crashhandler.h"
#include "blackmisc/swiftdirectories.h"
#include "blackmisc/directoryutils.h"
#include "blackmisc/logmessage.h"
#include "blackmisc/filelogger.h"
@@ -57,9 +58,9 @@ namespace BlackMisc
{
#ifdef BLACK_USE_CRASHPAD
static const QString crashpadHandler(CBuildConfig::isRunningOnWindowsNtPlatform() ? "swift_crashpad_handler.exe" : "swift_crashpad_handler");
static const QString handler = CFileUtils::appendFilePaths(CDirectoryUtils::binDirectory(), crashpadHandler);
const QString database = CDirectoryUtils::crashpadDatabaseDirectory();
const QString metrics = CDirectoryUtils::crashpadMetricsDirectory();
static const QString handler = CFileUtils::appendFilePaths(CSwiftDirectories::binDirectory(), crashpadHandler);
const QString database = CSwiftDirectories::crashpadDatabaseDirectory();
const QString metrics = CSwiftDirectories::crashpadMetricsDirectory();
if (!QFileInfo::exists(handler)) { return; }

View File

@@ -8,6 +8,7 @@
#include "blackmisc/crashinfo.h"
#include "blackmisc/fileutils.h"
#include "blackmisc/worker.h"
#include <QFile>
#include <QStringBuilder>
@@ -80,7 +81,7 @@ namespace BlackMisc
void CCrashInfo::triggerWritingFile() const
{
if (m_logFileAndPath.isEmpty()) { return; }
CFileUtils::writeStringToFileInBackground(this->summary(), m_logFileAndPath);
CWorker::fromTask(qApp, Q_FUNC_INFO, [this] { writeToFile(); });
}
bool CCrashInfo::writeToFile() const

View File

@@ -7,6 +7,7 @@
*/
#include "blackmisc/directories.h"
#include "blackmisc/swiftdirectories.h"
#include "blackmisc/directoryutils.h"
#include <QFileInfo>
#include <QDir>
@@ -15,12 +16,12 @@ namespace BlackMisc
{
QString CDirectories::getFlightPlanDirectoryOrDefault() const
{
return this->existingOrDefaultDir(this->getFlightPlanDirectory(), CDirectoryUtils::documentationDirectory());
return this->existingOrDefaultDir(this->getFlightPlanDirectory(), CSwiftDirectories::documentationDirectory());
}
QString CDirectories::getLastViewJsonDirectoryOrDefault() const
{
return this->existingOrDefaultDir(this->getLastViewJsonDirectory(), CDirectoryUtils::documentationDirectory());
return this->existingOrDefaultDir(this->getLastViewJsonDirectory(), CSwiftDirectories::documentationDirectory());
}
QString CDirectories::getLastModelDirectoryOrDefault() const
@@ -51,7 +52,7 @@ namespace BlackMisc
{
if (m_dirMatchingScript.isEmpty())
{
return CDirectoryUtils::shareMatchingScriptDirectory();
return CSwiftDirectories::shareMatchingScriptDirectory();
}
return m_dirMatchingScript;
}

View File

@@ -11,6 +11,7 @@
#include "blackmisc/directoryutils.h"
#include "blackmisc/fileutils.h"
#include "blackmisc/stringutils.h"
#include "blackmisc/network/networkutils.h"
#include "blackmisc/range.h"
#include "blackconfig/buildconfig.h"
#include <QCoreApplication>
@@ -22,97 +23,16 @@
#include <QStandardPaths>
using namespace BlackConfig;
using namespace BlackMisc::Network;
namespace BlackMisc
{
QString binDirectoryImpl()
{
QString appDirectoryString(qApp->applicationDirPath());
if (appDirectoryString.endsWith("Contents/MacOS")) { appDirectoryString += "/../../.."; }
QDir appDirectory(appDirectoryString);
return appDirectory.absolutePath();
}
const QString &CDirectoryUtils::binDirectory()
{
static const QString binDir(binDirectoryImpl());
return binDir;
}
bool CDirectoryUtils::isInApplicationDirectory(const QString &path)
{
if (path.isEmpty()) { return false; }
return path.contains(qApp->applicationDirPath(), CFileUtils::osFileNameCaseSensitivity());
}
const QString &CDirectoryUtils::pluginsDirectory()
{
static const QString pDir(CFileUtils::appendFilePaths(binDirectory(), "plugins"));
return pDir;
}
const QString &CDirectoryUtils::audioPluginDirectory()
{
static const QString pDir(CFileUtils::appendFilePaths(binDirectory(), "audio"));
return pDir;
}
const QString &CDirectoryUtils::getXSwiftBusBuildDirectory()
{
if (!CBuildConfig::isLocalDeveloperDebugBuild())
{
static const QString e;
return e;
}
// the xswiftbus directory in out, not in dist
static const QString bd = []
{
QDir dir(binDirectory());
if (!dir.cdUp()) { return QString(); }
if (!dir.cd("xswiftbus")) { return QString(); }
return dir.absolutePath();
}();
return bd;
}
QString CDirectoryUtils::executableFilePath(const QString &executable)
{
Q_ASSERT_X(!executable.isEmpty(), Q_FUNC_INFO, "Missing executable file path");
Q_ASSERT_X(CBuildConfig::isKnownExecutableName(executable), Q_FUNC_INFO, "Unknown exectuable");
QString s = CFileUtils::appendFilePaths(CDirectoryUtils::binDirectory(), executable);
if (CBuildConfig::isRunningOnMacOSPlatform())
{
// MacOS bundle may or may not be a bundle
const QDir dir(s + QLatin1String(".app/Contents/MacOS"));
if (dir.exists())
{
s += QLatin1String(".app/Contents/MacOS/") + executable;
}
}
else if (CBuildConfig::isRunningOnWindowsNtPlatform())
{
s += QLatin1String(".exe");
}
return s;
}
QString normalizedApplicationDirectoryImpl()
{
QString appDir = CDirectoryUtils::binDirectory();
Q_ASSERT(appDir.size() > 0);
// Remove leading '/' on Unix
if (appDir.at(0) == '/') { appDir.remove(0, 1); }
return QUrl::toPercentEncoding(appDir);
}
const QString &CDirectoryUtils::normalizedApplicationDirectory()
{
static const QString appDir(normalizedApplicationDirectoryImpl());
return appDir;
}
bool CDirectoryUtils::isMacOSAppBundle()
{
static const bool appBundle = CBuildConfig::isRunningOnMacOSPlatform() &&
@@ -120,320 +40,6 @@ namespace BlackMisc
return appBundle;
}
const QString &CDirectoryUtils::applicationDataDirectory()
{
static const QString p = CFileUtils::appendFilePaths(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation), "/org.swift-project/");
return p;
}
const QFileInfoList &CDirectoryUtils::applicationDataDirectories()
{
static QFileInfoList fileInfoList = currentApplicationDataDirectories();
return fileInfoList;
}
QFileInfoList CDirectoryUtils::currentApplicationDataDirectories()
{
const QDir swiftAppData(CDirectoryUtils::applicationDataDirectory()); // contains 1..n subdirs
if (!swiftAppData.isReadable()) { return QFileInfoList(); }
return swiftAppData.entryInfoList({}, QDir::Dirs | QDir::NoDotAndDotDot, QDir::Time);
}
int CDirectoryUtils::applicationDataDirectoriesCount()
{
return CDirectoryUtils::applicationDataDirectories().size();
}
QStringList CDirectoryUtils::applicationDataDirectoryList(bool withoutCurrent, bool decodedDirName)
{
QStringList dirs;
for (const QFileInfo &info : CDirectoryUtils::applicationDataDirectories())
{
if (withoutCurrent && info.filePath().contains(normalizedApplicationDirectory(), Qt::CaseInsensitive)) continue;
dirs.append(decodedDirName ?
CDirectoryUtils::decodeNormalizedDirectory(info.filePath()) :
info.filePath());
}
return dirs;
}
const CDirectoryUtils::FilePerApplication &CDirectoryUtils::applicationDataDirectoryMapWithoutCurrentVersion()
{
static const FilePerApplication directories = currentApplicationDataDirectoryMapWithoutCurrentVersion();
return directories;
}
CDirectoryUtils::FilePerApplication CDirectoryUtils::currentApplicationDataDirectoryMapWithoutCurrentVersion()
{
FilePerApplication directories;
for (const QFileInfo &info : CDirectoryUtils::currentApplicationDataDirectories())
{
// check for myself (the running swift)
if (caseInsensitiveStringCompare(info.filePath(), CDirectoryUtils::normalizedApplicationDataDirectory())) { continue; }
// the application info will be written by each swift application started
// so the application type will always contain that application
const QString appInfoFile = CFileUtils::appendFilePaths(info.filePath(), CApplicationInfo::fileName());
const QString appInfoJson = CFileUtils::readFileToString(appInfoFile);
CApplicationInfo appInfo;
if (appInfoJson.isEmpty())
{
// no JSON means the app no longer exists
const QString exeDir = CDirectoryUtils::decodeNormalizedDirectory(info.filePath());
appInfo.setExecutablePath(exeDir);
}
else
{
appInfo = CApplicationInfo::fromJson(appInfoJson);
}
appInfo.setApplicationDataDirectory(info.filePath());
directories.insert(info.filePath(), appInfo);
}
return directories;
}
bool CDirectoryUtils::hasOtherSwiftDataDirectories()
{
return CDirectoryUtils::applicationDataDirectoryMapWithoutCurrentVersion().size() > 0;
}
const QString &CDirectoryUtils::normalizedApplicationDataDirectory()
{
static const QString p = CFileUtils::appendFilePaths(applicationDataDirectory(), normalizedApplicationDirectory());
return p;
}
const QString &CDirectoryUtils::logDirectory()
{
static const QString p = CFileUtils::appendFilePaths(normalizedApplicationDataDirectory(), "/logs");
return p;
}
QString getSwiftShareDirImpl()
{
QDir dir(CDirectoryUtils::binDirectory());
const bool success = dir.cd("../share");
if (success)
{
Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "missing dir");
return dir.absolutePath();
}
Q_ASSERT_X(false, Q_FUNC_INFO, "missing dir");
return {};
}
const QString &CDirectoryUtils::shareDirectory()
{
static const QString s(getSwiftShareDirImpl());
return s;
}
const QString &CDirectoryUtils::shareTestDirectory()
{
static const QString test(CFileUtils::appendFilePaths(CDirectoryUtils::shareDirectory(), "test"));
return test;
}
const QString &CDirectoryUtils::shareMiscDirectory()
{
static const QString misc(CFileUtils::appendFilePaths(CDirectoryUtils::shareDirectory(), "misc"));
return misc;
}
const QString &CDirectoryUtils::shareTerrainProbeDirectory()
{
static const QString tpd(CFileUtils::appendFilePaths(CDirectoryUtils::shareDirectory(), "simulator/swiftTerrainProbe"));
return tpd;
}
const QString &CDirectoryUtils::shareMatchingScriptDirectory()
{
static const QString ms(CFileUtils::appendFilePaths(CDirectoryUtils::shareDirectory(), "matchingscript"));
return ms;
}
const QString &CDirectoryUtils::bootstrapFileName()
{
static const QString n("bootstrap.json");
return n;
}
const QString getBootstrapResourceFileImpl()
{
const QString d(CDirectoryUtils::shareDirectory());
if (d.isEmpty()) { return {}; }
const QFile file(QDir::cleanPath(d + QDir::separator() + "shared/bootstrap/" + CDirectoryUtils::bootstrapFileName()));
Q_ASSERT_X(file.exists(), Q_FUNC_INFO, "missing bootstrap file");
return QFileInfo(file).absoluteFilePath();
}
const QString &CDirectoryUtils::bootstrapResourceFilePath()
{
static const QString s(getBootstrapResourceFileImpl());
return s;
}
QString getSwiftStaticDbFilesDirImpl()
{
const QString d(CDirectoryUtils::shareDirectory());
if (d.isEmpty()) { return {}; }
const QDir dir(QDir::cleanPath(d + QDir::separator() + "shared/dbdata"));
Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "missing dir");
return dir.absolutePath();
}
const QString &CDirectoryUtils::staticDbFilesDirectory()
{
static const QString s(getSwiftStaticDbFilesDirImpl());
return s;
}
QString getSoundFilesDirImpl()
{
const QString d(CDirectoryUtils::shareDirectory());
if (d.isEmpty()) { return {}; }
const QDir dir(QDir::cleanPath(d + QDir::separator() + "sounds"));
Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "missing dir");
return dir.absolutePath();
}
const QString &CDirectoryUtils::soundFilesDirectory()
{
static const QString s(getSoundFilesDirImpl());
return s;
}
QString getStylesheetsDirImpl()
{
const QString d(CDirectoryUtils::shareDirectory());
if (d.isEmpty()) { return {}; }
const QDir dir(QDir::cleanPath(d + QDir::separator() + "qss"));
Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "missing dir");
return dir.absolutePath();
}
const QString &CDirectoryUtils::stylesheetsDirectory()
{
static const QString s(getStylesheetsDirImpl());
return s;
}
QString getImagesDirImpl()
{
const QString d(CDirectoryUtils::shareDirectory());
const QDir dir(QDir::cleanPath(d + QDir::separator() + "images"));
Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "missing dir");
return dir.absolutePath();
}
const QString &CDirectoryUtils::imagesDirectory()
{
static const QString s(getImagesDirImpl());
return s;
}
const QString &CDirectoryUtils::imagesAirlinesDirectory()
{
static const QString s(QDir::cleanPath(imagesDirectory() + QDir::separator() + "airlines"));
return s;
}
const QString &CDirectoryUtils::imagesFlagsDirectory()
{
static const QString s(QDir::cleanPath(imagesDirectory() + QDir::separator() + "flags"));
return s;
}
QString getHtmlDirImpl()
{
const QString d(CDirectoryUtils::shareDirectory());
const QDir dir(QDir::cleanPath(d + QDir::separator() + "html"));
Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "missing dir");
return dir.absolutePath();
}
const QString &CDirectoryUtils::htmlDirectory()
{
static const QString s(getHtmlDirImpl());
return s;
}
QString getLegalDirImpl()
{
const QString d(CDirectoryUtils::shareDirectory());
const QDir dir(QDir::cleanPath(d + QDir::separator() + "legal"));
Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "missing dir");
return dir.absolutePath();
}
const QString &CDirectoryUtils::legalDirectory()
{
static const QString s(getLegalDirImpl());
return s;
}
const QString &CDirectoryUtils::aboutFilePath()
{
static const QString about = QDir::cleanPath(CDirectoryUtils::legalDirectory() + QDir::separator() + "about.html");
return about;
}
QString testFilesDirImpl()
{
const QString d(CDirectoryUtils::shareDirectory());
if (d.isEmpty()) { return {}; }
const QDir dir(QDir::cleanPath(d + QDir::separator() + "test"));
Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "missing dir");
return dir.absolutePath();
}
const QString &CDirectoryUtils::testFilesDirectory()
{
static QString s(testFilesDirImpl());
return s;
}
const QString &CDirectoryUtils::htmlTemplateFilePath()
{
static const QString s(htmlDirectory() + QDir::separator() + "swifttemplate.html");
return s;
}
QString getDocumentationDirectoryImpl()
{
const QStringList pathes(QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation));
QString d = pathes.first();
d = QDir::cleanPath(CFileUtils::appendFilePaths(d, "swift"));
QDir dir(d);
if (dir.exists()) { return dir.absolutePath(); }
return pathes.first();
}
const QString &CDirectoryUtils::documentationDirectory()
{
static const QString d(getDocumentationDirectoryImpl());
return d;
}
const QString &CDirectoryUtils::crashpadDirectory()
{
static const QString p = CFileUtils::appendFilePaths(normalizedApplicationDataDirectory(), "/crashpad");
return p;
}
const QString &CDirectoryUtils::crashpadDatabaseDirectory()
{
static const QString p = CFileUtils::appendFilePaths(crashpadDirectory(), "/database");
return p;
}
const QString &CDirectoryUtils::crashpadMetricsDirectory()
{
static const QString p = CFileUtils::appendFilePaths(crashpadDirectory(), "/metrics");
return p;
}
QString CDirectoryUtils::decodeNormalizedDirectory(const QString &directory)
{
return QUrl::fromPercentEncoding(directory.toUtf8());
@@ -464,34 +70,6 @@ namespace BlackMisc
return false;
}
QStringList CDirectoryUtils::verifyRuntimeDirectoriesAndFiles()
{
QStringList failed;
QDir d(CDirectoryUtils::binDirectory());
if (!d.isReadable()) { failed.append(d.absolutePath()); }
d = QDir(CDirectoryUtils::imagesDirectory());
if (!d.isReadable()) { failed.append(d.absolutePath()); }
d = QDir(CDirectoryUtils::stylesheetsDirectory());
if (!d.isReadable()) { failed.append(d.absolutePath()); }
d = QDir(CDirectoryUtils::applicationDataDirectory());
if (!d.isReadable()) { failed.append(d.absolutePath()); }
// check if the executables are avialable
QString fn = CDirectoryUtils::executableFilePath(CBuildConfig::swiftCoreExecutableName());
if (!QFile::exists(fn)) { failed.append(fn); }
fn = CDirectoryUtils::executableFilePath(CBuildConfig::swiftDataExecutableName());
if (!QFile::exists(fn)) { failed.append(fn); }
fn = CDirectoryUtils::executableFilePath(CBuildConfig::swiftGuiExecutableName());
if (!QFile::exists(fn)) { failed.append(fn); }
return failed;
}
bool CDirectoryUtils::existsUnemptyDirectory(const QString &testDir)
{
if (testDir.isEmpty()) { return false; }
@@ -520,24 +98,43 @@ namespace BlackMisc
bool CDirectoryUtils::isDirExisting(const QString &path)
{
if (!CBuildConfig::isRunningOnWindowsNtPlatform())
if (CBuildConfig::isRunningOnWindowsNtPlatform() && CFileUtils::isWindowsUncPath(path))
{
const QDir dir(path);
return dir.exists();
const QString machine(CFileUtils::windowsUncMachine(path));
if (!canPingUncMachine(machine)) { return false; } // avoid long "hanging" if machine is switched off
}
return QDir(path).exists();
}
bool CDirectoryUtils::canPingUncMachine(const QString &machine)
{
static QMap<QString, qint64> good;
static QMap<QString, qint64> bad;
if (machine.isEmpty()) { return false; }
const QString m = machine.toLower();
if (good.contains(m)) { return true; } // good ones we only test once
if (bad.contains(m))
{
const qint64 ts = bad.value(m);
const qint64 dt = QDateTime::currentSecsSinceEpoch() - ts;
if (dt < 1000 * 60) { return false; } // still bad
// outdated, test again
}
// Windows
if (!CFileUtils::isWindowsUncPath(path))
const bool p = CNetworkUtils::canPing(m);
if (p)
{
const QDir dir(path);
return dir.exists();
good.insert(m, QDateTime::currentSecsSinceEpoch());
bad.remove(m);
}
const QString machine(CFileUtils::windowsUncMachine(path));
if (!CFileUtils::canPingUncMachine(machine)) { return false; } // avoid long "hanging" if machine is switched off
const QDir dir(path);
const bool e = dir.exists();
return e;
else
{
bad.insert(m, QDateTime::currentSecsSinceEpoch());
good.remove(m);
}
return p;
}
bool CDirectoryUtils::isDirExisting(const QDir &dir)

View File

@@ -11,7 +11,6 @@
#ifndef BLACKMISC_DIRECTORYUTILS_H
#define BLACKMISC_DIRECTORYUTILS_H
#include "blackmisc/applicationinfo.h"
#include "blackmisc/blackmiscexport.h"
#include <QMap>
#include <QSet>
@@ -28,136 +27,13 @@ namespace BlackMisc
class BLACKMISC_EXPORT CDirectoryUtils
{
public:
//! File path and swift application
using FilePerApplication = QMap<QString, CApplicationInfo>;
//! Returns the bin directory. On Windows/Linux this is the same directory as
//! QCoreApplication::applicationDirPath(), but on MacOS the exceutable is
//! located deeper in the hierarchy of the bundles
//! \see https://dev.swift-project.org/w/dev/swiftpc/dirstructure/
static const QString &binDirectory();
//! Path in application directory
static bool isInApplicationDirectory(const QString &path);
//! Plugins directory
static const QString &pluginsDirectory();
//! Audio plugins directory for Qt audio
//! \remark contains the audio plugins
static const QString &audioPluginDirectory();
//! The build directory
//! \remark if is a local build
static const QString &getXSwiftBusBuildDirectory();
//! The executable file path
static QString executableFilePath(const QString &executable);
//! swift application data directory, contains 0..n swift installation directories
//! \remark use CDirectoryUtils::normalizedApplicationDataDirectory for one specific version
static const QString &applicationDataDirectory();
//! swift application data sub directories
static const QFileInfoList &applicationDataDirectories();
//! number of data directories (including this version)
static int applicationDataDirectoriesCount();
//! swift application data sub directories
static QFileInfoList currentApplicationDataDirectories();
//! swift application data sub directories
static QStringList applicationDataDirectoryList(bool withoutCurrent = false, bool decodedDirName = false);
//! swift application data sub directories with info if available
static const FilePerApplication &applicationDataDirectoryMapWithoutCurrentVersion();
//! swift application data sub directories with info if available
static FilePerApplication currentApplicationDataDirectoryMapWithoutCurrentVersion();
//! Other swift data directories
static bool hasOtherSwiftDataDirectories();
//! Is MacOS application bundle?
//! \remark: Means the currently running executable is a MacOS bundle, but not all our executables are bundles on MacOS
static bool isMacOSAppBundle();
//! swift application data directory for one specific installation (a version)
//! \remark use CDirectoryUtils::applicationDataDirectory for one all swift versions
static const QString &normalizedApplicationDataDirectory();
//! Where resource files (static DB files, ...) etc are located
//! \remark share not shared (do no mix)
static const QString &shareDirectory();
//! The test data directory
static const QString &shareTestDirectory();
//! The misc data directory
static const QString &shareMiscDirectory();
//! FSX/P3D terrain probe
static const QString &shareTerrainProbeDirectory();
//! Matching script examples directories
static const QString &shareMatchingScriptDirectory();
//! Bootstrap file name
static const QString &bootstrapFileName();
//! Bootstrap resource file path
static const QString &bootstrapResourceFilePath();
//! Where static DB files are located
static const QString &staticDbFilesDirectory();
//! Where sound files are located
static const QString &soundFilesDirectory();
//! Where qss files are located
static const QString &stylesheetsDirectory();
//! Where images are located
static const QString &imagesDirectory();
//! Where airline images are located
static const QString &imagesAirlinesDirectory();
//! Where flags images are located
static const QString &imagesFlagsDirectory();
//! Where HTML files are located
static const QString &htmlDirectory();
//! Where Legal files are located
static const QString &legalDirectory();
//! The about document file location
static const QString &aboutFilePath();
//! Where test files are located
static const QString &testFilesDirectory();
//! HTML template
static const QString &htmlTemplateFilePath();
//! Directory where data can be stored
static const QString &documentationDirectory();
//! Directory for log files
//! \remark In BlackMisc so it can also be used from BlackMisc classes
static const QString &logDirectory();
//! Directory for crashpad files
static const QString &crashpadDirectory();
//! Directory for crashpad database files
static const QString &crashpadDatabaseDirectory();
//! Directory for crashpad metrics files
static const QString &crashpadMetricsDirectory();
//! Virtually the inverse operation of CDirectoryUtils::normalizedApplicationDirectory
static QString decodeNormalizedDirectory(const QString &directory);
@@ -167,9 +43,6 @@ namespace BlackMisc
//! Any file with filter like "*.txt"
static bool containsFileInDir(const QString &dir, const QString &filter, bool recursively);
//! Check if the (most important) runtime directories are available
static QStringList verifyRuntimeDirectoriesAndFiles();
//! Exists directory and does it contains files
static bool existsUnemptyDirectory(const QString &testDir);
@@ -226,11 +99,6 @@ namespace BlackMisc
static DirComparison compareTwoDirectories(const QString &dirSource, const QString &dirTarget, bool nestedDirs);
private:
//! Returns the application directory of the calling executable as normalized string.
//! \note There is no trailing '/'.
//! \warning The normalization rules are implementation specific and could change over time.
static const QString &normalizedApplicationDirectory();
//! Convert filenames to set
static QSet<QString> fileNamesToQSet(const QFileInfoList &fileInfoList);
@@ -239,6 +107,9 @@ namespace BlackMisc
//! File to canonical names
static const QSet<QString> filesToCanonicalNames(const QSet<QString> &fileNames, const QSet<QString> &canonicalFileNames);
//! Can connect the UNC machine
static bool canPingUncMachine(const QString &machine);
};
} // ns

View File

@@ -8,6 +8,7 @@
#include "blackmisc/filelogger.h"
#include "blackmisc/loghandler.h"
#include "blackmisc/swiftdirectories.h"
#include "blackmisc/directoryutils.h"
#include "blackconfig/buildconfig.h"
@@ -51,7 +52,7 @@ namespace BlackMisc
m_logFile(this)
{
Q_ASSERT(! applicationName().isEmpty());
QDir::root().mkpath(CDirectoryUtils::logDirectory());
QDir::root().mkpath(CSwiftDirectories::logDirectory());
removeOldLogFiles();
m_logFile.setFileName(getLogFilePath());
m_logFile.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text);
@@ -104,7 +105,7 @@ namespace BlackMisc
QString CFileLogger::getLogFilePath()
{
QString filePath = CDirectoryUtils::logDirectory() % '/' % logFileName();
QString filePath = CSwiftDirectories::logDirectory() % '/' % logFileName();
return filePath;
}
@@ -112,7 +113,7 @@ namespace BlackMisc
{
QString nameFilter(applicationName());
nameFilter += QLatin1String("*.log");
QDir dir(CDirectoryUtils::logDirectory(), nameFilter, QDir::Name, QDir::Files);
QDir dir(CSwiftDirectories::logDirectory(), nameFilter, QDir::Name, QDir::Files);
QDateTime now = QDateTime::currentDateTime();
for (const auto &logFileInfo : dir.entryInfoList())

View File

@@ -7,9 +7,6 @@
*/
#include "blackmisc/fileutils.h"
#include "blackmisc/network/networkutils.h"
#include "blackmisc/math/mathutils.h"
#include "blackmisc/worker.h"
#include "blackmisc/directoryutils.h"
#include "blackconfig/buildconfig.h"
@@ -29,8 +26,6 @@
#include <QStringBuilder>
using namespace BlackConfig;
using namespace BlackMisc::Math;
using namespace BlackMisc::Network;
namespace BlackMisc
{
@@ -101,17 +96,6 @@ namespace BlackMisc
return readLockedFileToString(appendFilePaths(filePath, fileName));
}
bool CFileUtils::writeStringToFileInBackground(const QString &content, const QString &fileNameAndPath)
{
if (fileNameAndPath.isEmpty()) { return false; }
CWorker *worker = CWorker::fromTask(QCoreApplication::instance(), "writeStringToFileInBackground", [content, fileNameAndPath]()
{
const bool s = CFileUtils::writeStringToFile(content, fileNameAndPath);
Q_UNUSED(s);
});
return worker ? true : false;
}
QString CFileUtils::appendFilePaths(const QString &path1, const QString &path2)
{
if (path1.isEmpty()) { return QDir::cleanPath(path2); }
@@ -531,37 +515,6 @@ namespace BlackMisc
return machines;
}
bool CFileUtils::canPingUncMachine(const QString &machine)
{
static QMap<QString, qint64> good;
static QMap<QString, qint64> bad;
if (machine.isEmpty()) { return false; }
const QString m = machine.toLower();
if (good.contains(m)) { return true; } // good ones we only test once
if (bad.contains(m))
{
const qint64 ts = bad.value(m);
const qint64 dt = QDateTime::currentSecsSinceEpoch() - ts;
if (dt < 1000 * 60) { return false; } // still bad
// outdated, test again
}
const bool p = CNetworkUtils::canPing(m);
if (p)
{
good.insert(m, QDateTime::currentSecsSinceEpoch());
bad.remove(m);
}
else
{
bad.insert(m, QDateTime::currentSecsSinceEpoch());
good.remove(m);
}
return p;
}
QString CFileUtils::toWindowsLocalPath(const QString &path)
{
QString p = CFileUtils::fixWindowsUncPath(path);
@@ -583,7 +536,7 @@ namespace BlackMisc
unit = i.next();
currentSize /= 1024.0;
}
return QStringLiteral("%1 %2").arg(CMathUtils::roundAsString(currentSize, 2), unit);
return QStringLiteral("%1 %2").arg(currentSize, 0, 'f', 2).arg(unit);
}
const QStringList &CFileUtils::executableSuffixes()
@@ -608,28 +561,4 @@ namespace BlackMisc
if (fileName.isEmpty()) { return false; }
return fileName.contains("swift", Qt::CaseInsensitive) && fileName.contains("installer");
}
QString CFileUtils::soundFilePathAndFileName(const QString &name)
{
if (name.isEmpty()) { return {}; }
return CFileUtils::appendFilePaths(CDirectoryUtils::soundFilesDirectory(), name);
}
QString CFileUtils::soundFilePathOrDefaultPath(const QString &directory, const QString &fileName)
{
if (!directory.isEmpty())
{
const QString fp = CFileUtils::appendFilePathsAndFixUnc(directory, fileName);
const QFileInfo fi(fp);
if (fi.exists()) { return fi.absoluteFilePath(); }
}
const QString fp = CFileUtils::appendFilePathsAndFixUnc(CDirectoryUtils::soundFilesDirectory(), fileName);
const QFileInfo fi(fp);
return (fi.exists()) ? fi.absoluteFilePath() : QString();
}
QUrl CFileUtils::soundFileQUrlOrDefault(const QString &directory, const QString &fileName)
{
return QUrl::fromLocalFile(soundFilePathOrDefaultPath(directory, fileName));
}
} // ns

View File

@@ -57,9 +57,6 @@ namespace BlackMisc
//! Read file into string, with a lock so two applications can't access at the same time
static QString readLockedFileToString(const QString &filePath, const QString &fileName);
//! Write string to text file in background
static bool writeStringToFileInBackground(const QString &content, const QString &fileNameAndPath);
//! Write byte array to file
static bool writeByteArrayToFile(const QByteArray &data, const QString &fileNameAndPath);
@@ -184,9 +181,6 @@ namespace BlackMisc
//! All UNC machines from the paths
static QSet<QString> windowsUncMachines(const QSet<QString> &paths);
//! Can connect the UNC machine
static bool canPingUncMachine(const QString &machine);
//! To Windows path using "\" delimiter
static QString toWindowsLocalPath(const QString &path);
@@ -201,15 +195,6 @@ namespace BlackMisc
//! swift installer
static bool isSwiftInstaller(const QString &fileName);
//! Returns the full path and file name for a sound file
static QString soundFilePathAndFileName(const QString &name);
//! File path (with file name) of file name and
static QString soundFilePathOrDefaultPath(const QString &directory, const QString &fileName);
//! QUrl of soundFilePathAndFileName
static QUrl soundFileQUrlOrDefault(const QString &directory, const QString &fileName);
};
} // ns

View File

@@ -9,6 +9,7 @@
//! \cond PRIVATE
#include "blackmisc/icons.h"
#include "blackmisc/swiftdirectories.h"
#include "blackmisc/directoryutils.h"
#include "blackmisc/fileutils.h"
#include "blackmisc/threadutils.h"
@@ -1342,7 +1343,7 @@ namespace BlackMisc
Q_ASSERT_X(!relativeFileName.isEmpty(), Q_FUNC_INFO, "missing filename");
Q_ASSERT_X(CThreadUtils::thisIsMainThread(), Q_FUNC_INFO, "not thread safe");
fullFilePath = CFileUtils::appendFilePaths(CDirectoryUtils::imagesDirectory(), relativeFileName);
fullFilePath = CFileUtils::appendFilePaths(CSwiftDirectories::imagesDirectory(), relativeFileName);
if (!getResourceFileCache().contains(relativeFileName))
{
QPixmap pm;

View File

@@ -16,6 +16,7 @@
#include "blackmisc/iterator.h"
#include "blackmisc/range.h"
#include "blackmisc/fileutils.h"
#include "blackmisc/swiftdirectories.h"
#include "blackmisc/directoryutils.h"
#include "blackmisc/statusmessage.h"
#include "blackmisc/stringutils.h"
@@ -1886,7 +1887,7 @@ namespace BlackMisc
const QString &CAircraftModelList::invalidModelFileAndPath()
{
static const QString f = CFileUtils::appendFilePathsAndFixUnc(CDirectoryUtils::logDirectory(), "invalidmodels.json");
static const QString f = CFileUtils::appendFilePathsAndFixUnc(CSwiftDirectories::logDirectory(), "invalidmodels.json");
return f;
}

View File

@@ -9,6 +9,7 @@
#include "blackmisc/simulation/aircraftmodelutils.h"
#include "blackmisc/simulation/fscommon/fscommonutil.h"
#include "blackmisc/simulation/aircraftmodellist.h"
#include "blackmisc/swiftdirectories.h"
#include "blackmisc/directoryutils.h"
#include "blackmisc/verify.h"
@@ -134,7 +135,7 @@ namespace BlackMisc
BLACK_VERIFY_X(dir.exists(), Q_FUNC_INFO, "Directory does not exist");
if (!dir.exists()) { return {}; }
const QString htmlTemplate = CFileUtils::readFileToString(CDirectoryUtils::htmlTemplateFilePath());
const QString htmlTemplate = CFileUtils::readFileToString(CSwiftDirectories::htmlTemplateFilePath());
const QString fn("airlineAircraftMatrix.html");
const bool ok = CFileUtils::writeStringToFile(htmlTemplate.arg(html), dir.absoluteFilePath(fn));
return ok ? dir.absoluteFilePath(fn) : "";

View File

@@ -7,6 +7,7 @@
*/
#include "autopublishdata.h"
#include "blackmisc/swiftdirectories.h"
#include "blackmisc/fileutils.h"
#include "blackmisc/json.h"
#include "blackmisc/logcategorylist.h"
@@ -106,7 +107,7 @@ namespace BlackMisc
{
if (this->isEmpty()) { return false; }
const QString fn = fileBaseName() % u'_' % QDateTime::currentDateTimeUtc().toString("yyyyMMddHHmmss") % fileAppendix();
return this->writeJsonToFile(CFileUtils::appendFilePaths(CDirectoryUtils::logDirectory(), fn));
return this->writeJsonToFile(CFileUtils::appendFilePaths(CSwiftDirectories::logDirectory(), fn));
}
bool CAutoPublishData::writeJsonToFile(const QString &pathAndFile) const

View File

@@ -16,6 +16,7 @@
#include "blackmisc/pq/length.h"
#include "blackmisc/datacache.h"
#include "blackmisc/statusmessagelist.h"
#include "blackmisc/swiftdirectories.h"
#include "blackmisc/directoryutils.h"
#include "blackmisc/blackmiscexport.h"
@@ -91,7 +92,7 @@ namespace BlackMisc
bool readFromJsonFile(const QString &fileAndPath, bool clear = true);
//! Read all JSON files matching the base name
int readFromJsonFiles(const QString &dirPath = CDirectoryUtils::logDirectory());
int readFromJsonFiles(const QString &dirPath = CSwiftDirectories::logDirectory());
//! Analyze against DB data
CStatusMessageList analyzeAgainstDBData(const CAircraftModelList &dbModels);
@@ -109,10 +110,10 @@ namespace BlackMisc
static const QString &fileAppendix();
//! Do any auto pubish files exist?
static bool existAutoPublishFiles(const QString &dirPath = CDirectoryUtils::logDirectory());
static bool existAutoPublishFiles(const QString &dirPath = CSwiftDirectories::logDirectory());
//! Delete any existing auto publish files
static int deleteAutoPublishFiles(const QString &dirPath = CDirectoryUtils::logDirectory());
static int deleteAutoPublishFiles(const QString &dirPath = CSwiftDirectories::logDirectory());
// ----------------- testing only ---------------

View File

@@ -8,6 +8,7 @@
#include "fscommonutil.h"
#include "aircraftcfgparser.h"
#include "blackmisc/swiftdirectories.h"
#include "blackmisc/directoryutils.h"
#include "blackmisc/fileutils.h"
#include "blackmisc/stringutils.h"
@@ -418,9 +419,9 @@ namespace BlackMisc
int CFsCommonUtil::copyFsxTerrainProbeFiles(const QString &simObjectDir, CStatusMessageList &messages)
{
messages.clear();
if (!CDirectoryUtils::existsUnemptyDirectory(CDirectoryUtils::shareTerrainProbeDirectory()))
if (!CDirectoryUtils::existsUnemptyDirectory(CSwiftDirectories::shareTerrainProbeDirectory()))
{
messages.push_back(CStatusMessage(getLogCategories(), CStatusMessage::SeverityError, u"No terrain probe source files in '%1'") << CDirectoryUtils::shareTerrainProbeDirectory());
messages.push_back(CStatusMessage(getLogCategories(), CStatusMessage::SeverityError, u"No terrain probe source files in '%1'") << CSwiftDirectories::shareTerrainProbeDirectory());
return -1;
}
@@ -438,7 +439,7 @@ namespace BlackMisc
return -1;
}
const QString lastSegment = CFileUtils::lastPathSegment(CDirectoryUtils::shareTerrainProbeDirectory());
const QString lastSegment = CFileUtils::lastPathSegment(CSwiftDirectories::shareTerrainProbeDirectory());
targetDir = CFileUtils::appendFilePathsAndFixUnc(targetDir, lastSegment);
const bool hasDir = td.mkpath(targetDir);
if (!hasDir)
@@ -447,8 +448,8 @@ namespace BlackMisc
return -1;
}
const int copied = CDirectoryUtils::copyDirectoryRecursively(CDirectoryUtils::shareTerrainProbeDirectory(), targetDir, true);
messages.push_back(CStatusMessage(getLogCategories(), CStatusMessage::SeverityInfo, u"Copied %1 files from '%2' to '%3'") << copied << CDirectoryUtils::shareTerrainProbeDirectory() << targetDir);
const int copied = CDirectoryUtils::copyDirectoryRecursively(CSwiftDirectories::shareTerrainProbeDirectory(), targetDir, true);
messages.push_back(CStatusMessage(getLogCategories(), CStatusMessage::SeverityInfo, u"Copied %1 files from '%2' to '%3'") << copied << CSwiftDirectories::shareTerrainProbeDirectory() << targetDir);
return copied;
}

View File

@@ -16,6 +16,7 @@
#include "blackmisc/pq/length.h"
#include "blackmisc/logmessage.h"
#include "blackmisc/worker.h"
#include "blackmisc/swiftdirectories.h"
#include "blackmisc/directoryutils.h"
#include "blackconfig/buildconfig.h"
#include <QDateTime>
@@ -72,7 +73,7 @@ namespace BlackMisc
QStringList CInterpolationLogger::getLatestLogFiles()
{
QStringList files({ "", "" });
const QString logDir = CDirectoryUtils::logDirectory();
const QString logDir = CSwiftDirectories::logDirectory();
QDir logs(logDir);
if (!logs.exists()) { return files; }
logs.setNameFilters(filePatterns());
@@ -91,14 +92,14 @@ namespace BlackMisc
QString CInterpolationLogger::getLogDirectory()
{
return CDirectoryUtils::logDirectory();
return CSwiftDirectories::logDirectory();
}
CStatusMessageList CInterpolationLogger::writeLogFiles(const QList<SituationLog> &interpolation, const QList<PartsLog> &parts)
{
if (parts.isEmpty() && interpolation.isEmpty()) { return CStatusMessage(static_cast<CInterpolationLogger *>(nullptr)).warning(u"No data for log"); }
static const QString html = QStringLiteral("Entries: %1\n\n%2");
const QString htmlTemplate = CFileUtils::readFileToString(CDirectoryUtils::htmlTemplateFilePath());
const QString htmlTemplate = CFileUtils::readFileToString(CSwiftDirectories::htmlTemplateFilePath());
CStatusMessageList msgs;
const QString ts = QDateTime::currentDateTimeUtc().toString("yyyyMMddhhmmss");
@@ -108,7 +109,7 @@ namespace BlackMisc
{
QString file = filePatternInterpolationLog();
file.remove('*');
const QString fn = CFileUtils::appendFilePaths(CDirectoryUtils::logDirectory(), QStringLiteral("%1 %2").arg(ts, file));
const QString fn = CFileUtils::appendFilePaths(CSwiftDirectories::logDirectory(), QStringLiteral("%1 %2").arg(ts, file));
const bool s = CFileUtils::writeStringToFile(htmlTemplate.arg(html.arg(interpolation.size()).arg(htmlInterpolation)), fn);
msgs.push_back(CInterpolationLogger::logStatusFileWriting(s, fn));
}
@@ -118,7 +119,7 @@ namespace BlackMisc
{
QString file = filePatternPartsLog();
file.remove('*');
const QString fn = CFileUtils::appendFilePaths(CDirectoryUtils::logDirectory(), QStringLiteral("%1 %2").arg(ts, file));
const QString fn = CFileUtils::appendFilePaths(CSwiftDirectories::logDirectory(), QStringLiteral("%1 %2").arg(ts, file));
const bool s = CFileUtils::writeStringToFile(htmlTemplate.arg(html.arg(parts.size()).arg(htmlParts)), fn);
msgs.push_back(CInterpolationLogger::logStatusFileWriting(s, fn));
}
@@ -126,7 +127,7 @@ namespace BlackMisc
QString kml = CKmlUtils::wrapAsKmlDocument(CInterpolationLogger::getKmlChangedSituations(interpolation));
if (!kml.isEmpty())
{
const QString fn = CFileUtils::appendFilePaths(CDirectoryUtils::logDirectory(), QStringLiteral("%1_changedSituations.kml").arg(ts));
const QString fn = CFileUtils::appendFilePaths(CSwiftDirectories::logDirectory(), QStringLiteral("%1_changedSituations.kml").arg(ts));
const bool s = CFileUtils::writeStringToFile(kml, fn);
msgs.push_back(CInterpolationLogger::logStatusFileWriting(s, fn));
}
@@ -134,7 +135,7 @@ namespace BlackMisc
kml = CKmlUtils::wrapAsKmlDocument(CInterpolationLogger::getKmlInterpolatedSituations(interpolation));
if (!kml.isEmpty())
{
const QString fn = CFileUtils::appendFilePaths(CDirectoryUtils::logDirectory(), QStringLiteral("%1_interpolatedSituations.kml").arg(ts));
const QString fn = CFileUtils::appendFilePaths(CSwiftDirectories::logDirectory(), QStringLiteral("%1_interpolatedSituations.kml").arg(ts));
const bool s = CFileUtils::writeStringToFile(kml, fn);
msgs.push_back(CInterpolationLogger::logStatusFileWriting(s, fn));
}
@@ -142,7 +143,7 @@ namespace BlackMisc
kml = CKmlUtils::wrapAsKmlDocument(CInterpolationLogger::getKmlElevations(interpolation));
if (!kml.isEmpty())
{
const QString fn = CFileUtils::appendFilePaths(CDirectoryUtils::logDirectory(), QStringLiteral("%1_elevations.kml").arg(ts));
const QString fn = CFileUtils::appendFilePaths(CSwiftDirectories::logDirectory(), QStringLiteral("%1_elevations.kml").arg(ts));
const bool s = CFileUtils::writeStringToFile(kml, fn);
msgs.push_back(CInterpolationLogger::logStatusFileWriting(s, fn));
}

View File

@@ -8,6 +8,7 @@
#include "blackmisc/simulation/xplane/xplaneutil.h"
#include "blackmisc/fileutils.h"
#include "blackmisc/swiftdirectories.h"
#include "blackmisc/directoryutils.h"
#include "qsystemdetection.h"
#include <QDir>
@@ -213,7 +214,7 @@ namespace BlackMisc
bool CXPlaneUtil::hasXSwiftBusBuildAndPluginDir(const QString &xplaneRootDir)
{
if (CDirectoryUtils::getXSwiftBusBuildDirectory().isEmpty()) { return false; }
if (CSwiftDirectories::getXSwiftBusBuildDirectory().isEmpty()) { return false; }
const QString xswiftBusPluginDir = CXPlaneUtil::xswiftbusPluginDir(xplaneRootDir);
return (!xswiftBusPluginDir.isEmpty());
}
@@ -255,11 +256,11 @@ namespace BlackMisc
bool CXPlaneUtil::hasNewerXSwiftBusBuild(const QString &xplaneRootDir)
{
if (CDirectoryUtils::getXSwiftBusBuildDirectory().isEmpty()) { return false; }
if (CSwiftDirectories::getXSwiftBusBuildDirectory().isEmpty()) { return false; }
const QString xswiftBusPluginDir = CXPlaneUtil::xswiftbusPluginDir(xplaneRootDir);
if (xswiftBusPluginDir.isEmpty()) { return false; }
const QFileInfo fiLatestBuild = CFileUtils::findLastModified(CDirectoryUtils::getXSwiftBusBuildDirectory(), true, xplFileFilter());
const QFileInfo fiLatestBuild = CFileUtils::findLastModified(CSwiftDirectories::getXSwiftBusBuildDirectory(), true, xplFileFilter());
if (!fiLatestBuild.lastModified().isValid()) { return false; }
const QFileInfo fiLatestDeployed = CFileUtils::findLastModified(xswiftBusPluginDir, true, xplFileFilter());
@@ -271,11 +272,11 @@ namespace BlackMisc
int CXPlaneUtil::copyXSwiftBusBuildFiles(const QString &xplaneRootDir)
{
if (CDirectoryUtils::getXSwiftBusBuildDirectory().isEmpty()) { return -1; }
if (CSwiftDirectories::getXSwiftBusBuildDirectory().isEmpty()) { return -1; }
const QString xswiftBusPluginDir = CXPlaneUtil::xswiftbusPluginDir(xplaneRootDir);
if (xswiftBusPluginDir.isEmpty()) { return -1; }
return CDirectoryUtils::copyDirectoryRecursively(CDirectoryUtils::getXSwiftBusBuildDirectory(), xswiftBusPluginDir, true);
return CDirectoryUtils::copyDirectoryRecursively(CSwiftDirectories::getXSwiftBusBuildDirectory(), xswiftBusPluginDir, true);
}
const QStringList &CXPlaneUtil::xplFileFilter()

View File

@@ -0,0 +1,468 @@
/* Copyright (C) 2020
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
* or distributed except according to the terms contained in the LICENSE file.
*/
//! \cond PRIVATE
#include "blackmisc/swiftdirectories.h"
#include "blackmisc/directoryutils.h"
#include "blackmisc/fileutils.h"
#include "blackmisc/stringutils.h"
#include "blackmisc/range.h"
#include "blackconfig/buildconfig.h"
#include <QCoreApplication>
#include <QDir>
#include <QUrl>
#include <QSet>
#include <QDateTime>
#include <QRegularExpression>
#include <QStandardPaths>
using namespace BlackConfig;
namespace BlackMisc
{
QString binDirectoryImpl()
{
QString appDirectoryString(qApp->applicationDirPath());
if (appDirectoryString.endsWith("Contents/MacOS")) { appDirectoryString += "/../../.."; }
QDir appDirectory(appDirectoryString);
return appDirectory.absolutePath();
}
const QString &CSwiftDirectories::binDirectory()
{
static const QString binDir(binDirectoryImpl());
return binDir;
}
const QString &CSwiftDirectories::pluginsDirectory()
{
static const QString pDir(CFileUtils::appendFilePaths(binDirectory(), "plugins"));
return pDir;
}
const QString &CSwiftDirectories::audioPluginDirectory()
{
static const QString pDir(CFileUtils::appendFilePaths(binDirectory(), "audio"));
return pDir;
}
const QString &CSwiftDirectories::getXSwiftBusBuildDirectory()
{
if (!CBuildConfig::isLocalDeveloperDebugBuild())
{
static const QString e;
return e;
}
// the xswiftbus directory in out, not in dist
static const QString bd = []
{
QDir dir(binDirectory());
if (!dir.cdUp()) { return QString(); }
if (!dir.cd("xswiftbus")) { return QString(); }
return dir.absolutePath();
}();
return bd;
}
QString CSwiftDirectories::executableFilePath(const QString &executable)
{
Q_ASSERT_X(!executable.isEmpty(), Q_FUNC_INFO, "Missing executable file path");
Q_ASSERT_X(CBuildConfig::isKnownExecutableName(executable), Q_FUNC_INFO, "Unknown exectuable");
QString s = CFileUtils::appendFilePaths(binDirectory(), executable);
if (CBuildConfig::isRunningOnMacOSPlatform())
{
// MacOS bundle may or may not be a bundle
const QDir dir(s + QLatin1String(".app/Contents/MacOS"));
if (dir.exists())
{
s += QLatin1String(".app/Contents/MacOS/") + executable;
}
}
else if (CBuildConfig::isRunningOnWindowsNtPlatform())
{
s += QLatin1String(".exe");
}
return s;
}
QString normalizedApplicationDirectoryImpl()
{
QString appDir = CSwiftDirectories::binDirectory();
Q_ASSERT(appDir.size() > 0);
// Remove leading '/' on Unix
if (appDir.at(0) == '/') { appDir.remove(0, 1); }
return QUrl::toPercentEncoding(appDir);
}
const QString &CSwiftDirectories::normalizedApplicationDirectory()
{
static const QString appDir(normalizedApplicationDirectoryImpl());
return appDir;
}
const QString &CSwiftDirectories::applicationDataDirectory()
{
static const QString p = CFileUtils::appendFilePaths(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation), "/org.swift-project/");
return p;
}
const QFileInfoList &CSwiftDirectories::applicationDataDirectories()
{
static QFileInfoList fileInfoList = currentApplicationDataDirectories();
return fileInfoList;
}
QFileInfoList CSwiftDirectories::currentApplicationDataDirectories()
{
const QDir swiftAppData(applicationDataDirectory()); // contains 1..n subdirs
if (!swiftAppData.isReadable()) { return QFileInfoList(); }
return swiftAppData.entryInfoList({}, QDir::Dirs | QDir::NoDotAndDotDot, QDir::Time);
}
int CSwiftDirectories::applicationDataDirectoriesCount()
{
return applicationDataDirectories().size();
}
QStringList CSwiftDirectories::applicationDataDirectoryList(bool withoutCurrent, bool decodedDirName)
{
QStringList dirs;
for (const QFileInfo &info : applicationDataDirectories())
{
if (withoutCurrent && info.filePath().contains(normalizedApplicationDirectory(), Qt::CaseInsensitive)) continue;
dirs.append(decodedDirName ?
CDirectoryUtils::decodeNormalizedDirectory(info.filePath()) :
info.filePath());
}
return dirs;
}
const CSwiftDirectories::FilePerApplication &CSwiftDirectories::applicationDataDirectoryMapWithoutCurrentVersion()
{
static const FilePerApplication directories = currentApplicationDataDirectoryMapWithoutCurrentVersion();
return directories;
}
CSwiftDirectories::FilePerApplication CSwiftDirectories::currentApplicationDataDirectoryMapWithoutCurrentVersion()
{
FilePerApplication directories;
for (const QFileInfo &info : currentApplicationDataDirectories())
{
// check for myself (the running swift)
if (caseInsensitiveStringCompare(info.filePath(), normalizedApplicationDataDirectory())) { continue; }
// the application info will be written by each swift application started
// so the application type will always contain that application
const QString appInfoFile = CFileUtils::appendFilePaths(info.filePath(), CApplicationInfo::fileName());
const QString appInfoJson = CFileUtils::readFileToString(appInfoFile);
CApplicationInfo appInfo;
if (appInfoJson.isEmpty())
{
// no JSON means the app no longer exists
const QString exeDir = CDirectoryUtils::decodeNormalizedDirectory(info.filePath());
appInfo.setExecutablePath(exeDir);
}
else
{
appInfo = CApplicationInfo::fromJson(appInfoJson);
}
appInfo.setApplicationDataDirectory(info.filePath());
directories.insert(info.filePath(), appInfo);
}
return directories;
}
bool CSwiftDirectories::hasOtherSwiftDataDirectories()
{
return applicationDataDirectoryMapWithoutCurrentVersion().size() > 0;
}
const QString &CSwiftDirectories::normalizedApplicationDataDirectory()
{
static const QString p = CFileUtils::appendFilePaths(applicationDataDirectory(), normalizedApplicationDirectory());
return p;
}
const QString &CSwiftDirectories::logDirectory()
{
static const QString p = CFileUtils::appendFilePaths(normalizedApplicationDataDirectory(), "/logs");
return p;
}
QString getSwiftShareDirImpl()
{
QDir dir(CSwiftDirectories::binDirectory());
const bool success = dir.cd("../share");
if (success)
{
Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "missing dir");
return dir.absolutePath();
}
Q_ASSERT_X(false, Q_FUNC_INFO, "missing dir");
return {};
}
const QString &CSwiftDirectories::shareDirectory()
{
static const QString s(getSwiftShareDirImpl());
return s;
}
const QString &CSwiftDirectories::shareTestDirectory()
{
static const QString test(CFileUtils::appendFilePaths(shareDirectory(), "test"));
return test;
}
const QString &CSwiftDirectories::shareMiscDirectory()
{
static const QString misc(CFileUtils::appendFilePaths(shareDirectory(), "misc"));
return misc;
}
const QString &CSwiftDirectories::shareTerrainProbeDirectory()
{
static const QString tpd(CFileUtils::appendFilePaths(shareDirectory(), "simulator/swiftTerrainProbe"));
return tpd;
}
const QString &CSwiftDirectories::shareMatchingScriptDirectory()
{
static const QString ms(CFileUtils::appendFilePaths(shareDirectory(), "matchingscript"));
return ms;
}
const QString &CSwiftDirectories::bootstrapFileName()
{
static const QString n("bootstrap.json");
return n;
}
const QString getBootstrapResourceFileImpl()
{
const QString d(CSwiftDirectories::shareDirectory());
if (d.isEmpty()) { return {}; }
const QFile file(QDir::cleanPath(d + QDir::separator() + "shared/bootstrap/" + CSwiftDirectories::bootstrapFileName()));
Q_ASSERT_X(file.exists(), Q_FUNC_INFO, "missing bootstrap file");
return QFileInfo(file).absoluteFilePath();
}
const QString &CSwiftDirectories::bootstrapResourceFilePath()
{
static const QString s(getBootstrapResourceFileImpl());
return s;
}
QString getSwiftStaticDbFilesDirImpl()
{
const QString d(CSwiftDirectories::shareDirectory());
if (d.isEmpty()) { return {}; }
const QDir dir(QDir::cleanPath(d + QDir::separator() + "shared/dbdata"));
Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "missing dir");
return dir.absolutePath();
}
const QString &CSwiftDirectories::staticDbFilesDirectory()
{
static const QString s(getSwiftStaticDbFilesDirImpl());
return s;
}
QString getSoundFilesDirImpl()
{
const QString d(CSwiftDirectories::shareDirectory());
if (d.isEmpty()) { return {}; }
const QDir dir(QDir::cleanPath(d + QDir::separator() + "sounds"));
Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "missing dir");
return dir.absolutePath();
}
const QString &CSwiftDirectories::soundFilesDirectory()
{
static const QString s(getSoundFilesDirImpl());
return s;
}
QString getStylesheetsDirImpl()
{
const QString d(CSwiftDirectories::shareDirectory());
if (d.isEmpty()) { return {}; }
const QDir dir(QDir::cleanPath(d + QDir::separator() + "qss"));
Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "missing dir");
return dir.absolutePath();
}
const QString &CSwiftDirectories::stylesheetsDirectory()
{
static const QString s(getStylesheetsDirImpl());
return s;
}
QString getImagesDirImpl()
{
const QString d(CSwiftDirectories::shareDirectory());
const QDir dir(QDir::cleanPath(d + QDir::separator() + "images"));
Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "missing dir");
return dir.absolutePath();
}
const QString &CSwiftDirectories::imagesDirectory()
{
static const QString s(getImagesDirImpl());
return s;
}
const QString &CSwiftDirectories::imagesAirlinesDirectory()
{
static const QString s(QDir::cleanPath(imagesDirectory() + QDir::separator() + "airlines"));
return s;
}
const QString &CSwiftDirectories::imagesFlagsDirectory()
{
static const QString s(QDir::cleanPath(imagesDirectory() + QDir::separator() + "flags"));
return s;
}
QString getHtmlDirImpl()
{
const QString d(CSwiftDirectories::shareDirectory());
const QDir dir(QDir::cleanPath(d + QDir::separator() + "html"));
Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "missing dir");
return dir.absolutePath();
}
const QString &CSwiftDirectories::htmlDirectory()
{
static const QString s(getHtmlDirImpl());
return s;
}
QString getLegalDirImpl()
{
const QString d(CSwiftDirectories::shareDirectory());
const QDir dir(QDir::cleanPath(d + QDir::separator() + "legal"));
Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "missing dir");
return dir.absolutePath();
}
const QString &CSwiftDirectories::legalDirectory()
{
static const QString s(getLegalDirImpl());
return s;
}
const QString &CSwiftDirectories::aboutFilePath()
{
static const QString about = QDir::cleanPath(legalDirectory() + QDir::separator() + "about.html");
return about;
}
QString testFilesDirImpl()
{
const QString d(CSwiftDirectories::shareDirectory());
if (d.isEmpty()) { return {}; }
const QDir dir(QDir::cleanPath(d + QDir::separator() + "test"));
Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "missing dir");
return dir.absolutePath();
}
const QString &CSwiftDirectories::testFilesDirectory()
{
static QString s(testFilesDirImpl());
return s;
}
const QString &CSwiftDirectories::htmlTemplateFilePath()
{
static const QString s(htmlDirectory() + QDir::separator() + "swifttemplate.html");
return s;
}
QString getDocumentationDirectoryImpl()
{
const QStringList pathes(QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation));
QString d = pathes.first();
d = QDir::cleanPath(CFileUtils::appendFilePaths(d, "swift"));
QDir dir(d);
if (dir.exists()) { return dir.absolutePath(); }
return pathes.first();
}
const QString &CSwiftDirectories::documentationDirectory()
{
static const QString d(getDocumentationDirectoryImpl());
return d;
}
const QString &CSwiftDirectories::crashpadDirectory()
{
static const QString p = CFileUtils::appendFilePaths(normalizedApplicationDataDirectory(), "/crashpad");
return p;
}
const QString &CSwiftDirectories::crashpadDatabaseDirectory()
{
static const QString p = CFileUtils::appendFilePaths(crashpadDirectory(), "/database");
return p;
}
const QString &CSwiftDirectories::crashpadMetricsDirectory()
{
static const QString p = CFileUtils::appendFilePaths(crashpadDirectory(), "/metrics");
return p;
}
QStringList CSwiftDirectories::verifyRuntimeDirectoriesAndFiles()
{
QStringList failed;
QDir d(binDirectory());
if (!d.isReadable()) { failed.append(d.absolutePath()); }
d = QDir(imagesDirectory());
if (!d.isReadable()) { failed.append(d.absolutePath()); }
d = QDir(stylesheetsDirectory());
if (!d.isReadable()) { failed.append(d.absolutePath()); }
d = QDir(applicationDataDirectory());
if (!d.isReadable()) { failed.append(d.absolutePath()); }
// check if the executables are avialable
QString fn = executableFilePath(CBuildConfig::swiftCoreExecutableName());
if (!QFile::exists(fn)) { failed.append(fn); }
fn = executableFilePath(CBuildConfig::swiftDataExecutableName());
if (!QFile::exists(fn)) { failed.append(fn); }
fn = executableFilePath(CBuildConfig::swiftGuiExecutableName());
if (!QFile::exists(fn)) { failed.append(fn); }
return failed;
}
QString CSwiftDirectories::soundFilePathOrDefaultPath(const QString &directory, const QString &fileName)
{
if (!directory.isEmpty())
{
const QString fp = CFileUtils::appendFilePathsAndFixUnc(directory, fileName);
const QFileInfo fi(fp);
if (fi.exists()) { return fi.absoluteFilePath(); }
}
const QString fp = CFileUtils::appendFilePathsAndFixUnc(CSwiftDirectories::soundFilesDirectory(), fileName);
const QFileInfo fi(fp);
return (fi.exists()) ? fi.absoluteFilePath() : QString();
}
} // ns
//! \endcond

View File

@@ -0,0 +1,168 @@
/* Copyright (C) 2020
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
* or distributed except according to the terms contained in the LICENSE file.
*/
//! \file
#ifndef BLACKMISC_SWIFTDIRECTORIES_H
#define BLACKMISC_SWIFTDIRECTORIES_H
#include "blackmisc/applicationinfo.h"
#include "blackmisc/blackmiscexport.h"
#include <QMap>
#include <QSet>
#include <QString>
#include <QDateTime>
#include <QDir>
#include <QFileInfoList>
namespace BlackMisc
{
/*!
* Locations of important directories for swift files
*/
class BLACKMISC_EXPORT CSwiftDirectories
{
public:
//! File path and swift application
using FilePerApplication = QMap<QString, CApplicationInfo>;
//! Returns the bin directory. On Windows/Linux this is the same directory as
//! QCoreApplication::applicationDirPath(), but on MacOS the exceutable is
//! located deeper in the hierarchy of the bundles
//! \see https://dev.swift-project.org/w/dev/swiftpc/dirstructure/
static const QString &binDirectory();
//! Plugins directory
static const QString &pluginsDirectory();
//! Audio plugins directory for Qt audio
//! \remark contains the audio plugins
static const QString &audioPluginDirectory();
//! The build directory
//! \remark if is a local build
static const QString &getXSwiftBusBuildDirectory();
//! The executable file path
static QString executableFilePath(const QString &executable);
//! swift application data directory, contains 0..n swift installation directories
//! \remark use CDirectoryUtils::normalizedApplicationDataDirectory for one specific version
static const QString &applicationDataDirectory();
//! swift application data sub directories
static const QFileInfoList &applicationDataDirectories();
//! number of data directories (including this version)
static int applicationDataDirectoriesCount();
//! swift application data sub directories
static QFileInfoList currentApplicationDataDirectories();
//! swift application data sub directories
static QStringList applicationDataDirectoryList(bool withoutCurrent = false, bool decodedDirName = false);
//! swift application data sub directories with info if available
static const FilePerApplication &applicationDataDirectoryMapWithoutCurrentVersion();
//! swift application data sub directories with info if available
static FilePerApplication currentApplicationDataDirectoryMapWithoutCurrentVersion();
//! Other swift data directories
static bool hasOtherSwiftDataDirectories();
//! swift application data directory for one specific installation (a version)
//! \remark use CDirectoryUtils::applicationDataDirectory for one all swift versions
static const QString &normalizedApplicationDataDirectory();
//! Where resource files (static DB files, ...) etc are located
//! \remark share not shared (do no mix)
static const QString &shareDirectory();
//! The test data directory
static const QString &shareTestDirectory();
//! The misc data directory
static const QString &shareMiscDirectory();
//! FSX/P3D terrain probe
static const QString &shareTerrainProbeDirectory();
//! Matching script examples directories
static const QString &shareMatchingScriptDirectory();
//! Bootstrap file name
static const QString &bootstrapFileName();
//! Bootstrap resource file path
static const QString &bootstrapResourceFilePath();
//! Where static DB files are located
static const QString &staticDbFilesDirectory();
//! Where sound files are located
static const QString &soundFilesDirectory();
//! Where qss files are located
static const QString &stylesheetsDirectory();
//! Where images are located
static const QString &imagesDirectory();
//! Where airline images are located
static const QString &imagesAirlinesDirectory();
//! Where flags images are located
static const QString &imagesFlagsDirectory();
//! Where HTML files are located
static const QString &htmlDirectory();
//! Where Legal files are located
static const QString &legalDirectory();
//! The about document file location
static const QString &aboutFilePath();
//! Where test files are located
static const QString &testFilesDirectory();
//! HTML template
static const QString &htmlTemplateFilePath();
//! Directory where data can be stored
static const QString &documentationDirectory();
//! Directory for log files
//! \remark In BlackMisc so it can also be used from BlackMisc classes
static const QString &logDirectory();
//! Directory for crashpad files
static const QString &crashpadDirectory();
//! Directory for crashpad database files
static const QString &crashpadDatabaseDirectory();
//! Directory for crashpad metrics files
static const QString &crashpadMetricsDirectory();
//! Check if the (most important) runtime directories are available
static QStringList verifyRuntimeDirectoriesAndFiles();
//! File path (with file name) of file name and
static QString soundFilePathOrDefaultPath(const QString &directory, const QString &fileName);
private:
//! Returns the application directory of the calling executable as normalized string.
//! \note There is no trailing '/'.
//! \warning The normalization rules are implementation specific and could change over time.
static const QString &normalizedApplicationDirectory();
};
} // ns
#endif // guard

View File

@@ -13,6 +13,7 @@
#include "blackmisc/network/userlist.h"
#include "blackmisc/network/server.h"
#include "blackmisc/fileutils.h"
#include "blackmisc/swiftdirectories.h"
#include "blackmisc/directoryutils.h"
#include "blackmisc/variantlist.h"
#include "blackmisc/math/mathutils.h"
@@ -243,7 +244,7 @@ namespace BlackMisc
const CAircraftIcaoCode &CTestData::getDBAircraftIcaoB737()
{
static const QString json = CFileUtils::readFileToString(CDirectoryUtils::testFilesDirectory(), "DBAircraftIcaoB737Boeing.json");
static const QString json = CFileUtils::readFileToString(CSwiftDirectories::testFilesDirectory(), "DBAircraftIcaoB737Boeing.json");
static const CAircraftIcaoCode icao(CAircraftIcaoCode::fromJson(json));
Q_ASSERT(icao.hasValidDbKey());
return icao;
@@ -251,7 +252,7 @@ namespace BlackMisc
const CAircraftIcaoCode &CTestData::getDBAircraftIcaoC172()
{
static const QString json = CFileUtils::readFileToString(CDirectoryUtils::testFilesDirectory(), "DBAircraftIcaoC172Cessna.json");
static const QString json = CFileUtils::readFileToString(CSwiftDirectories::testFilesDirectory(), "DBAircraftIcaoC172Cessna.json");
static const CAircraftIcaoCode icao(CAircraftIcaoCode::fromJson(json));
Q_ASSERT(icao.hasValidDbKey());
return icao;
@@ -259,7 +260,7 @@ namespace BlackMisc
const CAirlineIcaoCode &CTestData::getDbAirlineIcaoDLH()
{
static const QString json = CFileUtils::readFileToString(CDirectoryUtils::testFilesDirectory(), "DBAirlineIcaoDLH.json");
static const QString json = CFileUtils::readFileToString(CSwiftDirectories::testFilesDirectory(), "DBAirlineIcaoDLH.json");
static const CAirlineIcaoCode icao(CAirlineIcaoCode::fromJson(json));
Q_ASSERT(icao.hasValidDbKey());
return icao;
@@ -267,7 +268,7 @@ namespace BlackMisc
const CAirlineIcaoCode &CTestData::getDbAirlineIcaoBAW()
{
static const QString json = CFileUtils::readFileToString(CDirectoryUtils::testFilesDirectory(), "DBAirlineIcaoBAW.json");
static const QString json = CFileUtils::readFileToString(CSwiftDirectories::testFilesDirectory(), "DBAirlineIcaoBAW.json");
static const CAirlineIcaoCode icao(CAirlineIcaoCode::fromJson(json));
Q_ASSERT(icao.hasValidDbKey());
return icao;
@@ -275,7 +276,7 @@ namespace BlackMisc
const CLivery &CTestData::getDbLiveryDLHStarAlliance()
{
static const QString json = CFileUtils::readFileToString(CDirectoryUtils::testFilesDirectory(), "DBLiveryDLHStarAlliance.json");
static const QString json = CFileUtils::readFileToString(CSwiftDirectories::testFilesDirectory(), "DBLiveryDLHStarAlliance.json");
static const CLivery livery(CLivery::fromJson(json));
Q_ASSERT(livery.hasValidDbKey());
return livery;
@@ -283,7 +284,7 @@ namespace BlackMisc
const CAircraftModel &CTestData::getDbAircraftModelFsxA2AC172Skyhawk()
{
static const QString json = CFileUtils::readFileToString(CDirectoryUtils::testFilesDirectory(), "DBModelFSXA2ACessnaC172.json");
static const QString json = CFileUtils::readFileToString(CSwiftDirectories::testFilesDirectory(), "DBModelFSXA2ACessnaC172.json");
static const CAircraftModel model(CAircraftModel::fromDatabaseJson(Json::jsonObjectFromString(json)));
Q_ASSERT(model.hasValidDbKey());
Q_ASSERT(!model.getModelString().isEmpty());
@@ -292,7 +293,7 @@ namespace BlackMisc
const CAircraftModel &CTestData::getDbAircraftModelFsxAerosoftA320()
{
static const QString json = CFileUtils::readFileToString(CDirectoryUtils::testFilesDirectory(), "DBModelFSXAerosoftA320.json");
static const QString json = CFileUtils::readFileToString(CSwiftDirectories::testFilesDirectory(), "DBModelFSXAerosoftA320.json");
static const CAircraftModel model(CAircraftModel::fromDatabaseJson(Json::jsonObjectFromString(json)));
Q_ASSERT(model.hasValidDbKey());
Q_ASSERT(!model.getModelString().isEmpty());

View File

@@ -10,6 +10,7 @@
#include "blackmisc/valuecache.h"
#include "blackmisc/atomicfile.h"
#include "blackmisc/swiftdirectories.h"
#include "blackmisc/directoryutils.h"
#include "blackmisc/identifier.h"
#include "blackmisc/lockfree.h"
@@ -50,7 +51,7 @@ namespace BlackMisc
//! \private
std::pair<QString &, std::atomic<bool> &> getCacheRootDirectoryMutable()
{
static QString dir = CDirectoryUtils::normalizedApplicationDataDirectory();
static QString dir = CSwiftDirectories::normalizedApplicationDataDirectory();
static std::atomic<bool> frozen { false };
return { dir, frozen };
}