forked from mirrors/gio-qt
feat(DGIOSettings): replace QGSettings
和QGSettings接口基本一致,但是去掉了驼峰命名转换。
This commit is contained in:
parent
c1e47429f1
commit
f6abd96c77
7 changed files with 436 additions and 0 deletions
|
@ -13,6 +13,7 @@ set (QGIO_PUBLIC_HEADER_FILES
|
|||
include/dgiofileinfo.h
|
||||
include/dgiofileiterator.h
|
||||
include/dgiodrive.h
|
||||
include/dgiosettings.h
|
||||
)
|
||||
|
||||
set (QGIO_PRIVATE_HEADER_FILES
|
||||
|
@ -29,6 +30,7 @@ set (QGIO_PRIVATE_CPP_FILES
|
|||
source/dgiofileinfo.cpp
|
||||
source/dgiofileiterator.cpp
|
||||
source/dgiodrive.cpp
|
||||
source/dgiosettings.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;
|
||||
}
|
||||
|
||||
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 {
|
||||
QStringList getThemedIconNames(Glib::RefPtr<const Gio::Icon> icon);
|
||||
gchar * converToGChar(const QByteArray& array);
|
||||
}
|
||||
|
||||
#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
|
||||
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 a new issue