feat(DGIOSettings): replace QGSettings

和QGSettings接口基本一致,但是去掉了驼峰命名转换。
This commit is contained in:
justforlxz 2019-08-07 16:09:12 +08:00
parent c1e47429f1
commit f6abd96c77
7 changed files with 436 additions and 0 deletions

View File

@ -13,6 +13,7 @@ set (QGIO_PUBLIC_HEADER_FILES
include/dgiofileinfo.h include/dgiofileinfo.h
include/dgiofileiterator.h include/dgiofileiterator.h
include/dgiodrive.h include/dgiodrive.h
include/dgiosettings.h
) )
set (QGIO_PRIVATE_HEADER_FILES set (QGIO_PRIVATE_HEADER_FILES
@ -29,6 +30,7 @@ set (QGIO_PRIVATE_CPP_FILES
source/dgiofileinfo.cpp source/dgiofileinfo.cpp
source/dgiofileiterator.cpp source/dgiofileiterator.cpp
source/dgiodrive.cpp source/dgiodrive.cpp
source/dgiosettings.cpp
private/dgiohelper.cpp private/dgiohelper.cpp
) )

View File

@ -0,0 +1,58 @@
/*
* Copyright (C) 2011 ~ 2019 Deepin Technology Co., Ltd.
*
* Author: justforlxz <justforlxz@outlook.com>
*
* Maintainer: justforlxz <justforlxz@outlook.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DGIOSETTINGS_H
#define DGIOSETTINGS_H
#include <QObject>
#include <QScopedPointer>
class DGIOSettingsPrivate;
class DGIOSettings : public QObject
{
Q_OBJECT
public:
explicit DGIOSettings(const QString& schemaId, QObject* parent = nullptr);
DGIOSettings(const QString& schemaId, const QString& path, QObject* parent = nullptr);
~DGIOSettings();
void sync();
bool setValue(const QString& key, const QVariant& value, bool sync = false);
QVariant value(const QString& key) const;
Q_DECL_DEPRECATED QStringList keys() const;
void reset(const QString& key);
static bool isSchemaInstalled(const QString& schemaId);
Q_SIGNALS:
void valueChanged(const QString& key, const QVariant& value);
private:
QScopedPointer<DGIOSettingsPrivate> d_private;
Q_DECLARE_PRIVATE_D(d_private, DGIOSettings)
};
#endif // DGIOSETTINGS_H

View File

@ -73,5 +73,15 @@ QStringList getThemedIconNames(Glib::RefPtr<const Gio::Icon> icon)
return iconNames; return iconNames;
} }
gchar *converToGChar(const QByteArray &array) {
GString *str = g_string_new(nullptr);
for (const QChar c : array) {
g_string_append_c(str, c.toLower().toLatin1());
}
return g_string_free(str, FALSE);
}
} }

View File

@ -27,6 +27,7 @@
namespace DGioPrivate { namespace DGioPrivate {
QStringList getThemedIconNames(Glib::RefPtr<const Gio::Icon> icon); QStringList getThemedIconNames(Glib::RefPtr<const Gio::Icon> icon);
gchar * converToGChar(const QByteArray& array);
} }
#endif // DGIOHELPER_H #endif // DGIOHELPER_H

View File

@ -0,0 +1,325 @@
/*
* Copyright (C) 2011 ~ 2019 Deepin Technology Co., Ltd.
*
* Author: justforlxz <justforlxz@outlook.com>
*
* Maintainer: justforlxz <justforlxz@outlook.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "dgiosettings.h"
#include "private/dgiohelper.h"
#include <QVariant>
#include <QDebug>
#include <glib.h>
#include <gio/gio.h>
static QVariant qconf_types_to_qvariant(GVariant* value)
{
switch (g_variant_classify(value)) {
case G_VARIANT_CLASS_BOOLEAN:
return QVariant(static_cast<bool>(g_variant_get_boolean(value)));
case G_VARIANT_CLASS_BYTE:
return QVariant(static_cast<char>(g_variant_get_byte(value)));
case G_VARIANT_CLASS_INT16:
return QVariant(static_cast<int>(g_variant_get_int16(value)));
case G_VARIANT_CLASS_UINT16:
return QVariant(static_cast<unsigned int>(g_variant_get_uint16(value)));
case G_VARIANT_CLASS_INT32:
return QVariant(static_cast<int>(g_variant_get_int32(value)));
case G_VARIANT_CLASS_UINT32:
return QVariant(static_cast<unsigned int>(g_variant_get_uint32(value)));
case G_VARIANT_CLASS_INT64:
return QVariant(static_cast<long long>(g_variant_get_int64(value)));
case G_VARIANT_CLASS_UINT64:
return QVariant(static_cast<unsigned long long>(g_variant_get_uint64(value)));
case G_VARIANT_CLASS_DOUBLE:
return QVariant(g_variant_get_double(value));
case G_VARIANT_CLASS_STRING:
return QVariant(g_variant_get_string(value, nullptr));
case G_VARIANT_CLASS_ARRAY:
if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING_ARRAY)) {
GVariantIter iter;
QStringList list;
const gchar *str;
g_variant_iter_init (&iter, value);
while (g_variant_iter_next(&iter, "&s", &str)) {
list.append (str);
}
return QVariant(list);
}
else if (g_variant_is_of_type(value, G_VARIANT_TYPE_BYTESTRING)) {
return QVariant(QByteArray(g_variant_get_bytestring(value)));
}
else if (g_variant_is_of_type(value, G_VARIANT_TYPE("a{ss}"))) {
GVariantIter iter;
QMap<QString, QVariant> map;
const gchar* key;
const gchar* val;
g_variant_iter_init (&iter, value);
while (g_variant_iter_next(&iter, "{&s&s}", &key, &val)) {
map.insert(key, QVariant(val));
}
return map;
}
}
qWarning() << "No matching type! " << g_variant_classify(value);
return QVariant();
}
static GVariant *qconf_types_collect_from_variant(const GVariantType* gtype, const QVariant& v)
{
switch (g_variant_type_peek_string(gtype)[0]) {
case G_VARIANT_CLASS_BOOLEAN:
return g_variant_new_boolean(v.toBool());
case G_VARIANT_CLASS_BYTE:
return g_variant_new_byte(v.toChar().cell());
case G_VARIANT_CLASS_INT16:
return g_variant_new_int16(v.toInt());
case G_VARIANT_CLASS_UINT16:
return g_variant_new_uint16(v.toUInt());
case G_VARIANT_CLASS_INT32:
return g_variant_new_int32(v.toInt());
case G_VARIANT_CLASS_UINT32:
return g_variant_new_uint32(v.toUInt());
case G_VARIANT_CLASS_INT64:
return g_variant_new_int64(v.toLongLong());
case G_VARIANT_CLASS_UINT64:
return g_variant_new_int64(v.toULongLong());
case G_VARIANT_CLASS_DOUBLE:
return g_variant_new_double(v.toDouble());
case G_VARIANT_CLASS_STRING:
return g_variant_new_string(v.toString().toUtf8());
case G_VARIANT_CLASS_ARRAY:
if (g_variant_type_equal(gtype, G_VARIANT_TYPE_STRING_ARRAY)) {
const QStringList list = v.toStringList();
GVariantBuilder builder;
g_variant_builder_init(&builder, G_VARIANT_TYPE_STRING_ARRAY);
for (const QString& string : list) {
g_variant_builder_add(&builder, "s", string.toUtf8().constData());
}
return g_variant_builder_end(&builder);
}
else if (g_variant_type_equal(gtype, G_VARIANT_TYPE_BYTESTRING)) {
const QByteArray& array = v.toByteArray();
gsize size = static_cast<gsize>(array.size());
gpointer data;
data = g_memdup(array.data(), static_cast<guint>(size));
return g_variant_new_from_data(G_VARIANT_TYPE_BYTESTRING,
data, size, TRUE, g_free, data);
}
else if (g_variant_type_equal(gtype, G_VARIANT_TYPE("a{ss}"))) {
GVariantBuilder builder;
g_variant_builder_init(&builder, G_VARIANT_TYPE ("a{ss}"));
QMapIterator<QString, QVariant> it(v.toMap());
while (it.hasNext()) {
it.next();
const QByteArray& key = it.key().toUtf8();
const QByteArray& val = it.value().toByteArray();
g_variant_builder_add (&builder, "{ss}", key.constData(), val.constData());
}
return g_variant_builder_end (&builder);
}
}
qWarning() << "No matching type! " << g_variant_type_peek_string(gtype)[0];
return nullptr;
}
class DGIOSettingsPrivate
{
public:
DGIOSettingsPrivate(DGIOSettings* qq)
: ptr(qq)
{
}
QString schemaId;
QString path;
DGIOSettings* ptr;
GSettings* settings;
GSettingsSchema* schema;
gulong signalHandlerId;
QVariant value(GSettings* gsettings, const QString& key) const {
gchar* gkey = DGioPrivate::converToGChar(key.toUtf8());
GVariant* variant = g_settings_get_value(gsettings, gkey);
QVariant qvalue = qconf_types_to_qvariant(variant);
g_variant_unref(variant);
g_free(gkey);
return qvalue;
}
bool trySet(const QString& key, const QVariant& value)
{
const gchar* gkey = key.toUtf8().constData();
bool success = false;
/* fetch current value to find out the exact type */
GVariant* cur = g_settings_get_value(settings, gkey);
GVariant* new_value = qconf_types_collect_from_variant(g_variant_get_type(cur), value);
if (new_value) {
success = g_settings_set_value(settings, gkey, new_value);
}
g_variant_unref(cur);
return success;
}
void sync() {
g_settings_sync();
}
static void onSettingChanged(GSettings* settings, const gchar* key, gpointer pointer) {
DGIOSettingsPrivate* self = static_cast<DGIOSettingsPrivate*>(pointer);
Q_EMIT self->ptr->valueChanged(key, self->value(settings, key));
}
};
DGIOSettings::DGIOSettings(const QString& schemaId, QObject* parent)
: DGIOSettings(schemaId, QString(), parent)
{
}
DGIOSettings::DGIOSettings(const QString& schemaId, const QString& path, QObject* parent)
: QObject(parent)
, d_private(new DGIOSettingsPrivate(this))
{
d_private->schemaId = schemaId;
d_private->path = path;
d_private->settings = path.isEmpty()
? g_settings_new(d_private->schemaId.toUtf8().constData())
: g_settings_new_with_path(d_private->schemaId.toUtf8().constData(),
path.toUtf8().constData());
g_object_get(d_private->settings, "settings-schema", &d_private->schema, nullptr);
d_private->signalHandlerId = g_signal_connect(d_private->settings, "changed", G_CALLBACK(DGIOSettingsPrivate::onSettingChanged), d_ptr.data());
}
DGIOSettings::~DGIOSettings()
{
Q_D(DGIOSettings);
if (d->schema) {
g_settings_sync ();
g_signal_handler_disconnect(d->settings, d->signalHandlerId);
g_object_unref (d->settings);
g_settings_schema_unref (d->schema);
}
}
bool DGIOSettings::setValue(const QString& key, const QVariant& value, bool sync)
{
Q_D(DGIOSettings);
if (!d->trySet(key, value)) {
qWarning() << QString("unable to set key %1 to value %2").arg(key).arg(value.toString());
return false;
}
if (sync) {
d->sync();
}
return true;
}
QVariant DGIOSettings::value(const QString& key) const
{
Q_D(const DGIOSettings);
return d->value(d->settings, key);
}
QStringList DGIOSettings::keys() const
{
Q_D(const DGIOSettings);
QStringList list;
gchar** keys = g_settings_list_keys(d->settings);
for (int i = 0; keys[i]; i++) {
list.append(keys[i]);
}
g_strfreev(keys);
return list;
}
void DGIOSettings::reset(const QString& key)
{
Q_D(DGIOSettings);
g_settings_reset(d->settings, key.toUtf8().constData());
}
void DGIOSettings::sync()
{
Q_D(DGIOSettings);
d->sync();
}
bool DGIOSettings::isSchemaInstalled(const QString& schemaId)
{
GSettingsSchemaSource* source = g_settings_schema_source_get_default();
if (GSettingsSchema* schema = g_settings_schema_source_lookup(source, schemaId.toUtf8().constData(), true)) {
g_settings_schema_unref (schema);
return true;
}
else {
return false;
}
}

View File

@ -23,3 +23,5 @@ dgio_create_test (tst_matchgioenum tst_matchgioenum.cpp YES)
# Simple FileInfo # Simple FileInfo
dgio_create_test (tst_simplefileinfo tst_simplefileinfo.cpp NO) dgio_create_test (tst_simplefileinfo tst_simplefileinfo.cpp NO)
dgio_create_test (tst_dgiosettings tst_dgiosettings.cpp NO)

38
test/tst_dgiosettings.cpp Normal file
View File

@ -0,0 +1,38 @@
#include <QString>
#include <QtTest>
#include <dgiofile.h>
#include <dgiofileinfo.h>
#include "dgiosettings.h"
class DGioSettingsTest : public QObject {
Q_OBJECT
public:
DGioSettingsTest() {}
private Q_SLOTS:
void testCase_Settings() {
if (DGIOSettings::isSchemaInstalled("com.deepin.dde.appearance") == false) {
qWarning() << "com.deepin.dde.appearance" << "invalid";
return;
}
DGIOSettings settings("com.deepin.dde.appearance", this);
QVERIFY(settings.value("background-uris").isValid());
QVERIFY(settings.value("extra-picture-uris").isValid());
const QStringList& tmpValue = settings.value("extra-picture-uris").toStringList();
settings.setValue("extra-picture-uris", QStringList());
settings.setValue("extra-picture-uris", QStringList() << "ddd");
settings.sync();
QVERIFY(settings.value("extra-picture-uris").toStringList() == QStringList() << "ddd");
settings.setValue("extra-picture-uris", tmpValue, true);
QVERIFY(settings.value("extra-picture-uris").toStringList() == tmpValue);
QVERIFY(settings.keys().contains("extra-picture-uris"));
}
};
QTEST_APPLESS_MAIN(DGioSettingsTest)
#include "tst_dgiosettings.moc"