From b5dfd31e3d1ad7ca4bfe8262b62be259f6dc786a Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Wed, 21 Mar 2018 01:41:28 +0100 Subject: [PATCH] common: Make the Quassel class a proper singleton, clean up No longer have the various application classes inherit from the Quassel class, which is a precondition for making the latter a QObject down the line. Enable application-specific config reload and quit behaviors by providing the means to register handler functions, replacing the previous inheritance-based mechanism. Make the Quassel class a proper singleton, remove inline functions and modernize the code. --- src/common/main.cpp | 9 +- src/common/quassel.cpp | 320 ++++++++++++++++++++++------------- src/common/quassel.h | 131 +++++++------- src/core/coreapplication.cpp | 32 +--- src/core/coreapplication.h | 26 +-- src/qtui/monoapplication.cpp | 23 +-- src/qtui/monoapplication.h | 17 +- src/qtui/qtuiapplication.cpp | 38 +++-- src/qtui/qtuiapplication.h | 19 +-- 9 files changed, 329 insertions(+), 286 deletions(-) diff --git a/src/common/main.cpp b/src/common/main.cpp index 71579df4..8f75984b 100644 --- a/src/common/main.cpp +++ b/src/common/main.cpp @@ -19,6 +19,7 @@ ***************************************************************************/ #include +#include #include @@ -109,7 +110,7 @@ int main(int argc, char **argv) # endif #endif - AbstractCliParser *cliParser; + std::shared_ptr cliParser; #ifdef HAVE_KDE4 // We need to init KCmdLineArgs first @@ -121,11 +122,11 @@ int main(int argc, char **argv) aboutData.setOrganizationDomain(Quassel::buildInfo().organizationDomain.toUtf8()); KCmdLineArgs::init(argc, argv, &aboutData); - cliParser = new KCmdLineWrapper(); + cliParser = std::make_shared(); #elif defined HAVE_QT5 - cliParser = new Qt5CliParser(); + cliParser = std::make_shared(); #else - cliParser = new CliParser(); + cliParser = std::make_shared(); #endif Quassel::setCliParser(cliParser); diff --git a/src/common/quassel.cpp b/src/common/quassel.cpp index 8c2b7b49..16b8887d 100644 --- a/src/common/quassel.cpp +++ b/src/common/quassel.cpp @@ -50,26 +50,15 @@ #include "../../version.h" -Quassel::BuildInfo Quassel::_buildInfo; -AbstractCliParser *Quassel::_cliParser = 0; -Quassel::RunMode Quassel::_runMode; -QString Quassel::_configDirPath; -QString Quassel::_translationDirPath; -QStringList Quassel::_dataDirPaths; -bool Quassel::_initialized = false; -bool Quassel::DEBUG = false; -QString Quassel::_coreDumpFileName; -Quassel *Quassel::_instance = 0; -bool Quassel::_handleCrashes = true; -Quassel::LogLevel Quassel::_logLevel = InfoLevel; -QFile *Quassel::_logFile = 0; -bool Quassel::_logToSyslog = false; +Quassel *Quassel::instance() +{ + static Quassel instance; + return &instance; +} + Quassel::Quassel() { - Q_ASSERT(!_instance); - _instance = this; - // We catch SIGTERM and SIGINT (caused by Ctrl+C) to graceful shutdown Quassel. signal(SIGTERM, handleSignal); signal(SIGINT, handleSignal); @@ -81,22 +70,12 @@ Quassel::Quassel() } -Quassel::~Quassel() -{ - if (logFile()) { - logFile()->close(); - logFile()->deleteLater(); - } - delete _cliParser; -} - - bool Quassel::init() { - if (_initialized) + if (instance()->_initialized) return true; // allow multiple invocations because of MonolithicApplication - if (_handleCrashes) { + if (instance()->_handleCrashes) { // we have crashhandler for win32 and unix (based on execinfo). #if defined(Q_OS_WIN) || defined(HAVE_EXECINFO) # ifndef Q_OS_WIN @@ -116,18 +95,18 @@ bool Quassel::init() #endif /* Q_OS_WIN || HAVE_EXECINFO */ } - _initialized = true; + instance()->_initialized = true; qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime())); - setupEnvironment(); - registerMetaTypes(); + instance()->setupEnvironment(); + instance()->registerMetaTypes(); Network::setDefaultCodecForServer("ISO-8859-1"); Network::setDefaultCodecForEncoding("UTF-8"); Network::setDefaultCodecForDecoding("ISO-8859-15"); if (isOptionSet("help")) { - cliParser()->usage(); + instance()->_cliParser->usage(); return false; } @@ -136,30 +115,35 @@ bool Quassel::init() return false; } - DEBUG = isOptionSet("debug"); - // set up logging if (Quassel::runMode() != Quassel::ClientOnly) { if (isOptionSet("loglevel")) { QString level = optionValue("loglevel"); - if (level == "Debug") _logLevel = DebugLevel; - else if (level == "Info") _logLevel = InfoLevel; - else if (level == "Warning") _logLevel = WarningLevel; - else if (level == "Error") _logLevel = ErrorLevel; + if (level == "Debug") + setLogLevel(DebugLevel); + else if (level == "Info") + setLogLevel(InfoLevel); + else if (level == "Warning") + setLogLevel(WarningLevel); + else if (level == "Error") + setLogLevel(ErrorLevel); + else { + qWarning() << qPrintable(tr("Invalid log level %1; supported are Debug|Info|Warning|Error").arg(level)); + return false; + } } QString logfilename = optionValue("logfile"); if (!logfilename.isEmpty()) { - _logFile = new QFile(logfilename); - if (!_logFile->open(QIODevice::Append | QIODevice::Text)) { - qWarning() << "Could not open log file" << logfilename << ":" << _logFile->errorString(); - _logFile->deleteLater(); - _logFile = 0; + instance()->_logFile.reset(new QFile{logfilename}); + if (!logFile()->open(QIODevice::Append | QIODevice::Text)) { + qWarning() << "Could not open log file" << logfilename << ":" << logFile()->errorString(); + instance()->_logFile.reset(); } } #ifdef HAVE_SYSLOG - _logToSyslog = isOptionSet("syslog"); + instance()->_logToSyslog = isOptionSet("syslog"); #endif } @@ -167,9 +151,46 @@ bool Quassel::init() } +void Quassel::destroy() +{ + if (logFile()) { + logFile()->close(); + instance()->_logFile.reset(); + } +} + + +void Quassel::registerQuitHandler(QuitHandler handler) +{ + instance()->_quitHandlers.emplace_back(std::move(handler)); +} + void Quassel::quit() { - QCoreApplication::quit(); + if (_quitHandlers.empty()) { + QCoreApplication::quit(); + } + else { + for (auto &&handler : _quitHandlers) { + handler(); + } + } +} + + +void Quassel::registerReloadHandler(ReloadHandler handler) +{ + instance()->_reloadHandlers.emplace_back(std::move(handler)); +} + + +bool Quassel::reloadConfig() +{ + bool result{true}; + for (auto &&handler : _reloadHandlers) { + result = result && handler(); + } + return result; } @@ -256,64 +277,73 @@ void Quassel::setupEnvironment() void Quassel::setupBuildInfo() { - _buildInfo.applicationName = "quassel"; - _buildInfo.coreApplicationName = "quasselcore"; - _buildInfo.clientApplicationName = "quasselclient"; - _buildInfo.organizationName = "Quassel Project"; - _buildInfo.organizationDomain = "quassel-irc.org"; + BuildInfo buildInfo; + buildInfo.applicationName = "quassel"; + buildInfo.coreApplicationName = "quasselcore"; + buildInfo.clientApplicationName = "quasselclient"; + buildInfo.organizationName = "Quassel Project"; + buildInfo.organizationDomain = "quassel-irc.org"; - _buildInfo.protocolVersion = 10; // FIXME: deprecated, will be removed + buildInfo.protocolVersion = 10; // FIXME: deprecated, will be removed - _buildInfo.baseVersion = QUASSEL_VERSION_STRING; - _buildInfo.generatedVersion = GIT_DESCRIBE; + buildInfo.baseVersion = QUASSEL_VERSION_STRING; + buildInfo.generatedVersion = GIT_DESCRIBE; // Check if we got a commit hash if (!QString(GIT_HEAD).isEmpty()) { - _buildInfo.commitHash = GIT_HEAD; + buildInfo.commitHash = GIT_HEAD; QDateTime date; date.setTime_t(GIT_COMMIT_DATE); - _buildInfo.commitDate = date.toString(); + buildInfo.commitDate = date.toString(); } else if (!QString(DIST_HASH).contains("Format")) { - _buildInfo.commitHash = DIST_HASH; - _buildInfo.commitDate = QString(DIST_DATE); + buildInfo.commitHash = DIST_HASH; + buildInfo.commitDate = QString(DIST_DATE); } // create a nice version string - if (_buildInfo.generatedVersion.isEmpty()) { - if (!_buildInfo.commitHash.isEmpty()) { + if (buildInfo.generatedVersion.isEmpty()) { + if (!buildInfo.commitHash.isEmpty()) { // dist version - _buildInfo.plainVersionString = QString("v%1 (dist-%2)") - .arg(_buildInfo.baseVersion) - .arg(_buildInfo.commitHash.left(7)); - _buildInfo.fancyVersionString = QString("v%1 (dist-%2)") - .arg(_buildInfo.baseVersion) - .arg(_buildInfo.commitHash.left(7)) - .arg(_buildInfo.commitHash); + buildInfo.plainVersionString = QString{"v%1 (dist-%2)"} + .arg(buildInfo.baseVersion) + .arg(buildInfo.commitHash.left(7)); + buildInfo.fancyVersionString = QString{"v%1 (dist-%2)"} + .arg(buildInfo.baseVersion) + .arg(buildInfo.commitHash.left(7)) + .arg(buildInfo.commitHash); } else { // we only have a base version :( - _buildInfo.plainVersionString = QString("v%1 (unknown revision)").arg(_buildInfo.baseVersion); + buildInfo.plainVersionString = QString{"v%1 (unknown revision)"}.arg(buildInfo.baseVersion); } } else { // analyze what we got from git-describe - QRegExp rx("(.*)-(\\d+)-g([0-9a-f]+)(-dirty)?$"); - if (rx.exactMatch(_buildInfo.generatedVersion)) { - QString distance = rx.cap(2) == "0" ? QString() : QString("%1+%2 ").arg(rx.cap(1), rx.cap(2)); - _buildInfo.plainVersionString = QString("v%1 (%2git-%3%4)") - .arg(_buildInfo.baseVersion, distance, rx.cap(3), rx.cap(4)); - if (!_buildInfo.commitHash.isEmpty()) { - _buildInfo.fancyVersionString = QString("v%1 (%2git-%3%4)") - .arg(_buildInfo.baseVersion, distance, rx.cap(3), rx.cap(4), _buildInfo.commitHash); + static const QRegExp rx{"(.*)-(\\d+)-g([0-9a-f]+)(-dirty)?$"}; + if (rx.exactMatch(buildInfo.generatedVersion)) { + QString distance = rx.cap(2) == "0" ? QString{} : QString{"%1+%2 "}.arg(rx.cap(1), rx.cap(2)); + buildInfo.plainVersionString = QString{"v%1 (%2git-%3%4)"}.arg(buildInfo.baseVersion, distance, rx.cap(3), rx.cap(4)); + if (!buildInfo.commitHash.isEmpty()) { + buildInfo.fancyVersionString = QString{"v%1 (%2git-%3%4)"} + .arg(buildInfo.baseVersion, distance, rx.cap(3), rx.cap(4), buildInfo.commitHash); } } else { - _buildInfo.plainVersionString = QString("v%1 (invalid revision)").arg(_buildInfo.baseVersion); + buildInfo.plainVersionString = QString{"v%1 (invalid revision)"}.arg(buildInfo.baseVersion); } } - if (_buildInfo.fancyVersionString.isEmpty()) - _buildInfo.fancyVersionString = _buildInfo.plainVersionString; + if (buildInfo.fancyVersionString.isEmpty()) { + buildInfo.fancyVersionString = buildInfo.plainVersionString; + } + + instance()->_buildInfo = std::move(buildInfo); +} + + +const Quassel::BuildInfo &Quassel::buildInfo() +{ + return instance()->_buildInfo; } @@ -324,22 +354,16 @@ void Quassel::handleSignal(int sig) case SIGTERM: case SIGINT: qWarning("%s", qPrintable(QString("Caught signal %1 - exiting.").arg(sig))); - if (_instance) - _instance->quit(); - else - QCoreApplication::quit(); + instance()->quit(); break; #ifndef Q_OS_WIN // Windows does not support SIGHUP case SIGHUP: // Most applications use this as the 'configuration reload' command, e.g. nginx uses it for // graceful reloading of processes. - if (_instance) { - // If the instance exists, reload the configuration - quInfo() << "Caught signal" << SIGHUP <<"- reloading configuration"; - if (_instance->reloadConfig()) { - quInfo() << "Successfully reloaded configuration"; - } + quInfo() << "Caught signal" << SIGHUP << "- reloading configuration"; + if (instance()->reloadConfig()) { + quInfo() << "Successfully reloaded configuration"; } break; #endif @@ -348,21 +372,78 @@ void Quassel::handleSignal(int sig) #ifndef Q_OS_WIN case SIGBUS: #endif - logBacktrace(coreDumpFileName()); + instance()->logBacktrace(instance()->coreDumpFileName()); exit(EXIT_FAILURE); - break; default: - break; + ; } } +void Quassel::disableCrashHandler() +{ + instance()->_handleCrashes = false; +} + + +Quassel::RunMode Quassel::runMode() { + return instance()->_runMode; +} + + +void Quassel::setRunMode(RunMode runMode) +{ + instance()->_runMode = runMode; +} + + +void Quassel::setCliParser(std::shared_ptr parser) +{ + instance()->_cliParser = std::move(parser); +} + + +QString Quassel::optionValue(const QString &key) +{ + return instance()->_cliParser ? instance()->_cliParser->value(key) : QString{}; +} + + +bool Quassel::isOptionSet(const QString &key) +{ + return instance()->_cliParser ? instance()->_cliParser->isSet(key) : false; +} + + +Quassel::LogLevel Quassel::logLevel() +{ + return instance()->_logLevel; +} + + +void Quassel::setLogLevel(LogLevel logLevel) +{ + instance()->_logLevel = logLevel; +} + + +QFile *Quassel::logFile() { + return instance()->_logFile.get(); +} + + +bool Quassel::logToSyslog() +{ + return instance()->_logToSyslog; +} + + void Quassel::logFatalMessage(const char *msg) { #ifdef Q_OS_MAC Q_UNUSED(msg) #else - QFile dumpFile(coreDumpFileName()); + QFile dumpFile(instance()->coreDumpFileName()); dumpFile.open(QIODevice::Append); QTextStream dumpStream(&dumpFile); @@ -405,20 +486,21 @@ const QString &Quassel::coreDumpFileName() QString Quassel::configDirPath() { - if (!_configDirPath.isEmpty()) - return _configDirPath; + if (!instance()->_configDirPath.isEmpty()) + return instance()->_configDirPath; - if (Quassel::isOptionSet("datadir")) { + QString path; + if (isOptionSet("datadir")) { qWarning() << "Obsolete option --datadir used!"; - _configDirPath = Quassel::optionValue("datadir"); + path = Quassel::optionValue("datadir"); } - else if (Quassel::isOptionSet("configdir")) { - _configDirPath = Quassel::optionValue("configdir"); + else if (isOptionSet("configdir")) { + path = Quassel::optionValue("configdir"); } else { #ifdef Q_OS_MAC // On Mac, the path is always the same - _configDirPath = QDir::homePath() + "/Library/Application Support/Quassel/"; + path = QDir::homePath() + "/Library/Application Support/Quassel/"; #else // We abuse QSettings to find us a sensible path on the other platforms # ifdef Q_OS_WIN @@ -429,33 +511,41 @@ QString Quassel::configDirPath() # endif QSettings s(format, QSettings::UserScope, QCoreApplication::organizationDomain(), buildInfo().applicationName); QFileInfo fileInfo(s.fileName()); - _configDirPath = fileInfo.dir().absolutePath(); + path = fileInfo.dir().absolutePath(); #endif /* Q_OS_MAC */ } - if (!_configDirPath.endsWith(QDir::separator()) && !_configDirPath.endsWith('/')) - _configDirPath += QDir::separator(); + if (!path.endsWith(QDir::separator()) && !path.endsWith('/')) + path += QDir::separator(); - QDir qDir(_configDirPath); - if (!qDir.exists(_configDirPath)) { - if (!qDir.mkpath(_configDirPath)) { + QDir qDir{path}; + if (!qDir.exists(path)) { + if (!qDir.mkpath(path)) { qCritical() << "Unable to create Quassel config directory:" << qPrintable(qDir.absolutePath()); - return QString(); + return {}; } } - return _configDirPath; + instance()->_configDirPath = path; + + return path; +} + + +void Quassel::setDataDirPaths(const QStringList &paths) { + instance()->_dataDirPaths = paths; } QStringList Quassel::dataDirPaths() { - return _dataDirPaths; + return instance()->_dataDirPaths; } -QStringList Quassel::findDataDirPaths() const +QStringList Quassel::findDataDirPaths() { + // TODO Qt5 // We don't use QStandardPaths for now, as we still need to provide fallbacks for Qt4 and // want to stay consistent. @@ -538,19 +628,19 @@ QStringList Quassel::scriptDirPaths() QString Quassel::translationDirPath() { - if (_translationDirPath.isEmpty()) { + if (instance()->_translationDirPath.isEmpty()) { // We support only one translation dir; fallback mechanisms wouldn't work else. // This means that if we have a $data/translations dir, the internal :/i18n resource won't be considered. foreach(const QString &dir, dataDirPaths()) { if (QFile::exists(dir + "translations/")) { - _translationDirPath = dir + "translations/"; + instance()->_translationDirPath = dir + "translations/"; break; } } - if (_translationDirPath.isEmpty()) - _translationDirPath = ":/i18n/"; + if (instance()->_translationDirPath.isEmpty()) + instance()->_translationDirPath = ":/i18n/"; } - return _translationDirPath; + return instance()->_translationDirPath; } diff --git a/src/common/quassel.h b/src/common/quassel.h index c9bd3aba..8b106771 100644 --- a/src/common/quassel.h +++ b/src/common/quassel.h @@ -18,8 +18,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ -#ifndef QUASSEL_H_ -#define QUASSEL_H_ +#pragma once + +#include +#include +#include #include #include @@ -91,11 +94,11 @@ public: */ static Features features(); - virtual ~Quassel(); + static Quassel *instance(); static void setupBuildInfo(); - static inline const BuildInfo &buildInfo(); - static inline RunMode runMode(); + static const BuildInfo &buildInfo(); + static RunMode runMode(); static QString configDirPath(); @@ -125,14 +128,9 @@ public: static void loadTranslation(const QLocale &locale); - static inline void setCliParser(AbstractCliParser *cliParser); - static inline AbstractCliParser *cliParser(); - static inline QString optionValue(const QString &option); - static inline bool isOptionSet(const QString &option); - - static const QString &coreDumpFileName(); - - static bool DEBUG; + static void setCliParser(std::shared_ptr cliParser); + static QString optionValue(const QString &option); + static bool isOptionSet(const QString &option); enum LogLevel { DebugLevel, @@ -141,72 +139,83 @@ public: ErrorLevel }; - static inline LogLevel logLevel(); - static inline QFile *logFile(); - static inline bool logToSyslog(); + static LogLevel logLevel(); + static void setLogLevel(LogLevel logLevel); + static QFile *logFile(); + static bool logToSyslog(); static void logFatalMessage(const char *msg); + using ReloadHandler = std::function; + + static void registerReloadHandler(ReloadHandler handler); + + using QuitHandler = std::function; + + static void registerQuitHandler(QuitHandler quitHandler); + protected: + static bool init(); + static void destroy(); + + static void setRunMode(Quassel::RunMode runMode); + + static void setDataDirPaths(const QStringList &paths); + static QStringList findDataDirPaths(); + static void disableCrashHandler(); + + friend class CoreApplication; + friend class QtUiApplication; + friend class MonolithicApplication; + +private: Quassel(); - virtual bool init(); - virtual void quit(); + void setupEnvironment(); + void registerMetaTypes(); + + const QString &coreDumpFileName(); /** * Requests a reload of relevant runtime configuration. * - * Does not reload all configuration, but could catch things such as SSL certificates. Unless - * overridden, simply does nothing. + * Calls any registered reload handlers, and returns the cumulative result. If no handlers are registered, + * does nothing and returns true. * - * @return True if configuration reload successful, otherwise false + * @returns True if configuration reload successful, otherwise false */ - virtual bool reloadConfig() { return true; } + bool reloadConfig(); - inline void setRunMode(RunMode mode); - inline void setDataDirPaths(const QStringList &paths); - QStringList findDataDirPaths() const; - inline void disableCrashhandler(); + /** + * Requests to quit the application. + * + * Calls any registered quit handlers. If no handlers are registered, calls QCoreApplication::quit(). + */ + void quit(); -private: - void setupEnvironment(); - void registerMetaTypes(); + void logBacktrace(const QString &filename); static void handleSignal(int signal); - static void logBacktrace(const QString &filename); - - static Quassel *_instance; - static BuildInfo _buildInfo; - static AbstractCliParser *_cliParser; - static RunMode _runMode; - static bool _initialized; - static bool _handleCrashes; - - static QString _coreDumpFileName; - static QString _configDirPath; - static QStringList _dataDirPaths; - static QString _translationDirPath; - - static LogLevel _logLevel; - static QFile *_logFile; - static bool _logToSyslog; -}; +private: + BuildInfo _buildInfo; + RunMode _runMode; + bool _initialized{false}; + bool _handleCrashes{true}; -Q_DECLARE_OPERATORS_FOR_FLAGS(Quassel::Features); + QString _coreDumpFileName; + QString _configDirPath; + QStringList _dataDirPaths; + QString _translationDirPath; -const Quassel::BuildInfo &Quassel::buildInfo() { return _buildInfo; } -Quassel::RunMode Quassel::runMode() { return _runMode; } -void Quassel::setRunMode(Quassel::RunMode mode) { _runMode = mode; } -void Quassel::setDataDirPaths(const QStringList &paths) { _dataDirPaths = paths; } -void Quassel::disableCrashhandler() { _handleCrashes = false; } + LogLevel _logLevel{InfoLevel}; + bool _logToSyslog{false}; + std::unique_ptr _logFile; -void Quassel::setCliParser(AbstractCliParser *parser) { _cliParser = parser; } -AbstractCliParser *Quassel::cliParser() { return _cliParser; } -QString Quassel::optionValue(const QString &key) { return cliParser()->value(key); } -bool Quassel::isOptionSet(const QString &key) { return cliParser()->isSet(key); } + std::shared_ptr _cliParser; + + std::vector _reloadHandlers; + std::vector _quitHandlers; +}; -Quassel::LogLevel Quassel::logLevel() { return _logLevel; } -QFile *Quassel::logFile() { return _logFile; } -bool Quassel::logToSyslog() { return _logToSyslog; } -#endif +Q_DECLARE_OPERATORS_FOR_FLAGS(Quassel::Features); diff --git a/src/core/coreapplication.cpp b/src/core/coreapplication.cpp index 7426f177..1a689a22 100644 --- a/src/core/coreapplication.cpp +++ b/src/core/coreapplication.cpp @@ -55,6 +55,11 @@ bool CoreApplicationInternal::init() Core::instance(); // create and init the core _coreCreated = true; + Quassel::registerReloadHandler([]() { + // Currently, only reloading SSL certificates is supported + return Core::reloadCerts(); + }); + if (!Quassel::isOptionSet("norestore")) Core::restoreState(); @@ -62,27 +67,16 @@ bool CoreApplicationInternal::init() } -bool CoreApplicationInternal::reloadConfig() -{ - if (_coreCreated) { - // Currently, only reloading SSL certificates is supported - return Core::reloadCerts(); - } else { - return false; - } -} - - /*****************************************************************************/ CoreApplication::CoreApplication(int &argc, char **argv) - : QCoreApplication(argc, argv), Quassel() + : QCoreApplication(argc, argv) { #ifdef Q_OS_MAC - disableCrashhandler(); + Quassel::disableCrashHandler(); #endif /* Q_OS_MAC */ - setRunMode(Quassel::CoreOnly); + Quassel::setRunMode(Quassel::CoreOnly); _internal = new CoreApplicationInternal(); } @@ -105,13 +99,3 @@ bool CoreApplication::init() } return false; } - - -bool CoreApplication::reloadConfig() -{ - if (_internal) { - return _internal->reloadConfig(); - } else { - return false; - } -} diff --git a/src/core/coreapplication.h b/src/core/coreapplication.h index b350d52f..4c72b6bc 100644 --- a/src/core/coreapplication.h +++ b/src/core/coreapplication.h @@ -18,8 +18,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ -#ifndef COREAPPLICATION_H_ -#define COREAPPLICATION_H_ +#pragma once #include @@ -38,21 +37,12 @@ public: bool init(); - /** - * Requests a reload of relevant runtime configuration. - * - * In particular, signals to the Core to reload SSL certificates. - * - * @return True if configuration reload successful, otherwise false - */ - bool reloadConfig(); - private: bool _coreCreated; }; -class CoreApplication : public QCoreApplication, public Quassel +class CoreApplication : public QCoreApplication { Q_OBJECT public: @@ -61,18 +51,6 @@ public: bool init(); - /** - * Requests a reload of relevant runtime configuration. - * - * @see Quassel::reloadConfig() - * - * @return True if configuration reload successful, otherwise false - */ - bool reloadConfig(); - private: CoreApplicationInternal *_internal; }; - - -#endif diff --git a/src/qtui/monoapplication.cpp b/src/qtui/monoapplication.cpp index 5eb3a5cb..4b8fac41 100644 --- a/src/qtui/monoapplication.cpp +++ b/src/qtui/monoapplication.cpp @@ -32,25 +32,26 @@ MonolithicApplication::MonolithicApplication(int &argc, char **argv) { _internal = new CoreApplicationInternal(); // needed for parser options #if defined(HAVE_KDE4) || defined(Q_OS_MAC) - disableCrashhandler(); + Quassel::disableCrashHandler(); #endif /* HAVE_KDE4 || Q_OS_MAC */ - setRunMode(Quassel::Monolithic); + + Quassel::setRunMode(Quassel::Monolithic); } bool MonolithicApplication::init() { - if (!Quassel::init()) // parse args + if (!QtUiApplication::init()) return false; connect(Client::coreConnection(), SIGNAL(startInternalCore()), SLOT(startInternalCore())); - // FIXME what's this for? - if (isOptionSet("port")) { + // If port is given, start core so it can listen to incoming connections + if (Quassel::isOptionSet("port")) { startInternalCore(); } - return QtUiApplication::init(); + return true; } @@ -73,13 +74,3 @@ void MonolithicApplication::startInternalCore() connect(connection, SIGNAL(connectToInternalCore(InternalPeer*)), core, SLOT(setupInternalClientSession(InternalPeer*))); connect(core, SIGNAL(sessionState(Protocol::SessionState)), connection, SLOT(internalSessionStateReceived(Protocol::SessionState))); } - - -bool MonolithicApplication::reloadConfig() -{ - if (_internal) { - return _internal->reloadConfig(); - } else { - return false; - } -} diff --git a/src/qtui/monoapplication.h b/src/qtui/monoapplication.h index 6e7b9022..b68ac486 100644 --- a/src/qtui/monoapplication.h +++ b/src/qtui/monoapplication.h @@ -18,8 +18,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ -#ifndef MONOAPPLICATION_H_ -#define MONOAPPLICATION_H_ +#pragma once #include "qtuiapplication.h" @@ -32,16 +31,7 @@ public: MonolithicApplication(int &, char **); ~MonolithicApplication(); - bool init(); - - /** - * Requests a reload of relevant runtime configuration. - * - * @see Quassel::reloadConfig() - * - * @return True if configuration reload successful, otherwise false - */ - bool reloadConfig(); + bool init() override; private slots: void startInternalCore(); @@ -50,6 +40,3 @@ private: CoreApplicationInternal *_internal; bool _internalInitDone; }; - - -#endif diff --git a/src/qtui/qtuiapplication.cpp b/src/qtui/qtuiapplication.cpp index 927248f4..bd7ec7ef 100644 --- a/src/qtui/qtuiapplication.cpp +++ b/src/qtui/qtuiapplication.cpp @@ -36,12 +36,10 @@ QtUiApplication::QtUiApplication(int &argc, char **argv) #ifdef HAVE_KDE4 - : KApplication(), // KApplication is deprecated in KF5 + : KApplication() // KApplication is deprecated in KF5 #else - : QApplication(argc, argv), + : QApplication(argc, argv) #endif - Quassel(), - _aboutToQuit(false) { #ifdef HAVE_KDE4 Q_UNUSED(argc); Q_UNUSED(argv); @@ -74,18 +72,19 @@ QtUiApplication::QtUiApplication(int &argc, char **argv) } dataDirs.removeDuplicates(); - setDataDirPaths(dataDirs); + Quassel::setDataDirPaths(dataDirs); #else /* HAVE_KDE4 */ - setDataDirPaths(findDataDirPaths()); + Quassel::setDataDirPaths(Quassel::findDataDirPaths()); #endif /* HAVE_KDE4 */ #if defined(HAVE_KDE4) || defined(Q_OS_MAC) - disableCrashhandler(); + Quassel::disableCrashHandler(); #endif /* HAVE_KDE4 || Q_OS_MAC */ - setRunMode(Quassel::ClientOnly); + + Quassel::setRunMode(Quassel::ClientOnly); #if QT_VERSION < 0x050000 qInstallMsgHandler(Client::logMessage); @@ -170,13 +169,17 @@ bool QtUiApplication::init() // Some platforms don't set a default icon theme; chances are we can find our bundled theme though QIcon::setThemeName("breeze"); - // session resume - QtUi *gui = new QtUi(); - Client::init(gui); - // init gui only after the event loop has started - // QTimer::singleShot(0, gui, SLOT(init())); - gui->init(); - resumeSessionIfPossible(); + Client::init(new QtUi()); + + // Init UI only after the event loop has started + // TODO Qt5: Make this a lambda + QTimer::singleShot(0, this, SLOT(initUi())); + + Quassel::registerQuitHandler([]() { + QtUi::mainWindow()->quit(); + }); + + return true; } return false; @@ -189,9 +192,10 @@ QtUiApplication::~QtUiApplication() } -void QtUiApplication::quit() +void QtUiApplication::initUi() { - QtUi::mainWindow()->quit(); + QtUi::instance()->init(); + resumeSessionIfPossible(); } diff --git a/src/qtui/qtuiapplication.h b/src/qtui/qtuiapplication.h index e5e5d078..0bcb3e3c 100644 --- a/src/qtui/qtuiapplication.h +++ b/src/qtui/qtuiapplication.h @@ -18,8 +18,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ -#ifndef QTUIAPPLICATION_H_ -#define QTUIAPPLICATION_H_ +#pragma once #ifdef HAVE_KDE4 # include @@ -36,10 +35,10 @@ class QtUi; #ifdef HAVE_KDE4 -class QtUiApplication : public KApplication, public Quassel +class QtUiApplication : public KApplication { #else -class QtUiApplication : public QApplication, public Quassel +class QtUiApplication : public QApplication { #endif @@ -61,9 +60,6 @@ public: void saveState(QSessionManager &manager); #endif -protected: - virtual void quit(); - private: /** * Migrate settings if neccessary and possible @@ -87,8 +83,11 @@ private: */ bool applySettingsMigration(QtUiSettings settings, const uint newVersion); - bool _aboutToQuit; -}; +private slots: + void initUi(); +private: + bool _aboutToQuit{false}; -#endif + Quassel _quasselInstance; +}; -- 2.20.1