summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt4
-rw-r--r--src/account_portal.cpp209
-rw-r--r--src/account_portal.h73
-rw-r--r--src/email_portal.cpp1
-rw-r--r--src/file_chooser_portal.cpp20
-rw-r--r--src/permission_dialog.cpp100
-rw-r--r--src/permission_dialog.h54
-rw-r--r--src/portal_service.cpp9
-rw-r--r--src/util.cpp54
-rw-r--r--src/util.h13
10 files changed, 514 insertions, 23 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 0ed40be..b094414 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -28,8 +28,10 @@ tde_add_executable(
main.cpp
portal_daemon.cpp
portal_service.cpp
- file_chooser_portal.cpp
+ account_portal.cpp
email_portal.cpp
+ file_chooser_portal.cpp
+ permission_dialog.cpp
util.cpp
LINK
diff --git a/src/account_portal.cpp b/src/account_portal.cpp
new file mode 100644
index 0000000..a20559b
--- /dev/null
+++ b/src/account_portal.cpp
@@ -0,0 +1,209 @@
+/*******************************************************************************
+ XDG desktop portal implementation for TDE
+ Copyright © 2024 Mavridis Philippe <mavridisf@gmail.com>
+
+ Avatar detection code is based on code from the Redmond KSplash theme
+ Copyright © 2001-2003 Brian Ledbetter 2001-2003 <brian@shadowcom.net>
+ Copyright © 2003 Ravikiran Rajagopal 2003 <ravi@kde.org>
+
+ This program or library 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.1 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, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Improvements and feedback are welcome!
+*******************************************************************************/
+
+// TQt
+#include <tqfile.h>
+#include <tqhbox.h>
+#include <tqlabel.h>
+#include <tqdbusdata.h>
+
+// TDE
+#include <kstandarddirs.h>
+#include <ksimpleconfig.h>
+#include <tdelocale.h>
+#include <twin.h>
+#include <kuser.h>
+#include <kdebug.h>
+
+// Portal
+#include "permission_dialog.h"
+#include "account_portal.h"
+#include "account_portal.moc"
+
+#define TQSTRING_TO_DBUS_VARIANT(x) \
+ TQT_DBusData::fromString(x).getAsVariantData().toVariant()
+
+TDEAccountPortal::TDEAccountPortal(TQT_DBusConnection &connection)
+: m_connection(connection)
+{
+}
+
+TDEAccountPortal::~TDEAccountPortal()
+{
+}
+
+void TDEAccountPortal::handleMethodReply(const TQT_DBusMessage &reply)
+{
+ m_connection.send(reply);
+}
+
+bool TDEAccountPortal::handleSignalSend(const TQT_DBusMessage& reply) {
+ handleMethodReply(reply);
+ return true;
+}
+
+bool TDEAccountPortal::GetUserInformation(const TQT_DBusObjectPath& handle,
+ const TQString& app_id,
+ const TQString& window,
+ const TQT_DBusVariantMap& options,
+ TQ_UINT32& response,
+ TQT_DBusVariantMap& results,
+ TQT_DBusError& error)
+{
+ Dictionary details;
+
+ if (OPTION_VALID("reason", "s"))
+ {
+ TQString reason(options["reason"].value.toString());
+ if (!reason.isEmpty())
+ {
+ details[i18n("Reason")] = reason;
+ }
+ }
+
+ // Try to detect which application requested the permission
+ WId wid = parse_window_id(window);
+ ApplicationInfo app = application_info_from_wid(wid);
+
+ if (!app.path.isEmpty())
+ details[i18n("Path")] = app.path;
+
+ // Run the dialog
+ TDEPermissionDialog *dialog = new TDEPermissionDialog(
+ app.name,
+ i18n("Account information"),
+ "user-info",
+ details
+ );
+ AccountInfo info = getAccountInfo();
+ appendDataPreview(dialog, info);
+
+ if (wid > 0) KWin::setMainWindow(dialog, wid);
+
+ if (dialog->exec() == KDialogBase::Yes)
+ {
+ response = 0;
+ results.insert("id", TQSTRING_TO_DBUS_VARIANT(info.userId));
+ results.insert("name", TQSTRING_TO_DBUS_VARIANT(info.realName));
+ results.insert("image", TQSTRING_TO_DBUS_VARIANT(info.avatarPath));
+ }
+ else response = 1;
+
+ delete dialog;
+ return true;
+}
+
+AccountInfo TDEAccountPortal::getAccountInfo()
+{
+ AccountInfo info;
+ KUser user;
+ info.userId = TQString::number(user.uid());
+ info.loginName = user.loginName();
+ info.realName = user.fullName();
+ info.homeDirectory = user.homeDir();
+ findUserAvatar(info);
+ return info;
+}
+
+void TDEAccountPortal::findUserAvatar(AccountInfo &info)
+{
+ // Parse tdmrc settings to determine face source and system location
+ const int fAdminOnly = 1;
+ const int fAdminFirst = fAdminOnly + 1;
+ const int fUserFirst = fAdminFirst + 1;
+ const int fUserOnly = fUserFirst + 1;
+
+ int faceSource = fAdminOnly;
+ TDEConfig *tdmconfig = new TDEConfig("tdm/tdmrc", true);
+ tdmconfig->setGroup("X-*-Greeter");
+
+ TQString fs = tdmconfig->readEntry("FaceSource");
+ if (fs == TQString::fromLatin1("UserOnly"))
+ faceSource = fUserOnly;
+ else if (fs == TQString::fromLatin1("PreferUser"))
+ faceSource = fUserFirst;
+ else if (fs == TQString::fromLatin1("PreferAdmin"))
+ faceSource = fAdminFirst;
+ else
+ faceSource = fAdminOnly;
+
+ TQString userPicsDir = tdmconfig->readEntry("FaceDir",
+ TDEGlobal::dirs()->resourceDirs("data").last() + "tdm/faces") + '/';
+
+ delete tdmconfig;
+
+ // Faces provided by administrator (default and per user)
+ const TQString systemDefault(userPicsDir + ".default.face.icon");
+ const TQString systemUser(userPicsDir + info.loginName + ".face.icon");
+
+ TQString avatar;
+ if (faceSource == fAdminFirst)
+ {
+ avatar = systemUser;
+ if (!TQFile::exists(avatar))
+ faceSource = fUserOnly;
+ }
+
+ if (faceSource >= fUserFirst)
+ {
+ avatar = info.homeDirectory + "/.face.icon";
+ if (!TQFile::exists(avatar) && faceSource == fUserFirst)
+ avatar = systemUser;
+
+ if (!TQFile::exists(avatar))
+ avatar = systemDefault;
+ }
+
+ if (faceSource <= fAdminOnly)
+ {
+ avatar = systemUser;
+ if (!TQFile::exists(avatar))
+ avatar = systemDefault;
+ }
+
+ info.avatarPath = avatar;
+}
+
+void TDEAccountPortal::appendDataPreview(TDEPermissionDialog *dlg, AccountInfo info)
+{
+ TQHBox *frame = new TQHBox(dlg);
+ frame->setFrameStyle(TQFrame::StyledPanel | TQFrame::Sunken);
+
+ TQLabel *avatar = new TQLabel(frame);
+ avatar->setPixmap(TQPixmap(info.avatarPath));
+
+ TQString userDataStr = "<qt><h1>%1</h1><hr>ID: %2</qt>";
+ userDataStr = userDataStr.arg(info.realName, info.userId);
+ TQLabel *userData = new TQLabel(userDataStr, frame);
+
+ avatar->setMargin(TDEPermissionDialog::spacingHint());
+ userData->setMargin(TDEPermissionDialog::spacingHint());
+
+ frame->setSizePolicy(TQSizePolicy::MinimumExpanding, TQSizePolicy::Fixed);
+
+ dlg->appendWidget(frame);
+}
+
+// kate: replace-tabs true; tab-width 4; indent-width 4; \ No newline at end of file
diff --git a/src/account_portal.h b/src/account_portal.h
new file mode 100644
index 0000000..b75fe26
--- /dev/null
+++ b/src/account_portal.h
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ XDG desktop portal implementation for TDE
+ Copyright © 2024 Mavridis Philippe <mavridisf@gmail.com>
+
+ This program or library 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.1 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, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Improvements and feedback are welcome!
+*******************************************************************************/
+
+#ifndef __ACCOUNT_PORTAL_H
+#define __ACCOUNT_PORTAL_H
+
+// Portal
+#include "interfaces/accountInterface.h"
+#include "interface.h"
+
+struct AccountInfo
+{
+ TQString userId;
+ TQString loginName;
+ TQString realName;
+ TQString homeDirectory;
+ TQString avatarPath;
+};
+
+class TDEPermissionDialog;
+
+class TDEAccountPortal : public TQObject,
+ public org::freedesktop::impl::portal::AccountInterface
+{
+ public:
+ INTERFACE("org.freedesktop.impl.portal.Account")
+
+ TDEAccountPortal(TQT_DBusConnection &connection);
+ virtual ~TDEAccountPortal();
+
+ protected:
+ virtual void handleMethodReply(const TQT_DBusMessage& reply);
+ virtual bool handleSignalSend(const TQT_DBusMessage& reply);
+
+ virtual bool GetUserInformation(const TQT_DBusObjectPath& handle,
+ const TQString& app_id,
+ const TQString& window,
+ const TQT_DBusVariantMap& options,
+ TQ_UINT32& response,
+ TQT_DBusVariantMap& results,
+ TQT_DBusError& error);
+
+ AccountInfo getAccountInfo();
+ void appendDataPreview(TDEPermissionDialog *dlg, AccountInfo info);
+
+ private:
+ void findUserAvatar(AccountInfo &info);
+
+ private:
+ TQT_DBusConnection m_connection;
+};
+
+#endif // __ACCOUNT_PORTAL_H
+
+// kate: replace-tabs true; tab-width 4; indent-width 4; \ No newline at end of file
diff --git a/src/email_portal.cpp b/src/email_portal.cpp
index d12ba50..090ed8b 100644
--- a/src/email_portal.cpp
+++ b/src/email_portal.cpp
@@ -53,7 +53,6 @@ bool TDEEmailPortal::ComposeEmail(const TQT_DBusObjectPath& handle,
TQT_DBusVariantMap &results,
TQT_DBusError& error)
{
- // void invokeMailer (const TQString &to, const TQString &cc, const TQString &bcc, const TQString &subject, const TQString &body, const TQString &messageFile=TQString::null, const TQStringList &attachURLs=TQStringList())
EmailOpts opts;
if (OPTION_VALID("address", "s"))
opts.rcpt << options["address"].value.toString();
diff --git a/src/file_chooser_portal.cpp b/src/file_chooser_portal.cpp
index 4668abd..9b8f6e7 100644
--- a/src/file_chooser_portal.cpp
+++ b/src/file_chooser_portal.cpp
@@ -27,7 +27,6 @@
#include <tdeio/renamedlg.h>
#include <tdefiledialog.h>
#include <kpushbutton.h>
-#include <twin.h>
#include <kdebug.h>
// Portal
@@ -69,7 +68,7 @@ bool TDEFileChooserPortal::OpenFile(const TQT_DBusObjectPath& handle,
if (OPTION_VALID("filters", "a(sa(us))"))
opts.filters = parseFilterList(options["filters"], options["current_filter"]);
- opts.windowId = parseWindowId(parent_window);
+ opts.windowId = parse_window_id(parent_window);
return execFileDialog(opts, handle, response, results, error);
}
@@ -108,7 +107,7 @@ bool TDEFileChooserPortal::SaveFile(const TQT_DBusObjectPath& handle,
if (OPTION_VALID("current_name", "s"))
opts.startName = options["current_name"].value.toString();
- opts.windowId = parseWindowId(parent_window);
+ opts.windowId = parse_window_id(parent_window);
return execFileDialog(opts, handle, response, results, error);
}
@@ -255,21 +254,6 @@ bool TDEFileChooserPortal::execFileDialog(FileDialogOpts options,
return true;
}
-WId TDEFileChooserPortal::parseWindowId(const TQString data)
-{
- if (!data.startsWith("x11:"))
- {
- kdWarning() << "[FileChooser] Window Identifiers are currently only "
- << "supported for X11. Created dialog will be parentless."
- << endl;
- return 0;
- }
-
- bool ok;
- WId wid = data.mid(4).toInt(&ok, 16);
- return ok ? wid : 0;
-}
-
TQString TDEFileChooserPortal::parseFilter(const TQT_DBusData data)
{
TQStringList patternList;
diff --git a/src/permission_dialog.cpp b/src/permission_dialog.cpp
new file mode 100644
index 0000000..310bebb
--- /dev/null
+++ b/src/permission_dialog.cpp
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ XDG desktop portal implementation for TDE
+ Copyright © 2024 Mavridis Philippe <mavridisf@gmail.com>
+
+ This program or library 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.1 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, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Improvements and feedback are welcome!
+*******************************************************************************/
+
+// TQt
+#include <tqvbox.h>
+#include <tqhbox.h>
+#include <tqlayout.h>
+#include <tqlabel.h>
+
+// TDE
+#include <tdelocale.h>
+#include <kiconloader.h>
+#include <twin.h>
+
+// Portal
+#include "permission_dialog.h"
+#include "permission_dialog.moc"
+
+TDEPermissionDialog::TDEPermissionDialog(TQString application, TQString feature,
+ TQString icon, Dictionary details)
+
+: KDialogBase(TQString::null, /* we set plain caption below */
+ KDialogBase::Yes | KDialogBase::No | KDialogBase::Details,
+ KDialogBase::NoDefault, KDialogBase::No,
+ nullptr, "permissiondlg", true, true,
+ KGuiItem(i18n("&Allow"), "button_ok"),
+ KGuiItem(i18n("&Deny"), "button_cancel")),
+
+ m_vbox(new TQVBox(this)),
+ m_hbox(new TQHBox(m_vbox)),
+ m_icon(new TQLabel(m_hbox)),
+ m_text(new TQLabel(m_hbox)),
+ m_detail(new TQLabel(this))
+
+{
+ setPlainCaption(i18n("Permission request"));
+
+ TQString text;
+ if (!application.isEmpty())
+ {
+ text = "<qt>Application \"%1\" has requested the following permission: <b>%2</b></qt>";
+ text = text.arg(application);
+ }
+ else
+ text = "<qt>An unknown application has requested the following permission: <b>%1</b></qt>";
+ m_text->setText(text.arg(feature));
+
+ m_icon->setPixmap(DesktopIcon(icon));
+
+ m_icon->setSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Fixed);
+ m_text->setSizePolicy(TQSizePolicy::Minimum, TQSizePolicy::Fixed);
+
+ TQString detailStr = "<qt><table><tbody>";
+ for (Dictionary::iterator it = details.begin(); it != details.end(); ++it)
+ {
+ detailStr += TQString("<tr><td>%1:</td><td><b>%2</b></td></tr>")
+ .arg(it.key(), it.data());
+ }
+ detailStr += "</tbody></table></qt>";
+ m_detail->setText(detailStr);
+
+ setMainWidget(m_vbox);
+ setDetailsWidget(m_detail);
+
+ m_hbox->setSizePolicy(TQSizePolicy::Preferred, TQSizePolicy::Fixed);
+
+// m_vbox->setMargin(KDialogBase::marginHint());
+ m_icon->setMargin(KDialogBase::spacingHint());
+ m_text->setMargin(KDialogBase::spacingHint());
+ raise();
+}
+
+TDEPermissionDialog::~TDEPermissionDialog()
+{
+}
+
+void TDEPermissionDialog::appendWidget(TQWidget *widget)
+{
+ m_vbox->hide();
+ widget->reparent(m_vbox, TQPoint());
+ m_vbox->show();
+} \ No newline at end of file
diff --git a/src/permission_dialog.h b/src/permission_dialog.h
new file mode 100644
index 0000000..9fe3a99
--- /dev/null
+++ b/src/permission_dialog.h
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ XDG desktop portal implementation for TDE
+ Copyright © 2024 Mavridis Philippe <mavridisf@gmail.com>
+
+ This program or library 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.1 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, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Improvements and feedback are welcome!
+*******************************************************************************/
+
+#ifndef __PERMISSION_DIALOG_H
+#define __PERMISSION_DIALOG_H
+
+// TDE
+#include <kdialogbase.h>
+
+typedef TQMap<TQString, TQString> Dictionary;
+
+class TQVBox;
+class TQHBox;
+class TQLabel;
+
+class TDEPermissionDialog : public KDialogBase
+{
+ TQ_OBJECT
+
+ public:
+ TDEPermissionDialog(TQString application, TQString feature,
+ TQString icon = "messagebox_question",
+ Dictionary details = {});
+ virtual ~TDEPermissionDialog();
+
+ void appendWidget(TQWidget *widget);
+
+ private:
+ TQVBox *m_vbox;
+ TQHBox *m_hbox;
+ TQLabel *m_icon;
+ TQLabel *m_text;
+ TQLabel *m_detail;
+};
+
+#endif // __PERMISSION_DIALOG_H \ No newline at end of file
diff --git a/src/portal_service.cpp b/src/portal_service.cpp
index 280078d..0344830 100644
--- a/src/portal_service.cpp
+++ b/src/portal_service.cpp
@@ -30,8 +30,9 @@
#include <kdebug.h>
// Portal
-#include "file_chooser_portal.h"
+#include "account_portal.h"
#include "email_portal.h"
+#include "file_chooser_portal.h"
#include "portal_service.h"
@@ -44,16 +45,18 @@ DesktopNodeService::DesktopNodeService(TQT_DBusConnection &connection)
{
m_interfaces.insert("org.freedesktop.DBus.Introspectable", this);
- REGISTER_PORTAL(TDEFileChooserPortal)
+ REGISTER_PORTAL(TDEAccountPortal)
REGISTER_PORTAL(TDEEmailPortal)
+ REGISTER_PORTAL(TDEFileChooserPortal)
registerObject(connection, dbusObjectPath);
}
DesktopNodeService::~DesktopNodeService()
{
- DESTROY_PORTAL(TDEFileChooserPortal)
+ DESTROY_PORTAL(TDEAccountPortal)
DESTROY_PORTAL(TDEEmailPortal)
+ DESTROY_PORTAL(TDEFileChooserPortal)
}
TQT_DBusObjectBase* DesktopNodeService::createInterface(const TQString& iface)
diff --git a/src/util.cpp b/src/util.cpp
index 7474fa1..4975663 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -19,12 +19,66 @@
Improvements and feedback are welcome!
*******************************************************************************/
+// TQt
+#include <tqfileinfo.h>
+
// TDE
+#include <kservice.h>
#include <kdebug.h>
// Portal
#include "util.h"
+WId parse_window_id(const TQString data)
+{
+ if (!data.startsWith("x11:"))
+ {
+ kdWarning() << "[FileChooser] Window Identifiers are currently only "
+ << "supported for X11. Created dialog will be parentless."
+ << endl;
+ return 0;
+ }
+
+ bool ok;
+ WId wid = data.mid(4).toInt(&ok, 16);
+ return ok ? wid : 0;
+}
+
+ApplicationInfo application_info_from_wid(WId wid)
+{
+ ApplicationInfo app;
+ if (wid)
+ {
+ // we need to get the pid but only deprecated KWin::Info has it
+ KWin::Info info = KWin::info(wid);
+ TQFileInfo fi(TQString("/proc/%1/exe").arg(info.pid));
+ if (fi.exists() && fi.isSymLink()) {
+ fi = TQFileInfo(fi.readLink());
+
+ app.path = fi.filePath();
+
+ // try to find corresponding desktop file
+ KService::List all = KService::allServices();
+ KService::List::ConstIterator svc;
+ for (svc = all.begin(); svc != all.end(); ++svc) {
+ TQString exec((*svc)->exec());
+ if (exec.startsWith(fi.filePath()) ||
+ exec.startsWith(fi.fileName()))
+ {
+ app.desktopFile = (*svc)->desktopEntryPath();
+ app.name = (*svc)->name();
+ break;
+ }
+ }
+
+ // Last resort
+ if (app.name.isEmpty())
+ app.name = fi.fileName();
+ }
+ }
+ return app;
+}
+
bool check_variant(TQT_DBusVariant variant, TQString signature)
{
return !variant.signature.isNull() && variant.signature == signature;
diff --git a/src/util.h b/src/util.h
index f27b7b8..e5a2040 100644
--- a/src/util.h
+++ b/src/util.h
@@ -26,6 +26,7 @@
#include <tqdbusvariant.h>
#include <tqdbusdatalist.h>
#include <tqvariant.h>
+#include <twin.h>
// TDE
#include <kurl.h>
@@ -33,6 +34,18 @@
typedef TQMap<TQString, TQT_DBusVariant> TQT_DBusVariantMap;
typedef TQValueList<TQT_DBusData> TQT_DBusValueList;
+struct ApplicationInfo
+{
+ TQString name;
+ TQString path;
+ TQString desktopFile;
+ int pid;
+};
+
+extern WId parse_window_id(const TQString data);
+
+extern ApplicationInfo application_info_from_wid(WId wid);
+
extern bool check_variant(TQT_DBusVariant variant, TQString signature);
extern TQString bytelist_to_string(TQT_DBusDataList list);