summaryrefslogtreecommitdiffhomepage
path: root/facetracknoir/options.hpp
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2013-12-31 08:40:02 +0100
committerStanislaw Halik <sthalik@misaki.pl>2013-12-31 08:40:02 +0100
commit904add389667ff9d97cde3930a881fae89c3fb50 (patch)
treea7b828d66d0b5fee6a3d643d2581451a57cf0fe0 /facetracknoir/options.hpp
parentb7eb4245fe6dc261a926d31331b2af3fec959401 (diff)
options: fix some bugs
Diffstat (limited to 'facetracknoir/options.hpp')
-rw-r--r--facetracknoir/options.hpp96
1 files changed, 63 insertions, 33 deletions
diff --git a/facetracknoir/options.hpp b/facetracknoir/options.hpp
index 900f06c0..1305bd0a 100644
--- a/facetracknoir/options.hpp
+++ b/facetracknoir/options.hpp
@@ -7,11 +7,13 @@
#pragma once
-#include <QSettings>
+#include <QObject>
#include <QSettings>
#include <QMap>
#include <QString>
#include <QVariant>
+#include <QMutex>
+#include <QMutexLocker>
#include <memory>
#include <cassert>
#include <QWidget>
@@ -21,6 +23,13 @@
#include <QSpinBox>
#include <QSlider>
#include <QLineEdit>
+#include <QCoreApplication>
+
+#ifdef __GNUC__
+# define ov override
+#else
+# define ov
+#endif
namespace options {
template<typename T>
@@ -101,8 +110,10 @@ namespace options {
}
};
- class impl_bundle {
+ class impl_bundle : public QObject {
+ Q_OBJECT
private:
+ QMutex mtx;
const QString group_name;
group saved;
group transient;
@@ -111,6 +122,7 @@ namespace options {
bool modified;
public:
impl_bundle(const QString& group_name) :
+ mtx(QMutex::Recursive),
group_name(group_name),
saved(group_name),
transient(saved),
@@ -119,8 +131,10 @@ namespace options {
}
/* keep in mind doesn't fire signals */
void reload() {
+ QMutexLocker l(&mtx);
saved = group(group_name);
transient = saved;
+ emit reloaded();
}
std::shared_ptr<impl_bundle> make(const QString& name) {
@@ -128,33 +142,46 @@ namespace options {
}
void store(const QString& name, const QVariant& datum)
{
+ QMutexLocker l(&mtx);
if (!transient.contains(name) || datum != transient.get<QVariant>(name))
{
modified = true;
transient.put(name, datum);
+ emit bundleChanged();
}
}
bool contains(const QString& name)
{
+ QMutexLocker l(&mtx);
return transient.contains(name);
}
template<typename T>
- T get(QString& name) {
+ T get(const QString& name) {
+ QMutexLocker l(&mtx);
return transient.get<T>(name);
}
void save()
{
+ QMutexLocker l(&mtx);
modified = false;
saved = transient;
transient.save();
}
void revert()
{
+ QMutexLocker l(&mtx);
modified = false;
transient = saved;
+ emit bundleChanged();
}
- bool modifiedp() const { return modified; }
+ bool modifiedp() {
+ QMutexLocker l(&mtx);
+ return modified;
+ }
+ signals:
+ void bundleChanged();
+ void reloaded();
};
typedef std::shared_ptr<impl_bundle> pbundle;
@@ -162,7 +189,18 @@ namespace options {
class base_value : public QObject {
Q_OBJECT
public:
+ base_value(pbundle b, const QString& name) : b(b), self_name(name) {
+ connect(b.get(), SIGNAL(reloaded()), this, SLOT(reread_value()));
+ }
virtual QVariant operator=(const QVariant& datum) = 0;
+ protected:
+ pbundle b;
+ QString self_name;
+ public slots:
+ void reread_value()
+ {
+ this->operator=(b->get<QVariant>(self_name));
+ }
public slots:
#define DEFINE_SLOT(t) void setValue(t datum) { this->operator=(datum); }
DEFINE_SLOT(double)
@@ -179,13 +217,11 @@ namespace options {
template<typename T>
class value : public base_value {
- private:
- QString self_name;
- pbundle b;
+ private: T def;
public:
- value(pbundle& b, const QString& name, T def) :
- self_name(name),
- b(b)
+ static constexpr const Qt::ConnectionType CONNTYPE = Qt::QueuedConnection;
+ value(pbundle b, const QString& name, T def) :
+ base_value(b, name), def(def)
{
if (!b->contains(name))
{
@@ -196,15 +232,9 @@ namespace options {
operator T() { return b->get<T>(self_name); }
QVariant operator=(const QVariant& datum) {
b->store(self_name, datum);
- switch (datum.type())
- {
-#define BRANCH_ON(e, m) case QVariant::e: return valueChanged(datum.m()), datum
- BRANCH_ON(Int, toInt);
- BRANCH_ON(Double, toDouble);
- BRANCH_ON(String, toString);
- BRANCH_ON(Bool, toBool);
- default: abort();
- }
+ auto foo = qcruft_to_t<T>(datum);
+ emit valueChanged(foo);
+ return datum;
}
};
@@ -214,56 +244,56 @@ namespace options {
template<>
inline void tie_setting(value<int>& v, QComboBox* cb)
{
- base_value::connect(cb, SIGNAL(currentIndexChanged(int)), &v, SLOT(setValue(int)));
- base_value::connect(&v, SIGNAL(valueChanged(int)), cb, SLOT(setCurrentIndex(int)));
+ base_value::connect(cb, SIGNAL(currentIndexChanged(int)), &v, SLOT(setValue(int)), v.CONNTYPE);
+ base_value::connect(&v, SIGNAL(valueChanged(int)), cb, SLOT(setCurrentIndex(int)), v.CONNTYPE);
cb->setCurrentIndex(v);
}
template<>
inline void tie_setting(value<QString>& v, QComboBox* cb)
{
- base_value::connect(cb, SIGNAL(currentTextChanged(QString)), &v, SLOT(setValue(int)));
- base_value::connect(&v, SIGNAL(valueChanged(QString)), cb, SLOT(setCurrentText(QString)));
+ base_value::connect(cb, SIGNAL(currentTextChanged(QString)), &v, SLOT(setValue(QString)), v.CONNTYPE);
+ base_value::connect(&v, SIGNAL(valueChanged(QString)), cb, SLOT(setCurrentText(QString)), v.CONNTYPE);
cb->setCurrentText(v);
}
template<>
inline void tie_setting(value<bool>& v, QCheckBox* cb)
{
- base_value::connect(cb, SIGNAL(toggled(bool)), &v, SLOT(setValue(bool)));
- base_value::connect(&v, SIGNAL(valueChanged(bool)), cb, SLOT(setChecked(bool)));
+ base_value::connect(cb, SIGNAL(toggled(bool)), &v, SLOT(setValue(bool)), v.CONNTYPE);
+ base_value::connect(&v, SIGNAL(valueChanged(bool)), cb, SLOT(setChecked(bool)), v.CONNTYPE);
cb->setChecked(v);
}
template<>
inline void tie_setting(value<double>& v, QDoubleSpinBox* dsb)
{
- base_value::connect(dsb, SIGNAL(valueChanged(double)), &v, SLOT(setValue(double)));
- base_value::connect(&v, SIGNAL(valueChanged(double)), dsb, SLOT(setValue(double)));
+ base_value::connect(dsb, SIGNAL(valueChanged(double)), &v, SLOT(setValue(double)), v.CONNTYPE);
+ base_value::connect(&v, SIGNAL(valueChanged(double)), dsb, SLOT(setValue(double)), v.CONNTYPE);
dsb->setValue(v);
}
template<>
inline void tie_setting(value<int>& v, QSpinBox* sb)
{
- base_value::connect(sb, SIGNAL(valueChanged(int)), &v, SLOT(setValue(int)));
- base_value::connect(&v, SIGNAL(valueChanged(int)), sb, SLOT(setValue(int)));
+ base_value::connect(sb, SIGNAL(valueChanged(int)), &v, SLOT(setValue(int)), v.CONNTYPE);
+ base_value::connect(&v, SIGNAL(valueChanged(int)), sb, SLOT(setValue(int)), v.CONNTYPE);
sb->setValue(v);
}
template<>
inline void tie_setting(value<int>& v, QSlider* sl)
{
- base_value::connect(sl, SIGNAL(valueChanged(int)), &v, SLOT(setValue(int)));
- base_value::connect(&v, SIGNAL(valueChanged(int)), sl, SLOT(setValue(int)));
+ base_value::connect(sl, SIGNAL(valueChanged(int)), &v, SLOT(setValue(int)), v.CONNTYPE);
+ base_value::connect(&v, SIGNAL(valueChanged(int)), sl, SLOT(setValue(int)), v.CONNTYPE);
sl->setValue(v);
}
template<>
inline void tie_setting(value<QString>& v, QLineEdit* le)
{
- base_value::connect(le, SIGNAL(textChanged(QString)), &v, SLOT(setValue(QString)));
- base_value::connect(&v, SIGNAL(valueChanged(QString)),le, SLOT(setText(QString)));
+ base_value::connect(le, SIGNAL(textChanged(QString)), &v, SLOT(setValue(QString)), v.CONNTYPE);
+ base_value::connect(&v, SIGNAL(valueChanged(QString)),le, SLOT(setText(QString)), v.CONNTYPE);
le->setText(v);
}