diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/browser.h | 2 | ||||
| -rw-r--r-- | src/configuration.cpp | 169 | ||||
| -rw-r--r-- | src/configuration.h | 83 | ||||
| -rw-r--r-- | src/main.cpp | 11 | ||||
| -rw-r--r-- | src/widgets/mainwindowtabbar.cpp | 5 | 
5 files changed, 264 insertions, 6 deletions
| diff --git a/src/browser.h b/src/browser.h index 2cb6969..f58dce7 100644 --- a/src/browser.h +++ b/src/browser.h @@ -9,7 +9,7 @@  #ifndef BROWSER_H  #define BROWSER_H -#include "settings/configuration.h" +#include "configuration.h"  #include "singleapplication.h"  #include "webengine/webengineprofile.h"  #include <QVector> diff --git a/src/configuration.cpp b/src/configuration.cpp new file mode 100644 index 0000000..b281b70 --- /dev/null +++ b/src/configuration.cpp @@ -0,0 +1,169 @@ +/* + * This file is part of smolbote. It's copyrighted by the contributors recorded + * in the version control history of the file, available from its original + * location: https://neueland.iserlohn-fortress.net/smolbote.hg + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#include "configuration.h" +#include <QtCore/QStandardPaths> +#include <QFile> +#include <sstream> + +using namespace libconfig; + +Configuration::Configuration(const std::string &path, const std::string &home) +{ +    m_userCfg = new Config(); +    // prettier output +    m_userCfg->setOption(Config::OptionSemicolonSeparators, true); +    m_userCfg->setOption(Config::OptionColonAssignmentForGroups, false); +    m_userCfg->setOption(Config::OptionColonAssignmentForNonGroups, false); +    m_userCfg->setOption(Config::OptionOpenBraceOnSeparateLine, false); +    m_userCfg->setOption(Config::OptionFsync, true); + +    m_userCfgPath = path; +    m_homePath = home; +} + +Configuration::~Configuration() +{ +    delete m_userCfg; +} + +bool Configuration::read(const QString &path) +{ +    QFile conf(path); + +    if(!conf.open(QIODevice::ReadOnly)) { +        return false; +    } + +    try { +        m_userCfg->readString(conf.readAll().toStdString()); +        conf.close(); +    } catch(const ParseException &e) { +        return false; +    } + +    return true; +} + +bool Configuration::writeIfNeeded(const std::string &path) +{ +    if(!path.empty()) +        m_userCfgPath = path; + +    if(!changed) +        return true; + +    try { +        m_userCfg->writeFile(m_userCfgPath.c_str()); +    } catch(const FileIOException &e) { +        return false; +    } + +    changed = false; +    return true; +} + +std::vector<std::string> Configuration::childrenSettings(const char *name) +{ +    std::vector<std::string> groupNames; +    const Setting &root = m_userCfg->lookup(name); + +    for(const Setting &setting : root) { +        if(setting.getType() != Setting::TypeGroup) { +            groupNames.emplace_back(setting.getName()); +            //groupNames.push_back(setting.getName()); +        } +    } + +    return groupNames; +} + +std::vector<std::string> Configuration::childrenGroups(const char *name) +{ +    std::vector<std::string> groupNames; +    const Setting &root = m_userCfg->lookup(name); + +    for(const Setting &setting : root) { +        if(setting.getType() == Setting::TypeGroup) { +            groupNames.emplace_back(setting.getName()); +            //groupNames.push_back(setting.getName()); +        } +    } +    return groupNames; +} + +std::string castToString(const libconfig::Setting &v) +{ +    // cast depending on type +    // type checks are done during compile time +    switch(v.getType()) { +    case Setting::TypeNone: +        return std::string(); + +    case Setting::TypeInt: +        // int, unsigned int, long, unsigned long +        return std::to_string(static_cast<int32_t>(v)); + +    case Setting::TypeInt64: +        // int, unsigned int; long long, unsigned long long +        return std::to_string(static_cast<int64_t>(v)); + +    case Setting::TypeFloat: +        // float, double +        return std::to_string(static_cast<double>(v)); + +    case Setting::TypeString: +        // const char*, std::string +        return std::string(static_cast<const char *>(v)); + +    case Setting::TypeBoolean: +        // bool +        return std::string(static_cast<bool>(v) ? "true" : "false"); + +    case Setting::TypeGroup: +    case Setting::TypeArray: +    case Setting::TypeList: +        return std::string(); +    } +} + +void setFromString(libconfig::Setting &setting, const std::string &value) +{ +    switch(setting.getType()) { +        case libconfig::Setting::TypeNone: +            break; + +        case libconfig::Setting::TypeInt: +        case libconfig::Setting::TypeInt64: +            setting = std::stoi(value); +            break; + +        case libconfig::Setting::TypeFloat: +            setting = std::stod(value); +            break; + +        case libconfig::Setting::TypeString: +            setting = value.c_str(); +            break; + +        case libconfig::Setting::TypeBoolean: +            if(value == "true") { +                setting = true; +            } else if(value == "false") { +                setting = false; +            } +            break; + +        case libconfig::Setting::TypeGroup: +            break; +        case libconfig::Setting::TypeArray: +            break; +        case libconfig::Setting::TypeList: +            break; +    } +} diff --git a/src/configuration.h b/src/configuration.h new file mode 100644 index 0000000..8173a86 --- /dev/null +++ b/src/configuration.h @@ -0,0 +1,83 @@ +/* + * This file is part of smolbote. It's copyrighted by the contributors recorded + * in the version control history of the file, available from its original + * location: https://neueland.iserlohn-fortress.net/smolbote.hg + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#ifndef CONFIGURATION_H +#define CONFIGURATION_H + +#include <libconfig.h++> +#include <optional> +#include <string> +#include <vector> +#include <QString> + +std::string castToString(const libconfig::Setting &v); +void setFromString(libconfig::Setting &setting, const std::string &value); + +class Configuration +{ +public: +    explicit Configuration(const std::string &path, const std::string &home); +    ~Configuration(); + +    bool read(const QString &path); +    bool writeIfNeeded(const std::string &path = std::string()); + +    std::vector<std::string> childrenSettings(const char *name = ""); +    std::vector<std::string> childrenGroups(const char *name = ""); + +    template <typename T> +    std::optional<T> value(const char *path) const +    { +        // if setting doesn't exist, give back a nullopt +        if(!m_userCfg->exists(path)) { +            return std::nullopt; +        } + +        const libconfig::Setting &v = m_userCfg->lookup(path); +        if constexpr(std::is_same_v<T, std::string>) { +            std::string r = castToString(v); + +            // check if it's a path +            if(r.front() == '~') { +                r.replace(0, 1, m_homePath); +            } + +            return std::optional<std::string>(r); +        } else +            return std::optional<T>(static_cast<T>(v)); +    } + +    template <typename T> +    bool setValue(std::string path, const T &val) +    { +        if(!m_userCfg->exists(path)) { +            return false; +        } + +        libconfig::Setting &setting = m_userCfg->lookup(path); +        // compiler complained about operator= not taking unsinged ints, longs and long longs +        if constexpr(std::is_unsigned_v<T> && !std::is_same_v<T, bool>) { +            setting = static_cast<typename std::make_signed_t<T>>(val); +        } else if constexpr(std::is_same_v<T, std::string>) { +            setFromString(setting, val); +        } else { +            setting = val; +        } + +        changed = true; +        return true; +    } + +private: +    bool changed = false; +    std::string m_homePath; +    std::string m_userCfgPath; +    libconfig::Config *m_userCfg; +}; + +#endif // CONFIGURATION_H diff --git a/src/main.cpp b/src/main.cpp index 66df526..cce2c61 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -99,10 +99,17 @@ int main(int argc, char **argv)      instance.setConfiguration(config); -    instance.createSession(parser.value(profileOption), parser.isSet(newWindowOption), parser.positionalArguments()); +    if(parser.isSet(profileOption)) +        instance.createSession(parser.value(profileOption), parser.isSet(newWindowOption), parser.positionalArguments()); +    else +        instance.createSession(QString::fromStdString(config->value<std::string>("browser.profile").value()), parser.isSet(newWindowOption), parser.positionalArguments());  #ifdef QT_DEBUG      qDebug("Startup complete in %lldms", timer.elapsed());  #endif -    return instance.exec(); + +    // Normally we'd use +    //return instance.exec(); +    // but, Call to "exec" is ambiguous +    return static_cast<QApplication *>(&instance)->exec();  } diff --git a/src/widgets/mainwindowtabbar.cpp b/src/widgets/mainwindowtabbar.cpp index 5b7ce4b..213b2c2 100644 --- a/src/widgets/mainwindowtabbar.cpp +++ b/src/widgets/mainwindowtabbar.cpp @@ -7,11 +7,10 @@   */  #include "mainwindowtabbar.h" +#include "src/configuration.h" +#include "src/mainwindow/mainwindow.h"  #include <QContextMenuEvent>  #include <QShortcut> -#include <settings/configuration.h> - -#include "src/mainwindow/mainwindow.h"  MainWindowTabBar::MainWindowTabBar(const std::shared_ptr<Configuration> &config, MainWindow *parent)      : QTabBar(parent) | 
