9 #include <QCoreApplication>
13 #include <QHttpMultiPart>
14 #include <QNetworkReply>
15 #include <QNetworkRequest>
17 #include <QRegularExpression>
19 #include <QStandardPaths>
20 #include <QStringBuilder>
21 #include <QStringList>
23 #include <QTemporaryDir>
26 #include <QWriteLocker>
58 using namespace swift::config;
60 using namespace swift::misc::db;
61 using namespace swift::misc::network;
62 using namespace swift::misc::aviation;
63 using namespace swift::misc::simulation;
64 using namespace swift::misc::weather;
66 using namespace swift::core::context;
67 using namespace swift::core::vatsim;
74 static const QString &swiftDataRoot()
91 Q_ASSERT_X(!
sApp, Q_FUNC_INFO,
"already initialized");
126 this->tagApplicationDataDirectory();
161 CLogMessage(cat).
debug(u
"Worker named '%1' still exists after application destroyed")
162 << worker->objectName();
188 if (!apps.
contains(myself)) {
return true; }
201 Q_ASSERT_X(
instance(), Q_FUNC_INFO,
"missing application");
250 static const QString s(m_applicationName % u
" " % CBuildConfig::getVersionString());
264 if (!r) {
return {}; }
271 if (!m_gitHubPackagesReader) {
return {}; }
272 return m_gitHubPackagesReader->getUpdateInfo();
278 if (!m_gitHubPackagesReader) {
return; }
279 m_gitHubPackagesReader->readUpdateInfo();
284 if (CBuildConfig::isLocalDeveloperDebugBuild()) {
return CDistribution::localDeveloperBuild(); }
293 Q_ASSERT_X(
m_parsed, Q_FUNC_INFO,
"Call this function after parsing");
311 this->simulateCrash();
315 Q_ASSERT_X(m_setupReader && m_setupReader->isSetupAvailable(), Q_FUNC_INFO,
"Setup not available");
322 msgs.
push_back(this->initLocalSettings());
341 if (
m_shutdown || !m_setupReader) {
return false; }
342 return m_setupReader->isSetupAvailable();
347 return (this->
getGlobalSetup().isSwiftVersionMinimumMappingVersion());
353 return !m_webDataServices.isNull();
361 Q_ASSERT_X(m_webDataServices, Q_FUNC_INFO,
362 "Missing web data services, use hasWebDataServices to test if existing");
363 return m_webDataServices.data();
370 static const QString s(CBuildConfig::getVersionStringPlatform() % u
" [dev,DEVDBG]");
375 static const QString s(CBuildConfig::getVersionStringPlatform() % u
" [dev]");
378 if (CBuildConfig::isLocalDeveloperDebugBuild())
380 static const QString s(CBuildConfig::getVersionStringPlatform() % u
" [DEVDBG]");
383 return CBuildConfig::getVersionStringPlatform();
398 bool CApplication::initIsRunningInDeveloperEnvironment()
const
405 if (CBuildConfig::isLocalDeveloperDebugBuild()) {
return true; }
413 if (m_localSettingsLoaded) {
return {}; }
414 m_localSettingsLoaded =
true;
443 if (keys.
isEmpty()) {
return {}; }
457 QString str = CBuildConfig::getVersionString() % u
" " %
458 (CBuildConfig::isReleaseBuild() ? u
"Release build" : u
"Debug build") % separator %
459 u
"Local dev.dbg.: " % boolToYesNo(CBuildConfig::isLocalDeveloperDebugBuild()) % separator %
460 u
"dev.env.: " % boolToYesNo(this->
isDeveloperFlagSet()) % separator % u
"distribution: " %
462 boolToYesNo(CBuildConfig::isRunningOnWindowsNtPlatform()) % separator % u
"Linux: " %
463 boolToYesNo(CBuildConfig::isRunningOnLinuxPlatform()) %
" Unix: " %
464 boolToYesNo(CBuildConfig::isRunningOnUnixPlatform()) % separator % u
"MacOS: " %
465 boolToYesNo(CBuildConfig::isRunningOnMacOSPlatform()) % separator %
"Build Abi: " %
467 CBuildConfig::compiledWithInfo();
469 if (this->
supportsContexts()) { str += (separator % u
"Supporting contexts"); }
478 return this->
getFromNetwork(url, callback, progress, maxRedirects);
497 return this->
getFromNetwork(request, callback, progress, maxRedirects);
511 return this->httpRequestImpl(request, logId, callback, progress, maxRedirects,
522 return this->httpRequestImpl(request, logId, callback, progress, maxRedirects,
532 return this->httpRequestImpl(request, logId, callback,
NoRedirects,
545 return httpRequestImpl(request, logId, callback,
NoRedirects,
548 if (!myself) {
return nr; }
549 if (!multiPart) {
return nr; }
550 nr = qam.
post(request, multiPart);
564 return httpRequestImpl(
574 if (url.
isEmpty()) {
return nullptr; }
575 if (saveAsFileName.
isEmpty()) {
return nullptr; }
577 if (!fi.
dir().
exists()) {
return nullptr; }
586 << url.
getFullUrl() << nwReply->errorString();
594 u
"Saving file '%1' downloaded from '%2' failed")
599 if (!sApp || sApp->isShuttingDown()) { return; }
604 ProgressSlot progressSlot(
this, [=](
int, qint64, qint64,
const QUrl &) {
608 QNetworkReply *reply = this->getFromNetwork(url, callbackSlot, progressSlot, maxRedirects);
612 void CApplication::deleteAllCookies() { m_cookieManager->deleteAllCookies(); }
614 void CApplication::exit(
int retcode)
616 if (
sApp) { instance()->gracefulShutdown(); }
629 for (
const QString &arg : args)
644 const int index = indexOfCommandLineOption(option, args);
645 if (index < 0) {
return; }
652 void CApplication::processEventsFor(
int milliseconds)
664 Q_ASSERT_X(m_parsed, Q_FUNC_INFO,
"Call this function after parsing");
666 m_coreFacadeConfig = coreConfig;
672 if (!m_webDataServices)
675 CWebReaderFlags::AllReaders, CDatabaseReaderConfigList::forPilotClient());
678 return this->startCoreFacade();
683 Q_ASSERT_X(m_parsed, Q_FUNC_INFO,
"Call this function after parsing");
689 return this->startCoreFacade();
695 Q_ASSERT_X(m_webDataServices.isNull(), Q_FUNC_INFO,
"Services already started");
699 return this->startWebDataServices(webReader, dbReaderConfig);
702 bool CApplication::isLocalContext()
const
704 return this->getIContextApplication() && this->getIContextApplication()->isUsingImplementingObject();
707 bool CApplication::isDBusContext()
const
709 return this->getIContextApplication() && !this->getIContextApplication()->isUsingImplementingObject() &&
710 !this->getIContextApplication()->isEmptyObject();
715 Q_ASSERT_X(m_parsed, Q_FUNC_INFO,
"Call this function after parsing");
717 if (!m_setupReader || !m_setupReader->isSetupAvailable())
722 Q_ASSERT_X(m_coreFacade.isNull(), Q_FUNC_INFO,
"Cannot alter facade");
723 Q_ASSERT_X(m_setupReader, Q_FUNC_INFO,
"No facade without setup possible");
724 Q_ASSERT_X(m_webDataServices, Q_FUNC_INFO,
"Need running web data services");
727 m_coreFacade.reset(
new CCoreFacade(m_coreFacadeConfig));
728 emit this->coreFacadeStarted();
735 Q_ASSERT_X(m_parsed, Q_FUNC_INFO,
"Call this function after parsing");
737 if (!m_setupReader || !m_setupReader->isSetupAvailable())
742 Q_ASSERT_X(m_setupReader, Q_FUNC_INFO,
"No web data services without setup possible");
744 if (!m_webDataServices)
747 m_webDataServices.reset(
new CWebDataServices(webReader, dbReaderConfig,
this));
748 Q_ASSERT_X(m_webDataServices, Q_FUNC_INFO,
"Missing web services");
750 emit this->webDataServicesStarted(
true);
757 void CApplication::initLogging()
759 CLogHandler::instance()->install();
763 connect(CLogHandler::instance(), &CLogHandler::localMessageLogged, m_fileLogger.data(),
764 &CFileLogger::writeStatusMessageToFile);
765 connect(CLogHandler::instance(), &CLogHandler::remoteMessageLogged, m_fileLogger.data(),
766 &CFileLogger::writeStatusMessageToFile);
767 m_fileLogger->changeLogPattern(
CLogPattern().withSeverityAtOrAbove(CStatusMessage::SeverityDebug));
770 void CApplication::initParser()
773 m_parser.setApplicationDescription(m_applicationName);
774 m_cmdHelp = m_parser.addHelpOption();
775 m_cmdVersion = m_parser.addVersionOption();
776 m_allOptions.append(m_cmdHelp);
777 m_allOptions.append(m_cmdVersion);
782 this->addParserOption(m_cmdDevelopment);
787 this->addParserOption(m_cmdSkipSingleApp);
792 this->addParserOption(m_cmdClearCache);
797 this->addParserOption(m_cmdTestCrashpad);
800 bool CApplication::isSet(
const QCommandLineOption &option)
const {
return (m_parser.isSet(option)); }
802 void CApplication::registerMetadata()
810 const QStringList files(CDataCache::instance()->enumerateStore());
811 CDataCache::instance()->clearAllValues();
815 void CApplication::gracefulShutdown()
817 if (m_shutdown) {
return; }
818 if (m_shutdownInProgress) {
return; }
819 m_shutdownInProgress =
true;
824 emit this->aboutToShutdown();
830 CLogMessage(
this).
info(u
"Graceful shutdown of CApplication, released devices");
831 m_inputManager->releaseDevices();
835 if (m_parsed && m_saveSettingsOnShutdown)
837 const CStatusMessage m = this->supportsContexts() ? this->getIContextApplication()->saveSettings() :
838 CSettingsCache::instance()->saveToStore();
839 CLogMessage::preformatted(m);
845 if (this->supportsContexts(
true))
847 CLogMessage(
this).
info(u
"Graceful shutdown of CApplication, shutdown of contexts");
850 m_coreFacade->gracefulShutdown();
851 m_coreFacade.reset();
854 if (m_webDataServices)
856 CLogMessage(
this).
info(u
"Graceful shutdown of CApplication, shutdown of web services");
858 m_webDataServices->gracefulShutdown();
859 m_webDataServices.reset();
862 if (m_gitHubPackagesReader) { m_gitHubPackagesReader.reset(); }
864 if (m_setupReader) { m_setupReader.reset(); }
866 CLogMessage(
this).
info(u
"Graceful shutdown of CApplication, shutdown of logger");
867 m_fileLogger->close();
871 processEventsFor(500);
880 void CApplication::onStartUpCompleted()
885 void CApplication::initNetwork()
890 m_cookieManager->setParent(m_accessManager);
891 m_accessManager->setCookieJar(m_cookieManager);
894 Q_ASSERT_X(m_accessManager, Q_FUNC_INFO,
"Need QAM");
907 static const QStringList l({
"swift.application",
"swift." % executable() });
917 m_allOptions.
append(option);
918 return m_parser.addOption(option);
923 m_allOptions.append(options);
924 return m_parser.addOptions(options);
927 void CApplication::addDBusAddressOption()
930 {
"dbus",
"dbusaddress" },
933 this->addParserOption(m_cmdDBusAddress);
936 void CApplication::addNetworkOptions() { this->addParserOptions(IContextNetwork::getCmdLineOptions()); }
938 void CApplication::addAudioOptions() { this->addParserOptions(CContextAudioBase::getCmdLineOptions()); }
940 QString CApplication::getCmdDBusAddressValue()
const
942 if (!this->isParserOptionSet(m_cmdDBusAddress)) {
return {}; }
943 const QString v(this->getParserValue(m_cmdDBusAddress));
944 const QString dBusAddress(CDBusServer::normalizeAddress(v));
948 bool CApplication::isParserOptionSet(
const QString &option)
const {
return m_parser.isSet(option); }
950 bool CApplication::skipSingleApplicationCheck()
const {
return this->isParserOptionSet(m_cmdSkipSingleApp); }
952 bool CApplication::isParserOptionSet(
const QCommandLineOption &option)
const {
return m_parser.isSet(option); }
958 return m_parser.value(option).
trimmed();
961 bool CApplication::parseCommandLineArgsAndLoadSetup()
963 if (!this->startupCheck())
return false;
964 if (!this->parseCommandLineArguments())
return false;
965 if (!this->loadSetupAndHandleErrors())
return false;
969 bool CApplication::parseCommandLineArguments()
971 if (m_parsed) {
return m_parsed; }
975 if (!m_parser.parse(args))
977 this->cmdLineErrorMessage(
"Parser error:", m_parser.errorText());
981 if (m_alreadyRunning && !this->skipSingleApplicationCheck())
983 this->cmdLineErrorMessage(
"Program must only run once",
984 "You cannot run two or more instances side-by-side.");
989 if (m_parser.isSet(m_cmdHelp))
992 this->cmdLineHelpMessage();
995 if (m_parser.isSet(m_cmdVersion))
998 this->cmdLineVersionMessage();
1003 m_devFlag = this->initIsRunningInDeveloperEnvironment();
1006 if (!this->parsingHookIn()) {
return false; }
1013 bool CApplication::startupCheck()
const
1015 const QStringList verifyErrors = CSwiftDirectories::verifyRuntimeDirectoriesAndFiles();
1016 if (!verifyErrors.
isEmpty() && !m_applicationInfo.isUnitTest())
1018 cmdLineErrorMessage(
"Missing runtime directories/files:", verifyErrors.
join(
", "));
1024 bool CApplication::loadSetupAndHandleErrors()
1028 if (msgs.
isFailure()) { displaySetupLoadFailure(msgs); }
1038 void CApplication::cmdLineErrorMessage(
const QString &text,
const QString &informativeText)
const
1040 fputs(qPrintable(text + informativeText), stderr);
1045 if (msgs.
isEmpty()) {
return; }
1047 CApplication::cmdLineErrorMessage(msgs.
toQString(
true),
"");
1052 if (!this->hasSimulator()) {
return nullptr; }
1053 return this->getCoreFacade()->getCContextSimulator()->simulator();
1056 bool CApplication::hasSimulator()
const
1058 if (!this->getCoreFacade()) {
return false; }
1059 if (!this->getCoreFacade()->getIContextSimulator()->isUsingImplementingObject()) {
return false; }
1060 return (this->getCoreFacade()->getCContextSimulator());
1063 void CApplication::cmdLineHelpMessage()
1065 m_parser.showHelp();
1069 void CApplication::cmdLineVersionMessage()
1071 m_parser.showVersion();
1077 QStringList joinedArguments = CApplication::arguments();
1094 toBeRemoved.
append(
"--installer");
1103 const int n = indexOfCommandLineOption(option, toBeRemoved);
1104 if (n >= 0) { argumentsWithoutOption(option, joinedArguments); }
1108 joinedArguments.
append(newArgumentsChecked);
1109 return joinedArguments;
1118 bool CApplication::supportsContexts(
bool ignoreShutdownTest)
const
1120 if (!ignoreShutdownTest && m_shutdown) {
return false; }
1121 if (m_coreFacade.isNull()) {
return false; }
1122 if (!m_coreFacade->getIContextApplication()) {
return false; }
1123 return (!m_coreFacade->getIContextApplication()->isEmptyObject());
1128 if (!supportsContexts()) {
return nullptr; }
1134 if (!supportsContexts()) {
return nullptr; }
1140 if (!supportsContexts()) {
return nullptr; }
1141 return m_coreFacade->getCContextAudioBase();
1146 if (!supportsContexts()) {
return nullptr; }
1152 if (!supportsContexts()) {
return nullptr; }
1158 if (!supportsContexts()) {
return nullptr; }
1164 if (!supportsContexts()) {
return nullptr; }
1170 if (!supportsContexts()) {
return nullptr; }
1176 if (!supportsContexts()) {
return nullptr; }
1177 return m_coreFacade->getCContextAudioBase();
1182 if (!supportsContexts()) {
return nullptr; }
1188 if (!supportsContexts()) {
return nullptr; }
1194 if (!supportsContexts()) {
return nullptr; }
1198 void CApplication::onCoreFacadeStarted()
1207 bool CApplication::hasSetupReader()
const {
return !m_setupReader.isNull(); }
1209 CSetupReader *CApplication::getSetupReader()
const {
return m_setupReader.data(); }
1214 if (!m_setupReader) {
return CStatusMessage(
this).
error(u
"No reader for setup/version"); }
1215 Q_ASSERT_X(m_parsed, Q_FUNC_INFO,
"Not yet parsed");
1220 CUrl CApplication::getVatsimMetarUrl()
const
1222 if (m_shutdown) {
return {}; }
1223 if (m_webDataServices)
1225 const CUrl url(m_webDataServices->getVatsimMetarUrl());
1226 if (!url.
isEmpty()) {
return url; }
1228 if (m_setupReader) {
return m_setupReader->getSetup().getVatsimMetarsUrl(); }
1232 CUrl CApplication::getVatsimDataFileUrl()
const
1234 if (m_shutdown) {
return {}; }
1235 if (m_webDataServices)
1237 const CUrl url(m_webDataServices->getVatsimDataFileUrl());
1238 if (!url.
isEmpty()) {
return url; }
1240 if (m_setupReader) {
return m_setupReader->getSetup().getVatsimDataFileUrl(); }
1244 CUrl CApplication::getVatsimServerFileUrl()
const
1246 if (m_shutdown || !m_setupReader) {
return {}; }
1248 return m_setupReader->getSetup().getVatsimServerFileUrl();
1251 CUrl CApplication::getVatsimFsdHttpUrl()
const
1253 if (m_shutdown || !m_setupReader) {
return {}; }
1255 return m_setupReader->getSetup().getVatsimFsdHttpUrl();
1258 void CApplication::onCrashDumpUploadEnabledChanged()
1260 const bool enabled = CBuildConfig::isReleaseBuild() && m_crashDumpUploadEnabled.getThreadLocal();
1261 this->enableCrashDumpUpload(enabled);
1264 void CApplication::simulateCrash() { CCrashHandler::instance()->simulateCrash(); }
1266 void CApplication::simulateAssert() { CCrashHandler::instance()->simulateAssert(); }
1268 void CApplication::enableCrashDumpUpload(
bool enable) { CCrashHandler::instance()->setUploadsEnabled(enable); }
1270 bool CApplication::isSupportingCrashpad()
const
1272 #ifdef SWIFT_USE_CRASHPAD
1279 void CApplication::httpRequestImplInQAMThread(
const QNetworkRequest &request,
int logId,
1280 const CallbackSlot &callback,
const ProgressSlot &progress,
1281 int maxRedirects, NetworkRequestOrPostFunction getPostOrDeleteRequest)
1284 if (this->isShuttingDown()) {
return; }
1288 Q_ASSERT_X(CThreadUtils::isInThisThread(
sApp->m_accessManager), Q_FUNC_INFO,
1289 "Wrong thread, must be QAM thread");
1290 this->httpRequestImpl(request, logId, callback, progress, maxRedirects, getPostOrDeleteRequest);
1296 NetworkRequestOrPostFunction requestOrPostMethod)
1298 ProgressSlot progress;
1299 return this->httpRequestImpl(request, logId, callback, progress, maxRedirects, requestOrPostMethod);
1303 const CallbackSlot &callback,
const ProgressSlot &progress,
1304 int maxRedirects, NetworkRequestOrPostFunction getPostOrDeleteRequest)
1306 if (this->isShuttingDown()) {
return nullptr; }
1309 Q_ASSERT_X(m_accessManager->thread() == qApp->thread(), Q_FUNC_INFO,
1310 "Network manager supposed to be in main thread");
1311 if (!CThreadUtils::isInThisThread(m_accessManager))
1313 this->httpRequestImplInQAMThread(request, logId, callback, progress, maxRedirects, getPostOrDeleteRequest);
1317 Q_ASSERT_X(CThreadUtils::isInThisThread(m_accessManager), Q_FUNC_INFO,
"Network manager thread mismatch");
1319 CNetworkUtils::getSwiftNetworkRequest(request, this->getApplicationNameAndVersion());
1321 QNetworkReply *reply = getPostOrDeleteRequest(*m_accessManager, copiedRequest);
1325 QString urlStr = url.toString();
1330 [=](qint64 current, qint64 max) { progress(logId, current, max, url); });
1335 Q_ASSERT_X(callback.object(), Q_FUNC_INFO,
"Need callback object (to determine thread)");
1344 const bool isRedirect = CNetworkUtils::isHttpStatusRedirect(reply);
1345 if (isRedirect && maxRedirects > 0)
1347 const QUrl redirectUrl = CNetworkUtils::getHttpRedirectUrl(reply);
1348 if (!redirectUrl.isEmpty())
1350 QNetworkRequest redirectRequest(redirectUrl);
1351 const int redirectsLeft = maxRedirects - 1;
1352 CLogMessage(sApp).info(u
"Redirecting '%1' to '%2'") << urlStr << redirectUrl.toString();
1353 this->httpRequestImplInQAMThread(redirectRequest, logId, callback, progress, redirectsLeft,
1354 getPostOrDeleteRequest);
1366 void CApplication::tagApplicationDataDirectory()
1370 if (!dir.exists() || !dir.isReadable()) {
return; }
SWIFT_CORE_EXPORT swift::core::CApplication * sApp
Single instance of application object.
QStringList argumentsJoined(const QStringList &newArguments={}, const QStringList &removeArguments={}) const
Current parameters replaced by new arguments without the cmd line argument.
const QString & versionStringDetailed() const
String with beta, dev. and version.
~CApplication()
Destructor.
QNetworkReply * getFromNetwork(const swift::misc::network::CUrl &url, const CallbackSlot &callback, int maxRedirects=DefaultMaxRedirects)
Request to get network reply.
QNetworkReply * downloadFromNetwork(const swift::misc::network::CUrl &url, const QString &saveAsFileName, const swift::misc::CSlot< void(const swift::misc::CStatusMessage &)> &callback, int maxRedirects=DefaultMaxRedirects)
Download file from network and store it as passed.
std::atomic_bool m_shutdown
Is being shutdown?
void restartApplication(const QStringList &newArguments={}, const QStringList &removeArguments={})
Stop and restart application.
bool m_parsed
Parsing accomplished?
data::CGlobalSetup getGlobalSetup() const
Global setup.
static constexpr int NoLogRequestId
network request without logging
bool isDeveloperFlagSet() const
Running with dev.flag?
swift::misc::db::CDistribution getOwnDistribution() const
Own distribution.
bool m_alreadyRunning
Application already running.
const char * swiftVersionChar()
swift info string
std::atomic_bool m_incognito
Incognito mode?
QCommandLineOption m_cmdClearCache
Clear cache.
const context::IContextApplication * getIContextApplication() const
Direct access to contexts if a CCoreFacade has been initialized.
virtual void onStartUpCompleted()
Startup completed.
static bool unregisterAsRunning()
Unregister from running.
bool isIncognito() const
Is incognito mode?
bool hasUnsavedSettings() const
Unsaved settings.
QNetworkReply * postToNetwork(const QNetworkRequest &request, int logId, const QByteArray &data, const CallbackSlot &callback)
Post to network.
virtual void onCoreFacadeStarted()
Called when facade/contexts have been started.
const QString & swiftVersionString() const
swift info string
void coreFacadeStarted()
Facade started.
void setIncognito(bool incognito)
Set incognito mode.
static QString getTemporaryDirectory()
Directory for temporary files.
bool hasWebDataServices() const
Web data services available?
virtual void cmdLineErrorMessage(const QString &text, const QString &informativeText) const
Display error message.
void init(bool withMetadata)
Init class, allows to init from swift::gui::CGuiApplication as well (pseudo virtual)
void updateInfoAvailable(bool success)
Update info available (cache, web load)
swift::misc::CStatusMessage saveSettingsByKey(const QStringList &keys)
Save all settings.
CApplication(swift::misc::CApplicationInfo::Application application, bool init=true)
Constructor.
static void exit(int retcode=EXIT_SUCCESS)
Exit application, perform graceful shutdown and exit.
QString getInfoString(const QString &separator) const
Comprehensive info.
bool isShuttingDown() const
Is application shutting down?
QNetworkReply * deleteResourceFromNetwork(const QNetworkRequest &request, int logId, const CallbackSlot &callback, int maxRedirects=DefaultMaxRedirects)
Request to delete a network resource from network, supporting swift::misc::network::CUrlLog.
static constexpr int NoRedirects
network request not allowing redirects
QCommandLineOption m_cmdDevelopment
Development flag.
bool isSet(const QCommandLineOption &option) const
Flag set or explicitly set to true.
std::atomic_bool m_shutdownInProgress
shutdown in progress?
static swift::misc::CApplicationInfoList getRunningApplications()
Information about all running apps (including this one only if exec() has already been called)
QStringList getUnsavedSettingsKeys() const
All unsaved settings.
const QString & getApplicationNameVersionDetailed() const
Version, name beta and dev info.
void toggleIncognito()
Toggle incognito mode.
virtual swift::misc::CStatusMessageList startHookIn()
Can be used to start special services.
static bool isApplicationRunning(swift::misc::CApplicationInfo::Application application)
Is application running?
bool m_started
Started with success?
swift::misc::db::CUpdateInfo getUpdateInfo() const
Update info.
bool isSetupAvailable() const
Setup already synchronized.
static QStringList clearCaches()
Clear the caches.
virtual bool start()
Start services, if not yet parsed call CApplication::parse.
bool supportsContexts(bool ignoreShutdownTest=false) const
Supports contexts.
void reloadUpdateInfo()
Reload update info.
CWebDataServices * getWebDataServices() const
Get the web data services.
const swift::misc::CApplicationInfo & getApplicationInfo() const
swift application running
int exec()
Finishes initialization and executes the event loop.
const QString & getApplicationNameAndVersion() const
Application name and version.
virtual void gracefulShutdown()
Graceful shutdown.
void saveSettingsOnShutdown(bool saveSettings)
Save settings on shutdown.
QCommandLineOption m_cmdTestCrashpad
Test a crasphpad upload.
static void registerMetadata()
Register metadata.
bool isAlreadyRunning() const
True if this swift application is already running (including different versions)
virtual bool hasMinimumMappingVersion() const
Minimum mapping version check.
void startUpCompleted(bool success)
Startup has been completed Will be triggered shortly before starting the event loop.
QNetworkReply * headerFromNetwork(const swift::misc::network::CUrl &url, const CallbackSlot &callback, int maxRedirects=NoRedirects)
Request to get network repy using HTTP's HEADER method.
static CApplication * instance()
Similar to.
static bool registerAsRunning()
Register as running.
Threadsafe version of QNetworkCookieJar.
Configuration object for the contexts.
ContextMode getMode() const
Mode.
@ Remote
context runs in a different process.
The class providing facades (the contexts) for all DBus relevant operations.
Read available updates from GitHub Packages REST API.
void updateInfoAvailable(bool available)
Updates have been received from GitHub Packages.
Read the central URLs / locations of our data, setup and versions.
data::CGlobalSetup getSetup() const
Current setup (reader URLs, DB location, crash server)
Encapsulates reading data from web sources.
Audio context base class.
Application context interface.
virtual misc::CStatusMessage saveSettingsByKey(const QStringList &keys)=0
Save core settings to disk.
virtual QStringList getUnsavedSettingsKeys() const =0
Get keys of all unsaved settings currently in core settings cache.
const IContextSimulator * getIContextSimulator() const
Context for simulator.
IContextNetwork * getIContextNetwork()
Context for network.
const IContextApplication * getIContextApplication() const
Context for application.
IContextAudio * getIContextAudio()
Context for network.
IContextOwnAircraft * getIContextOwnAircraft()
Context for own aircraft.
Global settings for readers, debug flags, etc.
Value object encapsulating a list of reader configs.
Description of a swift application.
Application getApplication() const
Get application.
static const QString & fileName()
File name of the application info file.
Application
Enumeration of application roles.
const CProcessInfo & getProcessInfo() const
Get process info.
void setApplicationDataDirectory(const QString &appDataDir)
Set application data dir.
List of swift application descriptions.
bool containsApplication(CApplicationInfo::Application application) const
List containing entry for CApplicationInfo::Application ?
QString toJsonString(QJsonDocument::JsonFormat format=QJsonDocument::Indented) const
Convenience function JSON as string.
CStatusMessage convertFromJsonNoThrow(const QJsonObject &json, const CLogCategoryList &categories, const QString &prefix)
Call convertFromJson, catch any CJsonException that is thrown and return it as CStatusMessage.
Class to write log messages to file.
static QString readLockedFileToString(const QString &fileNameAndPath)
Read file into string, with a lock so two applications can't access at the same time.
static bool writeStringToFile(const QString &content, const QString &fileNameAndPath)
Write string to text file.
static bool writeByteArrayToFile(const QByteArray &data, const QString &fileNameAndPath)
Write byte array to file.
static bool writeStringToLockedFile(const QString &content, const QString &fileNameAndPath)
Write string to file, with a lock so two applications can't access at the same time.
static QString appendFilePaths(const QString &path1, const QString &path2)
Append file paths.
Base class with a member CIdentifier to be inherited by a class which has an identity in the environm...
A sequence of log categories.
Class for emitting a log message.
static void preformatted(const CStatusMessage &statusMessage)
Sends a verbatim, preformatted message to the log.
Value class for matching log messages based on their categories.
Derived & warning(const char16_t(&format)[N])
Set the severity to warning, providing a format string.
Derived & error(const char16_t(&format)[N])
Set the severity to error, providing a format string.
Derived & debug()
Set the severity to debug.
Derived & info(const char16_t(&format)[N])
Set the severity to info, providing a format string.
bool containsBy(Predicate p) const
Return true if there is an element for which a given predicate returns true.
bool contains(const T &object) const
Return true if there is an element equal to given object. Uses the most efficient implementation avai...
int removeIf(Predicate p)
Remove elements for which a given predicate returns true.
void push_back(const T &value)
Appends an element at the end of the sequence.
int remove(const T &object)
Remove all elements equal to the given object, if it is contained.
bool isEmpty() const
Synonym for empty.
CStatusMessage loadFromStore()
Load settings from disk.
void enableLocalSave()
Connects signal CValueCache::valuesSaveRequested to a private slot that saves the values....
static CSettingsCache * instance()
Return the singleton instance.
CStatusMessage saveToStore(const QString &keyPrefix={})
Save settings to disk.
Callable wrapper for a member function with function signature F.
Streamable status message, e.g.
constexpr static auto SeverityError
Status severities.
constexpr static auto SeverityInfo
Status severities.
bool isFailure() const
Operation considered unsuccessful.
Status messages, e.g. from Core -> GUI.
bool isFailure() const
Any message is marked as failure.
bool hasErrorMessages() const
Error messages.
bool isSuccess() const
All messages are marked as success.
static const QString & normalizedApplicationDataDirectory()
swift application data directory for one specific installation (a version)
QStringList getAllUnsavedKeys(const QString &keyPrefix={}) const
Return keys of all values which have been changed but not saved.
Base class for CWorker and CContinuousWorker.
static const QSet< CWorkerBase * > & allWorkers()
All workers currently existing.
Distributions for channel.
Update info, i.e. artifacts and distributions.
CDistribution anticipateOwnDistribution() const
Own distribution.
QString toQString(bool i18n=false) const
Cast as QString.
Value object encapsulating information of a location, kind of simplified CValueObject compliant versi...
bool isEmpty() const
Empty.
QNetworkRequest toNetworkRequest() const
To request.
QString getFullUrl(bool withQuery=true) const
Qualified name.
A transport mechanism using signals and slots distributed by DBus.
Core data traits (aka cached values) and classes.
Classes interacting with the swift database (aka "datastore").
Backend services of the swift project, like dealing with the network or the simulators.
void registerMetadata()
Register all relevant metadata in swift::core.
Free functions in swift::misc.
SWIFT_MISC_EXPORT void setMockCacheRootDirectory(const QString &path)
Overwrite the default root directory for cache and settings, for testing purposes.
void registerMetadata()
Register all relevant metadata in Misc.
QString applicationName()
Get application name.
const char * constData() const const
QStringList names() const const
QString valueName() const const
QString applicationFilePath()
void setApplicationName(const QString &application)
void setApplicationVersion(const QString &version)
void exit(int returnCode)
QCoreApplication * instance()
QString translate(const char *context, const char *sourceText, const char *disambiguation, int n)
qint64 currentMSecsSinceEpoch()
bool exists() const const
int exec(QEventLoop::ProcessEventsFlags flags)
void append(QList< T > &&value)
QList< T >::const_reference at(qsizetype i) const const
bool isEmpty() const const
void removeAt(qsizetype i)
qsizetype size() const const
bool startsWith(QList< T >::parameter_type value) const const
QNetworkReply * deleteResource(const QNetworkRequest &request)
QNetworkReply * get(const QNetworkRequest &request)
QNetworkReply * head(const QNetworkRequest &request)
QNetworkReply * post(const QNetworkRequest &request, QHttpMultiPart *multiPart)
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
QNetworkReply::NetworkError error() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void destroyed(QObject *obj)
bool moveToThread(QThread *targetThread)
void setObjectName(QAnyStringView name)
void setParent(QObject *parent)
bool setProperty(const char *name, QVariant &&value)
QThread * thread() const const
bool startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory, qint64 *pid)
QString writableLocation(QStandardPaths::StandardLocation type)
bool isEmpty() const const
QString mid(qsizetype position, qsizetype n) &&
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
QString trimmed() const const
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
QStringList filter(QLatin1StringView str, Qt::CaseSensitivity cs) const const
QString join(QChar separator) const const
qsizetype removeDuplicates()
QString buildCpuArchitecture()
bool isValid() const const
QString path() const const
QFuture< QtFuture::ArgsType< Signal >> connect(Sender *sender, Signal signal)
#define SWIFT_VERIFY_X(COND, WHERE, WHAT)
A weaker kind of assert.