diff --git a/src/settings.cpp b/src/settings.cpp
index e58b308..da91fcd 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -1,233 +1,267 @@
/*
- * Copyright © 2018 Red Hat, Inc
+ * Copyright © 2018-2019 Red Hat, Inc
*
* 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 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
*
* Authors:
* Jan Grulich
*/
#include "settings.h"
#include
#include
#include
#include
#include
#include
Q_LOGGING_CATEGORY(XdgDesktopPortalKdeSettings, "xdp-kde-settings")
Q_DECLARE_METATYPE(SettingsPortal::VariantMapMap)
QDBusArgument &operator<<(QDBusArgument &argument, const SettingsPortal::VariantMapMap &mymap)
{
argument.beginMap(QVariant::String, QVariant::Map);
QMapIterator i(mymap);
while (i.hasNext()) {
i.next();
argument.beginMapEntry();
argument << i.key() << i.value();
argument.endMapEntry();
}
argument.endMap();
return argument;
}
const QDBusArgument &operator>>(const QDBusArgument &argument, SettingsPortal::VariantMapMap &mymap)
{
argument.beginMap();
mymap.clear();
while (!argument.atEnd()) {
QString key;
QVariantMap value;
argument.beginMapEntry();
argument >> key >> value;
argument.endMapEntry();
mymap.insert(key, value);
}
argument.endMap();
return argument;
}
static bool groupMatches(const QString &group, const QStringList &patterns)
{
for (const QString &pattern : patterns) {
if (pattern.isEmpty()) {
return true;
}
if (pattern == group) {
return true;
}
if (pattern.endsWith(QLatin1Char('*')) && group.startsWith(pattern.left(pattern.length() - 1))) {
return true;
}
}
return false;
}
SettingsPortal::SettingsPortal(QObject *parent)
: QDBusAbstractAdaptor(parent)
{
qDBusRegisterMetaType();
m_kdeglobals = KSharedConfig::openConfig();
QDBusConnection::sessionBus().connect(QString(), QStringLiteral("/KDEPlatformTheme"), QStringLiteral("org.kde.KDEPlatformTheme"),
QStringLiteral("refreshFonts"), this, SLOT(fontChanged()));
QDBusConnection::sessionBus().connect(QString(), QStringLiteral("/KGlobalSettings"), QStringLiteral("org.kde.KGlobalSettings"),
QStringLiteral("notifyChange"), this, SLOT(globalSettingChanged(int,int)));
QDBusConnection::sessionBus().connect(QString(), QStringLiteral("/KToolBar"), QStringLiteral("org.kde.KToolBar"),
QStringLiteral("styleChanged"), this, SLOT(toolbarStyleChanged()));
}
SettingsPortal::~SettingsPortal()
{
}
void SettingsPortal::ReadAll(const QStringList &groups)
{
qCDebug(XdgDesktopPortalKdeSettings) << "ReadAll called with parameters:";
qCDebug(XdgDesktopPortalKdeSettings) << " groups: " << groups;
//FIXME this is super ugly, but I was unable to make it properly return VariantMapMap
QObject *obj = QObject::parent();
if (!obj) {
qCWarning(XdgDesktopPortalKdeSettings) << "Failed to get dbus context";
return;
}
void *ptr = obj->qt_metacast("QDBusContext");
QDBusContext *q_ptr = reinterpret_cast(ptr);
if (!q_ptr) {
qCWarning(XdgDesktopPortalKdeSettings) << "Failed to get dbus context";
return;
}
VariantMapMap result;
for (const QString &settingGroupName : m_kdeglobals->groupList()) {
//NOTE: use org.kde.kdeglobals prefix
QString uniqueGroupName = QStringLiteral("org.kde.kdeglobals.") + settingGroupName;
if (!groupMatches(uniqueGroupName, groups)) {
continue;
}
QVariantMap map;
KConfigGroup configGroup(m_kdeglobals, settingGroupName);
for (const QString &key : configGroup.keyList()) {
map.insert(key, configGroup.readEntry(key));
}
result.insert(uniqueGroupName, map);
}
QDBusMessage message = q_ptr->message();
QDBusMessage reply = message.createReply(QVariant::fromValue(result));
QDBusConnection::sessionBus().send(reply);
}
-QDBusVariant SettingsPortal::Read(const QString &group, const QString &key)
+void SettingsPortal::Read(const QString &group, const QString &key)
{
qCDebug(XdgDesktopPortalKdeSettings) << "Read called with parameters:";
qCDebug(XdgDesktopPortalKdeSettings) << " group: " << group;
qCDebug(XdgDesktopPortalKdeSettings) << " key: " << key;
- // All our namespaces start with this prefix
- if (!group.startsWith(QStringLiteral("org.kde.kdeglobals"))) {
- qCWarning(XdgDesktopPortalKdeSettings) << "Namespace " << group << " is not supported";
- return QDBusVariant();
+ //FIXME this is super ugly, but I was unable to make it properly return VariantMapMap
+ QObject *obj = QObject::parent();
+
+ if (!obj) {
+ qCWarning(XdgDesktopPortalKdeSettings) << "Failed to get dbus context";
+ return;
}
- QString groupName = group.right(group.length() - QStringLiteral("org.kde.kdeglobals.").length());
+ void *ptr = obj->qt_metacast("QDBusContext");
+ QDBusContext *q_ptr = reinterpret_cast(ptr);
- if (!m_kdeglobals->hasGroup(groupName)) {
- qCWarning(XdgDesktopPortalKdeSettings) << "Group " << group << " doesn't exist";
- return QDBusVariant();
+ if (!q_ptr) {
+ qCWarning(XdgDesktopPortalKdeSettings) << "Failed to get dbus context";
+ return;
}
- KConfigGroup configGroup(m_kdeglobals, groupName);
+ QDBusMessage reply;
+ QDBusMessage message = q_ptr->message();
- if (!configGroup.hasKey(key)) {
- qCWarning(XdgDesktopPortalKdeSettings) << "Key " << key << " doesn't exist";
- return QDBusVariant();
+ // All our namespaces start with this prefix
+ if (!group.startsWith(QStringLiteral("org.kde.kdeglobals"))) {
+ qCWarning(XdgDesktopPortalKdeSettings) << "Namespace " << group << " is not supported";
+ reply = message.createErrorReply(QDBusError::UnknownProperty, QStringLiteral("Namespace is not supported"));
+ QDBusConnection::sessionBus().send(reply);
+ return;
}
- return QDBusVariant(configGroup.readEntry(key));
+ QDBusVariant result = readProperty(group, key);
+ if (result.variant().isNull()) {
+ reply = message.createErrorReply(QDBusError::UnknownProperty, QStringLiteral("Property doesn't exist"));
+ } else {
+ reply = message.createReply(QVariant::fromValue(result));
+ }
+
+ QDBusConnection::sessionBus().send(reply);
}
void SettingsPortal::fontChanged()
{
- Q_EMIT SettingChanged(QStringLiteral("org.kde.kdeglobals.General"), QStringLiteral("font"), Read(QStringLiteral("org.kde.kdeglobals.General"), QStringLiteral("font")));
+ Q_EMIT SettingChanged(QStringLiteral("org.kde.kdeglobals.General"), QStringLiteral("font"), readProperty(QStringLiteral("org.kde.kdeglobals.General"), QStringLiteral("font")));
}
void SettingsPortal::globalSettingChanged(int type, int arg)
{
m_kdeglobals->reparseConfiguration();
// Mostly based on plasma-integration needs
switch (type) {
case PaletteChanged:
// Plasma-integration will be loading whole palette again, there is no reason to try to identify
// particular categories or colors
- Q_EMIT SettingChanged(QStringLiteral("org.kde.kdeglobals.General"), QStringLiteral("ColorScheme"), Read(QStringLiteral("org.kde.kdeglobals.General"), QStringLiteral("ColorScheme")));
+ Q_EMIT SettingChanged(QStringLiteral("org.kde.kdeglobals.General"), QStringLiteral("ColorScheme"), readProperty(QStringLiteral("org.kde.kdeglobals.General"), QStringLiteral("ColorScheme")));
break;
case FontChanged:
fontChanged();
break;
case StyleChanged:
- Q_EMIT SettingChanged(QStringLiteral("org.kde.kdeglobals.KDE"), QStringLiteral("widgetStyle"), Read(QStringLiteral("org.kde.kdeglobals.KDE"), QStringLiteral("widgetStyle")));
+ Q_EMIT SettingChanged(QStringLiteral("org.kde.kdeglobals.KDE"), QStringLiteral("widgetStyle"), readProperty(QStringLiteral("org.kde.kdeglobals.KDE"), QStringLiteral("widgetStyle")));
break;
case SettingsChanged: {
SettingsCategory category = static_cast(arg);
if (category == SETTINGS_QT || category == SETTINGS_MOUSE) {
// TODO
} else if (category == SETTINGS_STYLE) {
// TODO
}
break;
}
case IconChanged:
// we will get notified about each category, but it probably makes sense to send this signal just once
if (arg == 0) { // KIconLoader::Desktop
- Q_EMIT SettingChanged(QStringLiteral("org.kde.kdeglobals.Icons"), QStringLiteral("Theme"), Read(QStringLiteral("org.kde.kdeglobals.Icons"), QStringLiteral("Theme")));
+ Q_EMIT SettingChanged(QStringLiteral("org.kde.kdeglobals.Icons"), QStringLiteral("Theme"), readProperty(QStringLiteral("org.kde.kdeglobals.Icons"), QStringLiteral("Theme")));
}
break;
case CursorChanged:
// TODO
break;
case ToolbarStyleChanged:
toolbarStyleChanged();
break;
default:
break;
}
}
void SettingsPortal::toolbarStyleChanged()
{
- Q_EMIT SettingChanged(QStringLiteral("org.kde.kdeglobals.Toolbar style"), QStringLiteral("ToolButtonStyle"), Read(QStringLiteral("org.kde.kdeglobals.Toolbar style"), QStringLiteral("ToolButtonStyle")));
+ Q_EMIT SettingChanged(QStringLiteral("org.kde.kdeglobals.Toolbar style"), QStringLiteral("ToolButtonStyle"), readProperty(QStringLiteral("org.kde.kdeglobals.Toolbar style"), QStringLiteral("ToolButtonStyle")));
}
+
+QDBusVariant SettingsPortal::readProperty(const QString &group, const QString &key)
+{
+ QString groupName = group.right(group.length() - QStringLiteral("org.kde.kdeglobals.").length());
+
+ if (!m_kdeglobals->hasGroup(groupName)) {
+ qCWarning(XdgDesktopPortalKdeSettings) << "Group " << group << " doesn't exist";
+ return QDBusVariant();
+ }
+
+ KConfigGroup configGroup(m_kdeglobals, groupName);
+
+ if (!configGroup.hasKey(key)) {
+ qCWarning(XdgDesktopPortalKdeSettings) << "Key " << key << " doesn't exist";
+ return QDBusVariant();
+ }
+
+ return QDBusVariant(configGroup.readEntry(key));
+}
+
diff --git a/src/settings.h b/src/settings.h
index eb71cef..dc8b928 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -1,78 +1,80 @@
/*
- * Copyright © 2018 Red Hat, Inc
+ * Copyright © 2018-2019 Red Hat, Inc
*
* 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 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
*
* Authors:
* Jan Grulich
*/
#ifndef XDG_DESKTOP_PORTAL_KDE_SETTINGS_H
#define XDG_DESKTOP_PORTAL_KDE_SETTINGS_H
#include
#include
#include
#include
class SettingsPortal : public QDBusAbstractAdaptor
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.freedesktop.impl.portal.Settings")
public:
/**
* An identifier for change signals.
* @note Copied from KGlobalSettings
*/
enum ChangeType { PaletteChanged = 0, FontChanged, StyleChanged,
SettingsChanged, IconChanged, CursorChanged,
ToolbarStyleChanged, ClipboardConfigChanged,
BlockShortcuts, NaturalSortingChanged
};
/**
* Valid values for the settingsChanged signal
* @note Copied from KGlobalSettings
*/
enum SettingsCategory { SETTINGS_MOUSE, SETTINGS_COMPLETION, SETTINGS_PATHS,
SETTINGS_POPUPMENU, SETTINGS_QT, SETTINGS_SHORTCUTS,
SETTINGS_LOCALE, SETTINGS_STYLE
};
explicit SettingsPortal(QObject *parent);
~SettingsPortal();
typedef QMap > VariantMapMap;
uint version() const { return 1; }
public Q_SLOTS:
void ReadAll(const QStringList &groups);
- QDBusVariant Read(const QString &group, const QString &keys);
+ void Read(const QString &group, const QString &key);
Q_SIGNALS:
void SettingChanged(const QString &group, const QString &key, const QDBusVariant &value);
private Q_SLOTS:
void fontChanged();
void globalSettingChanged(int type, int arg);
void toolbarStyleChanged();
private:
+ QDBusVariant readProperty(const QString &group, const QString &key);
+
KSharedConfigPtr m_kdeglobals;
};
#endif // XDG_DESKTOP_PORTAL_KDE_SETTINGS_H