qt4-b-gone: Reorganize the initialization sequence
authorManuel Nickschas <sputnick@quassel-irc.org>
Thu, 26 Jul 2018 19:21:40 +0000 (21:21 +0200)
committerManuel Nickschas <sputnick@quassel-irc.org>
Sun, 18 Nov 2018 10:06:43 +0000 (11:06 +0100)
KDE4 required special handling during initialization, because command
line arguments needed to be parsed before instantiating the
application object. Since this is no longer required, the sequence
can now be simplified.

To prepare for enabling early translations (also for the CLI parser),
instantiate the application first, then explicitly initialize the
Quassel instance in main() (which will later both load translations,
and handle CLI options). Only then also initialize the application
itself.

Since initialization errors are handled by exceptions anyway, get rid
of the return values for the various init() methods, too.

src/common/logger.cpp
src/common/logger.h
src/common/main.cpp
src/common/quassel.cpp
src/common/quassel.h
src/core/coreapplication.cpp
src/qtui/monoapplication.cpp
src/qtui/qtuiapplication.cpp

index a72c68f..aabba5e 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "logger.h"
 #include "quassel.h"
 
 #include "logger.h"
 #include "quassel.h"
+#include "types.h"
 
 namespace {
 
 
 namespace {
 
@@ -74,7 +75,7 @@ std::vector<Logger::LogEntry> Logger::messages() const
 }
 
 
 }
 
 
-bool Logger::setup(bool keepMessages)
+void Logger::setup(bool keepMessages)
 {
     _keepMessages = keepMessages;
 
 {
     _keepMessages = keepMessages;
 
@@ -90,8 +91,7 @@ bool Logger::setup(bool keepMessages)
         else if (level == "error")
             _outputLevel = LogLevel::Error;
         else {
         else if (level == "error")
             _outputLevel = LogLevel::Error;
         else {
-            qCritical() << qPrintable(tr("Invalid log level %1; supported are Debug|Info|Warning|Error").arg(level));
-            return false;
+            throw ExitException{EXIT_FAILURE, qPrintable(tr("Invalid log level %1; supported are Debug|Info|Warning|Error").arg(level))};
         }
     }
 
         }
     }
 
@@ -121,8 +121,6 @@ bool Logger::setup(bool keepMessages)
     if (!_keepMessages) {
         _messages.clear();
     }
     if (!_keepMessages) {
         _messages.clear();
     }
-
-    return true;
 }
 
 
 }
 
 
index 7752a74..e6701fe 100644 (file)
@@ -61,9 +61,9 @@ public:
      * and won't store further ones.
      *
      * @param keepMessages Whether messages should be kept
      * and won't store further ones.
      *
      * @param keepMessages Whether messages should be kept
-     * @returns true, if initialization was successful
+     * @throws ExitException, if command line options are invalid
      */
      */
-    bool setup(bool keepMessages);
+    void setup(bool keepMessages);
 
     /**
      * Accesses the stores log messages, e.g. for consumption by DebugLogWidget.
 
     /**
      * Accesses the stores log messages, e.g. for consumption by DebugLogWidget.
index 598425f..4b13404 100644 (file)
@@ -64,25 +64,6 @@ Q_IMPORT_PLUGIN(qgif)
 
 int main(int argc, char **argv)
 {
 
 int main(int argc, char **argv)
 {
-#ifdef HAVE_UMASK
-    umask(S_IRWXG | S_IRWXO);
-#endif
-
-    // Instantiate early, so log messages are handled
-    Quassel quassel;
-
-    Quassel::setupBuildInfo();
-    QCoreApplication::setApplicationName(Quassel::buildInfo().applicationName);
-    QCoreApplication::setApplicationVersion(Quassel::buildInfo().plainVersionString);
-    QCoreApplication::setOrganizationName(Quassel::buildInfo().organizationName);
-    QCoreApplication::setOrganizationDomain(Quassel::buildInfo().organizationDomain);
-
-    //Setup the High-DPI settings
-# if QT_VERSION >= 0x050600 && defined(Q_OS_WIN)
-    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); //Added in Qt 5.6
-#endif
-    QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
-
     // We need to explicitly initialize the required resources when linking statically
 #ifndef BUILD_QTUI
     Q_INIT_RESOURCE(sql);
     // We need to explicitly initialize the required resources when linking statically
 #ifndef BUILD_QTUI
     Q_INIT_RESOURCE(sql);
@@ -99,7 +80,7 @@ int main(int argc, char **argv)
     Q_INIT_RESOURCE(breeze_icons);
     Q_INIT_RESOURCE(breeze_dark_icons);
 #  ifdef WITH_OXYGEN_ICONS
     Q_INIT_RESOURCE(breeze_icons);
     Q_INIT_RESOURCE(breeze_dark_icons);
 #  ifdef WITH_OXYGEN_ICONS
-    Q_INIT_RESOURCE(oxygen_icons);
+      Q_INIT_RESOURCE(oxygen_icons);
 #  endif
 #  ifdef WITH_BUNDLED_ICONS
       Q_INIT_RESOURCE(breeze_icon_theme);
 #  endif
 #  ifdef WITH_BUNDLED_ICONS
       Q_INIT_RESOURCE(breeze_icon_theme);
@@ -111,12 +92,50 @@ int main(int argc, char **argv)
 # endif
 #endif
 
 # endif
 #endif
 
-    std::shared_ptr<AbstractCliParser> cliParser = std::make_shared<Qt5CliParser>();
-    Quassel::setCliParser(cliParser);
+    // Set umask so files are created with restricted permissions
+#ifdef HAVE_UMASK
+    umask(S_IRWXG | S_IRWXO);
+#endif
+
+    // Instantiate early, so log messages are handled
+    Quassel quassel;
+
+    Quassel::setupBuildInfo();
+    QCoreApplication::setApplicationName(Quassel::buildInfo().applicationName);
+    QCoreApplication::setApplicationVersion(Quassel::buildInfo().plainVersionString);
+    QCoreApplication::setOrganizationName(Quassel::buildInfo().organizationName);
+    QCoreApplication::setOrganizationDomain(Quassel::buildInfo().organizationDomain);
+
+    // Migrate settings from KDE4 to KF5 if appropriate
+#ifdef HAVE_KF5
+    Kdelibs4ConfigMigrator migrator(QCoreApplication::applicationName());
+    migrator.setConfigFiles(QStringList() << "quasselrc" << "quassel.notifyrc");
+    migrator.migrate();
+#endif
+
+    //Setup the High-DPI settings
+# if QT_VERSION >= 0x050600 && defined(Q_OS_WIN)
+    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); //Added in Qt 5.6
+#endif
+    QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
+
+    // Instantiate application
+#if defined BUILD_CORE
+    CoreApplication app(argc, argv);
+    const auto runMode = Quassel::RunMode::CoreOnly;
+#elif defined BUILD_QTUI
+    QtUiApplication app(argc, argv);
+    const auto runMode = Quassel::RunMode::ClientOnly;
+#elif defined BUILD_MONO
+    MonolithicApplication app(argc, argv);
+    const auto runMode = Quassel::RunMode::Monolithic;
+#endif
 
     // Initialize CLI arguments
 
     // Initialize CLI arguments
-    // NOTE: We can't use tr() at this point, since app is not yet created
-    // TODO: Change this once we get rid of KDE4 and can initialize the parser after creating the app
+    // TODO: Move CLI option handling into Quassel::init(), after initializing the translation catalogue
+
+    std::shared_ptr<AbstractCliParser> cliParser = std::make_shared<Qt5CliParser>();
+    Quassel::setCliParser(cliParser);
 
     // put shared client&core arguments here
     cliParser->addSwitch("debug", 'd', "Enable debug output");
 
     // put shared client&core arguments here
     cliParser->addSwitch("debug", 'd', "Enable debug output");
@@ -171,33 +190,22 @@ int main(int argc, char **argv)
     cliParser->addSwitch("enable-experimental-dcc", 0, "Enable highly experimental and unfinished support for CTCP DCC (DANGEROUS)");
 #endif
 
     cliParser->addSwitch("enable-experimental-dcc", 0, "Enable highly experimental and unfinished support for CTCP DCC (DANGEROUS)");
 #endif
 
-#if defined BUILD_CORE
-    CoreApplication app(argc, argv);
-#elif defined BUILD_QTUI
-    QtUiApplication app(argc, argv);
-#elif defined BUILD_MONO
-    MonolithicApplication app(argc, argv);
-#endif
-
     if (!cliParser->init(app.arguments())) {
         cliParser->usage();
         return EXIT_FAILURE;
     }
 
     if (!cliParser->init(app.arguments())) {
         cliParser->usage();
         return EXIT_FAILURE;
     }
 
-// Migrate settings from KDE4 to KF5 if appropriate
-#ifdef HAVE_KF5
-    Kdelibs4ConfigMigrator migrator(QCoreApplication::applicationName());
-    migrator.setConfigFiles(QStringList() << "quasselrc" << "quassel.notifyrc");
-    migrator.migrate();
-#endif
+    try {
+        // Note: This method requires CLI options to be available
+        Quassel::instance()->init(runMode);
 
 #ifdef HAVE_KF5
 
 #ifdef HAVE_KF5
-    // FIXME: This should be done after loading the translation catalogue, but still in main()
-    AboutData aboutData;
-    AboutData::setQuasselPersons(&aboutData);
-    KAboutData::setApplicationData(aboutData.kAboutData());
+        AboutData aboutData;
+        AboutData::setQuasselPersons(&aboutData);
+        KAboutData::setApplicationData(aboutData.kAboutData());
 #endif
 #endif
-    try {
+
+        // Initialize the application
         app.init();
     }
     catch (ExitException e) {
         app.init();
     }
     catch (ExitException e) {
index 3598fa3..af4c69b 100644 (file)
@@ -60,18 +60,15 @@ Quassel::Quassel()
 }
 
 
 }
 
 
-bool Quassel::init()
+void Quassel::init(RunMode runMode)
 {
 {
-    if (instance()->_initialized)
-        return true;  // allow multiple invocations because of MonolithicApplication
+    _runMode = runMode;
 
     qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));
 
 
     qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));
 
-    instance()->setupSignalHandling();
-    instance()->setupEnvironment();
-    instance()->registerMetaTypes();
-
-    instance()->_initialized = true;
+    setupSignalHandling();
+    setupEnvironment();
+    registerMetaTypes();
 
     Network::setDefaultCodecForServer("UTF-8");
     Network::setDefaultCodecForEncoding("UTF-8");
 
     Network::setDefaultCodecForServer("UTF-8");
     Network::setDefaultCodecForEncoding("UTF-8");
@@ -79,16 +76,16 @@ bool Quassel::init()
 
     if (isOptionSet("help")) {
         instance()->_cliParser->usage();
 
     if (isOptionSet("help")) {
         instance()->_cliParser->usage();
-        return false;
+        return;
     }
 
     if (isOptionSet("version")) {
         std::cout << qPrintable("Quassel IRC: " + Quassel::buildInfo().plainVersionString) << std::endl;
     }
 
     if (isOptionSet("version")) {
         std::cout << qPrintable("Quassel IRC: " + Quassel::buildInfo().plainVersionString) << std::endl;
-        return false;
+        return;
     }
 
     // Don't keep a debug log on the core
     }
 
     // Don't keep a debug log on the core
-    return instance()->logger()->setup(runMode() != RunMode::CoreOnly);
+    logger()->setup(runMode != RunMode::CoreOnly);
 }
 
 
 }
 
 
@@ -335,12 +332,6 @@ Quassel::RunMode Quassel::runMode() {
 }
 
 
 }
 
 
-void Quassel::setRunMode(RunMode runMode)
-{
-    instance()->_runMode = runMode;
-}
-
-
 void Quassel::setCliParser(std::shared_ptr<AbstractCliParser> parser)
 {
     instance()->_cliParser = std::move(parser);
 void Quassel::setCliParser(std::shared_ptr<AbstractCliParser> parser)
 {
     instance()->_cliParser = std::move(parser);
index b658677..fc40bbb 100644 (file)
@@ -144,6 +144,8 @@ public:
 
     Quassel();
 
 
     Quassel();
 
+    void init(RunMode runMode);
+
     /**
      * Provides access to the Logger instance.
      *
     /**
      * Provides access to the Logger instance.
      *
@@ -217,10 +219,6 @@ signals:
     void messageLogged(const QDateTime &timeStamp, const QString &msg);
 
 protected:
     void messageLogged(const QDateTime &timeStamp, const QString &msg);
 
 protected:
-    static bool init();
-
-    static void setRunMode(Quassel::RunMode runMode);
-
     static void setDataDirPaths(const QStringList &paths);
     static QStringList findDataDirPaths();
 
     static void setDataDirPaths(const QStringList &paths);
     static QStringList findDataDirPaths();
 
@@ -251,7 +249,6 @@ private slots:
 private:
     BuildInfo _buildInfo;
     RunMode _runMode;
 private:
     BuildInfo _buildInfo;
     RunMode _runMode;
-    bool _initialized{false};
     bool _quitting{false};
 
     QString _coreDumpFileName;
     bool _quitting{false};
 
     QString _coreDumpFileName;
index 0f6bb95..d662820 100644 (file)
@@ -23,7 +23,6 @@
 CoreApplication::CoreApplication(int &argc, char **argv)
     : QCoreApplication(argc, argv)
 {
 CoreApplication::CoreApplication(int &argc, char **argv)
     : QCoreApplication(argc, argv)
 {
-    Quassel::setRunMode(Quassel::CoreOnly);
     Quassel::registerQuitHandler([this]() {
         connect(_core.get(), SIGNAL(shutdownComplete()), this, SLOT(onShutdownComplete()));
         _core->shutdown();
     Quassel::registerQuitHandler([this]() {
         connect(_core.get(), SIGNAL(shutdownComplete()), this, SLOT(onShutdownComplete()));
         _core->shutdown();
@@ -33,10 +32,6 @@ CoreApplication::CoreApplication(int &argc, char **argv)
 
 void CoreApplication::init()
 {
 
 void CoreApplication::init()
 {
-    if (!Quassel::init()) {
-        throw ExitException{EXIT_FAILURE, tr("Could not initialize Quassel!")};
-    }
-
     _core.reset(new Core{}); // FIXME C++14: std::make_unique
     _core->init();
 }
     _core.reset(new Core{}); // FIXME C++14: std::make_unique
     _core->init();
 }
index 34890ed..068ec71 100644 (file)
@@ -31,7 +31,6 @@ class InternalPeer;
 MonolithicApplication::MonolithicApplication(int &argc, char **argv)
     : QtUiApplication(argc, argv)
 {
 MonolithicApplication::MonolithicApplication(int &argc, char **argv)
     : QtUiApplication(argc, argv)
 {
-    Quassel::setRunMode(Quassel::Monolithic);
 }
 
 
 }
 
 
index 74be5b4..3f03f09 100644 (file)
@@ -36,7 +36,6 @@ QtUiApplication::QtUiApplication(int &argc, char **argv)
     : QApplication(argc, argv)
 {
     Quassel::setDataDirPaths(Quassel::findDataDirPaths());
     : QApplication(argc, argv)
 {
     Quassel::setDataDirPaths(Quassel::findDataDirPaths());
-    Quassel::setRunMode(Quassel::ClientOnly);
 
     connect(this, &QGuiApplication::commitDataRequest, this, &QtUiApplication::commitData, Qt::DirectConnection);
     connect(this, &QGuiApplication::saveStateRequest, this, &QtUiApplication::saveState, Qt::DirectConnection);
 
     connect(this, &QGuiApplication::commitDataRequest, this, &QtUiApplication::commitData, Qt::DirectConnection);
     connect(this, &QGuiApplication::saveStateRequest, this, &QtUiApplication::saveState, Qt::DirectConnection);
@@ -49,10 +48,6 @@ QtUiApplication::QtUiApplication(int &argc, char **argv)
 
 void QtUiApplication::init()
 {
 
 void QtUiApplication::init()
 {
-    if (!Quassel::init()) {
-        throw ExitException{EXIT_FAILURE, tr("Could not initialize Quassel!")};
-    }
-
     // Settings upgrade/downgrade handling
     if (!migrateSettings()) {
         throw ExitException{EXIT_FAILURE, tr("Could not load or upgrade client settings!")};
     // Settings upgrade/downgrade handling
     if (!migrateSettings()) {
         throw ExitException{EXIT_FAILURE, tr("Could not load or upgrade client settings!")};