diff options
author | Aqua-sama <aqua@iserlohn-fortress.net> | 2018-01-26 23:09:31 +0100 |
---|---|---|
committer | Aqua-sama <aqua@iserlohn-fortress.net> | 2018-01-26 23:09:31 +0100 |
commit | fcf3870b7c0f30a5991e518ad8a404a9d38c3a45 (patch) | |
tree | 3168f904fb2dd205ce1fbbac2daa0f381ec86b70 /src | |
parent | Added warning when trying to get value of non-existent options (diff) | |
download | smolbote-fcf3870b7c0f30a5991e518ad8a404a9d38c3a45.tar.xz |
Using boost::program_options instead of libconfig
Diffstat (limited to 'src')
-rw-r--r-- | src/browser.cpp | 3 | ||||
-rw-r--r-- | src/configuration.cpp | 228 | ||||
-rw-r--r-- | src/configuration.h | 54 | ||||
-rw-r--r-- | src/forms/aboutdialog.cpp | 11 | ||||
-rw-r--r-- | src/main.cpp | 17 | ||||
-rw-r--r-- | src/mainwindow/mainwindow.cpp | 6 |
6 files changed, 117 insertions, 202 deletions
diff --git a/src/browser.cpp b/src/browser.cpp index cd901e3..53ca5d6 100644 --- a/src/browser.cpp +++ b/src/browser.cpp @@ -24,12 +24,15 @@ Browser::Browser(int &argc, char *argv[]) Browser::~Browser() { + /* We can't modify config, so no point in saving it if(m_config) { //QtConcurrent::run(QThreadPool::globalInstance(), m_config.get(), &Configuration::writeIfNeeded); QtConcurrent::run([c = m_config.get()]() { qDebug("Writing configuration: %s", c->writeIfNeeded() ? "ok" : "failed"); }); } + */ + if(m_bookmarksManager) { QtConcurrent::run(QThreadPool::globalInstance(), m_bookmarksManager.get(), &BookmarksWidget::save); } diff --git a/src/configuration.cpp b/src/configuration.cpp index b281b70..4e72d18 100644 --- a/src/configuration.cpp +++ b/src/configuration.cpp @@ -7,163 +7,99 @@ */ #include "configuration.h" -#include <QtCore/QStandardPaths> -#include <QFile> -#include <sstream> +#include <QStandardPaths> +#include <fstream> -using namespace libconfig; +namespace po = boost::program_options; -Configuration::Configuration(const std::string &path, const std::string &home) +Configuration::Configuration(const QStringList &options) { - 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()); + m_homePath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation).toStdString(); + + // create description + desc.add_options() + + // Browser default settings + // default profile name the browser should use; "" is off-the-record + ("browser.profile", po::value<std::string>()->default_value("")) + + // default window size + ("browser.window.height", po::value<int>()->default_value(720)) + ("browser.window.width", po::value<int>()->default_value(1280)) + ("browser.window.maximized", po::value<bool>()->default_value(true)) + ("browser.window.title", po::value<std::string>()->default_value("title — smolbote [profile]")) + + // window ui + ("browser.ui.navtoolbarMovable", po::value<bool>()->default_value(false)) + ("browser.ui.tabtoolbarMovable", po::value<bool>()->default_value(false)) + + // browser shortcuts + + // browser menu + ("browser.shortcuts.newWindow", po::value<std::string>()->default_value("Ctrl+N")) + ("browser.shortcuts.newTab", po::value<std::string>()->default_value("Ctrl+T")) + ("browser.shortcuts.about", po::value<std::string>()->default_value("F1")) + ("browser.shortcuts.quit", po::value<std::string>()->default_value("Ctrl+Q")) + + // navigation + ("browser.shortcuts.back", po::value<std::string>()->default_value("Ctrl+Left")) + ("browser.shortcuts.forward", po::value<std::string>()->default_value("Ctrl+Right")) + ("browser.shortcuts.refresh", po::value<std::string>()->default_value("F5")) + ("browser.shortcuts.reload", po::value<std::string>()->default_value("Ctrl+F5")) + ("browser.shortcuts.home", po::value<std::string>()->default_value("Ctrl+Home")) + + // tabs + ("browser.shortcuts.tabClose", po::value<std::string>()->default_value("Ctrl+X")) + ("browser.shortcuts.tabLeft", po::value<std::string>()->default_value("Ctrl+O")) + ("browser.shortcuts.tabRight", po::value<std::string>()->default_value("Ctrl+P")) + + // page + ("browser.shortcuts.toggleSearchBox", po::value<std::string>()->default_value("F3")) + ("browser.shortcuts.focusAddress", po::value<std::string>()->default_value("F4")) + ("browser.shortcuts.fullscreen", po::value<std::string>()->default_value("F11")) + + // Filter settings + ("filter.path", po::value<std::string>()->default_value("~/.config/smolbote/hosts.d")) + + // Plugin settings + ("plugins.path", po::value<std::string>()->default_value("~/.config/smolbote/plugins.d")) + + // Profile settings + ("profile.path", po::value<std::string>()->default_value("~/.config/smolbote/profiles.d")) + ("profile.search", po::value<std::string>()->default_value("https://duckduckgo.com/?q=$term&ia=web")) + ("profile.homepage", po::value<std::string>()->default_value("about:blank")) + ("profile.newtab", po::value<std::string>()->default_value("about:blank")) + + // Bookmark settings + ("bookmarks.path", po::value<std::string>()->default_value("~/.config/smolbote/bookmarks.xbel")) + ("bookmarks.shortcut", po::value<std::string>()->default_value("Ctrl+B")) + + // Downloads settings + ("downloads.path", po::value<std::string>()->default_value("~/Downloads")) + ("downloads.shortcut", po::value<std::string>()->default_value("Ctrl+D")) + ; + + // store the defaults into the vm + { + int argc = options.length(); + const char* argv[argc]; + for(int i = 0; i < argc; ++i) { + argv[i] = qUtf8Printable(options.at(i)); } + + po::store(po::parse_command_line(argc, argv, desc), vm); } - return groupNames; } -std::vector<std::string> Configuration::childrenGroups(const char *name) +Configuration::~Configuration() { - 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) +bool Configuration::read(const QString &path) { - // 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(); - } + std::ifstream f(path.toStdString(), std::ifstream::in); + po::store(po::parse_config_file(f, desc, false), vm); + return true; } -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 index 913fa65..27988b9 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -9,39 +9,34 @@ #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); +#include <boost/program_options.hpp> +#include <QStringList> class Configuration { public: - explicit Configuration(const std::string &path, const std::string &home); + explicit Configuration(const QStringList &options = QStringList()); ~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)) { - qWarning("Requesting non-existent option %s", path); - return std::nullopt; + // if setting doesn't exist, we crash + // in debug builds, check if setting exists +#ifdef QT_DEBUG + if(vm.count(path) == 0) { + qWarning("value(%s) does not exist, probably crashing now", path); } +#endif - const libconfig::Setting &v = m_userCfg->lookup(path); if constexpr(std::is_same_v<T, std::string>) { - std::string r = castToString(v); + std::string r = vm[path].as<std::string>(); // check if it's a path if(r.front() == '~') { @@ -50,35 +45,14 @@ public: 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; + return std::optional<T>(vm[path].as<T>()); } private: - bool changed = false; + boost::program_options::options_description desc; + boost::program_options::variables_map vm; + std::string m_homePath; - std::string m_userCfgPath; - libconfig::Config *m_userCfg; }; #endif // CONFIGURATION_H diff --git a/src/forms/aboutdialog.cpp b/src/forms/aboutdialog.cpp index d9c75c3..89cb23e 100644 --- a/src/forms/aboutdialog.cpp +++ b/src/forms/aboutdialog.cpp @@ -9,11 +9,11 @@ #include "aboutdialog.h" #include "ui_aboutdialog.h" #include "version.h" -#include <libconfig.h++> +#include <boost/version.hpp> // The extra level of indirection will allow the preprocessor to expand the macros before they are converted to strings. -#define STR_HELPER(x) #x -#define STR(x) STR_HELPER(x) +#define STRINGIFY(x) #x +#define STR(x) STRINGIFY(x) // compiler // clang also defines __GNUC__, so we need to check for clang first @@ -25,9 +25,6 @@ #define compiler "unknown compiler"; #endif -// libconfig -#define LIBCONFIG_VERSION_STR STR(LIBCONFIGXX_VER_MAJOR) "." STR(LIBCONFIGXX_VER_MINOR) "." STR(LIBCONFIGXX_VER_REVISION) - AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent) , ui(new Ui::AboutDialog) @@ -64,7 +61,7 @@ AboutDialog::AboutDialog(QWidget *parent) "Compiled with " compiler "</p>" "<p><ul>" "<li>Qt " QT_VERSION_STR "</li>" - "<li>libconfig " LIBCONFIG_VERSION_STR "</li>" + "<li>Boost " BOOST_LIB_VERSION " </li>" "</ul></p>")); ui->toolBox->addItem(libsLabel, tr("Details")); } diff --git a/src/main.cpp b/src/main.cpp index cce2c61..70f22be 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -51,7 +51,6 @@ int main(int argc, char **argv) // default config, :/poi.cfg QCommandLineOption defaultConfigOption("default-config", "Set the default configuration file.", "path"); - defaultConfigOption.setDefaultValue(":/poi.cfg"); parser.addOption(defaultConfigOption); QCommandLineOption profileOption({ "p", "profile" }, "Use this profile.", "PROFILE"); @@ -76,14 +75,20 @@ int main(int argc, char **argv) qDebug("profile=%s", qUtf8Printable(parser.value(profileOption))); #endif - std::shared_ptr<Configuration> config = std::make_shared<Configuration>( - parser.value(configOption).toStdString(), - QStandardPaths::writableLocation(QStandardPaths::HomeLocation).toStdString()); + std::shared_ptr<Configuration> config = std::make_shared<Configuration>(); // first load the default configuration - config->read(parser.value(defaultConfigOption)); + if(parser.isSet(defaultConfigOption)) { + qDebug("Reading default configuration [%s]: %s", + qUtf8Printable(parser.value(defaultConfigOption)), + config->read(parser.value(defaultConfigOption)) ? "ok" : "failed"); + } // then load in the user configuration, which will overwrite it - config->read(parser.value(configOption)); + if(parser.isSet(configOption)) { + qDebug("Reading configuration [%s]: %s", + qUtf8Printable(parser.value(configOption)), + config->read(parser.value(configOption)) ? "ok" : "failed"); + } // check for other instances // if we socket hasn't been disabled (socket is not none) diff --git a/src/mainwindow/mainwindow.cpp b/src/mainwindow/mainwindow.cpp index d5efe5c..b0195a5 100644 --- a/src/mainwindow/mainwindow.cpp +++ b/src/mainwindow/mainwindow.cpp @@ -16,7 +16,7 @@ #include <bookmarks/bookmarkswidget.h> #include <downloads/downloadswidget.h> #include <src/addressbar/urllineedit.h> -#include <settings/settingsdialog.h> +//#include <settings/settingsdialog.h> MainWindow::MainWindow(std::shared_ptr<Configuration> config, QWidget *parent) : QMainWindow(parent) @@ -201,8 +201,8 @@ void MainWindow::about() void MainWindow::showSettingsDialog() { - SettingsDialog *dlg = new SettingsDialog(m_config, this); - dlg->exec(); + //SettingsDialog *dlg = new SettingsDialog(m_config, this); + //dlg->exec(); } void MainWindow::setProfile(std::shared_ptr<WebEngineProfile> profile) |