From 158efe819a4f76a5c7f9c216128f712176708e5a Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Mon, 14 Mar 2016 23:55:33 +0000 Subject: [PATCH] refs #485, first version of a Gui/Core application class Also specialized GUI application class for standard GUI --- src/blackcore/application.cpp | 432 ++++++++++++++++++ src/blackcore/application.h | 217 +++++++++ src/blackcore/coremodeenums.h | 61 +++ src/blackcore/voicevatlib.cpp | 6 - src/blackcore/webdataservices.cpp | 8 +- src/blackgui/guiapplication.cpp | 140 ++++++ src/blackgui/guiapplication.h | 87 ++++ src/blackgui/guiutility.cpp | 63 --- src/blackgui/guiutility.h | 12 - .../simulator/fscommon/simulatorfscommon.cpp | 1 - src/swiftcore/main.cpp | 104 +---- src/swiftcore/swiftcore.cpp | 36 +- src/swiftcore/swiftcore.h | 25 +- src/swiftdata/main.cpp | 9 +- src/swiftdata/swiftdata.cpp | 5 +- src/swiftdata/swiftdatamenus.cpp | 1 + src/swiftguistandard/guimodeenums.h | 56 --- src/swiftguistandard/main.cpp | 133 +----- src/swiftguistandard/swiftguistd.cpp | 35 +- src/swiftguistandard/swiftguistd.h | 12 +- src/swiftguistandard/swiftguistdaircraft.cpp | 5 +- .../swiftguistdapplication.cpp | 70 +++ src/swiftguistandard/swiftguistdapplication.h | 49 ++ src/swiftguistandard/swiftguistdinit.cpp | 20 +- src/swiftlauncher/main.cpp | 70 +-- src/swiftlauncher/swiftlauncher.cpp | 15 +- src/swiftlauncher/swiftlauncher.h | 4 +- 27 files changed, 1170 insertions(+), 506 deletions(-) create mode 100644 src/blackcore/application.cpp create mode 100644 src/blackcore/application.h create mode 100644 src/blackcore/coremodeenums.h create mode 100644 src/blackgui/guiapplication.cpp create mode 100644 src/blackgui/guiapplication.h delete mode 100644 src/swiftguistandard/guimodeenums.h create mode 100644 src/swiftguistandard/swiftguistdapplication.cpp create mode 100644 src/swiftguistandard/swiftguistdapplication.h diff --git a/src/blackcore/application.cpp b/src/blackcore/application.cpp new file mode 100644 index 000000000..e4ea5bc4a --- /dev/null +++ b/src/blackcore/application.cpp @@ -0,0 +1,432 @@ +/* Copyright (C) 2016 + * 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 and at http://www.swift-project.org/license.html. 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. + */ + +#include "application.h" +#include "blackcore/corefacade.h" +#include "blackcore/setupreader.h" +#include "blackcore/contextapplication.h" +#include "blackcore/registermetadata.h" +#include "blackcore/cookiemanager.h" +#include "blackmisc/logmessage.h" +#include "blackmisc/project.h" +#include "blackmisc/dbusserver.h" +#include "blackmisc/registermetadata.h" +#include "blackmisc/network/networkutils.h" +#include +#include +#include + +using namespace BlackMisc; +using namespace BlackMisc::Network; +using namespace BlackCore; + +BlackCore::CApplication *sApp = nullptr; // set by constructor + +namespace BlackCore +{ + CApplication::CApplication(const QString &applicationName) : + m_applicationName(applicationName) + { + Q_ASSERT_X(!sApp, Q_FUNC_INFO, "already initialized"); + Q_ASSERT_X(QCoreApplication::instance(), Q_FUNC_INFO, "no application object"); + if (!sApp) + { + CApplication::initEnvironment(); + QCoreApplication::setApplicationName(applicationName); + QCoreApplication::setApplicationVersion(CProject::version()); + this->setObjectName(applicationName); + this->initParser(); + this->initLogging(); + + // Translations + QFile file(":blackmisc/translations/blackmisc_i18n_de.qm"); + CLogMessage(this).debug() << (file.exists() ? "Found translations in resources" : "No translations in resources"); + QTranslator translator; + if (translator.load("blackmisc_i18n_de", ":blackmisc/translations/")) + { + CLogMessage(this).debug() << "Translator loaded"; + } + QCoreApplication::instance()->installTranslator(&translator); + + // Global setup / bootstraping + CCookieManager::instance(); // init cookie manager if ever needed + + // trigger loading of settings + //! \todo maybe loaded twice, context initializing might trigger loading of settings a second time + CStatusMessage m = CSettingsCache::instance()->loadFromStore(); + if (!m.isEmpty()) + { + m.setCategories(getLogCategories()); + CLogMessage(this).preformatted(m); + } + + // global setup + sApp = this; + this->m_setupReader.reset(new CSetupReader(this)); + this->m_parser.addOptions(this->m_setupReader->getCmdLineOptions()); + + // notify when app goes down + connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, this, &CApplication::gracefulShutdown); + } + } + + CApplication::~CApplication() + { + this->gracefulShutdown(); + } + + QString CApplication::getApplicationNameAndVersion() const + { + return QCoreApplication::instance()->applicationName() + " " + CProject::version(); + } + + bool CApplication::start() + { + if (!this->m_parsed) + { + bool s = this->parse(); + if (!s) { return false; } + } + + // parsing itself is done + if (this->m_startSetupReader) + { + CStatusMessage m(this->requestReloadOfSetupAndVersion()); + if (m.isWarningOrAbove()) + { + this->errorMessage(m.getMessage()); + return false; + } + } + + this->m_started = this->startHookIn(); + return this->m_started; + } + + bool CApplication::isSetupSyncronized() const + { + if (this->m_shutdown || !this->m_setupReader) { return false; } + return this->m_setupReader->isSetupSyncronized(); + } + + CStatusMessage CApplication::requestReloadOfSetupAndVersion() + { + if (!this->m_shutdown) + { + Q_ASSERT_X(this->m_setupReader, Q_FUNC_INFO, "Missing reader"); + Q_ASSERT_X(this->m_parsed, Q_FUNC_INFO, "Not yet parsed"); + return this->m_setupReader->asyncLoad(); + } + else + { + return CStatusMessage(getLogCategories(), CStatusMessage::SeverityError, "No reader for setup/version"); + } + } + + QNetworkReply *CApplication::requestNetworkResource(const QNetworkRequest &request, const BlackMisc::CSlot &callback) + { + if (this->m_shutdown) { return nullptr; } + QNetworkRequest r(request); + CNetworkUtils::ignoreSslVerification(r); + QNetworkReply *reply = this->m_accessManager.get(r); + if (callback) + { + connect(reply, &QNetworkReply::finished, callback.object(), [ = ] { callback(reply); }); + } + return reply; + } + + int CApplication::exec() + { + Q_ASSERT_X(instance(), Q_FUNC_INFO, "missing application"); + return QCoreApplication::exec(); + } + + void CApplication::exit(int retcode) + { + if (instance()) + { + instance()->gracefulShutdown(); + } + // when the event loop is not running, this does nothing + QCoreApplication::exit(retcode); + } + + QStringList CApplication::arguments() + { + return QCoreApplication::arguments(); + } + + void CApplication::useContexts(const CCoreFacadeConfig &coreConfig) + { + if (this->m_coreFacade.isNull()) + { + this->m_coreFacade.reset(new CCoreFacade(coreConfig)); + this->coreFacadeStarted(); + } + } + + void CApplication::initLogging() + { + CLogHandler::instance()->install(); // make sure we have a log handler! + + // File logger + static const QString logPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/org.swift-project/logs"; + this->m_fileLogger.reset(new CFileLogger(executable(), logPath)); + this->m_fileLogger->changeLogPattern(CLogPattern().withSeverityAtOrAbove(CStatusMessage::SeverityDebug)); + } + + void CApplication::initParser() + { + this->m_parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); + this->m_parser.setApplicationDescription(m_applicationName); + this->m_cmdHelp = this->m_parser.addHelpOption(); + this->m_cmdVersion = this->m_parser.addVersionOption(); + } + + void CApplication::initEnvironment() + { + BlackMisc::registerMetadata(); + BlackCore::registerMetadata(); + } + + void CApplication::gracefulShutdown() + { + if (this->m_shutdown) { return; } + this->m_shutdown = true; + + // save settings (but only when application was really alive) + CStatusMessage m; + if (this->m_parsed) + { + if (this->supportsContexts()) + { + m = this->getIContextApplication()->saveSettings(); + } + else + { + m = CSettingsCache::instance()->saveToStore(); + } + CLogMessage(getLogCategories()).preformatted(m); + } + + // from here on we really rip appart the application object + // and it should no longer be used + sApp = nullptr; + disconnect(this); + + if (this->m_setupReader) + { + this->m_setupReader->gracefulShutdown(); + } + + if (this->supportsContexts()) + { + // clean up facade + this->m_coreFacade->gracefulShutdown(); + this->m_coreFacade.reset(); + } + + this->m_fileLogger->close(); + } + + CApplication *BlackCore::CApplication::instance() + { + return sApp; + } + + const QString &CApplication::executable() + { + static const QString e(QFileInfo(QCoreApplication::applicationFilePath()).completeBaseName()); + return e; + } + + const BlackMisc::CLogCategoryList &CApplication::getLogCategories() + { + static const CLogCategoryList l({ CLogCategory("swift.application"), CLogCategory("swift." + executable())}); + return l; + } + + // --------------------------------------------------------------------------------- + // Parsing + // --------------------------------------------------------------------------------- + + bool CApplication::addParserOption(const QCommandLineOption &option) + { + return this->m_parser.addOption(option); + } + + void CApplication::addDBusAddressOption() + { + this->m_cmdDBusAddress = QCommandLineOption({ "dbus", "dbus-address", "dbusaddress" }, + QCoreApplication::translate("application", "DBus address."), + "dbusaddress"); + this->addParserOption(this->m_cmdDBusAddress); + } + + QString CApplication::getCmdDBusAddressValue() const + { + if (this->isParserOptionSet(this->m_cmdDBusAddress)) + { + const QString v(this->getParserOptionValue(m_cmdDBusAddress)); + const QString dBusAddress(CDBusServer:: normalizeAddress(v)); + return dBusAddress; + } + else + { + return ""; + } + } + + bool CApplication::isParserOptionSet(const QString &option) const + { + return this->m_parser.isSet(option); + } + + bool CApplication::isParserOptionSet(const QCommandLineOption &option) const + { + return this->m_parser.isSet(option); + } + + QString CApplication::getParserOptionValue(const QString &option) const + { + return this->m_parser.value(option).trimmed(); + } + + QString CApplication::getParserOptionValue(const QCommandLineOption &option) const + { + return this->m_parser.value(option).trimmed(); + } + + bool CApplication::parse() + { + if (this->m_parsed) { return m_parsed; } + + // we call parse because we also want to display a GUI error message when applicable + QStringList args(QCoreApplication::instance()->arguments()); + if (!this->m_parser.parse(args)) + { + this->errorMessage(this->m_parser.errorText()); + return false; + } + + // help/version + if (this->m_parser.isSet(this->m_cmdHelp)) + { + // Important parser help will already stop application + this->helpMessage(); + return true; + } + if (this->m_parser.isSet(this->m_cmdVersion)) + { + this->versionMessage(); + return true; + } + + // Hookin, other parsing + if (!this->parsingHookIn()) { return false; } + + // setup reader + this->m_startSetupReader = this->m_setupReader->parseCmdLineArguments(); + this->m_parsed = true; + return true; + } + + void CApplication::errorMessage(const QString &errorMessage) const + { + fputs(qPrintable(errorMessage), stderr); + fputs("\n\n", stderr); + fputs(qPrintable(this->m_parser.helpText()), stderr); + } + + void CApplication::helpMessage() + { + this->m_parser.showHelp(); // terminates + Q_UNREACHABLE(); + } + + void CApplication::versionMessage() const + { + printf("%s %s\n", qPrintable(QCoreApplication::applicationName()), qPrintable(QCoreApplication::applicationVersion())); + } + + // --------------------------------------------------------------------------------- + // Contexts + // --------------------------------------------------------------------------------- + + bool CApplication::supportsContexts() const + { + if (m_coreFacade.isNull()) { return false; } + if (!this->m_coreFacade->getIContextApplication()) { return false; } + return (!this->m_coreFacade->getIContextApplication()->isEmptyObject()); + } + + const IContextNetwork *CApplication::getIContextNetwork() const + { + if (!supportsContexts()) { return nullptr; } + return this->m_coreFacade->getIContextNetwork(); + } + + const IContextAudio *CApplication::getIContextAudio() const + { + if (!supportsContexts()) { return nullptr; } + return this->m_coreFacade->getIContextAudio(); + } + + const IContextApplication *CApplication::getIContextApplication() const + { + if (!supportsContexts()) { return nullptr; } + return this->m_coreFacade->getIContextApplication(); + } + + const IContextOwnAircraft *CApplication::getIContextOwnAircraft() const + { + if (!supportsContexts()) { return nullptr; } + return this->m_coreFacade->getIContextOwnAircraft(); + } + + const IContextSimulator *CApplication::getIContextSimulator() const + { + if (!supportsContexts()) { return nullptr; } + return this->m_coreFacade->getIContextSimulator(); + } + + IContextNetwork *CApplication::getIContextNetwork() + { + if (!supportsContexts()) { return nullptr; } + return this->m_coreFacade->getIContextNetwork(); + } + + IContextAudio *CApplication::getIContextAudio() + { + if (!supportsContexts()) { return nullptr; } + return this->m_coreFacade->getIContextAudio(); + } + + IContextApplication *CApplication::getIContextApplication() + { + if (!supportsContexts()) { return nullptr; } + return this->m_coreFacade->getIContextApplication(); + } + + IContextOwnAircraft *CApplication::getIContextOwnAircraft() + { + if (!supportsContexts()) { return nullptr; } + return this->m_coreFacade->getIContextOwnAircraft(); + } + + IContextSimulator *CApplication::getIContextSimulator() + { + if (!supportsContexts()) { return nullptr; } + return this->m_coreFacade->getIContextSimulator(); + } + + // --------------------------------------------------------------------------------- + +} // ns diff --git a/src/blackcore/application.h b/src/blackcore/application.h new file mode 100644 index 000000000..c8024352a --- /dev/null +++ b/src/blackcore/application.h @@ -0,0 +1,217 @@ +/* Copyright (C) 2016 + * 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 and at http://www.swift-project.org/license.html. 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 BLACKCORE_APPLICATION_H +#define BLACKCORE_APPLICATION_H + +#include "corefacadeconfig.h" +#include "blackmisc/logcategorylist.h" +#include "blackmisc/filelogger.h" +#include "blackmisc/slot.h" +#include "blackcoreexport.h" +#include +#include +#include +#include + +namespace BlackCore +{ + class CCoreFacade; + class CSetupReader; + + class IContextApplication; + class IContextAudio; + class IContextNetwork; + class IContextOwnAircraft; + class IContextSimulator; + + /*! + * Our runtime. Normally one instance is to be initialized at the beginning of main, and thereafter + * it can be used everywhere via QApplication::instance + * + * - A swift standard cmd line parser is part of the application. + * Hence cmd arguments can be optained any time / everywhere when required. + * Also some standard swift cmd arguments do not need to be re-implemented for each swift application. + * - The core facade (aka core runtime) is now part of the application. It can be started via cmd line arguments. + * - Settings are loaded + * - Setup is loaded (load the so called bootsrap file) to find servers and other resources + * + * \sa BlackGui::CGuiApplication for the GUI version of application + */ + class BLACKCORE_EXPORT CApplication : public QObject + { + Q_OBJECT + + public: + //! Similar to \sa QCoreApplication::instance() returns the single instance + static CApplication *instance(); + + //! Constructor + CApplication(const QString &applicationName = executable()); + + //! Destructor + virtual ~CApplication(); + + //! Application name and version + QString getApplicationNameAndVersion() const; + + //! Start services, if not yet parsed call CApplication::parse + virtual bool start(); + + //! Request to get network reply + QNetworkReply *requestNetworkResource(const QNetworkRequest &request, + const BlackMisc::CSlot &callback); + + //! Setup already syncronized + bool isSetupSyncronized() const; + + //! Reload setup and version + BlackMisc::CStatusMessage requestReloadOfSetupAndVersion(); + + //! Run event loop + static int exec(); + + //! Exit application, perform graceful shutdown and exit + static void exit(int retcode = 0); + + //! Similar to QCoreApplication::arguments + static QStringList arguments(); + + // ----------------------- parsing ---------------------------------------- + + //! \name parsing of command line options + //! @{ + + //! \copydoc QCommandLineParser::addOption(const QCommandLineOption &) + bool addParserOption(const QCommandLineOption &option); + + //! CMD line argument for DBus address + void addDBusAddressOption(); + + //! DBus address from CMD line, otherwise "" + QString getCmdDBusAddressValue() const; + + //! Delegates to QCommandLineParser::isSet + bool isParserOptionSet(const QString &option) const; + + //! Delegates to QCommandLineParser::isSet + bool isParserOptionSet(const QCommandLineOption &option) const; + + //! Delegates to QCommandLineParser::value + QString getParserOptionValue(const QString &option) const; + + //! Delegates to QCommandLineParser::value + QString getParserOptionValue(const QCommandLineOption &option) const; + + //! Display parser error message + virtual void errorMessage(const QString &errorMessage) const; + + //! Parses and handles the standard options such as help, version, parse error + //! \note in some cases (error, version, help) application is terminated during this step + //! \sa parsingHookIn + bool parse(); + //! @} + + // ----------------------- contexts ---------------------------------------- + + //! \name Context / core facade related + //! @{ + + //! Supports contexts + bool supportsContexts() const; + + //! Init the contexts part and start core facade + //! \sa coreFacadeStarted + void useContexts(const CCoreFacadeConfig &coreConfig); + + //! Get the facade + CCoreFacade *getCoreFacade() { return m_coreFacade.data(); } + + //! Get the facade + const CCoreFacade *getCoreFacade() const { return m_coreFacade.data(); } + //! @} + + //! \name Direct access to contexts if a CCoreFacade has been initialized + //! @{ + const IContextNetwork *getIContextNetwork() const; + const IContextAudio *getIContextAudio() const; + const IContextApplication *getIContextApplication() const; + const IContextOwnAircraft *getIContextOwnAircraft() const; + const IContextSimulator *getIContextSimulator() const; + IContextNetwork *getIContextNetwork(); + IContextAudio *getIContextAudio(); + IContextApplication *getIContextApplication(); + IContextOwnAircraft *getIContextOwnAircraft(); + IContextSimulator *getIContextSimulator(); + //! @} + + public slots: + //! Graceful shutdown + virtual void gracefulShutdown(); + + signals: + //! Facade started + void coreFacadeStarted(); + + protected: + //! Constructor + CApplication(const QString &applicationName, QCoreApplication *app); + + //! executable name + static const QString &executable(); + + //! Own log categories + static const BlackMisc::CLogCategoryList &cats(); + + //! Display help message + virtual void helpMessage(); + + //! Display version message + virtual void versionMessage() const; + + //! Can be used to parse specialized arguments + virtual bool parsingHookIn() { return true; } + + //! Can be used to start special services + virtual bool startHookIn() { return true; } + + // cmd parsing + QCommandLineParser m_parser; //!< cmd parser + QCommandLineOption m_cmdHelp {"help"}; //!< help option + QCommandLineOption m_cmdVersion { "version" }; //!< version option + QCommandLineOption m_cmdDBusAddress {"empty"}; //!< DBus address + bool m_parsed = false; //!< Parsing accomplished? + bool m_started = false; //!< started? + bool m_startSetupReader = false; //!< start the setup reader + + private: + //! init logging system + void initLogging(); + + //! Init parser + void initParser(); + + //! static init part + static void initEnvironment(); + + QScopedPointer m_coreFacade; //!< core facade if any + QScopedPointer m_setupReader; //!< setup reader + QScopedPointer m_fileLogger; //!< file logger + QNetworkAccessManager m_accessManager { this }; //!< single network access manager + QString m_applicationName; //!< application name + bool m_shutdown = false; //!< is being shut down + }; +} // namespace + +//! Single instance of application object +extern BLACKCORE_EXPORT BlackCore::CApplication *sApp; + +#endif // guard diff --git a/src/blackcore/coremodeenums.h b/src/blackcore/coremodeenums.h new file mode 100644 index 000000000..76f2e55a2 --- /dev/null +++ b/src/blackcore/coremodeenums.h @@ -0,0 +1,61 @@ +/* Copyright (C) 2013 + * 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 and at http://www.swift-project.org/license.html. 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 BLACKGUI_GUIMODEENUMS_H +#define BLACKGUI_GUIMODEENUMS_H + +#include + +namespace BlackCore +{ + //! Modes, how GUI can be started (core/GUI) + struct CoreModes + { + public: + //! Core runs how and where? + enum CoreMode + { + CoreInGuiProcess, + CoreExternalCoreAudio, + CoreExternalAudioGui + }; + + //! String to core mode + static CoreMode stringToCoreMode(const QString &m) + { + QString cm(m.toLower().trimmed()); + if (cm.isEmpty()) { return CoreInGuiProcess; } + if (m == coreModeToString(CoreExternalCoreAudio)) { return CoreExternalCoreAudio; } + if (m == coreModeToString(CoreInGuiProcess)) { return CoreInGuiProcess; } + if (m == coreModeToString(CoreExternalAudioGui)) { return CoreExternalAudioGui; } + + // some alternative names + if (cm.contains("audiolocal")) { return CoreExternalAudioGui; } + if (cm.contains("localaudio")) { return CoreExternalAudioGui; } + if (cm.contains("external")) { return CoreExternalCoreAudio; } + if (cm.contains("gui")) { return CoreInGuiProcess; } + return CoreInGuiProcess; + } + + //! Core mode as string + static QString coreModeToString(CoreMode mode) + { + switch (mode) + { + case CoreInGuiProcess: return "coreinguiprocess"; + case CoreExternalCoreAudio: return "coreexternal"; + case CoreExternalAudioGui: return "coreexternalaudiogui"; + } + return ""; + } + }; +} +#endif // guard diff --git a/src/blackcore/voicevatlib.cpp b/src/blackcore/voicevatlib.cpp index f0ae87302..284123c56 100644 --- a/src/blackcore/voicevatlib.cpp +++ b/src/blackcore/voicevatlib.cpp @@ -24,9 +24,6 @@ using namespace BlackMisc::Aviation; namespace BlackCore { - /* - * Constructor - */ CVoiceVatlib::CVoiceVatlib(QObject *parent) : IVoice(parent), m_audioService(Vat_CreateAudioService()), @@ -38,9 +35,6 @@ namespace BlackCore this->startTimer(10); } - /* - * Destructor - */ CVoiceVatlib::~CVoiceVatlib() {} QSharedPointer CVoiceVatlib::createVoiceChannel() diff --git a/src/blackcore/webdataservices.cpp b/src/blackcore/webdataservices.cpp index 525491904..448400205 100644 --- a/src/blackcore/webdataservices.cpp +++ b/src/blackcore/webdataservices.cpp @@ -7,6 +7,7 @@ * contained in the LICENSE file. */ +#include "blackcore/application.h" #include "blackcore/setupreader.h" #include "blackcore/webdataservices.h" #include "blackcore/modeldatareader.h" @@ -40,6 +41,7 @@ namespace BlackCore QObject(parent), m_readerFlags(readerFlags), m_autoReadAfterSetupMs(autoReadAfterSetupSynchronizedMs) { Q_ASSERT_X(QSslSocket::supportsSsl(), Q_FUNC_INFO, "missing SSL support"); + if (!sApp) { return; } // shutting doen this->setObjectName("CWebDataReader"); this->initReaders(readerFlags); this->initWriters(); @@ -47,14 +49,14 @@ namespace BlackCore { // wait for setup read completion // in case this was already fired or will never be fired set a time out - if (CSetupReader::instance().updatedWithinLastMs(10 * 1000)) + if (sApp->isSetupSyncronized()) { QTimer::singleShot(500, this, &CWebDataServices::ps_setupTimedOut); } else { - connect(&CSetupReader::instance(), &CSetupReader::setupSynchronized, this, &CWebDataServices::ps_setupRead); - QTimer::singleShot(10 * 1000, this, &CWebDataServices::ps_setupTimedOut); + //! \todo change !!!!!! + QTimer::singleShot(2500, this, &CWebDataServices::ps_setupTimedOut); } } } diff --git a/src/blackgui/guiapplication.cpp b/src/blackgui/guiapplication.cpp new file mode 100644 index 000000000..9b0e18ba3 --- /dev/null +++ b/src/blackgui/guiapplication.cpp @@ -0,0 +1,140 @@ +/* Copyright (C) 2016 + * 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 and at http://www.swift-project.org/license.html. 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. + */ + +#include "guiapplication.h" +#include "blackmisc/project.h" +#include +#include + +using namespace BlackMisc; + +BlackGui::CGuiApplication *sGui = nullptr; // set by constructor + +namespace BlackGui +{ + CGuiApplication *CGuiApplication::instance() + { + return qobject_cast(CApplication::instance()); + } + + CGuiApplication::CGuiApplication(const QString &applicationName, const QPixmap &icon) : CApplication(applicationName) + { + setWindowIcon(icon); + sGui = this; + } + + CGuiApplication::~CGuiApplication() + { + sGui = nullptr; + } + + void CGuiApplication::addWindowModeOption() + { + this->m_cmdWindowMode = QCommandLineOption(QStringList() << "w" << "window", + QCoreApplication::translate("main", "Windows: (n)ormal, (f)rameless, (t)ool."), + "windowtype"); + this->addParserOption(this->m_cmdWindowMode); + } + + void CGuiApplication::addWindowStateOption() + { + this->m_cmdWindowStateMinimized = QCommandLineOption({{"m", "minimized"}, QCoreApplication::translate("main", "Start minimized in system tray.")}); + this->addParserOption(this->m_cmdWindowStateMinimized); + } + + Qt::WindowState CGuiApplication::getWindowState() const + { + if (this->m_cmdWindowStateMinimized.valueName() == "empty") { return Qt::WindowNoState; } + if (this->m_parser.isSet(this->m_cmdWindowStateMinimized)) { return Qt::WindowMinimized; } + return Qt::WindowNoState; + } + + CEnableForFramelessWindow::WindowMode CGuiApplication::getWindowMode() const + { + if (this->isParserOptionSet(m_cmdWindowMode)) + { + const QString v(this->getParserOptionValue(this->m_cmdWindowMode)); + return CEnableForFramelessWindow::stringToWindowMode(v); + } + else + { + return CEnableForFramelessWindow::WindowNormal; + } + } + + void CGuiApplication::initMainApplicationWindow(QWidget *mainWindow) const + { + if (!mainWindow) { return; } + const QString name(this->getApplicationNameAndVersion()); + mainWindow->setObjectName(QCoreApplication::applicationName()); + mainWindow->setWindowTitle(name); + mainWindow->setWindowIcon(m_windowIcon); + mainWindow->setWindowIconText(name); + } + + void CGuiApplication::setWindowIcon(const QPixmap &icon) + { + instance()->m_windowIcon = icon; + QApplication::setWindowIcon(icon); + } + + void CGuiApplication::exit(int retcode) + { + CApplication::exit(retcode); + } + + void CGuiApplication::errorMessage(const QString &errorMessage) const + { + if (CProject::isRunningOnWindowsNtPlatform()) + { + QMessageBox::warning(nullptr, + QGuiApplication::applicationDisplayName(), + "

" + errorMessage + "

" + this->m_parser.helpText() + "
"); + } + else + { + CApplication::errorMessage(errorMessage); + } + } + + void CGuiApplication::helpMessage() + { + if (CProject::isRunningOnWindowsNtPlatform()) + { + QMessageBox::information(nullptr, + QGuiApplication::applicationDisplayName(), + "
" + this->m_parser.helpText() + "
"); + } + else + { + CApplication::helpMessage(); + } + } + + void CGuiApplication::versionMessage() const + { + if (CProject::isRunningOnWindowsNtPlatform()) + { + QMessageBox::information(nullptr, + QGuiApplication::applicationDisplayName(), + QGuiApplication::applicationDisplayName() + ' ' + QCoreApplication::applicationVersion()); + } + else + { + CApplication::versionMessage(); + } + } + + bool CGuiApplication::parsingHookIn() + { + // void + return true; + } + +} // ns diff --git a/src/blackgui/guiapplication.h b/src/blackgui/guiapplication.h new file mode 100644 index 000000000..d832cc971 --- /dev/null +++ b/src/blackgui/guiapplication.h @@ -0,0 +1,87 @@ +/* Copyright (C) 2016 + * 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 and at http://www.swift-project.org/license.html. 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 BLACKGUI_GUIAPPLICATION_H +#define BLACKGUI_GUIAPPLICATION_H + +#include "blackcore/application.h" +#include "blackgui/enableforframelesswindow.h" +#include "blackgui/blackguiexport.h" + +namespace BlackGui +{ + /*! + * \brief GUI application, a specialized version of BlackCore::CApplication for GUI applications. + * + * \details Analog to QCoreApplication and QApplication this class provides more details for swift + * GUI applications. It is normally used via the global sGui pointer. As an example of how to extend this + * class see CSwiftGuiStdApplication. + */ + class BLACKGUI_EXPORT CGuiApplication : public BlackCore::CApplication + { + Q_OBJECT + + public: + //! Similar to \sa QCoreApplication::instance() returns the single instance + static CGuiApplication *instance(); + + //! Constructor + CGuiApplication(const QString &applicationName = executable(), const QPixmap &icon = BlackMisc::CIcons::swift48()); + + //! Destructor + virtual ~CGuiApplication(); + + //! CMD line arguments + void addWindowStateOption(); + + //! CMD line arguments + void addWindowModeOption(); + + //! Window state + Qt::WindowState getWindowState() const; + + //! Window mode (window flags) + CEnableForFramelessWindow::WindowMode getWindowMode() const; + + //! Init the main application window based on information in this application + void initMainApplicationWindow(QWidget *mainWindow) const; + + //! \copydoc BlackCore::CApplication::errorMessage + virtual void errorMessage(const QString &errorMessage) const override; + + //! Set icon + //! \note Pixmap requires a valid QApplication, so it cannot be passed as constructor parameter + static void setWindowIcon(const QPixmap &icon); + + //! Exit application, perform graceful shutdown and exit + static void exit(int retcode = 0); + + protected: + //! \name print messages generated during parsing + //! @{ + virtual void helpMessage() override; + virtual void versionMessage() const override; + //! @} + + //! Handle paring of special GUI cmd arguments + virtual bool parsingHookIn() override; + + private: + QPixmap m_windowIcon; + QCommandLineOption m_cmdWindowStateMinimized { "empty" }; //!< window state (minimized) + QCommandLineOption m_cmdWindowMode { "empty" }; //!< window mode (flags: frameless ...) + }; +} // ns + +//! Single instance of GUI application object +extern BLACKGUI_EXPORT BlackGui::CGuiApplication *sGui; + +#endif // guard diff --git a/src/blackgui/guiutility.cpp b/src/blackgui/guiutility.cpp index 33614cf4d..0c7b397e4 100644 --- a/src/blackgui/guiutility.cpp +++ b/src/blackgui/guiutility.cpp @@ -69,39 +69,6 @@ namespace BlackGui return (mw && mw->isFrameless()); } - void CGuiUtility::initSwiftGuiApplication(QApplication &a, const QString &applicationName, const QPixmap &icon) - { - CCoreFacade::registerMetadata(); // register metadata - CCookieManager::instance(); // init cookie manager if ever needed - - CLogHandler::instance()->install(); // make sure we have a log handler! - - QApplication::setApplicationName(applicationName); - QApplication::setApplicationVersion(CProject::version()); - QApplication::setWindowIcon(icon); - - // Logging - QString executableName = QFileInfo(QCoreApplication::applicationFilePath()).completeBaseName(); - QString category("swift." + executableName); - - // Translations - QFile file(":blackmisc/translations/blackmisc_i18n_de.qm"); - CLogMessage(category).debug() << (file.exists() ? "Found translations in resources" : "No translations in resources"); - QTranslator translator; - if (translator.load("blackmisc_i18n_de", ":blackmisc/translations/")) - { - CLogMessage(category).debug() << "Translator loaded"; - } - - // File logger - static const QString logPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/org.swift-project/logs"; - CFileLogger *fileLogger = new CFileLogger(executableName, logPath, &a); - fileLogger->changeLogPattern(CLogPattern().withSeverityAtOrAbove(CStatusMessage::SeverityDebug)); - - // GUI icon - a.installTranslator(&translator); - } - bool CGuiUtility::lenientTitleComparison(const QString &title, const QString &comparison) { if (title == comparison) { return true; } @@ -274,34 +241,4 @@ namespace BlackGui // then finally delete layout; } - - void CGuiUtility::commandLineErrorMessage(const QString &errorMessage, const QCommandLineParser &parser) - { -# ifdef Q_OS_WIN - QMessageBox::warning(nullptr, QGuiApplication::applicationDisplayName(), "

" + errorMessage + "

" + parser.helpText() + "
"); -# else - fputs(qPrintable(errorMessage), stderr); - fputs("\n\n", stderr); - fputs(qPrintable(parser.helpText()), stderr); -# endif - } - - void CGuiUtility::commandLineVersionRequested() - { -# ifdef Q_OS_WIN - QMessageBox::information(nullptr, QGuiApplication::applicationDisplayName(), QGuiApplication::applicationDisplayName() + ' ' + QCoreApplication::applicationVersion()); -# else - printf("%s %s\n", qPrintable(QCoreApplication::applicationName()), qPrintable(QCoreApplication::applicationVersion())); -# endif - } - - void CGuiUtility::commandLineHelpRequested(QCommandLineParser &parser) - { -# ifdef Q_OS_WIN - QMessageBox::information(nullptr, QGuiApplication::applicationDisplayName(), "
" + parser.helpText() + "
"); -# else - parser.showHelp(); // terminates - Q_UNREACHABLE(); -# endif - } } // ns diff --git a/src/blackgui/guiutility.h b/src/blackgui/guiutility.h index 462ad6dc4..1acc1ee2c 100644 --- a/src/blackgui/guiutility.h +++ b/src/blackgui/guiutility.h @@ -48,18 +48,6 @@ namespace BlackGui //! Delete hierarchy of layouts static void deleteLayout(QLayout *layout, bool deleteWidgets); - //! Message box or command line warning (depending on OS) - static void commandLineErrorMessage(const QString &errorMessage, const QCommandLineParser &parser); - - //! Message box or command line version info - static void commandLineVersionRequested(); - - //! Message box or command line version info - static void commandLineHelpRequested(QCommandLineParser &parser); - - //! Standard initialization for a swift GUI application - static void initSwiftGuiApplication(QApplication &a, const QString &applicationName, const QPixmap &icon = BlackMisc::CIcons::swift24()); - //! Leninet / relaxed static bool lenientTitleComparison(const QString &title, const QString &comparison); diff --git a/src/plugins/simulator/fscommon/simulatorfscommon.cpp b/src/plugins/simulator/fscommon/simulatorfscommon.cpp index 32c7d304b..7e2be6be2 100644 --- a/src/plugins/simulator/fscommon/simulatorfscommon.cpp +++ b/src/plugins/simulator/fscommon/simulatorfscommon.cpp @@ -11,7 +11,6 @@ #include "blackmisc/logmessage.h" #include "blackmisc/makeunique.h" #include "blackmisc/simulation/fscommon/modelmappingsprovidervpilot.h" -#include "blackmisc/blackmiscfreefunctions.h" #include "blackmisc/makeunique.h" using namespace BlackMisc::PhysicalQuantities; diff --git a/src/swiftcore/main.cpp b/src/swiftcore/main.cpp index 074f78734..d53059c36 100644 --- a/src/swiftcore/main.cpp +++ b/src/swiftcore/main.cpp @@ -8,111 +8,43 @@ */ #include "swiftcore.h" -#include "blackcore/corefacade.h" +#include "blackgui/guiapplication.h" +#include "blackgui/stylesheetutility.h" +#include "blackgui/guiutility.h" #include "blackcore/contextapplication.h" #include "blackcore/contextapplicationimpl.h" #include "blackmisc/dbusserver.h" #include "blackmisc/icons.h" #include "blackmisc/worker.h" #include "blackmisc/network/networkutils.h" -#include "blackmisc/blackmiscfreefunctions.h" -#include "blackmisc/project.h" -#include "blackmisc/loghandler.h" -#include "blackmisc/filelogger.h" -#include "blackgui/guiutility.h" -#include "blackgui/stylesheetutility.h" - -#include #include using namespace BlackMisc; using namespace BlackCore; using namespace BlackGui; -enum CommandLineParseResult -{ - CommandLineOk, - CommandLineError, - CommandLineVersionRequested, - CommandLineHelpRequested -}; - -CommandLineParseResult parseCommandLine(QCommandLineParser &parser, CSwiftCore::SetupInfo *setup, QString *errorMessage) -{ - parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); - parser.addOption({{"d", "dbus"}, QCoreApplication::translate("main", "DBus options: session, system, p2p."), "dbus"}); - parser.addOption({{"m", "minimized"}, QCoreApplication::translate("main", "Start minimized in system tray.")}); - parser.addOption({{"r", "start"}, QCoreApplication::translate("main", "Start the server.")}); - parser.addOption({{"c", "coreaudio"}, QCoreApplication::translate("main", "Audio in core.")}); - - QCommandLineOption helpOption = parser.addHelpOption(); - QCommandLineOption versionOption = parser.addVersionOption(); - - if (!parser.parse(QCoreApplication::arguments())) - { - *errorMessage = parser.errorText(); - return CommandLineError; - } - - // help/version - if (parser.isSet(helpOption)) { return CommandLineHelpRequested; } - if (parser.isSet(versionOption)) { return CommandLineVersionRequested; } - - setup->m_dbusAddress = CDBusServer::sessionBusAddress(); // default - if (parser.isSet("dbus")) - { - QString v(parser.value("dbus").trimmed().toLower()); - if (v.startsWith("p2p") || v.contains("peer") || v.contains("tcp:") || v.contains("host")) - { - setup->m_dbusAddress = CDBusServer::p2pAddress(); - } - else if (v.contains("sys")) - { - setup->m_dbusAddress = CDBusServer::systemBusAddress(); // default - } - } - - if (parser.isSet("minimized")) { setup->m_minimzed = true; } - if (parser.isSet("start")) { setup->m_start = true; } - if (parser.isSet("coreaudio")) { setup->m_coreAudio = true; } - - return CommandLineOk; -} - int main(int argc, char *argv[]) { - QApplication a(argc, argv); - const QString appName("swift core"); - a.setApplicationVersion(CProject::version()); - a.setApplicationName(appName); - QCommandLineParser parser; - parser.setApplicationDescription(appName); + CGuiApplication a(argc, argv, "swift core"); + a.setWindowIcon(CIcons::swiftNova24()); + a.addWindowStateOption(); + a.addDBusAddressOption(); + a.addParserOption({{"r", "start"}, QCoreApplication::translate("main", "Start the server.")}); + a.addParserOption({{"c", "coreaudio"}, QCoreApplication::translate("main", "Audio in core.")}); + a.parse(); - CSwiftCore::SetupInfo setup; - QString errorMessage; - switch (parseCommandLine(parser, &setup, &errorMessage)) - { - case CommandLineOk: - break; - case CommandLineError: - CGuiUtility::commandLineErrorMessage(errorMessage, parser); - return 1; - case CommandLineVersionRequested: - CGuiUtility::commandLineVersionRequested(); - return 0; - case CommandLineHelpRequested: - CGuiUtility::commandLineHelpRequested(parser); - return 0; - } + const QString dBusAdress(a.getCmdDBusAddressValue()); + a.useContexts(a.isParserOptionSet("coreaudio") ? + CCoreFacadeConfig::forCoreAllLocalInDBus(dBusAdress) : + CCoreFacadeConfig::forCoreAllLocalInDBusNoAudio(dBusAdress)); if (!QSystemTrayIcon::isSystemTrayAvailable()) { - QMessageBox::critical(0, QObject::tr("Systray"), QObject::tr("I couldn't detect any system tray on this system.")); - return 1; + a.parserErrorMessage("I could not detect any system tray on this system."); + return EXIT_FAILURE; } - CGuiUtility::initSwiftGuiApplication(a, appName, CIcons::swiftNova24()); - CSwiftCore w(setup); - if (!setup.m_minimzed) { w.show(); } + CSwiftCore w; + if (a.getWindowState() != Qt::WindowMinimized) { w.show(); } return a.exec(); } diff --git a/src/swiftcore/swiftcore.cpp b/src/swiftcore/swiftcore.cpp index 3277106c5..2d938d458 100644 --- a/src/swiftcore/swiftcore.cpp +++ b/src/swiftcore/swiftcore.cpp @@ -13,6 +13,7 @@ #include "blackmisc/loghandler.h" #include "blackmisc/project.h" #include "blackmisc/dbusserver.h" +#include "blackgui/guiapplication.h" #include "blackgui/components/logcomponent.h" #include "blackgui/components/enableforruntime.h" #include "blackgui/stylesheetutility.h" @@ -25,25 +26,23 @@ using namespace BlackCore; using namespace BlackGui; using namespace BlackGui::Components; -CSwiftCore::CSwiftCore(const SetupInfo &info, QWidget *parent) : +CSwiftCore::CSwiftCore(QWidget *parent) : CSystemTrayWindow(CIcons::swiftNova24(), parent), CIdentifiable(this), ui(new Ui::CSwiftCore) { ui->setupUi(this); - const QString name(QCoreApplication::instance()->applicationName() + " " + CProject::version()); + sGui->initMainApplicationWindow(this); + const QString name(sGui->getApplicationNameAndVersion()); setSystemTrayMode(MinimizeToTray | QuitOnClose); setSystemTrayToolTip(name); - setWindowTitle(name); - setWindowIcon(CIcons::swiftNova24()); - setWindowIconText(name); initLogDisplay(); initSlots(); initStyleSheet(); - initDBusMode(info); + initDBusMode(); - if (info.m_start) { startCore(info); } + if (sGui->isParserOptionSet("start")) { startCore(sGui->getCmdDBusAddressValue()); } } void CSwiftCore::initStyleSheet() @@ -58,20 +57,21 @@ void CSwiftCore::initStyleSheet() this->setStyleSheet(s); } -void CSwiftCore::initDBusMode(const CSwiftCore::SetupInfo &setup) +void CSwiftCore::initDBusMode() { - if (setup.m_dbusAddress.startsWith(CDBusServer::sessionBusAddress())) + const QString dBusAddress(sGui->getCmdDBusAddressValue()); + if (dBusAddress.startsWith(CDBusServer::sessionBusAddress())) { this->ui->rb_SessionBus->setChecked(true); } - else if (setup.m_dbusAddress.startsWith(CDBusServer::systemBusAddress())) + else if (dBusAddress.startsWith(CDBusServer::systemBusAddress())) { this->ui->rb_SystemBus->setChecked(true); } else { this->ui->rb_P2PBus->setChecked(true); - this->ui->le_P2PAddress->setText(setup.m_dbusAddress); + this->ui->le_P2PAddress->setText(dBusAddress); } } @@ -80,9 +80,7 @@ CSwiftCore::~CSwiftCore() void CSwiftCore::ps_startCorePressed() { - SetupInfo setup; - setup.m_dbusAddress = getDBusAddress(); - startCore(setup); + startCore(getDBusAddress()); } void CSwiftCore::ps_stopCorePressed() @@ -131,10 +129,10 @@ void CSwiftCore::initLogDisplay() logHandler->subscribe(this, &CSwiftCore::ps_appendLogMessage); } -void CSwiftCore::startCore(const SetupInfo &setup) +void CSwiftCore::startCore(const QString &dBusAdress) { if (getRuntime()) { return; } - if (setup.m_dbusAddress.isEmpty()) { return; } + if (dBusAdress.isEmpty()) { return; } ui->pb_StartCore->setEnabled(false); ui->pb_StopCore->setEnabled(true); @@ -142,9 +140,9 @@ void CSwiftCore::startCore(const SetupInfo &setup) QCoreApplication::processEvents(QEventLoop::AllEvents, 100); // context - this->createRuntime(setup.m_coreAudio ? - CCoreFacadeConfig::forCoreAllLocalInDBus(setup.m_dbusAddress) : - CCoreFacadeConfig::forCoreAllLocalInDBusNoAudio(setup.m_dbusAddress), + this->createRuntime(sGui->isParserOptionSet("coreaudio") ? + CCoreFacadeConfig::forCoreAllLocalInDBus(dBusAdress) : + CCoreFacadeConfig::forCoreAllLocalInDBusNoAudio(dBusAdress), this); CEnableForRuntime::setRuntimeForComponents(this->getRuntime(), this); connect(ui->le_CommandLineInput, &CCommandInput::commandEntered, getRuntime(), &CCoreFacade::parseCommandLine); diff --git a/src/swiftcore/swiftcore.h b/src/swiftcore/swiftcore.h index be69b7f37..9d6d0f75b 100644 --- a/src/swiftcore/swiftcore.h +++ b/src/swiftcore/swiftcore.h @@ -31,41 +31,34 @@ class CSwiftCore : Q_OBJECT public: - - //! SwiftCore setup information - struct SetupInfo - { - SetupInfo() {} - - bool m_minimzed = false; //!< Start minimized to tray - bool m_start = false; //!< Start server when core is started - bool m_coreAudio = false; //!< Audio in core - QString m_dbusAddress; //!< DBus address (session, system, p2p) - }; - //! Constructor - CSwiftCore(const SetupInfo &info, QWidget *parent = nullptr); + CSwiftCore(QWidget *parent = nullptr); //! Destructor ~CSwiftCore(); private slots: - // PushButton slots + //! \name PushButton slots + //! @[ void ps_startCorePressed(); void ps_stopCorePressed(); void ps_appendLogMessage(const BlackMisc::CStatusMessage &message); void ps_p2pModeToggled(bool checked); + //! }@ //! Style sheet has changed virtual void ps_onStyleSheetsChanged(); private: + //! \name Init + //! @[ void initSlots(); void initLogDisplay(); void initStyleSheet(); - void initDBusMode(const SetupInfo &setup); + void initDBusMode(); + //! }@ - void startCore(const SetupInfo &setup); + void startCore(const QString &dBusAdress); void stopCore(); QString getDBusAddress() const; diff --git a/src/swiftdata/main.cpp b/src/swiftdata/main.cpp index 63d9068a0..3a7d16a56 100644 --- a/src/swiftdata/main.cpp +++ b/src/swiftdata/main.cpp @@ -8,14 +8,14 @@ */ #include "swiftdata.h" +#include "blackgui/guiapplication.h" +#include "blackcore/application.h" #include "blackmisc/icons.h" #include "blackmisc/worker.h" #include "blackmisc/network/networkutils.h" -#include "blackmisc/blackmiscfreefunctions.h" #include "blackmisc/project.h" #include "blackmisc/loghandler.h" #include "blackmisc/filelogger.h" -#include "blackgui/guiutility.h" #include "blackgui/stylesheetutility.h" #include @@ -27,9 +27,8 @@ using namespace BlackGui; int main(int argc, char *argv[]) { - QApplication a(argc, argv); - CGuiUtility::initSwiftGuiApplication(a, "swift mapping tool", CIcons::swiftDatabase24()); - + CGuiApplication a(argc, argv, "swift mapping tool"); + a.setWindowIcon(CIcons::swiftDatabase48()); CSwiftData w; w.show(); int r = a.exec(); diff --git a/src/swiftdata/swiftdata.cpp b/src/swiftdata/swiftdata.cpp index ac8b82831..5e69edcf7 100644 --- a/src/swiftdata/swiftdata.cpp +++ b/src/swiftdata/swiftdata.cpp @@ -9,6 +9,7 @@ #include "swiftdata.h" #include "ui_swiftdata.h" +#include "blackgui/guiapplication.h" #include "blackgui/components/datamaininfoareacomponent.h" #include "blackgui/components/datainfoareacomponent.h" #include "blackgui/components/logcomponent.h" @@ -78,9 +79,7 @@ void CSwiftData::ps_onStyleSheetsChanged() void CSwiftData::init() { - this->setWindowIcon(CIcons::swiftDatabase24()); - this->setWindowTitle(QCoreApplication::instance()->applicationName() + " " + CProject::versionStringDevBetaInfo()); - this->setObjectName("CSwiftData"); + sGui->initMainApplicationWindow(this); this->initStyleSheet(); this->initLogDisplay(); connect(&CStyleSheetUtility::instance(), &CStyleSheetUtility::styleSheetsChanged, this, &CSwiftData::ps_onStyleSheetsChanged); diff --git a/src/swiftdata/swiftdatamenus.cpp b/src/swiftdata/swiftdatamenus.cpp index 27b79c0f9..64b798a13 100644 --- a/src/swiftdata/swiftdatamenus.cpp +++ b/src/swiftdata/swiftdatamenus.cpp @@ -25,6 +25,7 @@ #include #include #include +#include using namespace BlackGui; using namespace BlackCore; diff --git a/src/swiftguistandard/guimodeenums.h b/src/swiftguistandard/guimodeenums.h deleted file mode 100644 index fdeb5dab8..000000000 --- a/src/swiftguistandard/guimodeenums.h +++ /dev/null @@ -1,56 +0,0 @@ -/* Copyright (C) 2013 - * 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 and at http://www.swift-project.org/license.html. 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. - */ - -#ifndef STDGUI_GUIMODEENUMS_H -#define STDGUI_GUIMODEENUMS_H - -#include - -//! Modes, how GUI can be started (core/GUI) -struct GuiModes -{ -public: - //! Core runs how and where? - enum CoreMode - { - CoreInGuiProcess, - CoreExternalCoreAudio, - CoreExternalAudioGui - }; - - //! String to core mode - static CoreMode stringToCoreMode(const QString &m) - { - QString cm(m.toLower().trimmed()); - if (cm.isEmpty()) { return CoreInGuiProcess; } - if (m == coreModeToString(CoreExternalCoreAudio)) { return CoreExternalCoreAudio; } - if (m == coreModeToString(CoreInGuiProcess)) { return CoreInGuiProcess; } - if (m == coreModeToString(CoreExternalAudioGui)) { return CoreExternalAudioGui; } - - // some alternative names - if (cm.contains("audiolocal")) { return CoreExternalAudioGui; } - if (cm.contains("localaudio")) { return CoreExternalAudioGui; } - if (cm.contains("external")) { return CoreExternalCoreAudio; } - if (cm.contains("gui")) { return CoreInGuiProcess; } - return CoreInGuiProcess; - } - - //! Core mode as string - static QString coreModeToString(CoreMode mode) - { - switch (mode) - { - case CoreInGuiProcess: return "coreinguiprocess"; - case CoreExternalCoreAudio: return "coreexternal"; - case CoreExternalAudioGui: return "coreexternalaudiogui"; - } - return ""; - } -}; -#endif // guard diff --git a/src/swiftguistandard/main.cpp b/src/swiftguistandard/main.cpp index abe7d49c0..89d77e282 100644 --- a/src/swiftguistandard/main.cpp +++ b/src/swiftguistandard/main.cpp @@ -8,20 +8,10 @@ */ #include "swiftguistd.h" -#include "guimodeenums.h" -#include "blackgui/stylesheetutility.h" -#include "blackcore/registermetadata.h" -#include "blackcore/corefacadeconfig.h" -#include "blackgui/guiutility.h" -#include "blackmisc/blackmiscfreefunctions.h" -#include "blackmisc/logmessage.h" -#include "blackmisc/icons.h" -#include "blackmisc/loghandler.h" -#include "blackmisc/filelogger.h" +#include "swiftguistdapplication.h" +#include "blackgui/enableforframelesswindow.h" #include -#include -#include #include #include @@ -29,127 +19,14 @@ using namespace BlackGui; using namespace BlackMisc; using namespace BlackCore; -enum CommandLineParseResult -{ - CommandLineOk, - CommandLineError, - CommandLineVersionRequested, - CommandLineHelpRequested -}; - -CommandLineParseResult parseCommandLine(QCommandLineParser &parser, - CEnableForFramelessWindow::WindowMode &windowMode, - GuiModes::CoreMode &coreMode, - QString &dBusAddress, - QString &errorMessage) -{ - parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); - - // value core mode - QCommandLineOption modeOption(QStringList() << "c" << "core", - QCoreApplication::translate("main", "Core mode: (e)xternal, (g)ui (in GUI process), (l)ocalaudio (external, but local audio)."), - "coremode"); - parser.addOption(modeOption); - - // value DBus address - QCommandLineOption dBusOption(QStringList() << "dbus" << "dbus-address", - QCoreApplication::translate("main", "DBUS address."), - "dbusaddress"); - parser.addOption(dBusOption); - - // Window type - QCommandLineOption windowOption(QStringList() << "w" << "window", - QCoreApplication::translate("main", "Windows: (n)ormal, (f)rameless, (t)ool."), - "windowtype"); - parser.addOption(windowOption); - - // help/version - QCommandLineOption helpOption = parser.addHelpOption(); - QCommandLineOption versionOption = parser.addVersionOption(); - - // evaluate - if (!parser.parse(QCoreApplication::arguments())) - { - errorMessage = parser.errorText(); - return CommandLineError; - } - - if (parser.isSet(helpOption)) { return CommandLineHelpRequested; } - if (parser.isSet(versionOption)) { return CommandLineVersionRequested; } - - if (parser.isSet(dBusOption)) - { - QString v(parser.value(dBusOption).trimmed()); - dBusAddress = CDBusServer::normalizeAddress(v); - if (!CDBusServer::isDBusAvailable(dBusAddress)) - { - errorMessage = "DBus server at " + dBusAddress + " can not be reached"; - return CommandLineError; - } - } - - if (parser.isSet(windowOption)) - { - QString v(parser.value(windowOption).trimmed()); - windowMode = CEnableForFramelessWindow::stringToWindowMode(v); - } - - if (parser.isSet(modeOption)) - { - QString v(parser.value(modeOption)); - coreMode = GuiModes::stringToCoreMode(v); - } - - return CommandLineOk; -} - int main(int argc, char *argv[]) { - QApplication a(argc, argv); - const QString appName("swift pilot client GUI"); - a.setApplicationVersion(CProject::version()); - a.setApplicationName(appName); - - // Process the actual command line arguments given by the user - QCommandLineParser parser; - parser.setApplicationDescription(appName); - - CEnableForFramelessWindow::WindowMode windowMode = CEnableForFramelessWindow::WindowNormal; - GuiModes::CoreMode coreMode = GuiModes::CoreInGuiProcess; - QString dBusAddress, errorMessage; - switch (parseCommandLine(parser, windowMode, coreMode, dBusAddress, errorMessage)) - { - case CommandLineOk: - break; - case CommandLineError: - CGuiUtility::commandLineErrorMessage(errorMessage, parser); - return 1; - case CommandLineVersionRequested: - CGuiUtility::commandLineVersionRequested(); - return 0; - case CommandLineHelpRequested: - CGuiUtility::commandLineHelpRequested(parser); - return 0; - } - - BlackCore::CCoreFacadeConfig runtimeConfig; - switch (coreMode) - { - case GuiModes::CoreExternalCoreAudio: - runtimeConfig = CCoreFacadeConfig::remote(dBusAddress); - break; - case GuiModes::CoreInGuiProcess: - runtimeConfig = CCoreFacadeConfig::local(dBusAddress); - break; - case GuiModes::CoreExternalAudioGui: - runtimeConfig = CCoreFacadeConfig::remoteLocalAudio(dBusAddress); - break; - } + CSwiftGuiStdApplication a(argc, argv); + a.startCoreFacade(); // show window - CGuiUtility::initSwiftGuiApplication(a, appName, CIcons::swift24()); + CEnableForFramelessWindow::WindowMode windowMode = a.getWindowMode(); SwiftGuiStd w(windowMode); - w.init(runtimeConfig); // object is complete by now w.show(); int r = a.exec(); diff --git a/src/swiftguistandard/swiftguistd.cpp b/src/swiftguistandard/swiftguistd.cpp index 2dd2344f1..522c83174 100644 --- a/src/swiftguistandard/swiftguistd.cpp +++ b/src/swiftguistandard/swiftguistd.cpp @@ -14,6 +14,7 @@ #include "blackgui/models/atcstationlistmodel.h" #include "blackgui/components/logcomponent.h" #include "blackgui/components/settingscomponent.h" +#include "blackgui/guiapplication.h" #include "blackcore/contextnetwork.h" #include "blackcore/contextapplication.h" #include "blackcore/contextownaircraft.h" @@ -47,6 +48,7 @@ SwiftGuiStd::SwiftGuiStd(BlackGui::CEnableForFramelessWindow::WindowMode windowM // GUI ui->setupUi(this); this->setDynamicProperties(windowMode == CEnableForFramelessWindow::WindowFrameless); + this->init(); } SwiftGuiStd::~SwiftGuiStd() @@ -73,15 +75,15 @@ void SwiftGuiStd::performGracefulShutdown() // if we have a context, we shut some things down if (this->m_contextNetworkAvailable) { - if (this->getIContextNetwork() && this->getIContextNetwork()->isConnected()) + if (sGui->getIContextNetwork() && sGui->getIContextNetwork()->isConnected()) { if (this->m_contextAudioAvailable) { - this->getIContextAudio()->leaveAllVoiceRooms(); - this->getIContextAudio()->disconnect(this); // break down signal / slots + sGui->getIContextAudio()->leaveAllVoiceRooms(); + sGui->getIContextAudio()->disconnect(this); // break down signal / slots } - this->getIContextNetwork()->disconnectFromNetwork(); - this->getIContextNetwork()->disconnect(this); // avoid any status update signals, etc. + sGui->getIContextNetwork()->disconnectFromNetwork(); + sGui->getIContextNetwork()->disconnect(this); // avoid any status update signals, etc. } } @@ -95,9 +97,9 @@ void SwiftGuiStd::performGracefulShutdown() emit requestGracefulShutdown(); // tell context GUI is going down - if (this->getIContextApplication()) + if (sGui->getIContextApplication()) { - this->getIContextApplication()->unregisterApplication(identifier()); + sGui->getIContextApplication()->unregisterApplication(identifier()); } // allow some other parts to react @@ -108,7 +110,7 @@ void SwiftGuiStd::closeEvent(QCloseEvent *event) { Q_UNUSED(event); this->performGracefulShutdown(); - QApplication::exit(); + CGuiApplication::exit(); } void SwiftGuiStd::changeEvent(QEvent *event) @@ -252,16 +254,16 @@ void SwiftGuiStd::setContextAvailability() { bool corePreviouslyAvailable = this->m_coreAvailable; - if (this->getIContextApplication()->isUsingImplementingObject()) + if (sGui->getIContextApplication()->isUsingImplementingObject()) { this->m_coreAvailable = true; } else { - this->m_coreAvailable = isMyIdentifier(this->getIContextApplication()->registerApplication(getCurrentTimestampIdentifier())); + this->m_coreAvailable = isMyIdentifier(sGui->getIContextApplication()->registerApplication(getCurrentTimestampIdentifier())); } - this->m_contextNetworkAvailable = this->m_coreAvailable || this->getIContextNetwork()->isUsingImplementingObject(); - this->m_contextAudioAvailable = this->m_coreAvailable || this->getIContextAudio()->isUsingImplementingObject(); + this->m_contextNetworkAvailable = this->m_coreAvailable || sGui->getIContextNetwork()->isUsingImplementingObject(); + this->m_contextAudioAvailable = this->m_coreAvailable || sGui->getIContextAudio()->isUsingImplementingObject(); // react to a change in core's availability if (this->m_coreAvailable != corePreviouslyAvailable) @@ -269,8 +271,8 @@ void SwiftGuiStd::setContextAvailability() if (this->m_coreAvailable) { // core has just become available - this->getIContextApplication()->synchronizeLogSubscriptions(); - this->getIContextApplication()->synchronizeLocalSettings(); + sGui->getIContextApplication()->synchronizeLogSubscriptions(); + sGui->getIContextApplication()->synchronizeLocalSettings(); } else { @@ -285,7 +287,7 @@ void SwiftGuiStd::updateGuiStatusInformation() QString network("unavailable"); if (this->m_contextNetworkAvailable) { - bool dbus = !this->getIContextNetwork()->isUsingImplementingObject(); + bool dbus = !sGui->getIContextNetwork()->isUsingImplementingObject(); network = dbus ? now : "local"; this->ui->comp_InfoBarStatus->setDBusStatus(dbus); } @@ -366,7 +368,7 @@ void SwiftGuiStd::playNotifcationSound(CNotificationSounds::Notification notific { if (!this->m_contextAudioAvailable) { return; } if (!this->ui->comp_MainInfoArea->getSettingsComponent()->playNotificationSounds()) { return; } - this->getIContextAudio()->playNotification(notification, true); + sGui->getIContextAudio()->playNotification(notification, true); } void SwiftGuiStd::displayConsole() @@ -378,4 +380,3 @@ void SwiftGuiStd::displayLog() { this->ui->comp_MainInfoArea->displayLog(); } - diff --git a/src/swiftguistandard/swiftguistd.h b/src/swiftguistandard/swiftguistd.h index 7427358b7..aef6737d6 100644 --- a/src/swiftguistandard/swiftguistd.h +++ b/src/swiftguistandard/swiftguistd.h @@ -16,7 +16,6 @@ #pragma push_macro("interface") #undef interface -#include "guimodeenums.h" #include "blackcore/contextallinterfaces.h" #include "blackcore/actionbind.h" #include "blackcore/data/globalsetup.h" @@ -48,8 +47,7 @@ namespace Ui { class SwiftGuiStd; } class SwiftGuiStd : public QMainWindow, public BlackMisc::CIdentifiable, - public BlackGui::CEnableForFramelessWindow, - public BlackGui::Components::CEnableForRuntime + public BlackGui::CEnableForFramelessWindow { Q_OBJECT @@ -65,14 +63,11 @@ public: }; //! Constructor - SwiftGuiStd(BlackGui::CEnableForFramelessWindow::WindowMode windowMode, QWidget *parent = nullptr); + SwiftGuiStd(WindowMode windowMode, QWidget *parent = nullptr); //! Destructor ~SwiftGuiStd(); - //! Init data - void init(const BlackCore::CCoreFacadeConfig &runtimeConfig); - //! Log message category static QString getMessageCategory() { return "swift.gui.stdgui"; } @@ -144,6 +139,9 @@ private: //! 1st data reads void initialDataReads(); + //! Init data (post GUI init) + void init(); + //! Init GUI signals void initGuiSignals(); diff --git a/src/swiftguistandard/swiftguistdaircraft.cpp b/src/swiftguistandard/swiftguistdaircraft.cpp index 6d2ed8324..a28f6e81f 100644 --- a/src/swiftguistandard/swiftguistdaircraft.cpp +++ b/src/swiftguistandard/swiftguistdaircraft.cpp @@ -9,6 +9,7 @@ #include "swiftguistd.h" #include "blackgui/models/atcstationlistmodel.h" +#include "blackgui/guiapplication.h" #include "blackmisc/dbusserver.h" #include "blackcore/contextnetwork.h" @@ -31,7 +32,7 @@ bool SwiftGuiStd::ps_reloadOwnAircraft() // check for changed aircraft bool changed = false; - CSimulatedAircraft loadedAircraft = this->getIContextOwnAircraft()->getOwnAircraft(); + CSimulatedAircraft loadedAircraft = sGui->getIContextOwnAircraft()->getOwnAircraft(); if (loadedAircraft != this->m_ownAircraft) { this->m_ownAircraft = loadedAircraft; @@ -52,5 +53,5 @@ void SwiftGuiStd::setTestPosition(const QString &wgsLatitude, const QString &wgs this->m_ownAircraft.setPosition(coordinate); this->m_ownAircraft.setAltitude(altitude); - this->getIContextOwnAircraft()->updateOwnPosition(coordinate, altitude); + sGui->getIContextOwnAircraft()->updateOwnPosition(coordinate, altitude); } diff --git a/src/swiftguistandard/swiftguistdapplication.cpp b/src/swiftguistandard/swiftguistdapplication.cpp new file mode 100644 index 000000000..0385bbd60 --- /dev/null +++ b/src/swiftguistandard/swiftguistdapplication.cpp @@ -0,0 +1,70 @@ +/* Copyright (C) 2016 + * 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 and at http://www.swift-project.org/license.html. 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. + */ + +#include "swiftguistdapplication.h" +#include "blackcore/coremodeenums.h" +#include "blackmisc/dbusserver.h" + +using namespace BlackMisc; +using namespace BlackCore; + +CSwiftGuiStdApplication::CSwiftGuiStdApplication(int argc, char *argv[]) : CGuiApplication(argc, argv, "swift pilot client GUI") +{ + this->setWindowIcon(CIcons::swift24()); + this->addParserOption(this->m_cmdFacadeMode); + this->addWindowModeOption(); + this->addDBusAddressOption(); +} + +void CSwiftGuiStdApplication::startCoreFacade() +{ + CoreModes::CoreMode coreMode = CoreModes::CoreInGuiProcess; + const QString dBusAddress(this->getCmdDBusAddressValue()); + if (this->isParserOptionSet(this->m_cmdFacadeMode)) + { + const QString v(this->getParserOptionValue(this->m_cmdFacadeMode)); + coreMode = CoreModes::stringToCoreMode(v); + } + + CCoreFacadeConfig runtimeConfig; + switch (coreMode) + { + case CoreModes::CoreExternalCoreAudio: + runtimeConfig = CCoreFacadeConfig::remote(dBusAddress); + break; + default: + case CoreModes::CoreInGuiProcess: + runtimeConfig = CCoreFacadeConfig::local(dBusAddress); + break; + case CoreModes::CoreExternalAudioGui: + runtimeConfig = CCoreFacadeConfig::remoteLocalAudio(dBusAddress); + break; + } + this->useContexts(runtimeConfig); +} + +void CSwiftGuiStdApplication::parsingHookIn() +{ + // Parse core relevant arguments + const QString dBusAddress(this->getCmdDBusAddressValue()); + if (!dBusAddress.isEmpty()) + { + // check if rechable + if (!CDBusServer::isDBusAvailable(dBusAddress)) + { + this->parserErrorMessage("DBus server at " + dBusAddress + " can not be reached"); + exit(EXIT_FAILURE); + } + } +} + +CSwiftGuiStdApplication *instance() +{ + return qobject_cast(CApplication::instance()); +} diff --git a/src/swiftguistandard/swiftguistdapplication.h b/src/swiftguistandard/swiftguistdapplication.h new file mode 100644 index 000000000..b6572bb01 --- /dev/null +++ b/src/swiftguistandard/swiftguistdapplication.h @@ -0,0 +1,49 @@ +/* Copyright (C) 2016 + * 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 and at http://www.swift-project.org/license.html. 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 SWIFTGUISTDAPPLICATION_H +#define SWIFTGUISTDAPPLICATION_H + +#include "blackgui/guiapplication.h" +#include "blackcore/corefacadeconfig.h" + +/*! + * Specialized GUI application for swift pilot client. + * Handles parsing of some specialized CMD line argumenets and startup of core + */ +class CSwiftGuiStdApplication : public BlackGui::CGuiApplication +{ + Q_OBJECT + +public: + //! Constructor + CSwiftGuiStdApplication(int argc, char *argv[]); + + //! Single instance + CSwiftGuiStdApplication *instance(); + + //! Start facade by cmd arguments + void startCoreFacade(); + +protected: + //! Parsing of special CMD args + virtual void parsingHookIn() override; + +private: + QCommandLineOption m_cmdFacadeMode + { + { "c" , "core" }, + QCoreApplication::translate("main", "Core mode: (e)xternal, (g)ui (in GUI process), (l)ocalaudio (external, but local audio)."), + "coremode" + }; //!< Facade startup mode +}; + +#endif // guard diff --git a/src/swiftguistandard/swiftguistdinit.cpp b/src/swiftguistandard/swiftguistdinit.cpp index 72516d2a8..c24e40bae 100644 --- a/src/swiftguistandard/swiftguistdinit.cpp +++ b/src/swiftguistandard/swiftguistdinit.cpp @@ -11,6 +11,7 @@ #include "ui_swiftguistd.h" #include "blackcore/contextallinterfaces.h" #include "blackgui/stylesheetutility.h" +#include "blackgui/guiapplication.h" #include "blackgui/guiutility.h" #include "blackgui/components/allmaininfoareacomponents.h" #include "blackgui/models/atcstationlistmodel.h" @@ -29,20 +30,18 @@ using namespace BlackMisc::Input; using namespace BlackGui; using namespace BlackGui::Components; -void SwiftGuiStd::init(const CCoreFacadeConfig &runtimeConfig) +void SwiftGuiStd::init() { // POST(!) GUI init if (this->m_init) { return; } this->setVisible(false); // hide all, so no flashing windows during init + sGui->initMainApplicationWindow(this); // init window - this->setWindowIcon(CIcons::swift24()); this->setWindowTitle(CProject::versionStringDevBetaInfo()); - this->setObjectName("SwiftGuiStd"); this->initStyleSheet(); - // with frameless window, we shift menu and statusbar into central widget // http://stackoverflow.com/questions/18316710/frameless-and-transparent-window-qt5 if (this->isFrameless()) @@ -71,9 +70,8 @@ void SwiftGuiStd::init(const CCoreFacadeConfig &runtimeConfig) } // context - this->createRuntime(runtimeConfig, this); - CEnableForRuntime::setRuntimeForComponents(this->getRuntime(), this); - this->getIContextApplication()->loadSettings(); + CEnableForRuntime::setRuntimeForComponents(sGui->getCoreFacade(), this); + sGui->getIContextApplication()->loadSettings(); // info bar and status bar this->m_statusBar.initStatusBar(this->ui->sb_MainStatusBar); @@ -92,10 +90,10 @@ void SwiftGuiStd::init(const CCoreFacadeConfig &runtimeConfig) this->initGuiSignals(); // signal / slots contexts / timers - connect(this->getIContextNetwork(), &IContextNetwork::connectionTerminated, this, &SwiftGuiStd::ps_onConnectionTerminated); - connect(this->getIContextNetwork(), &IContextNetwork::connectionStatusChanged, this, &SwiftGuiStd::ps_onConnectionStatusChanged); - connect(this->getIContextNetwork(), &IContextNetwork::textMessagesReceived, this->ui->comp_MainInfoArea->getTextMessageComponent(), &CTextMessageComponent::onTextMessageReceived); - connect(this->getIContextNetwork(), &IContextNetwork::textMessageSent, this->ui->comp_MainInfoArea->getTextMessageComponent(), &CTextMessageComponent::onTextMessageSent); + connect(sGui->getIContextNetwork(), &IContextNetwork::connectionTerminated, this, &SwiftGuiStd::ps_onConnectionTerminated); + connect(sGui->getIContextNetwork(), &IContextNetwork::connectionStatusChanged, this, &SwiftGuiStd::ps_onConnectionStatusChanged); + connect(sGui->getIContextNetwork(), &IContextNetwork::textMessagesReceived, this->ui->comp_MainInfoArea->getTextMessageComponent(), &CTextMessageComponent::onTextMessageReceived); + connect(sGui->getIContextNetwork(), &IContextNetwork::textMessageSent, this->ui->comp_MainInfoArea->getTextMessageComponent(), &CTextMessageComponent::onTextMessageSent); connect(this->m_timerContextWatchdog, &QTimer::timeout, this, &SwiftGuiStd::ps_handleTimerBasedUpdates); // log messages diff --git a/src/swiftlauncher/main.cpp b/src/swiftlauncher/main.cpp index 59251081c..fb545147b 100644 --- a/src/swiftlauncher/main.cpp +++ b/src/swiftlauncher/main.cpp @@ -7,11 +7,9 @@ * contained in the LICENSE file. */ -#include "swiftguistandard/guimodeenums.h" #include "swiftlauncher.h" +#include "blackgui/guiapplication.h" #include "blackcore/registermetadata.h" -#include "blackgui/guiutility.h" -#include "blackmisc/blackmiscfreefunctions.h" #include "blackmisc/logmessage.h" #include "blackmisc/icons.h" #include "blackmisc/project.h" @@ -27,75 +25,23 @@ using namespace BlackGui; using namespace BlackMisc; using namespace BlackCore; -enum CommandLineParseResult -{ - CommandLineOk, - CommandLineError, - CommandLineVersionRequested, - CommandLineHelpRequested -}; - -CommandLineParseResult parseCommandLine(QCommandLineParser &parser, bool &installer, QString &errorMessage) -{ - parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); - parser.addOption({{"i", "installer"}, QCoreApplication::translate("main", "Installer setup.")}); - - QCommandLineOption helpOption = parser.addHelpOption(); - QCommandLineOption versionOption = parser.addVersionOption(); - - if (!parser.parse(QCoreApplication::arguments())) - { - errorMessage = parser.errorText(); - return CommandLineError; - } - - // help/version - if (parser.isSet(helpOption)) { return CommandLineHelpRequested; } - if (parser.isSet(versionOption)) { return CommandLineVersionRequested; } - - installer = parser.isSet("installer"); - return CommandLineOk; -} - int main(int argc, char *argv[]) { - QApplication a(argc, argv); - const QString appName("swift launcher"); - a.setApplicationVersion(CProject::version()); - a.setApplicationName(appName); - CGuiUtility::initSwiftGuiApplication(a, appName, CIcons::swift24()); - - // Process the actual command line arguments given by the user - QCommandLineParser parser; - parser.setApplicationDescription(appName); - QString errorMessage; - bool installer = false; - switch (parseCommandLine(parser, installer, errorMessage)) - { - case CommandLineOk: - break; - case CommandLineError: - CGuiUtility::commandLineErrorMessage(errorMessage, parser); - return 1; - case CommandLineVersionRequested: - CGuiUtility::commandLineVersionRequested(); - return 0; - case CommandLineHelpRequested: - CGuiUtility::commandLineHelpRequested(parser); - return 0; - } + CGuiApplication a(argc, argv, "swift launcher"); + a.setWindowIcon(CIcons::swift24()); + a.addParserOption({{"i", "installer"}, QCoreApplication::translate("main", "Installer setup."), "installer"}); + a.parse(); // Dialog to decide external or internal core CSwiftLauncher launcher; - launcher.setWindowIcon(CIcons::swift24()); - if (launcher.exec() == QDialog::Rejected) { return 0; } + if (launcher.exec() == QDialog::Rejected) { return EXIT_SUCCESS; } launcher.close(); QString exe(launcher.getExecutable()); QStringList exeArgs(launcher.getExecutableArgs()); Q_ASSERT_X(!exe.isEmpty(), Q_FUNC_INFO, "Missing executable"); - CLogMessage(QCoreApplication::instance()).debug() << launcher.getCmdLine(); + CLogMessage(QCoreApplication::instance()).info(launcher.getCmdLine()); QProcess::startDetached(exe, exeArgs); - return 0; + return EXIT_SUCCESS; } diff --git a/src/swiftlauncher/swiftlauncher.cpp b/src/swiftlauncher/swiftlauncher.cpp index 8d7e9cbb3..f13edbc53 100644 --- a/src/swiftlauncher/swiftlauncher.cpp +++ b/src/swiftlauncher/swiftlauncher.cpp @@ -9,6 +9,7 @@ #include "swiftlauncher.h" #include "ui_swiftlauncher.h" +#include "blackgui/guiapplication.h" #include "blackgui/stylesheetutility.h" #include "blackcore/setupreader.h" #include "blackmisc/dbusserver.h" @@ -41,7 +42,6 @@ CSwiftLauncher::CSwiftLauncher(QWidget *parent) : ui(new Ui::CSwiftLauncher) { ui->setupUi(this); - this->setWindowTitle(QCoreApplication::instance()->applicationName() + " " + CProject::versionStringDevBetaInfo()); this->init(); connect(ui->pb_CheckForUpdates, &QPushButton::pressed, this, &CSwiftLauncher::ps_loadSetup); connect(ui->tb_SwiftCore, &QPushButton::pressed, this, &CSwiftLauncher::ps_startButtonPressed); @@ -72,14 +72,14 @@ CEnableForFramelessWindow::WindowMode CSwiftLauncher::getWindowMode() const return CEnableForFramelessWindow::WindowNormal; } -GuiModes::CoreMode CSwiftLauncher::getCoreMode() const +CoreModes::CoreMode CSwiftLauncher::getCoreMode() const { - if (ui->rb_SwiftStandalone->isChecked()) { return GuiModes::CoreInGuiProcess; } - if (ui->rb_SwiftCoreAudio->isChecked()) { return GuiModes::CoreExternalCoreAudio; } - if (ui->rb_SwiftCoreGuiAudio->isChecked()) { return GuiModes::CoreExternalAudioGui; } + if (ui->rb_SwiftStandalone->isChecked()) { return CoreModes::CoreInGuiProcess; } + if (ui->rb_SwiftCoreAudio->isChecked()) { return CoreModes::CoreExternalCoreAudio; } + if (ui->rb_SwiftCoreGuiAudio->isChecked()) { return CoreModes::CoreExternalAudioGui; } Q_ASSERT_X(false, Q_FUNC_INFO, "wrong mode"); - return GuiModes::CoreInGuiProcess; + return CoreModes::CoreInGuiProcess; } QString CSwiftLauncher::getDBusAddress() const @@ -103,6 +103,7 @@ void CSwiftLauncher::mousePressEvent(QMouseEvent *event) void CSwiftLauncher::init() { + sGui->initMainApplicationWindow(this); this->ui->lbl_NewVersionUrl->setTextFormat(Qt::RichText); this->ui->lbl_NewVersionUrl->setTextInteractionFlags(Qt::TextBrowserInteraction); this->ui->lbl_NewVersionUrl->setOpenExternalLinks(true); @@ -210,7 +211,7 @@ bool CSwiftLauncher::setSwiftGuiExecutable() m_executable = CProject::swiftGuiExecutableName(); QStringList args { - "--core", GuiModes::coreModeToString(getCoreMode()), + "--core", CoreModes::coreModeToString(getCoreMode()), "--window", CEnableForFramelessWindow::windowModeToString(getWindowMode()) }; if (!this->isStandaloneGuiSelected()) diff --git a/src/swiftlauncher/swiftlauncher.h b/src/swiftlauncher/swiftlauncher.h index a677a6c6b..e91f47c3f 100644 --- a/src/swiftlauncher/swiftlauncher.h +++ b/src/swiftlauncher/swiftlauncher.h @@ -16,10 +16,10 @@ #include #include "blackcore/data/globalsetup.h" #include "blackcore/data/updateinfo.h" +#include "blackcore/coremodeenums.h" #include "blackcore/settings/network.h" #include "blackgui/enableforframelesswindow.h" #include "blackgui/overlaymessagesframe.h" -#include "swiftguistandard/guimodeenums.h" namespace Ui { class CSwiftLauncher; } @@ -67,7 +67,7 @@ private: BlackMisc::CSetting m_dbusServerAddress { this }; //! Get core mode - GuiModes::CoreMode getCoreMode() const; + BlackCore::CoreModes::CoreMode getCoreMode() const; //! select DBus address/mode QString getDBusAddress() const;