summaryrefslogtreecommitdiffhomepage
path: root/opentrack/options.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'opentrack/options.hpp')
-rw-r--r--opentrack/options.hpp123
1 files changed, 80 insertions, 43 deletions
diff --git a/opentrack/options.hpp b/opentrack/options.hpp
index 6c15d729..5eae754f 100644
--- a/opentrack/options.hpp
+++ b/opentrack/options.hpp
@@ -26,17 +26,21 @@
#include <QSlider>
#include <QLineEdit>
#include <QLabel>
+#include <QTabWidget>
#include <QCoreApplication>
#include <cinttypes>
#include <QDebug>
+#include <memory>
+template<typename t> using mem = std::shared_ptr<t>;
+
namespace options {
template<typename k, typename v>
using map = std::map<k, v>;
using std::string;
-
+
template<typename t>
// don't elide usages of the function, qvariant default implicit
// conversion results in nonsensical runtime behavior -sh
@@ -77,12 +81,6 @@ namespace options {
private:
map<string, QVariant> kvs;
string name;
- static const QString ini_pathname()
- {
- QSettings settings(group::org);
- return settings.value("SettingsFile",
- QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString();
- }
public:
group(const string& name) : name(name)
{
@@ -97,8 +95,8 @@ namespace options {
}
conf.endGroup();
}
- static constexpr const char* org = "opentrack";
-
+ static constexpr const char* org = "opentrack-2.3";
+
void save()
{
QSettings s(ini_pathname(), QSettings::IniFormat);
@@ -110,26 +108,41 @@ namespace options {
s.setValue(k, i.second);
}
s.endGroup();
+ s.sync();
}
-
+
template<typename t>
t get(const string& k)
{
return qcruft_to_t<t>(kvs[k]);
}
-
+
void put(const string& s, const QVariant& d)
{
kvs[s] = d;
}
-
+
bool contains(const string& s)
{
return kvs.count(s) != 0;
}
+
+ static constexpr const char* filename_key = "settings-file";
+ static constexpr const char* default_path = "/settings/default.ini";
+
+ static const QString ini_pathname()
+ {
+ QSettings settings(group::org);
+ return settings.value(filename_key, QCoreApplication::applicationDirPath() + default_path).toString();
+ }
+ static const mem<QSettings> ini_file()
+ {
+ return std::make_shared<QSettings>(ini_pathname(), QSettings::IniFormat);
+ }
};
class impl_bundle : public QObject {
+ Q_OBJECT
protected:
QMutex mtx;
const string group_name;
@@ -138,6 +151,9 @@ namespace options {
bool modified;
impl_bundle(const impl_bundle&) = delete;
impl_bundle& operator=(const impl_bundle&) = delete;
+ signals:
+ void reloading();
+ void saving();
public:
impl_bundle(const string& group_name) :
mtx(QMutex::Recursive),
@@ -147,28 +163,29 @@ namespace options {
modified(false)
{
}
-
+
string name() { return group_name; }
-
+
void reload() {
- QMutexLocker l(&mtx);
- saved = group(group_name);
- transient = saved;
- modified = false;
+ {
+ QMutexLocker l(&mtx);
+ saved = group(group_name);
+ transient = saved;
+ modified = false;
+ }
+ emit reloading();
}
-
- bool store_kv(const string& name, const QVariant& datum)
+
+ void store_kv(const string& name, const QVariant& datum)
{
QMutexLocker l(&mtx);
-
+
auto old = transient.get<QVariant>(name);
if (!transient.contains(name) || datum != old)
{
modified = true;
transient.put(name, datum);
- return true;
}
- return false;
}
bool contains(const string& name)
{
@@ -183,10 +200,13 @@ namespace options {
}
void save()
{
- QMutexLocker l(&mtx);
- modified = false;
- saved = transient;
- transient.save();
+ {
+ QMutexLocker l(&mtx);
+ modified = false;
+ saved = transient;
+ transient.save();
+ }
+ emit saving();
}
bool modifiedp() {
@@ -194,9 +214,9 @@ namespace options {
return modified;
}
};
-
+
class opt_bundle;
-
+
namespace
{
template<typename k, typename v, typename cnt = int>
@@ -210,51 +230,52 @@ namespace options {
map<k, tt> implsgl_data;
public:
opt_singleton() : implsgl_mtx(QMutex::Recursive) {}
-
+
static opt_singleton<k, v>& datum()
{
static auto ret = std::make_shared<opt_singleton<k, v>>();
return *ret;
}
-
+
pbundle bundle(const k& key)
{
QMutexLocker l(&implsgl_mtx);
-
+
if (implsgl_data.count(key) != 0)
return std::get<1>(implsgl_data[key]);
+ qDebug() << "bundle +" << QString::fromStdString(key);
+
auto shr = std::make_shared<v>(key);
implsgl_data[key] = tt(cnt(1), shr);
return shr;
}
-
+
void bundle_decf(const k& key)
{
QMutexLocker l(&implsgl_mtx);
-
+
if (--std::get<0>(implsgl_data[key]) == 0)
implsgl_data.erase(key);
}
-
+
~opt_singleton() { implsgl_data.clear(); }
};
-
+
using pbundle = std::shared_ptr<opt_bundle>;
using t_fact = opt_singleton<string, opt_bundle>;
}
-
+
static inline t_fact::pbundle bundle(const string name) { return t_fact::datum().bundle(name); }
-
+
class opt_bundle : public impl_bundle
{
public:
opt_bundle() : impl_bundle("i-have-no-name") {}
opt_bundle(const string& group_name) : impl_bundle(group_name)
{
- qDebug() << "bundle +" << QString::fromStdString(group_name);
}
-
+
~opt_bundle()
{
qDebug() << "bundle -" << QString::fromStdString(group_name);
@@ -281,16 +302,18 @@ namespace options {
template<typename t>
void store(const t& datum)
{
- if (b->store_kv(self_name, datum))
- emit valueChanged(static_cast<t>(datum));
+ b->store_kv(self_name, datum);
+ emit valueChanged(static_cast<t>(datum));
}
public slots:
DEFINE_SLOT(double)
DEFINE_SLOT(int)
DEFINE_SLOT(QString)
DEFINE_SLOT(bool)
+ public slots:
+ virtual void reload() = 0;
};
-
+
static inline string string_from_qstring(const QString& datum)
{
auto tmp = datum.toUtf8();
@@ -309,6 +332,9 @@ namespace options {
static constexpr const Qt::ConnectionType SAFE_CONNTYPE = Qt::UniqueConnection;
value(pbundle b, const string& name, t def) : base_value(b, name)
{
+ QObject::connect(b.get(), SIGNAL(reloading()),
+ this, SLOT(reload()),
+ DIRECT_CONNTYPE);
if (!b->contains(name) || b->get<QVariant>(name).type() == QVariant::Invalid)
*this = def;
}
@@ -319,6 +345,9 @@ namespace options {
{
return b->get<t>(self_name);
}
+ void reload() override {
+ *this = static_cast<t>(*this);
+ }
};
template<typename t, typename q>
@@ -389,4 +418,12 @@ namespace options {
lb->setText(v);
base_value::connect(&v, SIGNAL(valueChanged(QString)), lb, SLOT(setText(QString)), v.SAFE_CONNTYPE);
}
+
+ template<>
+ inline void tie_setting(value<int>& v, QTabWidget* t)
+ {
+ t->setCurrentIndex(v);
+ base_value::connect(t, SIGNAL(currentChanged(int)), &v, SLOT(setValue(int)), v.DIRECT_CONNTYPE);
+ base_value::connect(&v, SIGNAL(valueChanged(int)), t, SLOT(setCurrentIndex(int)), v.SAFE_CONNTYPE);
+ }
}