1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
|
/*
* Copyright 2013 Canonical Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Author: Lars Uebernickel <lars.uebernickel@canonical.com>
*/
#include "gsettings-qml.h"
#include <QGSettings>
struct GSettingsSchemaQmlPrivate
{
QByteArray id;
QByteArray path;
bool isValid;
GSettingsSchemaQmlPrivate() : isValid(false) {}
};
struct GSettingsQmlPrivate
{
GSettingsSchemaQml *schema;
QGSettings *settings;
};
GSettingsSchemaQml::GSettingsSchemaQml(QObject *parent): QObject(parent)
{
priv = new GSettingsSchemaQmlPrivate;
}
GSettingsSchemaQml::~GSettingsSchemaQml()
{
delete priv;
}
QByteArray GSettingsSchemaQml::id() const
{
return priv->id;
}
void GSettingsSchemaQml::setId(const QByteArray &id)
{
if (!priv->id.isEmpty()) {
qWarning("GSettings.schema.id may only be set on construction");
return;
}
priv->id = id;
}
QByteArray GSettingsSchemaQml::path() const
{
return priv->path;
}
void GSettingsSchemaQml::setPath(const QByteArray &path)
{
if (!priv->path.isEmpty()) {
qWarning("GSettings.schema.path may only be set on construction");
return;
}
priv->path = path;
}
bool GSettingsSchemaQml::isValid() const
{
return priv->isValid;
}
void GSettingsSchemaQml::setIsValid(bool valid)
{
if (valid != priv->isValid) {
priv->isValid = valid;
Q_EMIT isValidChanged();
}
}
QVariantList GSettingsSchemaQml::choices(const QByteArray &key) const
{
GSettingsQml *parent = (GSettingsQml *) this->parent();
if (parent->priv->settings == NULL)
return QVariantList();
if (!parent->contains(key))
return QVariantList();
return parent->priv->settings->choices(key);
}
void GSettingsSchemaQml::reset(const QByteArray &key)
{
GSettingsQml *parent = (GSettingsQml *) this->parent();
if (parent->priv->settings != NULL) {
parent->priv->settings->reset(key);
// make sure this object gets the new value immediately and not on the
// next main loop iteration (see updateValue)
parent->settingChanged(key);
}
}
GSettingsQml::GSettingsQml(QObject *parent): QQmlPropertyMap(this, parent)
{
priv = new GSettingsQmlPrivate;
priv->schema = new GSettingsSchemaQml(this);
priv->settings = NULL;
}
GSettingsQml::~GSettingsQml()
{
delete priv;
}
GSettingsSchemaQml * GSettingsQml::schema() const
{
return priv->schema;
}
void GSettingsQml::classBegin()
{
}
void GSettingsQml::componentComplete()
{
bool schemaValid = QGSettings::isSchemaInstalled(priv->schema->id());
if (schemaValid) {
priv->settings = new QGSettings(priv->schema->id(), priv->schema->path(), this);
connect(priv->settings, &QGSettings::changed, this, &GSettingsQml::settingChanged);
Q_FOREACH(const QString &key, priv->settings->keys())
this->insert(key, priv->settings->get(key));
Q_EMIT schemaChanged();
}
// emit isValid notification only once everything is setup
priv->schema->setIsValid(schemaValid);
}
void GSettingsQml::settingChanged(const QString &key)
{
QVariant value = priv->settings->get(key);
if (this->value(key) != value) {
this->insert(key, value);
Q_EMIT changed(key, value);
}
}
QVariant GSettingsQml::updateValue(const QString& key, const QVariant &value)
{
if (priv->settings == NULL)
return QVariant();
if (priv->settings->trySet(key, value)) {
// due to QTBUG-32859, QGSettings doesn't dispatch its changed signal
// directly, but on a new main loop iteration. At that point, this
// object already has the new value set and doesn't emit its own
// changed signal (see ::settingChanged). Emit it here so that it is
// sent even when the setting is changed from qml.
Q_EMIT changed(key, value);
return value;
}
else {
qWarning("unable to set key '%s' to value '%s'", key.toUtf8().constData(), value.toString().toUtf8().constData());
return priv->settings->get(key);
}
}
|