diff --git a/data/kde.portal b/data/kde.portal --- a/data/kde.portal +++ b/data/kde.portal @@ -1,4 +1,4 @@ [portal] DBusName=org.freedesktop.impl.portal.desktop.kde -Interfaces=org.freedesktop.impl.portal.Access;org.freedesktop.impl.portal.AppChooser;org.freedesktop.impl.portal.Email;org.freedesktop.impl.portal.FileChooser;org.freedesktop.impl.portal.Inhibit;org.freedesktop.impl.portal.Notification;org.freedesktop.impl.portal.Print;org.freedesktop.impl.portal.ScreenCast;org.freedesktop.impl.portal.Screenshot;org.freedesktop.impl.portal.RemoteDesktop;org.freedesktop.impl.portal.Settings +Interfaces=org.freedesktop.impl.portal.Access;org.freedesktop.impl.portal.Account;org.freedesktop.impl.portal.AppChooser;org.freedesktop.impl.portal.Email;org.freedesktop.impl.portal.FileChooser;org.freedesktop.impl.portal.Inhibit;org.freedesktop.impl.portal.Notification;org.freedesktop.impl.portal.Print;org.freedesktop.impl.portal.ScreenCast;org.freedesktop.impl.portal.Screenshot;org.freedesktop.impl.portal.RemoteDesktop;org.freedesktop.impl.portal.Settings UseIn=KDE diff --git a/data/org.freedesktop.Accounts.User.xml b/data/org.freedesktop.Accounts.User.xml new file mode 100644 --- /dev/null +++ b/data/org.freedesktop.Accounts.User.xml @@ -0,0 +1,43 @@ + + + + + + + + The username of the user. + + + + + + + + + The users real name. + + + + + + + + + The filename of a png file containing the users icon. + + + + + + + + + Emitted when the user is changed. + + + + + + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,6 +6,7 @@ xdg-desktop-portal-kde.cpp access.cpp accessdialog.cpp + account.cpp appchooser.cpp appchooserdialog.cpp desktopportal.cpp @@ -20,6 +21,7 @@ screenshotdialog.cpp settings.cpp utils.cpp + userinfodialog.cpp ) if (SCREENCAST_ENABLED) @@ -42,8 +44,13 @@ accessdialog.ui appchooserdialog.ui screenshotdialog.ui + userinfodialog.ui ) +set_source_files_properties(../data/org.freedesktop.Accounts.User.xml PROPERTIES NO_NAMESPACE TRUE) + +qt5_add_dbus_interface(xdg_desktop_portal_kde_SRCS ../data/org.freedesktop.Accounts.User.xml user_interface) + add_executable(xdg-desktop-portal-kde ${xdg_desktop_portal_kde_SRCS}) target_link_libraries(xdg-desktop-portal-kde @@ -75,4 +82,5 @@ install(FILES qml/AppChooserDialog.qml + qml/UserInfoDialog.qml DESTINATION ${KDE_INSTALL_DATADIR}/xdg-desktop-portal-kde/qml) diff --git a/src/account.h b/src/account.h new file mode 100644 --- /dev/null +++ b/src/account.h @@ -0,0 +1,45 @@ +/* + * Copyright © 2020 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_ACCOUNT_H +#define XDG_DESKTOP_PORTAL_KDE_ACCOUNT_H + +#include +#include + +class AccountPortal : public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.freedesktop.impl.portal.Account") +public: + explicit AccountPortal(QObject *parent); + ~AccountPortal(); + +public Q_SLOTS: + uint GetUserInformation(const QDBusObjectPath &handle, + const QString &app_id, + const QString &parent_window, + const QVariantMap &options, + QVariantMap &results); +}; + +#endif // XDG_DESKTOP_PORTAL_KDE_ACCOUNT_H + + diff --git a/src/account.cpp b/src/account.cpp new file mode 100644 --- /dev/null +++ b/src/account.cpp @@ -0,0 +1,69 @@ +/* + * Copyright © 2020 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 "account.h" +#include "userinfodialog.h" +#include "utils.h" + +#include + +Q_LOGGING_CATEGORY(XdgDesktopPortalKdeAccount, "xdp-kde-account") + +AccountPortal::AccountPortal(QObject *parent) + : QDBusAbstractAdaptor(parent) +{ +} + +AccountPortal::~AccountPortal() +{ +} + +uint AccountPortal::GetUserInformation(const QDBusObjectPath &handle, + const QString &app_id, + const QString &parent_window, + const QVariantMap &options, + QVariantMap &results) +{ + qCDebug(XdgDesktopPortalKdeAccount) << "GetUserInformation called with parameters:"; + qCDebug(XdgDesktopPortalKdeAccount) << " handle: " << handle.path(); + qCDebug(XdgDesktopPortalKdeAccount) << " parent_window: " << parent_window; + qCDebug(XdgDesktopPortalKdeAccount) << " app_id: " << app_id; + qCDebug(XdgDesktopPortalKdeAccount) << " options: " << options; + + QString reason; + + if (options.contains(QStringLiteral("reason"))) { + reason = options.value(QStringLiteral("reason")).toString(); + } + + UserInfoDialog *userInfoDialog = new UserInfoDialog(reason); + Utils::setParentWindow(userInfoDialog, parent_window); + + int result = userInfoDialog->exec(); + + if (result) { + results.insert(QStringLiteral("id"), userInfoDialog->id()); + results.insert(QStringLiteral("name"), userInfoDialog->name()); + results.insert(QStringLiteral("image"), userInfoDialog->image()); + } + + userInfoDialog->deleteLater(); + + return !result; +} diff --git a/src/desktopportal.h b/src/desktopportal.h --- a/src/desktopportal.h +++ b/src/desktopportal.h @@ -25,6 +25,7 @@ #include #include "access.h" +#include "account.h" #include "appchooser.h" #include "email.h" #include "filechooser.h" @@ -48,6 +49,7 @@ private: AccessPortal *m_access; + AccountPortal *m_account; AppChooserPortal *m_appChooser; EmailPortal *m_email; FileChooserPortal *m_fileChooser; diff --git a/src/desktopportal.cpp b/src/desktopportal.cpp --- a/src/desktopportal.cpp +++ b/src/desktopportal.cpp @@ -27,6 +27,7 @@ DesktopPortal::DesktopPortal(QObject *parent) : QObject(parent) , m_access(new AccessPortal(this)) + , m_account(new AccountPortal(this)) , m_appChooser(new AppChooserPortal(this)) , m_email(new EmailPortal(this)) , m_fileChooser(new FileChooserPortal(this)) diff --git a/src/qml/UserInfoDialog.qml b/src/qml/UserInfoDialog.qml new file mode 100644 --- /dev/null +++ b/src/qml/UserInfoDialog.qml @@ -0,0 +1,96 @@ +/* + * Copyright © 2020 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 + */ + + +import QtQuick 2.12 +import QtQuick.Controls 2.12 as QQC2 +import QtQuick.Layouts 1.12 +import org.kde.plasma.core 2.0 +import org.kde.kirigami 2.9 as Kirigami + +Item { + id: root + + signal accepted() + signal rejected() + + Rectangle { + id: background + anchors.fill: parent + color: Kirigami.Theme.backgroundColor + } + + + ColumnLayout { + anchors.fill: parent + + RowLayout { + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + + Kirigami.Icon { + height: units.iconSizes.enormous + width: units.iconSizes.enormous + source: image + } + + ColumnLayout { + Kirigami.Heading { + id: nameText + Layout.fillWidth: true + text: name + } + Kirigami.Heading { + id: idText + Layout.fillWidth: true + level: 3 + text: id + } + } + } + + QQC2.Label { + Layout.alignment: Qt.AlignTop + Layout.fillWidth: true + text: i18n("Share your personal information with the requesting application?") + wrapMode: Text.WordWrap + } + + QQC2.Label { + Layout.fillWidth: true + text: reason + wrapMode: Text.WordWrap + } + + RowLayout { + Layout.alignment: Qt.AlignBottom | Qt.AlignRight + + QQC2.Button { + text: i18n("Share") + + onClicked: accepted() + } + QQC2.Button { + text: i18n("Cancel") + + onClicked: rejected() + } + } + } +} diff --git a/src/userinfodialog.h b/src/userinfodialog.h new file mode 100644 --- /dev/null +++ b/src/userinfodialog.h @@ -0,0 +1,50 @@ +/* + * Copyright © 2020 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_USERINFO_DIALOG_H +#define XDG_DESKTOP_PORTAL_KDE_USERINFO_DIALOG_H + +#include + +namespace Ui +{ +class UserInfoDialog; +} + +class OrgFreedesktopAccountsUserInterface; + +class UserInfoDialog : public QDialog +{ + Q_OBJECT +public: + explicit UserInfoDialog(const QString &reason, QDialog *parent = nullptr, Qt::WindowFlags flags = {}); + ~UserInfoDialog(); + + QString id() const; + QString name() const; + QString image() const; + +private: + Ui::UserInfoDialog *m_dialog; + OrgFreedesktopAccountsUserInterface *m_userInterface; +}; + +#endif // XDG_DESKTOP_PORTAL_KDE_USERINFO_DIALOG_H + diff --git a/src/userinfodialog.cpp b/src/userinfodialog.cpp new file mode 100644 --- /dev/null +++ b/src/userinfodialog.cpp @@ -0,0 +1,92 @@ +/* + * Copyright © 2020 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 "userinfodialog.h" +#include "ui_userinfodialog.h" + +#include "user_interface.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +UserInfoDialog::UserInfoDialog(const QString &reason, QDialog *parent, Qt::WindowFlags flags) + : QDialog(parent, flags) + , m_dialog(new Ui::UserInfoDialog) +{ + m_dialog->setupUi(this); + + KDeclarative::KDeclarative kdeclarative; + kdeclarative.setDeclarativeEngine(m_dialog->quickWidget->engine()); + kdeclarative.setTranslationDomain(QStringLiteral(TRANSLATION_DOMAIN)); + kdeclarative.setupEngine(m_dialog->quickWidget->engine()); + kdeclarative.setupContext(); + + QString ifacePath = QStringLiteral("/org/freedesktop/Accounts/User%1").arg(getuid()); + m_userInterface = new OrgFreedesktopAccountsUserInterface(QStringLiteral("org.freedesktop.Accounts"), ifacePath, QDBusConnection::systemBus(), this); + + QString image = QFileInfo::exists(m_userInterface->iconFile()) ? m_userInterface->iconFile() : QString(); + + m_dialog->quickWidget->rootContext()->setContextProperty(QStringLiteral("reason"), reason); + m_dialog->quickWidget->rootContext()->setContextProperty(QStringLiteral("id"), m_userInterface->userName()); + m_dialog->quickWidget->rootContext()->setContextProperty(QStringLiteral("name"), m_userInterface->realName()); + if (QFileInfo::exists(m_userInterface->iconFile())) { + m_dialog->quickWidget->rootContext()->setContextProperty(QStringLiteral("image"), m_userInterface->iconFile()); + } else { + m_dialog->quickWidget->rootContext()->setContextProperty(QStringLiteral("image"), QIcon::fromTheme(QStringLiteral("user-identity"))); + } + m_dialog->quickWidget->setClearColor(Qt::transparent); + m_dialog->quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView); + m_dialog->quickWidget->setSource(QUrl::fromLocalFile(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("xdg-desktop-portal-kde/qml/UserInfoDialog.qml")))); + + QObject *rootItem = m_dialog->quickWidget->rootObject(); + connect(rootItem, SIGNAL(accepted()), this, SLOT(accept())); + connect(rootItem, SIGNAL(rejected()), this, SLOT(reject())); + + setWindowTitle(i18n("Share Information")); +} + +UserInfoDialog::~UserInfoDialog() +{ + delete m_dialog; +} + +QString UserInfoDialog::id() const +{ + return m_userInterface->userName(); +} + +QString UserInfoDialog::image() const +{ + return m_userInterface->realName(); +} + +QString UserInfoDialog::name() const +{ + return m_userInterface->iconFile(); +} diff --git a/src/userinfodialog.ui b/src/userinfodialog.ui new file mode 100644 --- /dev/null +++ b/src/userinfodialog.ui @@ -0,0 +1,48 @@ + + + UserInfoDialog + + + + 0 + 0 + 360 + 300 + + + + + 0 + 0 + + + + Dialog + + + + + + + 0 + 0 + + + + QQuickWidget::SizeRootObjectToView + + + + + + + + QQuickWidget + QWidget +
QtQuickWidgets/QQuickWidget
+
+
+ + +
+