common: Rework command line option handling
authorManuel Nickschas <sputnick@quassel-irc.org>
Mon, 30 Jul 2018 22:15:52 +0000 (00:15 +0200)
committerManuel Nickschas <sputnick@quassel-irc.org>
Sun, 18 Nov 2018 10:06:43 +0000 (11:06 +0100)
Since we can now rely on Qt5's QCommandLineParser, there is
no longer a need for an abstraction for command line parsing.
Use QCommandLineParser directly, and remove the now obsolete
AbstractCliParser and its various implementations.

Move command line parsing into Quassel::init(), which allows for
using translated strings. Make user-visible strings translateable.

Remove the long-deprecated --datadir option for now (may come
back if we decide to allow for specifying the database location
independently of config files).

12 files changed:
src/common/CMakeLists.txt
src/common/abstractcliparser.h [deleted file]
src/common/cliparser.cpp [deleted file]
src/common/cliparser.h [deleted file]
src/common/main.cpp
src/common/qt5cliparser.cpp [deleted file]
src/common/qt5cliparser.h [deleted file]
src/common/quassel.cpp
src/common/quassel.h
src/qtui/qtuiapplication.cpp
src/uisupport/kcmdlinewrapper.cpp [deleted file]
src/uisupport/kcmdlinewrapper.h [deleted file]

index 661d10c..1c0fd26 100644 (file)
@@ -37,7 +37,6 @@ set(SOURCES
     peer.cpp
     peerfactory.cpp
     presetnetworks.cpp
     peer.cpp
     peerfactory.cpp
     presetnetworks.cpp
-    qt5cliparser.cpp
     quassel.cpp
     remotepeer.cpp
     settings.cpp
     quassel.cpp
     remotepeer.cpp
     settings.cpp
diff --git a/src/common/abstractcliparser.h b/src/common/abstractcliparser.h
deleted file mode 100644 (file)
index 953ea3e..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/***************************************************************************
- *   Copyright (C) 2005-2018 by the Quassel Project                        *
- *   devel@quassel-irc.org                                                 *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) version 3.                                           *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
- ***************************************************************************/
-
-#ifndef ABSTRACTCLIPARSER_H
-#define ABSTRACTCLIPARSER_H
-
-#include <QStringList>
-
-class AbstractCliParser
-{
-public:
-    virtual bool init(const QStringList &arguments = QStringList()) = 0;
-
-    virtual QString value(const QString &longName) = 0;
-    virtual bool isSet(const QString &longName) = 0;
-    inline void addSwitch(const QString &longName, const char shortName = 0, const QString &help = QString())
-    {
-        addArgument(longName, CliParserArg(CliParserArg::CliArgSwitch, shortName, help));
-    }
-
-
-    inline void addOption(const QString &longName, const char shortName = 0, const QString &help = QString(), const QString &valueName = QString(), const QString &def = QString())
-    {
-        addArgument(longName, CliParserArg(CliParserArg::CliArgOption, shortName, help, valueName, def));
-    }
-
-
-    virtual void usage() = 0;
-
-    virtual ~AbstractCliParser() {};
-
-protected:
-    struct CliParserArg {
-        enum CliArgType {
-            CliArgInvalid,
-            CliArgSwitch,
-            CliArgOption
-        };
-
-        CliParserArg(const CliArgType type = CliArgInvalid, const char shortName = 0, const QString &help = QString(), const QString &valueName = QString(), const QString &def = QString())
-            : type(type)
-            , shortName(shortName)
-            , help(help)
-            , valueName(valueName)
-            , def(def)
-            {};
-
-        CliArgType type;
-        char shortName;
-        QString help;
-        QString valueName;
-        QString def;
-        QString value;
-        bool boolValue = false;
-    };
-
-    virtual void addArgument(const QString &longName, const CliParserArg &arg) = 0;
-};
-
-
-#endif
diff --git a/src/common/cliparser.cpp b/src/common/cliparser.cpp
deleted file mode 100644 (file)
index c1d253d..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-/***************************************************************************
- *   Copyright (C) 2005-2018 by the Quassel Project                        *
- *   devel@quassel-irc.org                                                 *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) version 3.                                           *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
- ***************************************************************************/
-
-#include "cliparser.h"
-
-#include <QDir>
-#include <QDebug>
-#include <QString>
-#include <QFileInfo>
-
-#include <iostream>
-
-CliParser::CliParser() : AbstractCliParser()
-{
-}
-
-
-void CliParser::addArgument(const QString &longName, const CliParserArg &arg)
-{
-    if (argsMap.contains(longName)) qWarning() << "Warning: Multiple definition of argument" << longName;
-    if (arg.shortName != 0 && !lnameOfShortArg(arg.shortName).isNull())
-        qWarning().nospace() << "Warning: Redefining shortName '" << arg.shortName << "' for " << longName << " previously defined for " << lnameOfShortArg(arg.shortName);
-    argsMap.insert(longName, arg);
-}
-
-
-bool CliParser::addLongArg(const CliParserArg::CliArgType type, const QString &name, const QString &value)
-{
-    if (argsMap.contains(name)) {
-        if (type == CliParserArg::CliArgOption && argsMap.value(name).type == type) {
-            argsMap[name].value = escapedValue(value);
-            return true;
-        }
-        else if (type == CliParserArg::CliArgSwitch && argsMap.value(name).type == type) {
-            argsMap[name].boolValue = true;
-            return true;
-        }
-    }
-    qWarning() << "Warning: Unrecognized argument:" << name;
-    return false;
-}
-
-
-bool CliParser::addShortArg(const CliParserArg::CliArgType type, const char shortName, const QString &value)
-{
-    QString longName = lnameOfShortArg(shortName);
-    if (!longName.isNull()) {
-        if (type == CliParserArg::CliArgOption && argsMap.value(longName).type == type) {
-            argsMap[longName].value = escapedValue(value);
-            return true;
-        }
-        else if (type == CliParserArg::CliArgSwitch) {
-            if (argsMap.value(longName).type == type) {
-                argsMap[longName].boolValue = true;
-                return true;
-            }
-            // arg is an option but detected as a switch -> argument is missing
-            else {
-                qWarning().nospace() << "Warning: '" << shortName << "' is an option which needs an argument";
-                return false;
-            }
-        }
-    }
-    qWarning().nospace() << "Warning: Unrecognized argument: '" << shortName << "'";
-    return false;
-}
-
-
-QString CliParser::escapedValue(const QString &value)
-{
-    QString escapedValue = value;
-    if (escapedValue.startsWith("~"))
-        escapedValue.replace(0, 1, QDir::homePath());
-
-    return escapedValue;
-}
-
-
-bool CliParser::init(const QStringList &args)
-{
-    argsRaw = args;
-    QStringList::const_iterator currentArg;
-    for (currentArg = argsRaw.constBegin(); currentArg != argsRaw.constEnd(); ++currentArg) {
-        if (currentArg->startsWith("--")) {
-            // long
-            QString name;
-            if (currentArg->contains("=")) {
-                // option
-                QStringList tmp = currentArg->mid(2).split("=");
-                name = tmp.at(0);
-                QString value;
-                // this is needed to allow --option=""
-                if (tmp.at(1).isNull()) value = QString("");
-                else value = tmp.at(1);
-                if (!addLongArg(CliParserArg::CliArgOption, name, value)) return false;
-            }
-            else {
-                // switch
-                name = currentArg->mid(2);
-                if (!addLongArg(CliParserArg::CliArgSwitch, name)) return false;
-            }
-        }
-        else if (currentArg->startsWith("-")) {
-            // short
-            char name;
-            QStringList::const_iterator nextArg = currentArg+1;
-            // if next arg is a short/long option/switch the current arg is one too
-            if (nextArg == argsRaw.constEnd() || nextArg->startsWith("-")) {
-                // switch
-                for (int i = 0; i < currentArg->mid(1).toLatin1().size(); i++) {
-                    name = currentArg->mid(1).toLatin1().at(i);
-                    if (!addShortArg(CliParserArg::CliArgSwitch, name)) return false;
-                }
-            }
-            // if next arg is is no option/switch it's an argument to a shortoption
-            else {
-                // option
-                // short options are not freely mixable with other shortargs
-                if (currentArg->mid(1).toLatin1().size() > 1) {
-                    qWarning() << "Warning: Shortoptions may not be combined with other shortoptions or switches";
-                    return false;
-                }
-                QString value;
-                bool skipNext = false;
-                if (nextArg != argsRaw.constEnd()) {
-                    value = nextArg->toLocal8Bit();
-                    skipNext = true;
-                }
-                else value = currentArg->toLocal8Bit();
-                name = currentArg->mid(1).toLatin1().at(0);
-                // we took one argument as argument to an option so skip it next time
-                if (skipNext) ++currentArg;
-                if (!addShortArg(CliParserArg::CliArgOption, name, value)) return false;
-            }
-        }
-        else {
-            // we don't support plain arguments without -/--
-            if (currentArg->toLatin1() != argsRaw.at(0)) return false;
-        }
-    }
-    return true;
-}
-
-
-void CliParser::usage()
-{
-    std::cout << "Usage: " << qPrintable(QFileInfo(argsRaw.at(0)).completeBaseName()) << " [arguments]" << std::endl;
-
-    // get size of longName field
-    QStringList keys = argsMap.keys();
-    uint lnameFieldSize = 0;
-    foreach(QString key, keys) {
-        uint size = 0;
-        if (argsMap.value(key).type == CliParserArg::CliArgOption)
-            size += key.size()*2;
-        else
-            size += key.size();
-        // this is for " --...=[....] "
-        size += 8;
-        if (size > lnameFieldSize) lnameFieldSize = size;
-    }
-
-    QMap<QString, CliParserArg>::const_iterator arg;
-    for (arg = argsMap.constBegin(); arg != argsMap.constEnd(); ++arg) {
-        QString output;
-        QString lnameField;
-
-        if (arg.value().shortName) {
-            output.append(" -").append(arg.value().shortName).append(",");
-        }
-        else output.append("    ");
-        lnameField.append(" --").append(arg.key());
-        if (arg.value().type == CliParserArg::CliArgOption && !arg.value().valueName.isEmpty()) {
-            lnameField.append("=<").append(arg.value().valueName).append(">");
-        }
-        output.append(lnameField.leftJustified(lnameFieldSize));
-        if (!arg.value().help.isEmpty()) {
-            output.append(arg.value().help);
-        }
-        if (arg.value().type == CliParserArg::CliArgOption && !arg.value().def.isNull()) {
-            output.append(". Default is: ").append(arg.value().def);
-        }
-        std::cout << qPrintable(output) << std::endl;
-    }
-}
-
-
-QString CliParser::value(const QString &longName)
-{
-    if (argsMap.contains(longName) && argsMap.value(longName).type == CliParserArg::CliArgOption) {
-        if (!argsMap.value(longName).value.isNull())
-            return argsMap.value(longName).value;
-        else
-            return argsMap.value(longName).def;
-    }
-    else {
-        qWarning() << "Warning: Requested value of not defined argument" << longName << "or argument is a switch";
-        return QString();
-    }
-}
-
-
-bool CliParser::isSet(const QString &longName)
-{
-    if (argsMap.contains(longName)) {
-        if (argsMap.value(longName).type == CliParserArg::CliArgOption) return !argsMap.value(longName).value.isNull();
-        else return argsMap.value(longName).boolValue;
-    }
-    else {
-        qWarning() << "Warning: Requested isSet of not defined argument" << longName;
-        return false;
-    }
-}
-
-
-QString CliParser::lnameOfShortArg(const char arg)
-{
-    QMap<QString, CliParserArg>::const_iterator cur;
-    for (cur = argsMap.constBegin(); cur != argsMap.constEnd(); ++cur) {
-        if (cur.value().shortName == arg) return cur.key();
-    }
-    return QString();
-}
diff --git a/src/common/cliparser.h b/src/common/cliparser.h
deleted file mode 100644 (file)
index cc9f9ab..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/***************************************************************************
- *   Copyright (C) 2005-2018 by the Quassel Project                        *
- *   devel@quassel-irc.org                                                 *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) version 3.                                           *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
- ***************************************************************************/
-
-#ifndef CLIPARSER_H
-#define CLIPARSER_H
-
-#include <QMap>
-
-#include "abstractcliparser.h"
-
-//! Quassel's own parser for command line arguments
-class CliParser : public AbstractCliParser
-{
-public:
-    CliParser();
-
-    bool init(const QStringList &arguments = QStringList());
-
-    QString value(const QString &longName);
-    bool isSet(const QString &longName);
-    void usage();
-
-private:
-    void addArgument(const QString &longName, const CliParserArg &arg);
-    bool addLongArg(const CliParserArg::CliArgType type, const QString &name, const QString &value = QString());
-    bool addShortArg(const CliParserArg::CliArgType type, const char shortName, const QString &value = QString());
-    QString escapedValue(const QString &value);
-    QString lnameOfShortArg(const char arg);
-
-    QStringList argsRaw;
-    QMap<QString, CliParserArg> argsMap;
-};
-
-
-#endif
index 4b13404..20ea4d3 100644 (file)
@@ -58,7 +58,6 @@ Q_IMPORT_PLUGIN(qjpeg)
 Q_IMPORT_PLUGIN(qgif)
 #endif
 
 Q_IMPORT_PLUGIN(qgif)
 #endif
 
-#include "qt5cliparser.h"
 #include "quassel.h"
 #include "types.h"
 
 #include "quassel.h"
 #include "types.h"
 
@@ -131,72 +130,7 @@ int main(int argc, char **argv)
     const auto runMode = Quassel::RunMode::Monolithic;
 #endif
 
     const auto runMode = Quassel::RunMode::Monolithic;
 #endif
 
-    // Initialize CLI arguments
-    // 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");
-    cliParser->addSwitch("help", 'h', "Display this help and exit");
-    cliParser->addSwitch("version", 'v', "Display version information");
-#ifdef BUILD_QTUI
-    cliParser->addOption("configdir", 'c', "Specify the directory holding the client configuration", "path");
-#else
-    cliParser->addOption("configdir", 'c', "Specify the directory holding configuration files, the SQlite database and the SSL certificate", "path");
-#endif
-    cliParser->addOption("datadir", 0, "DEPRECATED - Use --configdir instead", "path");
-    cliParser->addOption("loglevel", 'L', "Loglevel Debug|Info|Warning|Error", "level", "Info");
-#ifdef HAVE_SYSLOG
-    cliParser->addSwitch("syslog", 0, "Log to syslog");
-#endif
-    cliParser->addOption("logfile", 'l', "Log to a file", "path");
-
-#ifndef BUILD_CORE
-    // put client-only arguments here
-    cliParser->addOption("icontheme", 0, "Override the system icon theme ('breeze' is recommended)", "theme");
-    cliParser->addOption("qss", 0, "Load a custom application stylesheet", "file.qss");
-    cliParser->addSwitch("debugbufferswitches", 0, "Enables debugging for bufferswitches");
-    cliParser->addSwitch("debugmodel", 0, "Enables debugging for models");
-    cliParser->addSwitch("hidewindow", 0, "Start the client minimized to the system tray");
-#endif
-#ifndef BUILD_QTUI
-    // put core-only arguments here
-    cliParser->addOption("listen", 0, "The address(es) quasselcore will listen on", "<address>[,<address>[,...]]", "::,0.0.0.0");
-    cliParser->addOption("port", 'p', "The port quasselcore will listen at", "port", "4242");
-    cliParser->addSwitch("norestore", 'n', "Don't restore last core's state");
-    cliParser->addSwitch("config-from-environment", 0, "Load configuration from environment variables");
-    cliParser->addOption("select-backend", 0, "Switch storage backend (migrating data if possible)", "backendidentifier");
-    cliParser->addOption("select-authenticator", 0, "Select authentication backend", "authidentifier");
-    cliParser->addSwitch("add-user", 0, "Starts an interactive session to add a new core user");
-    cliParser->addOption("change-userpass", 0, "Starts an interactive session to change the password of the user identified by <username>", "username");
-    cliParser->addSwitch("oidentd", 0, "Enable oidentd integration.  In most cases you should also enable --strict-ident");
-    cliParser->addOption("oidentd-conffile", 0, "Set path to oidentd configuration file", "file");
-    cliParser->addSwitch("strict-ident", 0, "Use users' quasselcore username as ident reply. Ignores each user's configured ident setting.");
-    cliParser->addSwitch("ident-daemon", 0, "Enable internal ident daemon");
-    cliParser->addOption("ident-port", 0, "The port quasselcore will listen at for ident requests. Only meaningful with --ident-daemon", "port", "10113");
-#ifdef HAVE_SSL
-    cliParser->addSwitch("require-ssl", 0, "Require SSL for remote (non-loopback) client connections");
-    cliParser->addOption("ssl-cert", 0, "Specify the path to the SSL Certificate", "path", "configdir/quasselCert.pem");
-    cliParser->addOption("ssl-key", 0, "Specify the path to the SSL key", "path", "ssl-cert-path");
-#endif
-    cliParser->addSwitch("debug-irc", 0,
-                         "Enable logging of all raw IRC messages to debug log, including "
-                         "passwords!  In most cases you should also set --loglevel Debug");
-    cliParser->addOption("debug-irc-id", 0,
-                         "Limit raw IRC logging to this network ID.  Implies --debug-irc",
-                         "database network ID", "-1");
-    cliParser->addSwitch("enable-experimental-dcc", 0, "Enable highly experimental and unfinished support for CTCP DCC (DANGEROUS)");
-#endif
-
-    if (!cliParser->init(app.arguments())) {
-        cliParser->usage();
-        return EXIT_FAILURE;
-    }
-
     try {
     try {
-        // Note: This method requires CLI options to be available
         Quassel::instance()->init(runMode);
 
 #ifdef HAVE_KF5
         Quassel::instance()->init(runMode);
 
 #ifdef HAVE_KF5
diff --git a/src/common/qt5cliparser.cpp b/src/common/qt5cliparser.cpp
deleted file mode 100644 (file)
index a302619..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/***************************************************************************
- *   Copyright (C) 2005-2018 by the Quassel Project                        *
- *   devel@quassel-irc.org                                                 *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) version 3.                                           *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
- ***************************************************************************/
-
-#include "qt5cliparser.h"
-
-#include <QCoreApplication>
-#include <QDebug>
-
-bool Qt5CliParser::init(const QStringList &arguments)
-{
-    _qCliParser.addHelpOption();
-    _qCliParser.addVersionOption();
-    _qCliParser.setApplicationDescription(QCoreApplication::translate("CliParser", "Quassel IRC is a modern, distributed IRC client."));
-
-    _qCliParser.process(arguments);
-    return true; // process() does error handling by itself
-}
-
-
-bool Qt5CliParser::isSet(const QString &longName)
-{
-
-    return _qCliParser.isSet(longName);
-}
-
-
-QString Qt5CliParser::value(const QString &longName)
-{
-    return _qCliParser.value(longName);
-}
-
-
-void Qt5CliParser::usage()
-{
-    _qCliParser.showHelp();
-}
-
-
-void Qt5CliParser::addArgument(const QString &longName, const AbstractCliParser::CliParserArg &arg)
-{
-    QStringList names(longName);
-    if (arg.shortName != 0)
-        names << QString(arg.shortName);
-
-    switch(arg.type) {
-    case CliParserArg::CliArgSwitch:
-        _qCliParser.addOption(QCommandLineOption(names, arg.help));
-        break;
-    case CliParserArg::CliArgOption:
-        _qCliParser.addOption(QCommandLineOption(names, arg.help, arg.valueName, arg.def));
-        break;
-    default:
-        qWarning() << "Warning: Unrecognized argument:" << longName;
-    }
-}
diff --git a/src/common/qt5cliparser.h b/src/common/qt5cliparser.h
deleted file mode 100644 (file)
index 13dca78..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/***************************************************************************
- *   Copyright (C) 2005-2018 by the Quassel Project                        *
- *   devel@quassel-irc.org                                                 *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) version 3.                                           *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
- ***************************************************************************/
-
-#pragma once
-
-#include <QCommandLineParser>
-
-#include "abstractcliparser.h"
-
-
-class Qt5CliParser : public AbstractCliParser
-{
-public:
-    bool init(const QStringList &arguments = QStringList());
-
-    QString value(const QString &longName);
-    bool isSet(const QString &longName);
-    void usage();
-
-private:
-    void addArgument(const QString &longName, const CliParserArg &arg);
-
-    QCommandLineParser _qCliParser;
-
-};
index ee8876f..f83cbc7 100644 (file)
@@ -73,22 +73,14 @@ void Quassel::init(RunMode runMode)
     // Initial translation (may be overridden in UI settings)
     loadTranslation(QLocale::system());
 
     // Initial translation (may be overridden in UI settings)
     loadTranslation(QLocale::system());
 
-    Network::setDefaultCodecForServer("UTF-8");
-    Network::setDefaultCodecForEncoding("UTF-8");
-    Network::setDefaultCodecForDecoding("ISO-8859-15");
-
-    if (isOptionSet("help")) {
-        instance()->_cliParser->usage();
-        return;
-    }
-
-    if (isOptionSet("version")) {
-        std::cout << qPrintable("Quassel IRC: " + Quassel::buildInfo().plainVersionString) << std::endl;
-        return;
-    }
+    setupCliParser();
 
     // Don't keep a debug log on the core
     logger()->setup(runMode != RunMode::CoreOnly);
 
     // Don't keep a debug log on the core
     logger()->setup(runMode != RunMode::CoreOnly);
+
+    Network::setDefaultCodecForServer("UTF-8");
+    Network::setDefaultCodecForEncoding("UTF-8");
+    Network::setDefaultCodecForDecoding("ISO-8859-15");
 }
 
 
 }
 
 
@@ -335,21 +327,95 @@ Quassel::RunMode Quassel::runMode() {
 }
 
 
 }
 
 
-void Quassel::setCliParser(std::shared_ptr<AbstractCliParser> parser)
+void Quassel::setupCliParser()
 {
 {
-    instance()->_cliParser = std::move(parser);
+    QList<QCommandLineOption> options;
+
+    // General options
+    /// @todo Bring back --datadir to specify the database location independent of config
+    if (runMode() == RunMode::ClientOnly) {
+        options += {{"c", "configdir"}, tr("Specify the directory holding the client configuration."), tr("path")};
+    }
+    else {
+        options += {{"c", "configdir"}, tr("Specify the directory holding configuration files, the SQlite database and the SSL certificate."), tr("path")};
+    }
+
+    // Client options
+    if (runMode() != RunMode::CoreOnly) {
+        options += {
+            {"icontheme", tr("Override the system icon theme ('breeze' is recommended)."), tr("theme")},
+            {"qss", tr("Load a custom application stylesheet."), tr("file.qss")},
+            {"hidewindow", tr("Start the client minimized to the system tray.")},
+        };
+    }
+
+    // Core options
+    if (runMode() != RunMode::ClientOnly) {
+        options += {
+            {"listen", tr("The address(es) quasselcore will listen on."), tr("<address>[,<address>[,...]]"), "::,0.0.0.0"},
+            {{"p", "port"}, tr("The port quasselcore will listen at."), tr("port"), "4242"},
+            {{"n", "norestore"}, tr("Don't restore last core's state.")},
+            {"config-from-environment", tr("Load configuration from environment variables.")},
+            {"select-backend", tr("Switch storage backend (migrating data if possible)."), tr("backendidentifier")},
+            {"select-authenticator", tr("Select authentication backend."), tr("authidentifier")},
+            {"add-user", tr("Starts an interactive session to add a new core user.")},
+            {"change-userpass", tr("Starts an interactive session to change the password of the user identified by <username>."), tr("username")},
+            {"strict-ident", tr("Use users' quasselcore username as ident reply. Ignores each user's configured ident setting.")},
+            {"ident-daemon", tr("Enable internal ident daemon.")},
+            {"ident-port", tr("The port quasselcore will listen at for ident requests. Only meaningful with --ident-daemon."), tr("port"), "10113"},
+            {"oidentd", tr("Enable oidentd integration. In most cases you should also enable --strict-ident.")},
+            {"oidentd-conffile", tr("Set path to oidentd configuration file."), tr("file")},
+#ifdef HAVE_SSL
+            {"require-ssl", tr("Require SSL for remote (non-loopback) client connections.")},
+            {"ssl-cert", tr("Specify the path to the SSL certificate."), tr("path"), "configdir/quasselCert.pem"},
+            {"ssl-key", tr("Specify the path to the SSL key."), tr("path"), "ssl-cert-path"},
+#endif
+        };
+    }
+
+    // Logging options
+    options += {
+        {{"L", "loglevel"}, tr("Supports one of Debug|Info|Warning|Error; default is Info."), tr("level"), "Info"},
+        {{"l", "logfile"}, tr("Log to a file."), "path"},
+#ifdef HAVE_SYSLOG
+        {"syslog", tr("Log to syslog.")},
+#endif
+    };
+
+    // Debug options
+    options += {{"d", "debug"}, tr("Enable debug output.")};
+    if (runMode() != RunMode::CoreOnly) {
+        options += {
+            {"debugbufferswitches", tr("Enables debugging for bufferswitches.")},
+            {"debugmodel", tr("Enables debugging for models.")},
+        };
+    }
+    if (runMode() != RunMode::ClientOnly) {
+        options += {
+            {"debug-irc", tr("Enable logging of all raw IRC messages to debug log, including passwords!  In most cases you should also set --loglevel Debug")},
+            {"debug-irc-id", tr("Limit raw IRC logging to this network ID.  Implies --debug-irc"), tr("database network ID"), "-1"},
+        };
+    }
+
+    _cliParser.addOptions(options);
+    _cliParser.addHelpOption();
+    _cliParser.addVersionOption();
+    _cliParser.setApplicationDescription(tr("Quassel IRC is a modern, distributed IRC client."));
+
+    // This will call ::exit() for --help, --version and in case of errors
+    _cliParser.process(*QCoreApplication::instance());
 }
 
 
 QString Quassel::optionValue(const QString &key)
 {
 }
 
 
 QString Quassel::optionValue(const QString &key)
 {
-    return instance()->_cliParser ? instance()->_cliParser->value(key) : QString{};
+    return instance()->_cliParser.value(key);
 }
 
 
 bool Quassel::isOptionSet(const QString &key)
 {
 }
 
 
 bool Quassel::isOptionSet(const QString &key)
 {
-    return instance()->_cliParser ? instance()->_cliParser->isSet(key) : false;
+    return instance()->_cliParser.isSet(key);
 }
 
 
 }
 
 
@@ -376,11 +442,7 @@ QString Quassel::configDirPath()
         return instance()->_configDirPath;
 
     QString path;
         return instance()->_configDirPath;
 
     QString path;
-    if (isOptionSet("datadir")) {
-        qWarning() << "Obsolete option --datadir used!";
-        path = Quassel::optionValue("datadir");
-    }
-    else if (isOptionSet("configdir")) {
+    if (isOptionSet("configdir")) {
         path = Quassel::optionValue("configdir");
     }
     else {
         path = Quassel::optionValue("configdir");
     }
     else {
index 097481d..2b57a31 100644 (file)
 #pragma once
 
 #include <functional>
 #pragma once
 
 #include <functional>
-#include <memory>
 #include <vector>
 
 #include <vector>
 
+#include <QCommandLineParser>
 #include <QCoreApplication>
 #include <QFile>
 #include <QCoreApplication>
 #include <QFile>
-#include <QObject>
 #include <QLocale>
 #include <QLocale>
+#include <QObject>
 #include <QString>
 #include <QStringList>
 
 #include <QString>
 #include <QStringList>
 
-#include "abstractcliparser.h"
 #include "abstractsignalwatcher.h"
 #include "singleton.h"
 
 #include "abstractsignalwatcher.h"
 #include "singleton.h"
 
@@ -185,7 +184,6 @@ public:
 
     static void loadTranslation(const QLocale &locale);
 
 
     static void loadTranslation(const QLocale &locale);
 
-    static void setCliParser(std::shared_ptr<AbstractCliParser> cliParser);
     static QString optionValue(const QString &option);
     static bool isOptionSet(const QString &option);
 
     static QString optionValue(const QString &option);
     static bool isOptionSet(const QString &option);
 
@@ -219,9 +217,10 @@ signals:
     void messageLogged(const QDateTime &timeStamp, const QString &msg);
 
 private:
     void messageLogged(const QDateTime &timeStamp, const QString &msg);
 
 private:
-    void setupEnvironment();
     void registerMetaTypes();
     void setupSignalHandling();
     void registerMetaTypes();
     void setupSignalHandling();
+    void setupEnvironment();
+    void setupCliParser();
 
     /**
      * Requests a reload of relevant runtime configuration.
 
     /**
      * Requests a reload of relevant runtime configuration.
@@ -248,7 +247,7 @@ private:
     QStringList _dataDirPaths;
     QString _translationDirPath;
 
     QStringList _dataDirPaths;
     QString _translationDirPath;
 
-    std::shared_ptr<AbstractCliParser> _cliParser;
+    QCommandLineParser _cliParser;
 
     Logger *_logger;
     AbstractSignalWatcher *_signalWatcher{nullptr};
 
     Logger *_logger;
     AbstractSignalWatcher *_signalWatcher{nullptr};
index 608d39a..7ae97df 100644 (file)
@@ -25,7 +25,6 @@
 #include <QStringList>
 
 #include "chatviewsettings.h"
 #include <QStringList>
 
 #include "chatviewsettings.h"
-#include "cliparser.h"
 #include "logmessage.h"
 #include "mainwin.h"
 #include "qtui.h"
 #include "logmessage.h"
 #include "mainwin.h"
 #include "qtui.h"
diff --git a/src/uisupport/kcmdlinewrapper.cpp b/src/uisupport/kcmdlinewrapper.cpp
deleted file mode 100644 (file)
index afab45a..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/***************************************************************************
- *   Copyright (C) 2005-2018 by the Quassel Project                        *
- *   devel@quassel-irc.org                                                 *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) version 3.                                           *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
- ***************************************************************************/
-
-#include "kcmdlinewrapper.h"
-
-#include <KCmdLineArgs>
-
-KCmdLineWrapper::KCmdLineWrapper()
-{
-}
-
-
-void KCmdLineWrapper::addArgument(const QString &longName_, const CliParserArg &arg)
-{
-    QString longName = longName_;
-    if (arg.type == CliParserArg::CliArgOption && !arg.valueName.isEmpty())
-        longName += " <" + arg.valueName + ">";
-
-    if (arg.shortName != 0) {
-        _cmdLineOptions.add(QByteArray(1, arg.shortName));
-    }
-
-    _cmdLineOptions.add(longName.toUtf8(), ki18n(arg.help.toUtf8()), arg.def.toUtf8());
-}
-
-
-bool KCmdLineWrapper::init(const QStringList &)
-{
-    KCmdLineArgs::addCmdLineOptions(_cmdLineOptions);
-    return true;
-}
-
-
-QString KCmdLineWrapper::value(const QString &longName)
-{
-    return KCmdLineArgs::parsedArgs()->getOption(longName.toUtf8());
-}
-
-
-bool KCmdLineWrapper::isSet(const QString &longName)
-{
-    // KCmdLineArgs handles --nooption like NOT --option
-    if (longName.startsWith("no"))
-        return !KCmdLineArgs::parsedArgs()->isSet(longName.mid(2).toUtf8());
-    return KCmdLineArgs::parsedArgs()->isSet(longName.toUtf8());
-}
-
-
-void KCmdLineWrapper::usage()
-{
-    KCmdLineArgs::usage();
-}
diff --git a/src/uisupport/kcmdlinewrapper.h b/src/uisupport/kcmdlinewrapper.h
deleted file mode 100644 (file)
index 317d438..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/***************************************************************************
- *   Copyright (C) 2005-2018 by the Quassel Project                        *
- *   devel@quassel-irc.org                                                 *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) version 3.                                           *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
- ***************************************************************************/
-
-#ifndef KCMDLINEWRAPPER_H
-#define KCMDLINEWRAPPER_H
-
-#include "abstractcliparser.h"
-
-#include <KCmdLineOptions>
-
-//! Wrapper for KCmdLineOptions
-class KCmdLineWrapper : public AbstractCliParser
-{
-public:
-    KCmdLineWrapper();
-
-    bool init(const QStringList &arguments = QStringList());
-
-    QString value(const QString &longName);
-    bool isSet(const QString &longName);
-    void usage();
-
-private:
-    void addArgument(const QString &longName, const CliParserArg &arg);
-
-    KCmdLineOptions _cmdLineOptions;
-};
-
-
-#endif