diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/settings/configuration.cpp | 177 | ||||
-rw-r--r-- | lib/settings/configuration.h | 97 | ||||
-rw-r--r-- | lib/settings/settingsdialog.cpp | 7 |
3 files changed, 77 insertions, 204 deletions
diff --git a/lib/settings/configuration.cpp b/lib/settings/configuration.cpp index 64e8b38..10c284c 100644 --- a/lib/settings/configuration.cpp +++ b/lib/settings/configuration.cpp @@ -8,6 +8,7 @@ #include "configuration.h" #include <QtCore/QStandardPaths> +#include <QFile> #include <sstream> using namespace libconfig; @@ -16,40 +17,36 @@ Configuration::Configuration(const std::string &path, const std::string &home) { m_userCfg = new Config(); // prettier output - m_userCfg->setOptions(Config::OptionSemicolonSeparators | Config::OptionOpenBraceOnSeparateLine); + 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; - - m_defaultCfg = new Config(); } Configuration::~Configuration() { delete m_userCfg; - delete m_defaultCfg; } -bool Configuration::read() +bool Configuration::read(const QString &path) { - try { - m_userCfg->readFile(m_userCfgPath.c_str()); - } catch(const FileIOException &e) { - return false; - } catch(const ParseException &e) { + QFile conf(path); + + if(!conf.open(QIODevice::ReadOnly)) { return false; } - return true; -} -bool Configuration::parse(const std::string &contents) -{ try { - m_userCfg->readString(contents); + m_userCfg->readString(conf.readAll().toStdString()); + conf.close(); } catch(const ParseException &e) { return false; } + return true; } @@ -71,16 +68,6 @@ bool Configuration::writeIfNeeded(const std::string &path) return true; } -bool Configuration::parseDefaultConfiguration(const std::string &contents) -{ - try { - m_defaultCfg->readString(contents); - } catch(const ParseException &e) { - return false; - } - return true; -} - std::vector<std::string> Configuration::childrenSettings(const char *name) { std::vector<std::string> groupNames; @@ -110,77 +97,6 @@ std::vector<std::string> Configuration::childrenGroups(const char *name) return groupNames; } -void Configuration::resetValue(const char *path) -{ - if(!m_userCfg->exists(path) && m_defaultCfg->exists(path)) { - // entry doesn't exist, create path to it - // split path into array of items, sep=. - std::string s(path); - std::vector<std::string> pathTokens; - std::string::size_type prev_pos = 0, pos = 0; - while((pos = s.find('.', pos)) != std::string::npos) { - std::string substring(s.substr(prev_pos, pos - prev_pos)); - pathTokens.push_back(substring); - prev_pos = ++pos; - } - pathTokens.push_back(s.substr(prev_pos, pos - prev_pos)); // Last word - - s.clear(); - // iterate through items, creating the path along the way - for(const std::string &t : pathTokens) { - Setting &v = m_userCfg->lookup(s); - Setting &d = m_defaultCfg->lookup(s).lookup(t); - - if(!v.exists(t)) { - v.add(t, d.getType()); - } - - if(s.empty()) - s.append(t); - else - s.append('.' + t); - } - } - - // if the path doesn't exist in the defaultCfg, this will crash - - // entry exists, reset it - Setting &v = m_userCfg->lookup(path); - switch(v.getType()) { - case Setting::TypeNone: - break; - case Setting::TypeInt: - v = static_cast<int>(m_defaultCfg->lookup(path)); - break; - case Setting::TypeInt64: - v = static_cast<long>(m_defaultCfg->lookup(path)); - break; - case Setting::TypeFloat: - v = static_cast<double>(m_defaultCfg->lookup(path)); - break; - case Setting::TypeString: - v = static_cast<const char *>(m_defaultCfg->lookup(path)); - break; - case Setting::TypeBoolean: - v = static_cast<bool>(m_defaultCfg->lookup(path)); - break; - case Setting::TypeGroup: - break; - case Setting::TypeArray: - break; - case Setting::TypeList: - break; - } - - // if it's a string, it may contain a path - if(v.getType() == Setting::TypeString) { - std::string val(static_cast<const char *>(v)); - v = patchHome(val, m_homePath).c_str(); - } - - changed = true; -} - std::string Configuration::castToString(const libconfig::Setting &v) const { // cast depending on type @@ -216,75 +132,6 @@ std::string Configuration::castToString(const libconfig::Setting &v) const } } -template <typename T> -bool Configuration::setValue(std::string path, const T &val) -{ - if(m_userCfg->exists(path)) { - 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>) { - switch(setting.getType()) { - case Setting::TypeNone: - break; - - case Setting::TypeInt: - case Setting::TypeInt64: - setting = std::stoi(static_cast<std::string>(val)); - break; - - case Setting::TypeFloat: - setting = std::stod(static_cast<std::string>(val)); - break; - - case Setting::TypeString: - setting = static_cast<std::string>(val).c_str(); - break; - - case Setting::TypeBoolean: - if(static_cast<std::string>(val) == "true") { - setting = true; - } else if(static_cast<std::string>(val) == "false") { - setting = false; - } - break; - - case Setting::TypeGroup: - break; - case Setting::TypeArray: - break; - case Setting::TypeList: - break; - } - - } else { - setting = val; - } - - changed = true; - return true; - } - - // the entry doesn't exist - return false; -} - -template bool Configuration::setValue<int>(std::string path, const int &val); -template bool Configuration::setValue<unsigned int>(std::string path, const unsigned int &val); -template bool Configuration::setValue<long>(std::string path, const long &val); -template bool Configuration::setValue<unsigned long>(std::string path, const unsigned long &val); - -template bool Configuration::setValue<long long>(std::string path, const long long &val); -template bool Configuration::setValue<unsigned long long>(std::string path, const unsigned long long &val); - -template bool Configuration::setValue<float>(std::string path, const float &val); -template bool Configuration::setValue<double>(std::string path, const double &val); - -template bool Configuration::setValue<bool>(std::string path, const bool &val); - -template bool Configuration::setValue<std::string>(std::string path, const std::string &val); - std::string patchHome(const std::string &path, const std::string &home) { std::string r = path; diff --git a/lib/settings/configuration.h b/lib/settings/configuration.h index db93760..82e0c58 100644 --- a/lib/settings/configuration.h +++ b/lib/settings/configuration.h @@ -13,6 +13,7 @@ #include <optional> #include <string> #include <vector> +#include <QString> class Configuration { @@ -20,35 +21,86 @@ public: explicit Configuration(const std::string &path, const std::string &home); ~Configuration(); - bool read(); - bool parse(const std::string &contents); + bool read(const QString &path); bool writeIfNeeded(const std::string &path = std::string()); - bool parseDefaultConfiguration(const std::string &contents); - std::vector<std::string> childrenSettings(const char *name = ""); std::vector<std::string> childrenGroups(const char *name = ""); - void resetValue(const char *path); - 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)) { - const_cast<Configuration *>(this)->resetValue(path); - return value<T>(path); + return std::nullopt; } const libconfig::Setting &v = m_userCfg->lookup(path); - if constexpr(std::is_same_v<T, std::string>) - return std::optional<std::string>(castToString(v)); - else + 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); + 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>) { + switch(setting.getType()) { + case libconfig::Setting::TypeNone: + break; + + case libconfig::Setting::TypeInt: + case libconfig::Setting::TypeInt64: + setting = std::stoi(static_cast<std::string>(val)); + break; + + case libconfig::Setting::TypeFloat: + setting = std::stod(static_cast<std::string>(val)); + break; + + case libconfig::Setting::TypeString: + setting = static_cast<std::string>(val).c_str(); + break; + + case libconfig::Setting::TypeBoolean: + if(static_cast<std::string>(val) == "true") { + setting = true; + } else if(static_cast<std::string>(val) == "false") { + setting = false; + } + break; + + case libconfig::Setting::TypeGroup: + break; + case libconfig::Setting::TypeArray: + break; + case libconfig::Setting::TypeList: + break; + } + + } else { + setting = val; + } + + changed = true; + return true; + } private: std::string castToString(const libconfig::Setting &v) const; @@ -56,29 +108,10 @@ private: bool changed = false; std::string m_homePath; std::string m_userCfgPath; - libconfig::Config *m_userCfg, *m_defaultCfg; + libconfig::Config *m_userCfg; }; // replace ~ with home std::string patchHome(const std::string &path, const std::string &home); -// instantiate functions -// this needs to be done because the implementation is in the cpp file - -// Settings::setValue<> -extern template bool Configuration::setValue<int>(std::string path, const int &val); -extern template bool Configuration::setValue<unsigned int>(std::string path, const unsigned int &val); -extern template bool Configuration::setValue<long>(std::string path, const long &val); -extern template bool Configuration::setValue<unsigned long>(std::string path, const unsigned long &val); - -extern template bool Configuration::setValue<long long>(std::string path, const long long &val); -extern template bool Configuration::setValue<unsigned long long>(std::string path, const unsigned long long &val); - -extern template bool Configuration::setValue<float>(std::string path, const float &val); -extern template bool Configuration::setValue<double>(std::string path, const double &val); - -extern template bool Configuration::setValue<bool>(std::string path, const bool &val); - -extern template bool Configuration::setValue<std::string>(std::string path, const std::string &val); - #endif // CONFIGURATION_H diff --git a/lib/settings/settingsdialog.cpp b/lib/settings/settingsdialog.cpp index 2cad476..36b7d2c 100644 --- a/lib/settings/settingsdialog.cpp +++ b/lib/settings/settingsdialog.cpp @@ -71,20 +71,13 @@ inline QHBoxLayout *createEntry(Configuration *config, const std::string &path, { QLineEdit *lineEdit = new QLineEdit(widget); lineEdit->setText(QString::fromStdString(config->value<std::string>(path.c_str()).value())); - QToolButton *resetButton = new QToolButton(widget); - resetButton->setIcon(widget->style()->standardIcon(QStyle::SP_DialogResetButton)); - QObject::connect(resetButton, &QToolButton::clicked, widget, [config, path, lineEdit]() { - config->resetValue(path.c_str()); - lineEdit->setText(QString::fromStdString(config->value<std::string>(path.c_str()).value())); - }); QObject::connect(lineEdit, &QLineEdit::editingFinished, widget, [config, path, lineEdit]() { config->setValue<std::string>(path, lineEdit->text().toStdString()); }); QHBoxLayout *hBox = new QHBoxLayout(); hBox->addWidget(lineEdit); - hBox->addWidget(resetButton); return hBox; } |