forked from mirrors/gio-qt
feat(DGIOSettings): replace QGSettings
和QGSettings接口基本一致,但是去掉了驼峰命名转换。
This commit is contained in:
parent
c1e47429f1
commit
f6abd96c77
@ -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
|
||||||
)
|
)
|
||||||
|
|
||||||
|
58
gio-qt/include/dgiosettings.h
Normal file
58
gio-qt/include/dgiosettings.h
Normal 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
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
325
gio-qt/source/dgiosettings.cpp
Normal file
325
gio-qt/source/dgiosettings.cpp
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
@ -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
38
test/tst_dgiosettings.cpp
Normal 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"
|
Loading…
Reference in New Issue
Block a user