mirror of https://github.com/linuxdeepin/dtkcore
feat: Add DConfig class
DConfig 用于读取程序配置文件,符合 DSG 标准: https://gitlabwh.uniontech.com/wuhan/se/deepin-specifications/-/issues/3 当配置文件的DBus服务未注册时将直接使用 DConfigFile, 在非 Linux 系统上 使用 QSettings。 Log: Change-Id: Id4ab32f9f5fc1d870b35203a3cb4d8476d28c839
This commit is contained in:
parent
07bb75f6c0
commit
b541e07bd5
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
#include "dconfig.h"
|
|
@ -0,0 +1,40 @@
|
|||
<interface name='org.desktopspec.ConfigManager.Manager'>
|
||||
<property access="read" type="s" name="version"/>
|
||||
<property access="read" type="as" name="keyList"/>
|
||||
<property access="read" type="b" name="canRead"/>
|
||||
<property access="read" type="b" name="canWrite"/>
|
||||
<property access="read" type="b" name="canOverride"/>
|
||||
<!--为每个 key 提供一个只读属性,如:
|
||||
<property access="read" type="v" name="key1"/>
|
||||
...
|
||||
<property access="read" type="v" name="key2"/>
|
||||
-->
|
||||
<method name='value'>
|
||||
<arg type='s' name='key' direction='in'/>
|
||||
<arg type='v' name='value' direction='out'/>
|
||||
</method>
|
||||
<method name='setValue'>
|
||||
<arg type='s' name='key' direction='in'/>
|
||||
<arg type='v' name='value' direction='in'/>
|
||||
</method>
|
||||
<method name='name'>
|
||||
<arg type='s' name='key' direction='in'/>
|
||||
<arg type='s' name='language' direction='in'/>
|
||||
<arg type='s' name='name' direction='out'/>
|
||||
</method>
|
||||
<method name='description'>
|
||||
<arg type='s' name='key' direction='in'/>
|
||||
<arg type='s' name='language' direction='in'/>
|
||||
<arg type='s' name='description' direction='out'/>
|
||||
</method>
|
||||
<method name='visibility'>
|
||||
<arg type='s' name='key' direction='in'/>
|
||||
<arg type='s' name='visibility' direction='out'/>
|
||||
</method>
|
||||
<!--采用引用计数的方式,引用为 0 时才真正的销毁-->
|
||||
<method name='release'>
|
||||
</method>
|
||||
<signal name="valueChanged">
|
||||
<arg name="key" type="s" direction="out"/>'
|
||||
</signal>
|
||||
</interface>
|
|
@ -0,0 +1,8 @@
|
|||
<interface name='org.desktopspec.ConfigManager'>
|
||||
<method name='acquireManager'>
|
||||
<arg type='s' name='appid' direction='in'/>
|
||||
<arg type='s' name='name' direction='in'/>
|
||||
<arg type='s' name='subpath' direction='in'/>
|
||||
<arg type='o' name='path' direction='out'/>
|
||||
</method>
|
||||
</interface>
|
|
@ -0,0 +1,220 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Uniontech Technology Co., Ltd.
|
||||
*
|
||||
* Author: zccrs <zccrs@live.com>
|
||||
*
|
||||
* Maintainer: zccrs <zhangjide@uniontech.com>
|
||||
*
|
||||
* 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, 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 Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "dconfig.h"
|
||||
#ifndef D_DISABLE_DCONFIG
|
||||
#include "dconfigfile.h"
|
||||
#ifndef D_DISABLE_DBUS_CONFIG
|
||||
#include "configmanager_interface.h"
|
||||
#include "manager_interface.h"
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
#else
|
||||
#include <QSettings>
|
||||
#endif
|
||||
#include "dobject_p.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
#include <QCoreApplication>
|
||||
|
||||
// https://gitlabwh.uniontech.com/wuhan/se/deepin-specifications/-/issues/3
|
||||
|
||||
DCORE_BEGIN_NAMESPACE
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(cfLog)
|
||||
|
||||
#define DSG_CONFIG "org.desktopspec.ConfigManager"
|
||||
#define DSG_CONFIG_MANAGER "org.desktopspec.ConfigManager"
|
||||
|
||||
inline static QString getAppId() {
|
||||
// TODO: 应该使用更可靠的接口获取 appid
|
||||
return QCoreApplication::applicationName();
|
||||
}
|
||||
|
||||
class Q_DECL_HIDDEN DConfigPrivate : public DObjectPrivate
|
||||
{
|
||||
public:
|
||||
DConfigPrivate(DConfig *qq)
|
||||
: DObjectPrivate(qq)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QString name;
|
||||
QString subpath;
|
||||
#ifndef D_DISABLE_DCONFIG
|
||||
inline static QString getUserName() {
|
||||
uid_t uid = geteuid();
|
||||
passwd *pw = getpwuid(uid);
|
||||
return pw ? QString::fromLocal8Bit(pw->pw_name) : QString();
|
||||
}
|
||||
|
||||
#ifndef D_DISABLE_DBUS_CONFIG
|
||||
DSGConfigManager *config = nullptr;
|
||||
#endif
|
||||
QScopedPointer<DConfigFile> configFile;
|
||||
|
||||
inline QStringList keyList() const {
|
||||
#ifndef D_DISABLE_DBUS_CONFIG
|
||||
if (Q_LIKELY(config)) {
|
||||
return config->keyList();
|
||||
}
|
||||
#endif
|
||||
return configFile->keyList();
|
||||
}
|
||||
inline QVariant value(const QString &key, const QVariant &fallback) const {
|
||||
#ifndef D_DISABLE_DBUS_CONFIG
|
||||
if (Q_LIKELY(config)) {
|
||||
const QDBusVariant &dv = config->value(key);
|
||||
const QVariant &v = dv.variant();
|
||||
return v.isValid() ? v : fallback;
|
||||
}
|
||||
#endif
|
||||
return configFile->value(key, fallback);
|
||||
}
|
||||
inline void setValue(const QString &key, const QVariant &value) {
|
||||
#ifndef D_DISABLE_DBUS_CONFIG
|
||||
if (Q_LIKELY(config)) {
|
||||
config->setValue(key, QDBusVariant(value));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
configFile->setValue(key, value, getUserName(), getAppId());
|
||||
}
|
||||
#else
|
||||
QSettings *settings = nullptr;
|
||||
|
||||
inline QStringList keyList() const {
|
||||
return settings->childKeys();
|
||||
}
|
||||
inline QVariant value(const QString &key, const QVariant &fallback) const {
|
||||
return settings->value(key, fallback);
|
||||
}
|
||||
inline void setValue(const QString &key, const QVariant &value) {
|
||||
settings->setValue(key, value);
|
||||
}
|
||||
#endif
|
||||
|
||||
D_DECLARE_PUBLIC(DConfig)
|
||||
};
|
||||
|
||||
DConfig::DConfig(const QString &name, const QString &subpath,
|
||||
QObject *parent)
|
||||
: QObject(parent)
|
||||
, DObject(*new DConfigPrivate(this))
|
||||
{
|
||||
D_D(DConfig);
|
||||
d->name = name;
|
||||
d->subpath = subpath;
|
||||
}
|
||||
|
||||
bool DConfig::load()
|
||||
{
|
||||
D_D(DConfig);
|
||||
|
||||
const auto &appid = getAppId();
|
||||
Q_ASSERT(!appid.isEmpty());
|
||||
|
||||
qCDebug(cfLog, "Load config of appid=%s name=%s, subpath=%s",
|
||||
qPrintable(appid), qPrintable(d->name), qPrintable(d->subpath));
|
||||
|
||||
#ifndef D_DISABLE_DCONFIG
|
||||
bool use_dbus_config = false;
|
||||
#ifndef D_DISABLE_DBUS_CONFIG
|
||||
if (d->config)
|
||||
return true;
|
||||
|
||||
use_dbus_config = QDBusConnection::systemBus().interface()->isServiceRegistered(DSG_CONFIG);
|
||||
|
||||
if (use_dbus_config) {
|
||||
qCDebug(cfLog, "Try acquire config manager object form DBus");
|
||||
DSGConfig dsg_config(DSG_CONFIG, "/", QDBusConnection::systemBus());
|
||||
const QDBusObjectPath dbus_path = dsg_config.acquireManager(appid, d->name, d->subpath);
|
||||
if (dbus_path.path().isEmpty()) {
|
||||
qCWarning(cfLog, "Can't acquire config manager");
|
||||
return false;
|
||||
} else {
|
||||
d->config = new DSGConfigManager(DSG_CONFIG_MANAGER, dbus_path.path(),
|
||||
QDBusConnection::systemBus(), this);
|
||||
if (!d->config->isValid()) {
|
||||
delete d->config;
|
||||
d->config = nullptr;
|
||||
return false;
|
||||
} else {
|
||||
connect(d->config, &DSGConfigManager::valueChanged, this, &DConfig::valueChanged);
|
||||
use_dbus_config = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!use_dbus_config) {
|
||||
qCDebug(cfLog, "Can't use DBus config service, fallback to DConfigFile mode");
|
||||
if (d->configFile)
|
||||
return true;
|
||||
d->configFile.reset(new DConfigFile(appid, d->name, d->subpath));
|
||||
}
|
||||
#else
|
||||
qCDebug(cfLog, "Fallback to QSettings mode");
|
||||
if (d->settings)
|
||||
return true;
|
||||
|
||||
d->settings = new QSettings(d->name, QSettings::IniFormat, this);
|
||||
d->settings->beginGroup(d->subpath);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QStringList DConfig::keyList() const
|
||||
{
|
||||
D_DC(DConfig);
|
||||
return d->keyList();
|
||||
}
|
||||
|
||||
bool DConfig::isValid() const
|
||||
{
|
||||
D_DC(DConfig);
|
||||
#ifndef D_DISABLE_DCONFIG
|
||||
if (d->configFile)
|
||||
return true;
|
||||
|
||||
#ifndef D_DISABLE_DBUS_CONFIG
|
||||
return d->config;
|
||||
#endif
|
||||
#else
|
||||
return d->settings;
|
||||
#endif
|
||||
}
|
||||
|
||||
QVariant DConfig::value(const QString &key, const QVariant &fallback) const
|
||||
{
|
||||
D_DC(DConfig);
|
||||
return d->value(key, fallback);
|
||||
}
|
||||
|
||||
void DConfig::setValue(const QString &key, const QVariant &value)
|
||||
{
|
||||
D_D(DConfig);
|
||||
d->setValue(key, value);
|
||||
}
|
||||
|
||||
DCORE_END_NAMESPACE
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Uniontech Technology Co., Ltd.
|
||||
*
|
||||
* Author: zccrs <zccrs@live.com>
|
||||
*
|
||||
* Maintainer: zccrs <zhangjide@uniontech.com>
|
||||
*
|
||||
* 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, 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 Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef DCONFIG_H
|
||||
#define DCONFIG_H
|
||||
|
||||
#include <dtkcore_global.h>
|
||||
#include <DObject>
|
||||
|
||||
#include <QObject>
|
||||
#include <QVariant>
|
||||
|
||||
DCORE_BEGIN_NAMESPACE
|
||||
|
||||
class DConfigPrivate;
|
||||
class LIBDTKCORESHARED_EXPORT DConfig : public QObject, public DObject
|
||||
{
|
||||
Q_OBJECT
|
||||
D_DECLARE_PRIVATE(DConfig)
|
||||
|
||||
Q_PROPERTY(QStringList keyList READ keyList FINAL)
|
||||
|
||||
public:
|
||||
explicit DConfig(const QString &name, const QString &subpath = QString(),
|
||||
QObject *parent = nullptr);
|
||||
|
||||
bool load();
|
||||
|
||||
QStringList keyList() const;
|
||||
|
||||
bool isValid() const;
|
||||
QVariant value(const QString &key, const QVariant &fallback = QVariant()) const;
|
||||
void setValue(const QString &key, const QVariant &value);
|
||||
|
||||
Q_SIGNALS:
|
||||
void valueChanged(const QString &key);
|
||||
};
|
||||
|
||||
DCORE_END_NAMESPACE
|
||||
|
||||
#endif // DCONFIG_H
|
24
src/src.pro
24
src/src.pro
|
@ -11,11 +11,13 @@ QMAKE_CXXFLAGS_RELEASE += -fvisibility=hidden
|
|||
|
||||
INCLUDEPATH += $$PWD
|
||||
HEADERS += $$PWD/dtkcore_global.h \
|
||||
dconfig.h \
|
||||
dsysinfo.h \
|
||||
dsecurestring.h \
|
||||
ddesktopentry.h
|
||||
|
||||
SOURCES += \
|
||||
dconfig.cpp \
|
||||
dsysinfo.cpp \
|
||||
dsecurestring.cpp \
|
||||
ddesktopentry.cpp
|
||||
|
@ -26,6 +28,25 @@ linux: {
|
|||
|
||||
SOURCES += \
|
||||
$$PWD/dconfigfile.cpp
|
||||
|
||||
# generic dbus interfaces
|
||||
isEmpty(DTK_DISABLE_DBUS_CONFIG) {
|
||||
QT += dbus
|
||||
|
||||
config.files = $$PWD/dbus/org.desktopspec.ConfigManager.xml
|
||||
config.header_flags += -c DSGConfig -N
|
||||
config.source_flags += -c DSGConfig -N
|
||||
|
||||
manager.files = $$PWD/dbus/org.desktopspec.ConfigManager.Manager.xml
|
||||
manager.header_flags += -c DSGConfigManager -N
|
||||
manager.source_flags += -c DSGConfigManager -N
|
||||
|
||||
DBUS_INTERFACES += config manager
|
||||
} else {
|
||||
DEFINES += D_DISABLE_DBUS_CONFIG
|
||||
}
|
||||
} else {
|
||||
DEFINES += D_DISABLE_DCONFIG
|
||||
}
|
||||
|
||||
include($$PWD/base/base.pri)
|
||||
|
@ -46,7 +67,8 @@ includes.files += \
|
|||
$$PWD/DSysInfo \
|
||||
$$PWD/DSecureString \
|
||||
$$PWD/DDesktopEntry \
|
||||
$$PWD/DConfigFile
|
||||
$$PWD/DConfigFile \
|
||||
$$PWD/DConfig
|
||||
|
||||
INSTALLS += includes target
|
||||
|
||||
|
|
Loading…
Reference in New Issue