From 8e065a8fef047995f9c6f841dcb9b1d8f7edb228 Mon Sep 17 00:00:00 2001 From: Mat Sutcliffe Date: Mon, 24 Aug 2020 22:04:10 +0100 Subject: [PATCH] Issue #77 Factor out parts of CDirectoryUtils into CSwiftDirectories CDirectoryUtils is utilities for manipulating directories. CSwiftDirectories is getters that return directories used by swift. --- samples/blackmisc/samplesperformance.cpp | 3 +- src/blackcore/aircraftmatcher.cpp | 7 +- src/blackcore/application.cpp | 7 +- src/blackcore/data/globalsetup.cpp | 13 +- src/blackcore/db/databasereader.cpp | 9 +- src/blackcore/db/icaodatareader.cpp | 22 +- src/blackcore/db/icaodatareader.h | 2 +- src/blackcore/db/modeldatareader.cpp | 20 +- src/blackcore/db/modeldatareader.h | 2 +- src/blackcore/fsd/fsdclient.cpp | 3 +- src/blackcore/pluginmanager.cpp | 3 +- src/blackcore/pluginmanagersimulator.cpp | 3 +- src/blackcore/pluginmanagerweatherdata.cpp | 3 +- src/blackcore/setupreader.cpp | 7 +- src/blackcore/vatsim/vatsimsettings.h | 3 +- src/blackcore/webdataservices.cpp | 19 +- src/blackcore/webdataservices.h | 2 +- .../components/abouthtmlcomponent.cpp | 5 +- .../components/copyconfigurationcomponent.cpp | 11 +- ...ymodelsfromotherswiftversionscomponent.cpp | 3 +- .../components/datainfoareacomponent.cpp | 5 +- .../components/dbmappingcomponent.cpp | 3 +- .../components/dbownmodelscomponent.cpp | 3 +- .../components/flightplancomponent.cpp | 3 +- .../installfsxterrainprobecomponent.cpp | 3 +- .../otherswiftversionscomponent.cpp | 3 +- .../components/setuploadingdialog.cpp | 5 +- src/blackgui/copyxswiftbusdialog.cpp | 3 +- src/blackgui/guiapplication.cpp | 7 +- src/blackgui/stylesheetutility.cpp | 19 +- src/blackgui/views/viewbase.cpp | 8 +- src/blackmisc/applicationinfolist.cpp | 5 +- src/blackmisc/audio/audiosettings.cpp | 6 +- src/blackmisc/aviation/airlineicaocode.cpp | 5 +- src/blackmisc/aviation/altitude.cpp | 3 +- src/blackmisc/compressutils.cpp | 3 +- src/blackmisc/crashhandler.cpp | 7 +- src/blackmisc/crashinfo.cpp | 3 +- src/blackmisc/directories.cpp | 7 +- src/blackmisc/directoryutils.cpp | 471 ++---------------- src/blackmisc/directoryutils.h | 135 +---- src/blackmisc/filelogger.cpp | 7 +- src/blackmisc/fileutils.cpp | 73 +-- src/blackmisc/fileutils.h | 15 - src/blackmisc/icons.cpp | 3 +- .../simulation/aircraftmodellist.cpp | 3 +- .../simulation/aircraftmodelutils.cpp | 3 +- src/blackmisc/simulation/autopublishdata.cpp | 3 +- src/blackmisc/simulation/autopublishdata.h | 7 +- .../simulation/fscommon/fscommonutil.cpp | 11 +- .../simulation/interpolationlogger.cpp | 17 +- .../simulation/xplane/xplaneutil.cpp | 11 +- src/blackmisc/swiftdirectories.cpp | 468 +++++++++++++++++ src/blackmisc/swiftdirectories.h | 168 +++++++ src/blackmisc/test/testdata.cpp | 15 +- src/blackmisc/valuecache.cpp | 3 +- src/blacksound/notificationplayer.cpp | 4 +- src/swiftdata/swiftdatamenus.cpp | 3 +- src/swiftlauncher/swiftlauncher.cpp | 9 +- .../simulation/testxplane/testxplane.cpp | 3 +- tests/blackmisc/testcompress/testcompress.cpp | 3 +- 61 files changed, 880 insertions(+), 803 deletions(-) create mode 100644 src/blackmisc/swiftdirectories.cpp create mode 100644 src/blackmisc/swiftdirectories.h diff --git a/samples/blackmisc/samplesperformance.cpp b/samples/blackmisc/samplesperformance.cpp index 037f6a585..733cbee56 100644 --- a/samples/blackmisc/samplesperformance.cpp +++ b/samples/blackmisc/samplesperformance.cpp @@ -25,6 +25,7 @@ #include "blackmisc/math/mathutils.h" #include "blackmisc/pq/units.h" #include "blackmisc/test/testing.h" +#include "blackmisc/swiftdirectories.h" #include "blackmisc/directoryutils.h" #include "blackmisc/stringutils.h" @@ -278,7 +279,7 @@ namespace BlackSample int CSamplesPerformance::samplesJsonModelAndLivery(QTextStream &out) { - const QString dir = CDirectoryUtils::staticDbFilesDirectory(); + const QString dir = CSwiftDirectories::staticDbFilesDirectory(); const QString modelFileName = QDir(dir).filePath("models.json"); const QString liveriesFileName = QDir(dir).filePath("liveries.json"); diff --git a/src/blackcore/aircraftmatcher.cpp b/src/blackcore/aircraftmatcher.cpp index 6ffe57d47..353b0a128 100644 --- a/src/blackcore/aircraftmatcher.cpp +++ b/src/blackcore/aircraftmatcher.cpp @@ -22,6 +22,7 @@ #include "blackmisc/logcategorylist.h" #include "blackmisc/logmessage.h" #include "blackmisc/statusmessagelist.h" +#include "blackmisc/swiftdirectories.h" #include "blackmisc/directoryutils.h" #include "aircraftmatcher.h" @@ -538,8 +539,8 @@ namespace BlackCore // matching script const bool msReverse = (script == ReverseLookup); const QString lf = msReverse ? setup.getMsReverseLookupFile() : setup.getMsMatchingStageFile(); - static const QString logFileR = CFileUtils::appendFilePaths(CDirectoryUtils::logDirectory(), "logMatchingScriptReverseLookup.log"); - static const QString logFileM = CFileUtils::appendFilePaths(CDirectoryUtils::logDirectory(), "logMatchingScriptMatchingStage.log"); + static const QString logFileR = CFileUtils::appendFilePaths(CSwiftDirectories::logDirectory(), "logMatchingScriptReverseLookup.log"); + static const QString logFileM = CFileUtils::appendFilePaths(CSwiftDirectories::logDirectory(), "logMatchingScriptMatchingStage.log"); if (log) { @@ -1390,7 +1391,7 @@ namespace BlackCore // log the models const QString ts = QDateTime::currentDateTimeUtc().toString("yyyyMMddHHmmss"); const QString json = m_disabledModels.toJsonString(); - return CFileUtils::writeStringToFile(json, CFileUtils::appendFilePathsAndFixUnc(CDirectoryUtils::logDirectory(), QStringLiteral("removed models %1.json").arg(ts))); + return CFileUtils::writeStringToFile(json, CFileUtils::appendFilePathsAndFixUnc(CSwiftDirectories::logDirectory(), QStringLiteral("removed models %1.json").arg(ts))); } CAircraftModelList CAircraftMatcher::getClosestMatchStepwiseReduceImplementation(const CAircraftModelList &modelSet, const CAircraftMatcherSetup &setup, const CCategoryMatcher &categoryMatcher, const CSimulatedAircraft &remoteAircraft, MatchingLog whatToLog, CStatusMessageList *log) diff --git a/src/blackcore/application.cpp b/src/blackcore/application.cpp index afec40fea..85060424d 100644 --- a/src/blackcore/application.cpp +++ b/src/blackcore/application.cpp @@ -24,6 +24,7 @@ #include "blackmisc/crashhandler.h" #include "blackmisc/datacache.h" #include "blackmisc/dbusserver.h" +#include "blackmisc/swiftdirectories.h" #include "blackmisc/directoryutils.h" #include "blackmisc/eventloop.h" #include "blackmisc/filelogger.h" @@ -107,7 +108,7 @@ namespace BlackCore Q_ASSERT_X(!sApp, Q_FUNC_INFO, "already initialized"); Q_ASSERT_X(QCoreApplication::instance(), Q_FUNC_INFO, "no application object"); - m_applicationInfo.setApplicationDataDirectory(CDirectoryUtils::normalizedApplicationDataDirectory()); + m_applicationInfo.setApplicationDataDirectory(CSwiftDirectories::normalizedApplicationDataDirectory()); QCoreApplication::setApplicationName(m_applicationName); QCoreApplication::setApplicationVersion(CBuildConfig::getVersionString()); this->setObjectName(m_applicationName); @@ -1437,7 +1438,7 @@ namespace BlackCore "You'll need to update swift in order to use it thereafter."); } - const QStringList verifyErrors = CDirectoryUtils::verifyRuntimeDirectoriesAndFiles(); + const QStringList verifyErrors = CSwiftDirectories::verifyRuntimeDirectoriesAndFiles(); if (!verifyErrors.isEmpty() && !m_applicationInfo.isUnitTest()) { this->cmdLineErrorMessage("Missing runtime directories/files:", verifyErrors.join(", ")); @@ -1862,7 +1863,7 @@ namespace BlackCore void CApplication::tagApplicationDataDirectory() { - const QString d = CDirectoryUtils::normalizedApplicationDataDirectory(); + const QString d = CSwiftDirectories::normalizedApplicationDataDirectory(); const QDir dir(d); if (!dir.exists() || !dir.isReadable()) { return; } const QString aiStr(this->getApplicationInfo().toJsonString()); diff --git a/src/blackcore/data/globalsetup.cpp b/src/blackcore/data/globalsetup.cpp index aa2e5d28b..265a4559b 100644 --- a/src/blackcore/data/globalsetup.cpp +++ b/src/blackcore/data/globalsetup.cpp @@ -10,6 +10,7 @@ #include "blackcore/data/globalsetup.h" #include "blackcore/application.h" #include "blackmisc/json.h" +#include "blackmisc/swiftdirectories.h" #include "blackmisc/directoryutils.h" #include "blackmisc/network/server.h" #include "blackmisc/network/user.h" @@ -110,7 +111,7 @@ namespace BlackCore CUrlList CGlobalSetup::getSwiftBootstrapFileUrls() const { - return getSwiftSharedUrls().withAppendedPath(CGlobalSetup::schemaVersionString() + "/bootstrap/" + CDirectoryUtils::bootstrapFileName()); + return getSwiftSharedUrls().withAppendedPath(CGlobalSetup::schemaVersionString() + "/bootstrap/" + CSwiftDirectories::bootstrapFileName()); } CUrlList CGlobalSetup::getSwiftUpdateInfoFileUrls() const @@ -217,23 +218,23 @@ namespace BlackCore { if (candidate.isEmpty()) return {}; // not possible static const QString version(QString(CGlobalSetup::schemaVersionString()).append("/")); - if (candidate.endsWith(CDirectoryUtils::bootstrapFileName())) { return candidate; } + if (candidate.endsWith(CSwiftDirectories::bootstrapFileName())) { return candidate; } CUrl url(candidate); if (candidate.contains("/bootstrap")) { - url.appendPath(CDirectoryUtils::bootstrapFileName()); + url.appendPath(CSwiftDirectories::bootstrapFileName()); } else if (candidate.endsWith(CGlobalSetup::schemaVersionString()) || candidate.endsWith(version)) { - url.appendPath("/bootstrap/" + CDirectoryUtils::bootstrapFileName()); + url.appendPath("/bootstrap/" + CSwiftDirectories::bootstrapFileName()); } else if (candidate.endsWith("shared") || candidate.endsWith("shared/")) { - url.appendPath(CGlobalSetup::schemaVersionString() + "/bootstrap/" + CDirectoryUtils::bootstrapFileName()); + url.appendPath(CGlobalSetup::schemaVersionString() + "/bootstrap/" + CSwiftDirectories::bootstrapFileName()); } else { - url.appendPath("shared/" + CGlobalSetup::schemaVersionString() + "/bootstrap/" + CDirectoryUtils::bootstrapFileName()); + url.appendPath("shared/" + CGlobalSetup::schemaVersionString() + "/bootstrap/" + CSwiftDirectories::bootstrapFileName()); } return url.getFullUrl(); } diff --git a/src/blackcore/db/databasereader.cpp b/src/blackcore/db/databasereader.cpp index 4dcf10b78..64971f88f 100644 --- a/src/blackcore/db/databasereader.cpp +++ b/src/blackcore/db/databasereader.cpp @@ -15,6 +15,7 @@ #include "blackmisc/db/datastoreutility.h" #include "blackmisc/network/networkutils.h" #include "blackmisc/network/entityflags.h" +#include "blackmisc/swiftdirectories.h" #include "blackmisc/directoryutils.h" #include "blackmisc/logcategory.h" #include "blackmisc/logcategorylist.h" @@ -621,14 +622,14 @@ namespace BlackCore if (inBackground || !CThreadUtils::isInThisThread(this)) { - const bool s = this->readFromJsonFilesInBackground(CDirectoryUtils::staticDbFilesDirectory(), entities, overrideNewerOnly); + const bool s = this->readFromJsonFilesInBackground(CSwiftDirectories::staticDbFilesDirectory(), entities, overrideNewerOnly); return s ? - CStatusMessage(this).info(u"Started reading in background from '%1' of entities: '%2'") << CDirectoryUtils::staticDbFilesDirectory() << CEntityFlags::flagToString(entities) : - CStatusMessage(this).error(u"Starting reading in background from '%1' of entities: '%2' failed") << CDirectoryUtils::staticDbFilesDirectory() << CEntityFlags::flagToString(entities); + CStatusMessage(this).info(u"Started reading in background from '%1' of entities: '%2'") << CSwiftDirectories::staticDbFilesDirectory() << CEntityFlags::flagToString(entities) : + CStatusMessage(this).error(u"Starting reading in background from '%1' of entities: '%2' failed") << CSwiftDirectories::staticDbFilesDirectory() << CEntityFlags::flagToString(entities); } else { - return this->readFromJsonFiles(CDirectoryUtils::staticDbFilesDirectory(), entities, overrideNewerOnly); + return this->readFromJsonFiles(CSwiftDirectories::staticDbFilesDirectory(), entities, overrideNewerOnly); } } //! \endcond diff --git a/src/blackcore/db/icaodatareader.cpp b/src/blackcore/db/icaodatareader.cpp index d53e2666b..71cacbcfe 100644 --- a/src/blackcore/db/icaodatareader.cpp +++ b/src/blackcore/db/icaodatareader.cpp @@ -687,38 +687,42 @@ namespace BlackCore return true; } - bool CIcaoDataReader::writeToJsonFiles(const QString &dir) const + bool CIcaoDataReader::writeToJsonFiles(const QString &dir) { QDir directory(dir); if (!directory.exists()) { return false; } + QList> fileContents; if (this->getCountriesCount() > 0) { const QString json(QJsonDocument(this->getCountries().toJson()).toJson()); - const bool s = CFileUtils::writeStringToFileInBackground(json, CFileUtils::appendFilePaths(directory.absolutePath(), CDbInfo::entityToSharedName(CEntityFlags::CountryEntity))); - if (!s) { return false; } + fileContents.push_back({ CEntityFlags::CountryEntity, json }); } if (this->getAircraftIcaoCodesCount() > 0) { const QString json(QJsonDocument(this->getAircraftIcaoCodes().toJson()).toJson()); - const bool s = CFileUtils::writeStringToFileInBackground(json, CFileUtils::appendFilePaths(directory.absolutePath(), CDbInfo::entityToSharedName(CEntityFlags::AircraftIcaoEntity))); - if (!s) { return false; } + fileContents.push_back({ CEntityFlags::AircraftIcaoEntity, json }); } if (this->getAirlineIcaoCodesCount() > 0) { const QString json(QJsonDocument(this->getAirlineIcaoCodes().toJson()).toJson()); - const bool s = CFileUtils::writeStringToFileInBackground(json, CFileUtils::appendFilePaths(directory.absolutePath(), CDbInfo::entityToSharedName(CEntityFlags::AirlineIcaoEntity))); - if (!s) { return false; } + fileContents.push_back({ CEntityFlags::AirlineIcaoEntity, json }); } if (this->getAircraftCategoryCount() > 0) { const QString json(QJsonDocument(this->getAirlineIcaoCodes().toJson()).toJson()); - const bool s = CFileUtils::writeStringToFileInBackground(json, CFileUtils::appendFilePaths(directory.absolutePath(), CDbInfo::entityToSharedName(CEntityFlags::AircraftCategoryEntity))); - if (!s) { return false; } + fileContents.push_back({ CEntityFlags::AircraftCategoryEntity, json }); } + for (const auto &pair : fileContents) + { + CWorker::fromTask(this, Q_FUNC_INFO, [pair, directory] + { + CFileUtils::writeStringToFile(CFileUtils::appendFilePaths(directory.absolutePath(), CDbInfo::entityToSharedName(pair.first)), pair.second); + }); + } return true; } diff --git a/src/blackcore/db/icaodatareader.h b/src/blackcore/db/icaodatareader.h index b10005ada..a50773485 100644 --- a/src/blackcore/db/icaodatareader.h +++ b/src/blackcore/db/icaodatareader.h @@ -140,7 +140,7 @@ namespace BlackCore bool areAllDataRead() const; //! Write to static DB data file - bool writeToJsonFiles(const QString &dir) const; + bool writeToJsonFiles(const QString &dir); // data read from local data virtual BlackMisc::CStatusMessageList readFromJsonFiles(const QString &dir, BlackMisc::Network::CEntityFlags::Entity whatToRead, bool overrideNewerOnly) override; diff --git a/src/blackcore/db/modeldatareader.cpp b/src/blackcore/db/modeldatareader.cpp index 5b31b7d87..78b50de7e 100644 --- a/src/blackcore/db/modeldatareader.cpp +++ b/src/blackcore/db/modeldatareader.cpp @@ -599,29 +599,35 @@ namespace BlackCore return true; } - bool CModelDataReader::writeToJsonFiles(const QString &dir) const + bool CModelDataReader::writeToJsonFiles(const QString &dir) { QDir directory(dir); if (!directory.exists()) { return false; } + QList> fileContents; if (this->getLiveriesCount() > 0) { const QString json(QJsonDocument(this->getLiveries().toJson()).toJson()); - const bool s = CFileUtils::writeStringToFileInBackground(json, CFileUtils::appendFilePaths(directory.absolutePath(), "liveries.json")); - if (!s) { return false; } + fileContents.push_back({ "liveries.json", json }); } if (this->getModelsCount() > 0) { const QString json(QJsonDocument(this->getModels().toJson()).toJson()); - const bool s = CFileUtils::writeStringToFileInBackground(json, CFileUtils::appendFilePaths(directory.absolutePath(), "models.json")); - if (!s) { return false; } + fileContents.push_back({ "models.json", json }); } if (this->getDistributorsCount() > 0) { const QString json(QJsonDocument(this->getDistributors().toJson()).toJson()); - const bool s = CFileUtils::writeStringToFileInBackground(json, CFileUtils::appendFilePaths(directory.absolutePath(), "distributors.json")); - if (!s) { return false; } + fileContents.push_back({ "distributors.json", json }); + } + + for (const auto &pair : fileContents) + { + CWorker::fromTask(this, Q_FUNC_INFO, [pair, directory] + { + CFileUtils::writeStringToFile(CFileUtils::appendFilePaths(directory.absolutePath(), pair.first), pair.second); + }); } return true; } diff --git a/src/blackcore/db/modeldatareader.h b/src/blackcore/db/modeldatareader.h index 33d42d9af..8789f403e 100644 --- a/src/blackcore/db/modeldatareader.h +++ b/src/blackcore/db/modeldatareader.h @@ -134,7 +134,7 @@ namespace BlackCore bool areAllDataRead() const; //! Write to JSON file - bool writeToJsonFiles(const QString &dir) const; + bool writeToJsonFiles(const QString &dir); // Data read from local data virtual BlackMisc::CStatusMessageList readFromJsonFiles(const QString &dir, BlackMisc::Network::CEntityFlags::Entity whatToRead, bool overrideNewerOnly) override; diff --git a/src/blackcore/fsd/fsdclient.cpp b/src/blackcore/fsd/fsdclient.cpp index e0e68ba25..42e48f76a 100644 --- a/src/blackcore/fsd/fsdclient.cpp +++ b/src/blackcore/fsd/fsdclient.cpp @@ -38,6 +38,7 @@ #include "blackmisc/aviation/flightplan.h" #include "blackmisc/network/rawfsdmessage.h" +#include "blackmisc/swiftdirectories.h" #include "blackmisc/threadutils.h" #include "blackmisc/logmessage.h" #include "blackmisc/range.h" @@ -2080,7 +2081,7 @@ namespace BlackCore const QString s = this->getNetworkStatisticsAsText(false, "\n"); if (s.isEmpty()) { return false; } const QString fn = QStringLiteral("networkstatistics_%1_%2.log").arg(QDateTime::currentDateTimeUtc().toString("yyMMddhhmmss"), server); - const QString fp = CFileUtils::appendFilePaths(CDirectoryUtils::logDirectory(), fn); + const QString fp = CFileUtils::appendFilePaths(CSwiftDirectories::logDirectory(), fn); return CFileUtils::writeStringToFile(s, fp); } diff --git a/src/blackcore/pluginmanager.cpp b/src/blackcore/pluginmanager.cpp index ecc0c0400..0ef1a8301 100644 --- a/src/blackcore/pluginmanager.cpp +++ b/src/blackcore/pluginmanager.cpp @@ -8,6 +8,7 @@ #include "blackcore/pluginmanager.h" #include "blackcore/application.h" +#include "blackmisc/swiftdirectories.h" #include "blackmisc/directoryutils.h" #include "blackmisc/logmessage.h" #include "blackmisc/statusmessage.h" @@ -51,7 +52,7 @@ namespace BlackCore const QString &IPluginManager::pluginDirectory() const { - return CDirectoryUtils::pluginsDirectory(); + return CSwiftDirectories::pluginsDirectory(); } bool IPluginManager::isValid(const QJsonObject &metadata) const diff --git a/src/blackcore/pluginmanagersimulator.cpp b/src/blackcore/pluginmanagersimulator.cpp index 0e3747b12..475e24d11 100644 --- a/src/blackcore/pluginmanagersimulator.cpp +++ b/src/blackcore/pluginmanagersimulator.cpp @@ -9,6 +9,7 @@ #include "blackcore/application.h" #include "blackcore/pluginmanagersimulator.h" #include "blackcore/simulator.h" +#include "blackmisc/swiftdirectories.h" #include "blackmisc/directoryutils.h" #include "blackmisc/logmessage.h" @@ -112,7 +113,7 @@ namespace BlackCore const QString &CPluginManagerSimulator::pluginDirectory() const { - static const QString d(CFileUtils::appendFilePaths(CDirectoryUtils::pluginsDirectory(), "simulator")); + static const QString d(CFileUtils::appendFilePaths(CSwiftDirectories::pluginsDirectory(), "simulator")); return d; } } diff --git a/src/blackcore/pluginmanagerweatherdata.cpp b/src/blackcore/pluginmanagerweatherdata.cpp index f1919bb05..587685ada 100644 --- a/src/blackcore/pluginmanagerweatherdata.cpp +++ b/src/blackcore/pluginmanagerweatherdata.cpp @@ -9,6 +9,7 @@ #include "blackcore/application.h" #include "blackcore/pluginmanagerweatherdata.h" #include "blackcore/weatherdata.h" +#include "blackmisc/swiftdirectories.h" #include "blackmisc/directoryutils.h" #include @@ -65,7 +66,7 @@ namespace BlackCore const QString &CPluginManagerWeatherData::pluginDirectory() const { - static const QString d(CFileUtils::appendFilePaths(CDirectoryUtils::pluginsDirectory(), "weatherdata")); + static const QString d(CFileUtils::appendFilePaths(CSwiftDirectories::pluginsDirectory(), "weatherdata")); return d; } } diff --git a/src/blackcore/setupreader.cpp b/src/blackcore/setupreader.cpp index af80eedad..0658250a0 100644 --- a/src/blackcore/setupreader.cpp +++ b/src/blackcore/setupreader.cpp @@ -11,6 +11,7 @@ #include "blackmisc/verify.h" #include "blackmisc/compare.h" #include "blackmisc/fileutils.h" +#include "blackmisc/swiftdirectories.h" #include "blackmisc/directoryutils.h" #include "blackmisc/logcategory.h" #include "blackmisc/logcategorylist.h" @@ -115,7 +116,7 @@ namespace BlackCore if (m_bootstrapUrls.isEmpty()) { // after all still empty - msgs.push_back(CStatusMessage(this, CStatusMessage::SeverityInfo, u"Your log files are here: " % CDirectoryUtils::logDirectory())); + msgs.push_back(CStatusMessage(this, CStatusMessage::SeverityInfo, u"Your log files are here: " % CSwiftDirectories::logDirectory())); msgs.push_back(CStatusMessage(this, CStatusMessage::SeverityError, u"No bootstrap URLs, cannot load setup")); } else @@ -307,7 +308,7 @@ namespace BlackCore if (dir.isEmpty()) { return CStatusMessage(this).error(u"Empty shared directory '%1' for bootstrap file") << dir; } // no version for local files, as those come with the current code - fn = CFileUtils::appendFilePaths(dir, "bootstrap/" + CDirectoryUtils::bootstrapFileName()); + fn = CFileUtils::appendFilePaths(dir, "bootstrap/" + CSwiftDirectories::bootstrapFileName()); } else { @@ -482,7 +483,7 @@ namespace BlackCore CLogMessage(this).info(u"Setup cache prefill (bootstrap already cached, no prefill needed"); return false; } - const QString fn = CDirectoryUtils::bootstrapResourceFilePath(); + const QString fn = CSwiftDirectories::bootstrapResourceFilePath(); const CStatusMessageList msgs = this->readLocalBootstrapFile(fn); CLogMessage::preformatted(msgs); return true; diff --git a/src/blackcore/vatsim/vatsimsettings.h b/src/blackcore/vatsim/vatsimsettings.h index 3f9877e67..a26ebb419 100644 --- a/src/blackcore/vatsim/vatsimsettings.h +++ b/src/blackcore/vatsim/vatsimsettings.h @@ -16,6 +16,7 @@ #include "blackmisc/valueobject.h" #include "blackmisc/pq/time.h" #include "blackmisc/network/serverlist.h" +#include "blackmisc/swiftdirectories.h" #include "blackmisc/directoryutils.h" #include "blackmisc/fileutils.h" @@ -211,7 +212,7 @@ namespace BlackCore //! \copydoc BlackMisc::TSettingTrait::defaultValue static const CRawFsdMessageSettings &defaultValue() { - static const CRawFsdMessageSettings setting { false, BlackMisc::CDirectoryUtils::logDirectory() }; + static const CRawFsdMessageSettings setting { false, BlackMisc::CSwiftDirectories::logDirectory() }; return setting; } }; diff --git a/src/blackcore/webdataservices.cpp b/src/blackcore/webdataservices.cpp index d251f3ed8..2c287b264 100644 --- a/src/blackcore/webdataservices.cpp +++ b/src/blackcore/webdataservices.cpp @@ -1538,7 +1538,7 @@ namespace BlackCore CLogMessage(this).info(u"Changed data service ecosystem to '%1'") << es.toQString(true); } - bool CWebDataServices::writeDbDataToDisk(const QString &dir) const + bool CWebDataServices::writeDbDataToDisk(const QString &dir) { if (dir.isEmpty()) { return false; } const QDir directory(dir); @@ -1547,28 +1547,33 @@ namespace BlackCore const bool s = directory.mkpath(dir); if (!s) { return false; } } + QList> fileContents; if (this->getModelsCount() > 0) { const QString json(QJsonDocument(this->getModels().toJson()).toJson()); - const bool s = CFileUtils::writeStringToFileInBackground(json, CFileUtils::appendFilePaths(directory.absolutePath(), "models.json")); - if (!s) { return false; } + fileContents.push_back({ "models.json", json }); } if (this->getLiveriesCount() > 0) { const QString json(QJsonDocument(this->getLiveries().toJson()).toJson()); - const bool s = CFileUtils::writeStringToFileInBackground(json, CFileUtils::appendFilePaths(directory.absolutePath(), "liveries.json")); - if (!s) { return false; } + fileContents.push_back({ "liveries.json", json }); } if (this->getAirportsCount() > 0) { const QString json(QJsonDocument(this->getAirports().toJson()).toJson()); - const bool s = CFileUtils::writeStringToFileInBackground(json, CFileUtils::appendFilePaths(directory.absolutePath(), "airports.json")); - if (!s) { return false; } + fileContents.push_back({ "airports.json", json }); } + for (const auto &pair : fileContents) + { + CWorker::fromTask(this, Q_FUNC_INFO, [pair, directory] + { + CFileUtils::writeStringToFile(CFileUtils::appendFilePaths(directory.absolutePath(), pair.first), pair.second); + }); + } return true; } diff --git a/src/blackcore/webdataservices.h b/src/blackcore/webdataservices.h index 665611b9b..695b82209 100644 --- a/src/blackcore/webdataservices.h +++ b/src/blackcore/webdataservices.h @@ -499,7 +499,7 @@ namespace BlackCore void synchronizeDbCaches(BlackMisc::Network::CEntityFlags::Entity entities); //! Write data to disk (mainly for testing scenarios) - bool writeDbDataToDisk(const QString &dir) const; + bool writeDbDataToDisk(const QString &dir); //! Load DB data from disk (mainly for initial data load and testing scenarios) //! \remark if the DB readers are alred in aother thread reads in background diff --git a/src/blackgui/components/abouthtmlcomponent.cpp b/src/blackgui/components/abouthtmlcomponent.cpp index 30cf280e5..a1e472a17 100644 --- a/src/blackgui/components/abouthtmlcomponent.cpp +++ b/src/blackgui/components/abouthtmlcomponent.cpp @@ -10,6 +10,7 @@ #include "blackmisc/fileutils.h" #include "blackmisc/directoryutils.h" #include "abouthtmlcomponent.h" +#include "blackmisc/swiftdirectories.h" #include "blackmisc/directoryutils.h" #include "blackmisc/fileutils.h" #include "ui_abouthtmlcomponent.h" @@ -53,7 +54,7 @@ namespace BlackGui // workaround: // 1) Only reading as HTML gives proper formatting // 2) Reading the file resource fails (likely because of the style sheet) - const QString html = CFileUtils::readFileToString(CDirectoryUtils::aboutFilePath()); + const QString html = CFileUtils::readFileToString(CSwiftDirectories::aboutFilePath()); return html; // no longer replacing the URLs, doing this on anchor clicked @@ -75,7 +76,7 @@ namespace BlackGui QDesktopServices::openUrl(url); return; } - const QString possibleLegalFile = CFileUtils::appendFilePaths(CDirectoryUtils::legalDirectory(), url.fileName()); + const QString possibleLegalFile = CFileUtils::appendFilePaths(CSwiftDirectories::legalDirectory(), url.fileName()); QFile f(possibleLegalFile); if (f.exists()) { diff --git a/src/blackgui/components/copyconfigurationcomponent.cpp b/src/blackgui/components/copyconfigurationcomponent.cpp index 7069ca3f8..9bfb8a943 100644 --- a/src/blackgui/components/copyconfigurationcomponent.cpp +++ b/src/blackgui/components/copyconfigurationcomponent.cpp @@ -12,6 +12,7 @@ #include "blackcore/data/globalsetup.h" #include "blackgui/guiapplication.h" #include "blackconfig/buildconfig.h" +#include "blackmisc/swiftdirectories.h" #include "blackmisc/directoryutils.h" #include "blackmisc/settingscache.h" #include "blackmisc/datacache.h" @@ -50,7 +51,7 @@ namespace BlackGui ui->setupUi(this); this->initOtherSwiftVersions(); this->setWidths(); - m_hasOtherSwiftVersions = CDirectoryUtils::hasOtherSwiftDataDirectories(); + m_hasOtherSwiftVersions = CSwiftDirectories::hasOtherSwiftDataDirectories(); ui->cb_ShowAll->setChecked(m_nameFilterDisables); connect(ui->rb_Cache, &QRadioButton::toggled, [ = ](bool) { this->initCurrentDirectories(true); }); @@ -191,7 +192,7 @@ namespace BlackGui static const QStringList cacheFilterBs = [ = ] { QStringList f(cacheFilter); - f.push_back(CDirectoryUtils::bootstrapFileName()); + f.push_back(CSwiftDirectories::bootstrapFileName()); return f; }(); return cacheFilterBs; @@ -324,7 +325,7 @@ namespace BlackGui QString CCopyConfigurationComponent::getOtherVersionsSelectedDirectory() const { if (ui->cb_OtherVersions->count() < 1) { return {}; } - const QFileInfoList dirs(CDirectoryUtils::applicationDataDirectories()); + const QFileInfoList dirs(CSwiftDirectories::applicationDataDirectories()); if (dirs.isEmpty()) { return {}; } const QString otherVersionDir = m_otherVersionDirs.at(ui->cb_OtherVersions->currentIndex()); QString dir; @@ -390,7 +391,7 @@ namespace BlackGui { this->initMultiSimulatorCache(&m_modelCaches, file); } - else if (file.contains(CDirectoryUtils::bootstrapFileName())) + else if (file.contains(CSwiftDirectories::bootstrapFileName())) { CData setup { this }; //!< data cache setup const CGlobalSetup s = CGlobalSetup::fromJsonFile(file, true); @@ -418,7 +419,7 @@ namespace BlackGui void CCopyConfigurationComponent::initOtherSwiftVersions() { ui->cb_OtherVersions->clear(); - const QMap otherVersions = CDirectoryUtils::currentApplicationDataDirectoryMapWithoutCurrentVersion(); + const QMap otherVersions = CSwiftDirectories::currentApplicationDataDirectoryMapWithoutCurrentVersion(); for (const auto &pair : makePairsRange(otherVersions)) { const CApplicationInfo &info(pair.second); diff --git a/src/blackgui/components/copymodelsfromotherswiftversionscomponent.cpp b/src/blackgui/components/copymodelsfromotherswiftversionscomponent.cpp index 045d62cbc..b52b32b12 100644 --- a/src/blackgui/components/copymodelsfromotherswiftversionscomponent.cpp +++ b/src/blackgui/components/copymodelsfromotherswiftversionscomponent.cpp @@ -12,6 +12,7 @@ #include "blackcore/application.h" #include "blackmisc/stringutils.h" #include "blackmisc/fileutils.h" +#include "blackmisc/swiftdirectories.h" #include "blackmisc/directoryutils.h" #include @@ -128,7 +129,7 @@ namespace BlackGui // create relative file name QString relativeModelFile = thisVersionModelFile; - relativeModelFile = relativeModelFile.replace(CDirectoryUtils::applicationDataDirectory(), "", Qt::CaseInsensitive); + relativeModelFile = relativeModelFile.replace(CSwiftDirectories::applicationDataDirectory(), "", Qt::CaseInsensitive); if (relativeModelFile.length() < 2) { return false; } relativeModelFile = relativeModelFile.mid(relativeModelFile.indexOf('/', 1)); diff --git a/src/blackgui/components/datainfoareacomponent.cpp b/src/blackgui/components/datainfoareacomponent.cpp index 2dde3a78c..448e44040 100644 --- a/src/blackgui/components/datainfoareacomponent.cpp +++ b/src/blackgui/components/datainfoareacomponent.cpp @@ -20,6 +20,7 @@ #include "blackmisc/logmessage.h" #include "blackmisc/network/entityflags.h" #include "blackmisc/statusmessage.h" +#include "blackmisc/swiftdirectories.h" #include "blackmisc/directoryutils.h" #include "blackmisc/verify.h" #include "ui_datainfoareacomponent.h" @@ -95,7 +96,7 @@ namespace BlackGui } // write to disk - const bool s = sGui->getWebDataServices()->writeDbDataToDisk(CDirectoryUtils::staticDbFilesDirectory()); + const bool s = sGui->getWebDataServices()->writeDbDataToDisk(CSwiftDirectories::staticDbFilesDirectory()); if (s) { CLogMessage(this).info(u"Written DB data"); @@ -116,7 +117,7 @@ namespace BlackGui bool ok = false; if (msgs.isSuccess()) { - CLogMessage(this).info(u"Read DB data from directory: %1") << CDirectoryUtils::staticDbFilesDirectory(); + CLogMessage(this).info(u"Read DB data from directory: %1") << CSwiftDirectories::staticDbFilesDirectory(); ui->comp_DbAircraftIcao->showLoadIndicator(); ui->comp_DbAirlineIcao->showLoadIndicator(); ui->comp_DbCountries->showLoadIndicator(); diff --git a/src/blackgui/components/dbmappingcomponent.cpp b/src/blackgui/components/dbmappingcomponent.cpp index 408ce78f2..d5d91077b 100644 --- a/src/blackgui/components/dbmappingcomponent.cpp +++ b/src/blackgui/components/dbmappingcomponent.cpp @@ -30,6 +30,7 @@ #include "blackmisc/aviation/aircrafticaocode.h" #include "blackmisc/aviation/livery.h" #include "blackmisc/icons.h" +#include "blackmisc/swiftdirectories.h" #include "blackmisc/logmessage.h" #include "blackmisc/network/authenticateduser.h" #include "blackmisc/propertyindexvariantmap.h" @@ -545,7 +546,7 @@ namespace BlackGui void CDbMappingComponent::loadRemovedModels() { if (!ui->comp_ModelWorkbench->view()) { return; } - const QString logDir = CDirectoryUtils::logDirectory(); + const QString logDir = CSwiftDirectories::logDirectory(); ui->comp_ModelWorkbench->view()->showFileLoadDialog(logDir); } diff --git a/src/blackgui/components/dbownmodelscomponent.cpp b/src/blackgui/components/dbownmodelscomponent.cpp index 0ca616ac2..6620599df 100644 --- a/src/blackgui/components/dbownmodelscomponent.cpp +++ b/src/blackgui/components/dbownmodelscomponent.cpp @@ -16,6 +16,7 @@ #include "blackcore/webdataservices.h" #include "blackcore/db/databaseutils.h" #include "blackmisc/icons.h" +#include "blackmisc/swiftdirectories.h" #include "blackmisc/logmessage.h" #include "blackmisc/processctrl.h" #include "blackmisc/statusmessage.h" @@ -295,7 +296,7 @@ namespace BlackGui void CDbOwnModelsComponent::runScriptCSL2XSB() { - static const QString script = QDir(CDirectoryUtils::shareDirectory()).filePath("CSL2XSB/CSL2XSB.exe"); + static const QString script = QDir(CSwiftDirectories::shareDirectory()).filePath("CSL2XSB/CSL2XSB.exe"); for (const QString &modelDir : m_simulatorSettings.getModelDirectoriesOrDefault(CSimulatorInfo::xplane())) { CLogMessage(this).info(u"Running CSL2XSB on model directory %1") << modelDir; diff --git a/src/blackgui/components/flightplancomponent.cpp b/src/blackgui/components/flightplancomponent.cpp index 52865e1cd..375a036c5 100644 --- a/src/blackgui/components/flightplancomponent.cpp +++ b/src/blackgui/components/flightplancomponent.cpp @@ -29,6 +29,7 @@ #include "blackmisc/logcategory.h" #include "blackmisc/logmessage.h" #include "blackmisc/network/user.h" +#include "blackmisc/swiftdirectories.h" #include "blackmisc/directoryutils.h" #include "blackmisc/statusmessage.h" #include "blackmisc/stringutils.h" @@ -682,7 +683,7 @@ namespace BlackGui { const QString fn = CFileUtils::appendFilePathsAndFixUnc( - CDirectoryUtils::normalizedApplicationDataDirectory(), + CSwiftDirectories::normalizedApplicationDataDirectory(), QStringLiteral("swiftFlightPlanTemplate.json") ); return fn; diff --git a/src/blackgui/components/installfsxterrainprobecomponent.cpp b/src/blackgui/components/installfsxterrainprobecomponent.cpp index edcf710cb..37d1f17d5 100644 --- a/src/blackgui/components/installfsxterrainprobecomponent.cpp +++ b/src/blackgui/components/installfsxterrainprobecomponent.cpp @@ -12,6 +12,7 @@ #include "blackgui/guiutility.h" #include "blackmisc/simulation/fscommon/fscommonutil.h" #include "blackmisc/simulation/simulatorinfo.h" +#include "blackmisc/swiftdirectories.h" #include "blackmisc/directoryutils.h" #include "blackmisc/fileutils.h" @@ -33,7 +34,7 @@ namespace BlackGui ui(new Ui::CInstallFsxTerrainProbeComponent) { ui->setupUi(this); - ui->le_Source->setText(CDirectoryUtils::shareTerrainProbeDirectory()); + ui->le_Source->setText(CSwiftDirectories::shareTerrainProbeDirectory()); ui->comp_SimulatorSelector->setMode(CSimulatorSelector::RadioButtons); ui->comp_SimulatorSelector->setFsxP3DOnly(); diff --git a/src/blackgui/components/otherswiftversionscomponent.cpp b/src/blackgui/components/otherswiftversionscomponent.cpp index 855d8913b..93b556684 100644 --- a/src/blackgui/components/otherswiftversionscomponent.cpp +++ b/src/blackgui/components/otherswiftversionscomponent.cpp @@ -8,6 +8,7 @@ #include "otherswiftversionscomponent.h" #include "ui_otherswiftversionscomponent.h" +#include "blackmisc/swiftdirectories.h" #include "blackmisc/directoryutils.h" #include "guiapplication.h" #include @@ -70,7 +71,7 @@ namespace BlackGui void COtherSwiftVersionsComponent::openDataDirectory() { - const QString dir = CDirectoryUtils::applicationDataDirectory(); + const QString dir = CSwiftDirectories::applicationDataDirectory(); const QUrl url = QUrl::fromLocalFile(dir); QDesktopServices::openUrl(url); } diff --git a/src/blackgui/components/setuploadingdialog.cpp b/src/blackgui/components/setuploadingdialog.cpp index baca65274..4cb0dfa19 100644 --- a/src/blackgui/components/setuploadingdialog.cpp +++ b/src/blackgui/components/setuploadingdialog.cpp @@ -12,6 +12,7 @@ #include "blackgui/guiapplication.h" #include "blackcore/data/globalsetup.h" #include "blackcore/setupreader.h" +#include "blackmisc/swiftdirectories.h" #include "blackmisc/directoryutils.h" #include "blackmisc/network/urllist.h" @@ -187,14 +188,14 @@ namespace BlackGui void CSetupLoadingDialog::displayOtherVersionsInfo() { - const int other = CDirectoryUtils::applicationDataDirectoriesCount() - 1 ; + const int other = CSwiftDirectories::applicationDataDirectoriesCount() - 1 ; ui->le_OtherSwiftVersions->setText(QStringLiteral("There is/are %1 other swift version(s) installed").arg(other)); ui->pb_CopyFromSwift->setEnabled(other > 0); } void CSetupLoadingDialog::openDirectory() { - const QUrl url = QUrl::fromLocalFile(CDirectoryUtils::normalizedApplicationDataDirectory()); + const QUrl url = QUrl::fromLocalFile(CSwiftDirectories::normalizedApplicationDataDirectory()); QDesktopServices::openUrl(url); } diff --git a/src/blackgui/copyxswiftbusdialog.cpp b/src/blackgui/copyxswiftbusdialog.cpp index 5bdbf3115..125e6fc78 100644 --- a/src/blackgui/copyxswiftbusdialog.cpp +++ b/src/blackgui/copyxswiftbusdialog.cpp @@ -13,6 +13,7 @@ #include "guiapplication.h" #include "blackcore/context/contextsimulator.h" #include "blackmisc/simulation/xplane/xplaneutil.h" +#include "blackmisc/swiftdirectories.h" #include "blackmisc/directoryutils.h" #include "blackconfig/buildconfig.h" @@ -40,7 +41,7 @@ namespace BlackGui const QMessageBox::StandardButton reply = QMessageBox::question(parent, "Copy XSwiftBus", - QStringLiteral("Copy XSwiftBus from build directory '%1' to plugin directory '%2'?").arg(CDirectoryUtils::getXSwiftBusBuildDirectory(), CXPlaneUtil::xswiftbusPluginDir(xplaneRootDir)), + QStringLiteral("Copy XSwiftBus from build directory '%1' to plugin directory '%2'?").arg(CSwiftDirectories::getXSwiftBusBuildDirectory(), CXPlaneUtil::xswiftbusPluginDir(xplaneRootDir)), QMessageBox::Yes | QMessageBox::No); if (reply != QMessageBox::Yes) { return 0; } return CXPlaneUtil::copyXSwiftBusBuildFiles(xplaneRootDir); diff --git a/src/blackgui/guiapplication.cpp b/src/blackgui/guiapplication.cpp index a67c17ce2..fced75373 100644 --- a/src/blackgui/guiapplication.cpp +++ b/src/blackgui/guiapplication.cpp @@ -22,6 +22,7 @@ #include "blackcore/setupreader.h" #include "blackmisc/slot.h" #include "blackmisc/stringutils.h" +#include "blackmisc/swiftdirectories.h" #include "blackmisc/directoryutils.h" #include "blackmisc/datacache.h" #include "blackmisc/logcategory.h" @@ -406,7 +407,7 @@ namespace BlackGui { static const QString filename = [] { - QString dir = CFileUtils::appendFilePaths(CDirectoryUtils::normalizedApplicationDataDirectory(), "settings/qgeom"); + QString dir = CFileUtils::appendFilePaths(CSwiftDirectories::normalizedApplicationDataDirectory(), "settings/qgeom"); return CFileUtils::appendFilePaths(dir, QFileInfo(QCoreApplication::applicationFilePath()).completeBaseName() + ".ini"); }(); return filename; @@ -1085,14 +1086,14 @@ namespace BlackGui bool CGuiApplication::openStandardLogDirectory() { - const QString path(QDir::toNativeSeparators(CDirectoryUtils::logDirectory())); + const QString path(QDir::toNativeSeparators(CSwiftDirectories::logDirectory())); if (!QDir(path).exists()) { return false; } return QDesktopServices::openUrl(QUrl::fromLocalFile(path)); } bool CGuiApplication::openStandardCrashDumpDirectory() { - const QString path(QDir::toNativeSeparators(CDirectoryUtils::crashpadDatabaseDirectory())); + const QString path(QDir::toNativeSeparators(CSwiftDirectories::crashpadDatabaseDirectory())); if (!QDir(path).exists()) { return false; } return QDesktopServices::openUrl(QUrl::fromLocalFile(path)); } diff --git a/src/blackgui/stylesheetutility.cpp b/src/blackgui/stylesheetutility.cpp index 99b541ba0..96462b445 100644 --- a/src/blackgui/stylesheetutility.cpp +++ b/src/blackgui/stylesheetutility.cpp @@ -10,6 +10,7 @@ #include "blackgui/stylesheetutility.h" #include "blackmisc/fileutils.h" #include "blackmisc/logmessage.h" +#include "blackmisc/swiftdirectories.h" #include "blackmisc/directoryutils.h" #include "blackmisc/restricted.h" @@ -140,12 +141,12 @@ namespace BlackGui bool CStyleSheetUtility::read() { - QDir directory(CDirectoryUtils::stylesheetsDirectory()); + QDir directory(CSwiftDirectories::stylesheetsDirectory()); if (!directory.exists()) { return false; } // qss/css files const bool needsWatcher = m_fileWatcher.files().isEmpty(); - if (needsWatcher) { m_fileWatcher.addPath(CDirectoryUtils::stylesheetsDirectory()); } // directory to deleted file watching + if (needsWatcher) { m_fileWatcher.addPath(CSwiftDirectories::stylesheetsDirectory()); } // directory to deleted file watching directory.setNameFilters({"*.qss", "*.css"}); directory.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks); @@ -167,7 +168,7 @@ namespace BlackGui // save files for debugging if (CBuildConfig::isLocalDeveloperDebugBuild()) { - const QString fn = CFileUtils::appendFilePaths(CDirectoryUtils::logDirectory(), f); + const QString fn = CFileUtils::appendFilePaths(CSwiftDirectories::logDirectory(), f); CFileUtils::writeStringToFile(c, fn); } @@ -255,7 +256,7 @@ namespace BlackGui bool CStyleSheetUtility::updateFont(const QString &qss) { const QString qssWidget(u"QWidget {\n" % qss % u"}\n"); - const QString fn = CFileUtils::appendFilePaths(CDirectoryUtils::stylesheetsDirectory(), fileNameFontsModified()); + const QString fn = CFileUtils::appendFilePaths(CSwiftDirectories::stylesheetsDirectory(), fileNameFontsModified()); QFile fontFile(fn); bool ok = fontFile.open(QFile::Text | QFile::WriteOnly); if (ok) @@ -274,7 +275,7 @@ namespace BlackGui bool CStyleSheetUtility::resetFont() { - QFile fontFile(CFileUtils::appendFilePaths(CDirectoryUtils::stylesheetsDirectory(), fileNameFontsModified())); + QFile fontFile(CFileUtils::appendFilePaths(CSwiftDirectories::stylesheetsDirectory(), fileNameFontsModified())); return fontFile.remove(); } @@ -317,7 +318,7 @@ namespace BlackGui bool CStyleSheetUtility::deleteModifiedFontFile() { - const QString fn = CFileUtils::appendFilePaths(CDirectoryUtils::stylesheetsDirectory(), fileNameFontsModified()); + const QString fn = CFileUtils::appendFilePaths(CSwiftDirectories::stylesheetsDirectory(), fileNameFontsModified()); QFile file(fn); if (!file.exists()) { return false; } bool r = file.remove(); @@ -334,7 +335,7 @@ namespace BlackGui const QString &CStyleSheetUtility::fileNameAndPathSwiftStandardGui() { - static const QString fn = CFileUtils::appendFilePaths(CDirectoryUtils::stylesheetsDirectory(), CStyleSheetUtility::fileNameSwiftStandardGui()); + static const QString fn = CFileUtils::appendFilePaths(CSwiftDirectories::stylesheetsDirectory(), CStyleSheetUtility::fileNameSwiftStandardGui()); return fn; } @@ -364,7 +365,7 @@ namespace BlackGui const QString &CStyleSheetUtility::fileNameAndPathStandardWidget() { - static const QString fn = CFileUtils::appendFilePaths(CDirectoryUtils::stylesheetsDirectory(), CStyleSheetUtility::fileNameStandardWidget()); + static const QString fn = CFileUtils::appendFilePaths(CSwiftDirectories::stylesheetsDirectory(), CStyleSheetUtility::fileNameStandardWidget()); return fn; } @@ -513,7 +514,7 @@ namespace BlackGui bool CStyleSheetUtility::qssFileExists(const QString &filename) { if (filename.isEmpty()) { return false; } - const QFileInfo f(CFileUtils::appendFilePaths(CDirectoryUtils::stylesheetsDirectory(), filename)); + const QFileInfo f(CFileUtils::appendFilePaths(CSwiftDirectories::stylesheetsDirectory(), filename)); return f.exists() && f.isReadable(); } } // ns diff --git a/src/blackgui/views/viewbase.cpp b/src/blackgui/views/viewbase.cpp index f83e738b7..b0d720bc9 100644 --- a/src/blackgui/views/viewbase.cpp +++ b/src/blackgui/views/viewbase.cpp @@ -843,11 +843,9 @@ namespace BlackGui const QString json(this->toJsonString(QJsonDocument::Indented, selectedOnly)); // save as CVariant JSON // save file - const bool ok = CFileUtils::writeStringToFileInBackground(json, fileName); - if (ok) { this->rememberLastJsonDirectory(fileName); } - return ok ? - CStatusMessage(this, CStatusMessage::SeverityInfo, u"Writing " % fileName % u" in progress", true) : - CStatusMessage(this, CStatusMessage::SeverityError, u"Writing " % fileName % u" failed", true); + CWorker::fromTask(qApp, Q_FUNC_INFO, [ = ] { CFileUtils::writeStringToFile(json, fileName); }); + this->rememberLastJsonDirectory(fileName); + return CStatusMessage(this, CStatusMessage::SeverityInfo, u"Writing " % fileName % u" in progress", true); } template diff --git a/src/blackmisc/applicationinfolist.cpp b/src/blackmisc/applicationinfolist.cpp index 1d548ee9a..fdb4d1840 100644 --- a/src/blackmisc/applicationinfolist.cpp +++ b/src/blackmisc/applicationinfolist.cpp @@ -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 otherVersions = reinit ? - CDirectoryUtils::currentApplicationDataDirectoryMapWithoutCurrentVersion() : - CDirectoryUtils::applicationDataDirectoryMapWithoutCurrentVersion(); + CSwiftDirectories::currentApplicationDataDirectoryMapWithoutCurrentVersion() : + CSwiftDirectories::applicationDataDirectoryMapWithoutCurrentVersion(); for (const CApplicationInfo &info : otherVersions) { diff --git a/src/blackmisc/audio/audiosettings.cpp b/src/blackmisc/audio/audiosettings.cpp index ff65340d9..e0f05268e 100644 --- a/src/blackmisc/audio/audiosettings.cpp +++ b/src/blackmisc/audio/audiosettings.cpp @@ -7,7 +7,7 @@ */ #include "blackmisc/audio/audiosettings.h" -#include "blackmisc/directoryutils.h" +#include "blackmisc/swiftdirectories.h" #include "blackmisc/fileutils.h" #include #include @@ -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) diff --git a/src/blackmisc/aviation/airlineicaocode.cpp b/src/blackmisc/aviation/airlineicaocode.cpp index 95742e97d..79c685bb8 100644 --- a/src/blackmisc/aviation/airlineicaocode.cpp +++ b/src/blackmisc/aviation/airlineicaocode.cpp @@ -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 iconIdsImpl() { - QDir dir(CDirectoryUtils::imagesAirlinesDirectory()); + QDir dir(CSwiftDirectories::imagesAirlinesDirectory()); Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "image directory missing"); QSet ids; diff --git a/src/blackmisc/aviation/altitude.cpp b/src/blackmisc/aviation/altitude.cpp index 248dd99c9..efb6b9785 100644 --- a/src/blackmisc/aviation/altitude.cpp +++ b/src/blackmisc/aviation/altitude.cpp @@ -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 initMetricValues() { QVector 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) diff --git a/src/blackmisc/compressutils.cpp b/src/blackmisc/compressutils.cpp index ea08ca5db..bc59ee33f 100644 --- a/src/blackmisc/compressutils.cpp +++ b/src/blackmisc/compressutils.cpp @@ -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"); diff --git a/src/blackmisc/crashhandler.cpp b/src/blackmisc/crashhandler.cpp index 6df46b586..3eae13b4c 100644 --- a/src/blackmisc/crashhandler.cpp +++ b/src/blackmisc/crashhandler.cpp @@ -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; } diff --git a/src/blackmisc/crashinfo.cpp b/src/blackmisc/crashinfo.cpp index b16d0f4b7..cd8cf650c 100644 --- a/src/blackmisc/crashinfo.cpp +++ b/src/blackmisc/crashinfo.cpp @@ -8,6 +8,7 @@ #include "blackmisc/crashinfo.h" #include "blackmisc/fileutils.h" +#include "blackmisc/worker.h" #include #include @@ -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 diff --git a/src/blackmisc/directories.cpp b/src/blackmisc/directories.cpp index c67fe8893..b7e12c116 100644 --- a/src/blackmisc/directories.cpp +++ b/src/blackmisc/directories.cpp @@ -7,6 +7,7 @@ */ #include "blackmisc/directories.h" +#include "blackmisc/swiftdirectories.h" #include "blackmisc/directoryutils.h" #include #include @@ -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; } diff --git a/src/blackmisc/directoryutils.cpp b/src/blackmisc/directoryutils.cpp index 00f25a093..44c9e5d51 100644 --- a/src/blackmisc/directoryutils.cpp +++ b/src/blackmisc/directoryutils.cpp @@ -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 @@ -22,97 +23,16 @@ #include 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 good; + static QMap 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) diff --git a/src/blackmisc/directoryutils.h b/src/blackmisc/directoryutils.h index 3bdff954e..bdb501489 100644 --- a/src/blackmisc/directoryutils.h +++ b/src/blackmisc/directoryutils.h @@ -11,7 +11,6 @@ #ifndef BLACKMISC_DIRECTORYUTILS_H #define BLACKMISC_DIRECTORYUTILS_H -#include "blackmisc/applicationinfo.h" #include "blackmisc/blackmiscexport.h" #include #include @@ -28,136 +27,13 @@ namespace BlackMisc class BLACKMISC_EXPORT CDirectoryUtils { public: - //! File path and swift application - using FilePerApplication = QMap; - - //! 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 fileNamesToQSet(const QFileInfoList &fileInfoList); @@ -239,6 +107,9 @@ namespace BlackMisc //! File to canonical names static const QSet filesToCanonicalNames(const QSet &fileNames, const QSet &canonicalFileNames); + + //! Can connect the UNC machine + static bool canPingUncMachine(const QString &machine); }; } // ns diff --git a/src/blackmisc/filelogger.cpp b/src/blackmisc/filelogger.cpp index 44ba880bb..3631ef7eb 100644 --- a/src/blackmisc/filelogger.cpp +++ b/src/blackmisc/filelogger.cpp @@ -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()) diff --git a/src/blackmisc/fileutils.cpp b/src/blackmisc/fileutils.cpp index 5779b4c85..8d5c6eccc 100644 --- a/src/blackmisc/fileutils.cpp +++ b/src/blackmisc/fileutils.cpp @@ -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 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 good; - static QMap 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 diff --git a/src/blackmisc/fileutils.h b/src/blackmisc/fileutils.h index a289837c6..8f72fc8d5 100644 --- a/src/blackmisc/fileutils.h +++ b/src/blackmisc/fileutils.h @@ -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 windowsUncMachines(const QSet &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 diff --git a/src/blackmisc/icons.cpp b/src/blackmisc/icons.cpp index 1668901cf..bc34e9a1e 100644 --- a/src/blackmisc/icons.cpp +++ b/src/blackmisc/icons.cpp @@ -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; diff --git a/src/blackmisc/simulation/aircraftmodellist.cpp b/src/blackmisc/simulation/aircraftmodellist.cpp index 9f8f8137b..468744cef 100644 --- a/src/blackmisc/simulation/aircraftmodellist.cpp +++ b/src/blackmisc/simulation/aircraftmodellist.cpp @@ -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; } diff --git a/src/blackmisc/simulation/aircraftmodelutils.cpp b/src/blackmisc/simulation/aircraftmodelutils.cpp index 324233fc3..82e21a757 100644 --- a/src/blackmisc/simulation/aircraftmodelutils.cpp +++ b/src/blackmisc/simulation/aircraftmodelutils.cpp @@ -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) : ""; diff --git a/src/blackmisc/simulation/autopublishdata.cpp b/src/blackmisc/simulation/autopublishdata.cpp index 50ffc05bd..f6a7c8362 100644 --- a/src/blackmisc/simulation/autopublishdata.cpp +++ b/src/blackmisc/simulation/autopublishdata.cpp @@ -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 diff --git a/src/blackmisc/simulation/autopublishdata.h b/src/blackmisc/simulation/autopublishdata.h index a87358470..64ce84c30 100644 --- a/src/blackmisc/simulation/autopublishdata.h +++ b/src/blackmisc/simulation/autopublishdata.h @@ -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 --------------- diff --git a/src/blackmisc/simulation/fscommon/fscommonutil.cpp b/src/blackmisc/simulation/fscommon/fscommonutil.cpp index 0cdc9ee18..e211846e8 100644 --- a/src/blackmisc/simulation/fscommon/fscommonutil.cpp +++ b/src/blackmisc/simulation/fscommon/fscommonutil.cpp @@ -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; } diff --git a/src/blackmisc/simulation/interpolationlogger.cpp b/src/blackmisc/simulation/interpolationlogger.cpp index b55c15158..7520e6c92 100644 --- a/src/blackmisc/simulation/interpolationlogger.cpp +++ b/src/blackmisc/simulation/interpolationlogger.cpp @@ -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 @@ -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 &interpolation, const QList &parts) { if (parts.isEmpty() && interpolation.isEmpty()) { return CStatusMessage(static_cast(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)); } diff --git a/src/blackmisc/simulation/xplane/xplaneutil.cpp b/src/blackmisc/simulation/xplane/xplaneutil.cpp index 5acf7e4e6..28e58504a 100644 --- a/src/blackmisc/simulation/xplane/xplaneutil.cpp +++ b/src/blackmisc/simulation/xplane/xplaneutil.cpp @@ -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 @@ -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() diff --git a/src/blackmisc/swiftdirectories.cpp b/src/blackmisc/swiftdirectories.cpp new file mode 100644 index 000000000..70889415a --- /dev/null +++ b/src/blackmisc/swiftdirectories.cpp @@ -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 +#include +#include +#include +#include +#include +#include + +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 diff --git a/src/blackmisc/swiftdirectories.h b/src/blackmisc/swiftdirectories.h new file mode 100644 index 000000000..365159c26 --- /dev/null +++ b/src/blackmisc/swiftdirectories.h @@ -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 +#include +#include +#include +#include +#include + +namespace BlackMisc +{ + /*! + * Locations of important directories for swift files + */ + class BLACKMISC_EXPORT CSwiftDirectories + { + public: + //! File path and swift application + using FilePerApplication = QMap; + + //! 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 diff --git a/src/blackmisc/test/testdata.cpp b/src/blackmisc/test/testdata.cpp index 5396db1b8..96aa2c982 100644 --- a/src/blackmisc/test/testdata.cpp +++ b/src/blackmisc/test/testdata.cpp @@ -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()); diff --git a/src/blackmisc/valuecache.cpp b/src/blackmisc/valuecache.cpp index 0e051ad5a..7d81c5dc3 100644 --- a/src/blackmisc/valuecache.cpp +++ b/src/blackmisc/valuecache.cpp @@ -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 &> getCacheRootDirectoryMutable() { - static QString dir = CDirectoryUtils::normalizedApplicationDataDirectory(); + static QString dir = CSwiftDirectories::normalizedApplicationDataDirectory(); static std::atomic frozen { false }; return { dir, frozen }; } diff --git a/src/blacksound/notificationplayer.cpp b/src/blacksound/notificationplayer.cpp index 58a910f13..3b4b212dd 100644 --- a/src/blacksound/notificationplayer.cpp +++ b/src/blacksound/notificationplayer.cpp @@ -8,7 +8,7 @@ #include "notificationplayer.h" #include "blackmisc/logmessage.h" -#include "blackmisc/fileutils.h" +#include "blackmisc/swiftdirectories.h" #include "blacksound/sampleprovider/samples.h" #include #include @@ -95,7 +95,7 @@ namespace BlackSound if (e) { e->deleteLater(); } // file if existing - const QUrl url = CFileUtils::soundFileQUrlOrDefault(directory, name); + const QUrl url = QUrl::fromLocalFile(CSwiftDirectories::soundFilePathOrDefaultPath(directory, name)); if (url.isEmpty() || !url.isLocalFile()) { // remove notification as not existing diff --git a/src/swiftdata/swiftdatamenus.cpp b/src/swiftdata/swiftdatamenus.cpp index 1766b64c3..f05018ba7 100644 --- a/src/swiftdata/swiftdatamenus.cpp +++ b/src/swiftdata/swiftdatamenus.cpp @@ -11,6 +11,7 @@ #include "blackgui/components/dbmappingcomponent.h" #include "blackgui/guiapplication.h" #include "blackmisc/icons.h" +#include "blackmisc/swiftdirectories.h" #include "blackmisc/directoryutils.h" #include "swiftdata.h" #include "ui_swiftdata.h" @@ -57,7 +58,7 @@ void CSwiftData::initDynamicMenus() // menu entry for auto publish data ui->menu_Mapping->addAction(CIcons::database16(), "Auto publish data", this, &CSwiftData::showAutoPublishing); - QString resourceDir(CDirectoryUtils::shareDirectory()); + QString resourceDir(CSwiftDirectories::shareDirectory()); if (!resourceDir.isEmpty() && QDir(resourceDir).exists()) { Q_ASSERT_X(ui->comp_MainInfoArea, Q_FUNC_INFO, "Missing main info area"); diff --git a/src/swiftlauncher/swiftlauncher.cpp b/src/swiftlauncher/swiftlauncher.cpp index 7a0392e09..3a9c7d24f 100644 --- a/src/swiftlauncher/swiftlauncher.cpp +++ b/src/swiftlauncher/swiftlauncher.cpp @@ -20,6 +20,7 @@ #include "blackcore/context/contextnetwork.h" #include "blackmisc/network/networkutils.h" #include "blackmisc/dbusserver.h" +#include "blackmisc/swiftdirectories.h" #include "blackmisc/directoryutils.h" #include "blackmisc/icons.h" #include "blackmisc/logmessage.h" @@ -133,7 +134,7 @@ void CSwiftLauncher::installerMode() bool runDialog = false; do { - const QDir dir = CDirectoryUtils::logDirectory(); + const QDir dir = CSwiftDirectories::logDirectory(); if (!dir.exists()) { break; } if (sGui && sGui->getSetupReader()) @@ -344,13 +345,13 @@ bool CSwiftLauncher::setSwiftCoreExecutable() if (ui->cb_DisableCoreAudio->isChecked()) { args.append("--noaudio"); } m_executableArgs = sGui->argumentsJoined(args); - m_executable = CDirectoryUtils::executableFilePath(CBuildConfig::swiftCoreExecutableName()); + m_executable = CSwiftDirectories::executableFilePath(CBuildConfig::swiftCoreExecutableName()); return true; } bool CSwiftLauncher::setSwiftDataExecutable() { - m_executable = CDirectoryUtils::executableFilePath(CBuildConfig::swiftDataExecutableName()); + m_executable = CSwiftDirectories::executableFilePath(CBuildConfig::swiftDataExecutableName()); QStringList fsdArgs; int id = 0; @@ -369,7 +370,7 @@ bool CSwiftLauncher::setSwiftDataExecutable() bool CSwiftLauncher::setSwiftGuiExecutable() { if (!sGui || sGui->isShuttingDown()) { return false; } - m_executable = CDirectoryUtils::executableFilePath(CBuildConfig::swiftGuiExecutableName()); + m_executable = CSwiftDirectories::executableFilePath(CBuildConfig::swiftGuiExecutableName()); QStringList args { "--core", CoreModes::coreModeToString(getCoreMode()), diff --git a/tests/blackmisc/simulation/testxplane/testxplane.cpp b/tests/blackmisc/simulation/testxplane/testxplane.cpp index 1ace33ba5..240523238 100644 --- a/tests/blackmisc/simulation/testxplane/testxplane.cpp +++ b/tests/blackmisc/simulation/testxplane/testxplane.cpp @@ -13,6 +13,7 @@ #include "blackmisc/simulation/xplane/qtfreeutils.h" #include "blackmisc/simulation/settings/xswiftbussettings.h" #include "blackmisc/simulation/settings/xswiftbussettingsqtfree.inc" +#include "blackmisc/swiftdirectories.h" #include "blackmisc/directoryutils.h" #include "test.h" @@ -94,7 +95,7 @@ namespace BlackMiscTest void CTestXPlane::acfPropertiesTest() { - QString testAcfFile = CDirectoryUtils::testFilesDirectory() + "/testaircraft.acf"; + QString testAcfFile = CSwiftDirectories::testFilesDirectory() + "/testaircraft.acf"; AcfProperties acfProperties = extractAcfProperties(testAcfFile.toStdString()); QCOMPARE(QString::fromStdString(acfProperties.aircraftIcaoCode), QString("BE58")); QCOMPARE(QString::fromStdString(acfProperties.modelDescription), QString("[ACF] Beechcraft Baron B58")); diff --git a/tests/blackmisc/testcompress/testcompress.cpp b/tests/blackmisc/testcompress/testcompress.cpp index 449bfc83f..d5b1f9c3b 100644 --- a/tests/blackmisc/testcompress/testcompress.cpp +++ b/tests/blackmisc/testcompress/testcompress.cpp @@ -15,6 +15,7 @@ #include "blackconfig/buildconfig.h" #include "blackmisc/compressutils.h" +#include "blackmisc/swiftdirectories.h" #include "blackmisc/directoryutils.h" #include "blackmisc/fileutils.h" #include "test.h" @@ -63,7 +64,7 @@ namespace BlackMiscTest QVERIFY2(zip7Exists, "No 7zip"); const QString td = tempDir.path(); - const QString compressedFile(CFileUtils::appendFilePaths(CDirectoryUtils::shareTestDirectory(), "countries.json.gz")); + const QString compressedFile(CFileUtils::appendFilePaths(CSwiftDirectories::shareTestDirectory(), "countries.json.gz")); const QString unCompressedFile(CFileUtils::appendFilePaths(td, "countries.json")); const bool c = CCompressUtils::zip7Uncompress(compressedFile, td);