Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sync: from linuxdeepin/dtkcore #16

Merged
merged 1 commit into from
Oct 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions docs/global/dconfigfile.zh_CN.dox
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,16 @@ dtk_add_config_meta_files(
"name": "map",
"permissions": "readwrite",
"visibility": "public"
},
"publicConfig": {
"value": true,
"serial": 0,
"flags": ["user-public"],
"name": "public configure",
"name[zh_CN]": "我是公开的配置",
"description": "I am public configure",
"permissions": "readwrite",
"visibility": "private"
}
}
}
Expand Down Expand Up @@ -188,6 +198,8 @@ sudo ./dconfigfile-example
@brief 存在此标记时,将表明则此配置项不可被覆盖(详见下述 override 机制)。反之,不存在此标记时表明此配置项允许被覆盖,对于此类配置项,如若其有界面设置入口,则当此项不可写时,应当隐藏或禁用界面的设置入口.
@var Dtk::Core::DConfigFile::Flag Dtk::Core::DConfigFile::Global
@brief 当读写此类配置时,将忽略用户身份,无论程序使用哪个用户身份执行,读操作都将获取到同样的数据,写操作将对所有用户都生效。但是,如果对应的配置存储目录不存在或无权限写入,则忽略此标志
@var Dtk::Core::DConfigFile::Flag Dtk::Core::DConfigFile::UserPublic
@brief 该类配置项允许被其他用户访问


@enum Dtk::Core::DConfigFile::Permissions
Expand Down
31 changes: 31 additions & 0 deletions docs/util/dutil.zh_CN.dox
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*!
@chinese
@ingroup dutil
@file include/util/dutil.h

该文件定义和实现了一些小的工具函数.

@fn QString DUtil::escapeToObjectPath(const QString &str)
@brief 将字符串转义成符合DBus ObjectPath规则字符串
@param[in] str 需要转义的字符串
@return 转义后字符串
@attention 不要传入完整的dbus路径, 否则'/'也会被转义

@fn QString DUtil::unescapeFromObjectPath(const QString &str)
@brief 将DBus ObjectPath的部分路径转义成原来的字符串
@param[in] str 需要转义的字符串
@return 转义后字符串

@fn QString DUtil::getAppIdFromAbsolutePath(const QString &path)
@brief 从desktop文件的绝对路径中提取出AppId
@param[in] path 文件路径
@return 代表AppId的字符串
@attention AppId可能为空, 代表无法获取AppId

@fn QStringList DUtil::getAbsolutePathFromAppId(const QString &appId)
@brief 从appId中获取符合条件的Desktop文件路径
@param[in] appId app的Id
@return desktop文件的路径
@attention 可能有多个desktop文件的appId相同, 所以返回所有符合条件的列表

*/
3 changes: 2 additions & 1 deletion include/global/dconfigfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ class LIBDTKCORESHARED_EXPORT DConfigFile : public DObject{
public:
enum Flag {
NoOverride = 1 << 0,
Global = 1 << 1
Global = 1 << 1,
UserPublic = 1 << 2
};
Q_DECLARE_FLAGS(Flags, Flag)

Expand Down
79 changes: 78 additions & 1 deletion include/util/dutil.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2016 - 2022 UnionTech Software Technology Co., Ltd.
// SPDX-FileCopyrightText: 2016 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later

Expand All @@ -8,6 +8,9 @@
#include <QThread>
#include <QMetaObject>
#include <QCoreApplication>
#include <QRegularExpression>
#include <QStandardPaths>
#include <QDir>
#include <type_traits>
#include <cstring>

Expand Down Expand Up @@ -51,4 +54,78 @@ void SecureErase(T &obj)
}
}

inline QString escapeToObjectPath(const QString &str)
{
if (str.isEmpty()) {
return "_";
}

auto ret = str;
QRegularExpression re{R"([^a-zA-Z0-9])"};
auto matcher = re.globalMatch(ret);
while (matcher.hasNext()) {
auto replaceList = matcher.next().capturedTexts();
replaceList.removeDuplicates();
for (const auto &c : replaceList) {
auto hexStr = QString::number(static_cast<uint>(c.front().toLatin1()), 16);
ret.replace(c, QString{R"(_%1)"}.arg(hexStr));
}
}
return ret;
}

inline QString unescapeFromObjectPath(const QString &str)
{
auto ret = str;
for (int i = 0; i < str.size(); ++i) {
if (str[i] == '_' and i + 2 < str.size()) {
auto hexStr = str.mid(i + 1, 2);
ret.replace(QString{"_%1"}.arg(hexStr), QChar::fromLatin1(hexStr.toUInt(nullptr, 16)));
i += 2;
}
}
return ret;
}

inline QString getAppIdFromAbsolutePath(const QString &path)
{
decltype(auto) desktopSuffix = u8".desktop";
const auto &appDirs = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation);
if (!path.endsWith(desktopSuffix) or
!std::any_of(appDirs.cbegin(), appDirs.constEnd(), [&path](const QString &dir) { return path.startsWith(dir); })) {
return {};
}

auto tmp = path.chopped(sizeof(desktopSuffix) - 1);
auto components = tmp.split(QDir::separator(), Qt::SkipEmptyParts);
auto location = std::find(components.cbegin(), components.cend(), "applications");
if (location == components.cend()) {
return {};
}

auto appId = QStringList{location + 1, components.cend()}.join('-');
return appId;
}

inline QStringList getAbsolutePathFromAppId(const QString &appId)
{
auto components = appId.split('-', Qt::SkipEmptyParts);
auto appDirs = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation);

QStringList ret;
for (const auto &dirPath : appDirs) {
auto currentDir = dirPath;
for (auto it = components.cbegin(); it != components.cend(); ++it) {
auto currentName = QStringList{it, components.cend()}.join('-') + QString{".desktop"};
QDir dir{currentDir};
if (dir.exists(currentName)) {
ret.append(dir.filePath(currentName));
}

currentDir.append(QDir::separator() + *it);
}
}

return ret;
}
}
2 changes: 2 additions & 0 deletions src/dconfigfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,8 @@ class Q_DECL_HIDDEN DConfigInfo {
flags |= DConfigFile::NoOverride;
} else if (flag == QLatin1String("global")) {
flags |= DConfigFile::Global;
} else if (flag == QLatin1String("user-public")) {
flags |= DConfigFile::UserPublic;
}
}

Expand Down
10 changes: 10 additions & 0 deletions tests/data/dconf-example.meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,16 @@
"name": "array value type",
"permissions": "readwrite",
"visibility": "public"
},
"publicConfig": {
"value": true,
"serial": 0,
"flags": ["user-public"],
"name": "public configure",
"name[zh_CN]": "我是公开的配置",
"description": "I am public configure",
"permissions": "readwrite",
"visibility": "private"
}
}
}
11 changes: 11 additions & 0 deletions tests/ut_dconfigfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -485,3 +485,14 @@ TEST_F(ut_DConfigFile, setSubpath) {
ASSERT_FALSE(config.load(LocalPrefix));
}
}

TEST_F(ut_DConfigFile, userPublic) {

FileCopyGuard guard(":/data/dconf-example.meta.json", QString("%1/%2.json").arg(metaPath, FILE_NAME));
{
DConfigFile config(APP_ID, FILE_NAME);
ASSERT_TRUE(config.load(LocalPrefix));
ASSERT_TRUE(config.meta()->flags("publicConfig").testFlag(DConfigFile::UserPublic));
ASSERT_FALSE(config.meta()->flags("canExit").testFlag(DConfigFile::UserPublic));
}
}