aboutsummaryrefslogtreecommitdiff
path: root/lib/settings
diff options
context:
space:
mode:
authorAqua-sama <aqua@iserlohn-fortress.net>2018-01-24 17:55:24 +0100
committerAqua-sama <aqua@iserlohn-fortress.net>2018-01-24 17:55:24 +0100
commit3ef990acb99b954beda6614815022b7f017c2b4b (patch)
tree49c6fc64eff5013becc38c257c748967a3bbc7f4 /lib/settings
parentPressing enter/return sets bookmark items (diff)
downloadsmolbote-3ef990acb99b954beda6614815022b7f017c2b4b.tar.xz
Configuration class rework
- Moved setValue to the header - Code readability - Removed secondary defaultCfg
Diffstat (limited to 'lib/settings')
-rw-r--r--lib/settings/configuration.cpp177
-rw-r--r--lib/settings/configuration.h97
-rw-r--r--lib/settings/settingsdialog.cpp7
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;
}