From 87769ed51d8087ddc4a02705f39fe4f21431b66f Mon Sep 17 00:00:00 2001
From: Mavridis Philippe <mavridisf@gmail.com>
Date: Mon, 8 Jul 2024 01:04:09 +0300
Subject: Added Email interface, minor refactoring

Signed-off-by: Mavridis Philippe <mavridisf@gmail.com>
---
 README.md                   |   2 +-
 interfaces/CMakeLists.txt   |  45 +++++------------
 interfaces/filechooser.xml  |  32 ------------
 interfaces/interfaces.xml   |  46 +++++++++++++++++
 src/CMakeLists.txt          |   2 +
 src/email_portal.cpp        |  86 ++++++++++++++++++++++++++++++++
 src/email_portal.h          |  65 ++++++++++++++++++++++++
 src/file_chooser_portal.cpp |  21 +++-----
 src/file_chooser_portal.h   |  27 ++++------
 src/interface.h             |  46 +++++++++++++++++
 src/portal_service.cpp      |   3 ++
 src/util.cpp                | 117 ++++++++++++++++++++++++++++++++++++++++++++
 src/util.h                  |  92 +++-------------------------------
 13 files changed, 404 insertions(+), 180 deletions(-)
 delete mode 100644 interfaces/filechooser.xml
 create mode 100644 interfaces/interfaces.xml
 create mode 100644 src/email_portal.cpp
 create mode 100644 src/email_portal.h
 create mode 100644 src/interface.h
 create mode 100644 src/util.cpp

diff --git a/README.md b/README.md
index 9b09bad..b2b3d5a 100644
--- a/README.md
+++ b/README.md
@@ -20,13 +20,13 @@ if they are set to 2, set them to 1.
 ## State of implementation
 
 Currently implemented are the following interfaces:
+* Email - request to send an e-mail via the system e-mail client
 * FileChooser - request a file dialog
 
 The following implementations are planned (listed in no particular order):
 * Screenshot - request a screenshot
 * App Chooser - show a "Open with..." dialog for a file
 * Clipboard - request clipboard access (*)
-* Email - request to send an e-mail via the system e-mail client
 * OpenURI - request to open a URL
 * Secret - integration with TDEWallet
 * Account - request user information (username, full name, user icon)
diff --git a/interfaces/CMakeLists.txt b/interfaces/CMakeLists.txt
index 5a45e9f..d8e44c0 100644
--- a/interfaces/CMakeLists.txt
+++ b/interfaces/CMakeLists.txt
@@ -15,43 +15,24 @@ link_directories(
     ${DBUS_TQT_LIBRARY_DIRS}
 )
 
-set(interfaces filechooser)
+set(interfaces filechooser email)
+set(interface_HDRS introspectableInterface.h desktopNode.h dbusbaseNode.h)
+set(interface_SRCS introspectableInterface.cpp desktopNode.cpp dbusbaseNode.cpp)
 
 foreach(interface IN LISTS interfaces)
-    set(interface_HDRS
-        introspectableInterface.h
-        ${interface}Interface.h
-        ${interface}Proxy.h
-        desktopNode.h
-        dbusbaseNode.h
-    )
-
-    set(interface_SRCS
-        introspectableInterface.cpp
-        ${interface}Interface.cpp
-        ${interface}Proxy.cpp
-        desktopNode.cpp
-        dbusbaseNode.cpp
-    )
-
-    set(interface_xml ${CMAKE_CURRENT_SOURCE_DIR}/${interface}.xml)
-
-    add_custom_command(
-        OUTPUT ${interface_HDRS} ${interface_SRCS}
-        COMMAND ${DBUSXML2QT3_EXECUTABLE} ${interface_xml}
-        DEPENDS ${interface_xml}
-        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
-    )
-
-    add_custom_target(${interface} DEPENDS ${interface_SRCS})
-
-    list(APPEND interfaces_SRCS ${interface_SRCS})
-
+    list(APPEND interface_HDRS ${interface}Interface.h ${interface}Proxy.h)
+    list(APPEND interface_SRCS ${interface}Interface.cpp ${interface}Proxy.cpp)
 endforeach()
 
+add_custom_command(
+    OUTPUT ${interface_HDRS} ${interface_SRCS}
+    COMMAND ${DBUSXML2QT3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/interfaces.xml
+    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/interfaces.xml
+    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+)
+
 tde_add_library(portalinterfaces STATIC_PIC AUTOMOC
-    DEPENDENCIES ${interfaces}
-    SOURCES ${interfaces_SRCS}
+    SOURCES ${interface_SRCS}
     LINK ${DBUS_TQT_LIBRARIES}
 )
 
diff --git a/interfaces/filechooser.xml b/interfaces/filechooser.xml
deleted file mode 100644
index 5524d45..0000000
--- a/interfaces/filechooser.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
-<node name="/org/freedesktop/portal/desktop">
- <interface name="org.freedesktop.impl.portal.FileChooser">
-  <method name="OpenFile">
-   <arg name="handle" type="o" direction="in" />
-   <arg name="app_id" type="s" direction="in" />
-   <arg name="parent_window" type="s" direction="in" />
-   <arg name="title" type="s" direction="in" />
-   <arg name="options" type="a{sv}" direction="in" />
-   <arg name="response" type="u" direction="out" />
-   <arg name="results" type="a{sv}" direction="out" />
-  </method>
-  <method name="SaveFile">
-   <arg name="handle" type="o" direction="in" />
-   <arg name="app_id" type="s" direction="in" />
-   <arg name="parent_window" type="s" direction="in" />
-   <arg name="title" type="s" direction="in" />
-   <arg name="options" type="a{sv}" direction="in" />
-   <arg name="response" type="u" direction="out" />
-   <arg name="results" type="a{sv}" direction="out" />
-  </method>
-  <method name="SaveFiles">
-   <arg name="handle" type="o" direction="in" />
-   <arg name="app_id" type="s" direction="in" />
-   <arg name="parent_window" type="s" direction="in" />
-   <arg name="title" type="s" direction="in" />
-   <arg name="options" type="a{sv}" direction="in" />
-   <arg name="response" type="u" direction="out" />
-   <arg name="results" type="a{sv}" direction="out" />
-  </method>
- </interface>
-</node>
\ No newline at end of file
diff --git a/interfaces/interfaces.xml b/interfaces/interfaces.xml
new file mode 100644
index 0000000..003cdbd
--- /dev/null
+++ b/interfaces/interfaces.xml
@@ -0,0 +1,46 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node name="/org/freedesktop/portal/desktop">
+ <!-- Email -->
+ <interface name="org.freedesktop.impl.portal.Email">
+  <method name="ComposeEmail">+
+   <arg type="o" name="handle" direction="in"/>
+   <arg type="s" name="app_id" direction="in"/>
+   <arg type="s" name="parent_window" direction="in"/>
+   <arg type="a{sv}" name="options" direction="in"/>
+   <arg type="u" name="response" direction="out"/>
+   <arg type="a{sv}" name="results" direction="out"/>
+  </method>
+  <property name="version" type="u" access="read"/>
+ </interface>
+
+ <!-- FileChooser -->
+ <interface name="org.freedesktop.impl.portal.FileChooser">
+  <method name="OpenFile">
+   <arg name="handle" type="o" direction="in" />
+   <arg name="app_id" type="s" direction="in" />
+   <arg name="parent_window" type="s" direction="in" />
+   <arg name="title" type="s" direction="in" />
+   <arg name="options" type="a{sv}" direction="in" />
+   <arg name="response" type="u" direction="out" />
+   <arg name="results" type="a{sv}" direction="out" />
+  </method>
+  <method name="SaveFile">
+   <arg name="handle" type="o" direction="in" />
+   <arg name="app_id" type="s" direction="in" />
+   <arg name="parent_window" type="s" direction="in" />
+   <arg name="title" type="s" direction="in" />
+   <arg name="options" type="a{sv}" direction="in" />
+   <arg name="response" type="u" direction="out" />
+   <arg name="results" type="a{sv}" direction="out" />
+  </method>
+  <method name="SaveFiles">
+   <arg name="handle" type="o" direction="in" />
+   <arg name="app_id" type="s" direction="in" />
+   <arg name="parent_window" type="s" direction="in" />
+   <arg name="title" type="s" direction="in" />
+   <arg name="options" type="a{sv}" direction="in" />
+   <arg name="response" type="u" direction="out" />
+   <arg name="results" type="a{sv}" direction="out" />
+  </method>
+ </interface>
+</node>
\ No newline at end of file
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 8ca6297..0ed40be 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -29,6 +29,8 @@ tde_add_executable(
         portal_daemon.cpp
         portal_service.cpp
         file_chooser_portal.cpp
+        email_portal.cpp
+        util.cpp
 
     LINK
         tdecore-shared
diff --git a/src/email_portal.cpp b/src/email_portal.cpp
new file mode 100644
index 0000000..d12ba50
--- /dev/null
+++ b/src/email_portal.cpp
@@ -0,0 +1,86 @@
+/*******************************************************************************
+  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!
+*******************************************************************************/
+
+// TDE
+#include <tdeapplication.h>
+
+// Portal
+#include "email_portal.h"
+#include "email_portal.moc"
+
+TDEEmailPortal::TDEEmailPortal(TQT_DBusConnection &connection)
+: m_connection(connection)
+{
+}
+
+TDEEmailPortal::~TDEEmailPortal()
+{
+}
+
+void TDEEmailPortal::handleMethodReply(const TQT_DBusMessage &reply)
+{
+    m_connection.send(reply);
+}
+
+bool TDEEmailPortal::handleSignalSend(const TQT_DBusMessage& reply) {
+    handleMethodReply(reply);
+    return true;
+}
+
+bool TDEEmailPortal::ComposeEmail(const TQT_DBusObjectPath& handle,
+                                  const TQString& app_id,
+                                  const TQString& parent_window,
+                                  const TQT_DBusVariantMap& options,
+                                  TQ_UINT32& response,
+                                  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();
+
+    if (OPTION_VALID("addresses", "as"))
+        opts.rcpt += options["addresses"].value.toList().toTQStringList();
+
+    if (OPTION_VALID("cc", "as"))
+        opts.cc += options["cc"].value.toList().toTQStringList();
+
+    if (OPTION_VALID("bcc", "as"))
+        opts.bcc += options["bcc"].value.toList().toTQStringList();
+
+    if (OPTION_VALID("subject", "s"))
+        opts.subj = options["subject"].value.toString();
+
+    if (OPTION_VALID("body", "s"))
+        opts.body = options["body"].value.toString();
+
+    if (OPTION_VALID("attachments", "as"))
+    {
+        opts.attach += options["attachments"].value.toList().toTQStringList();
+    }
+
+    kapp->invokeMailer(opts.rcpt.join(";"), opts.cc.join(";"), opts.bcc.join(";"),
+                       opts.subj, opts.body, TQString::null, opts.attach);
+    return true;
+}
+
+// kate: replace-tabs true; tab-width 4; indent-width 4;
\ No newline at end of file
diff --git a/src/email_portal.h b/src/email_portal.h
new file mode 100644
index 0000000..0a59346
--- /dev/null
+++ b/src/email_portal.h
@@ -0,0 +1,65 @@
+/*******************************************************************************
+  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 __EMAIL_PORTAL_H
+#define __EMAIL_PORTAL_H
+
+// Portal
+#include "interfaces/emailInterface.h"
+#include "interface.h"
+
+struct EmailOpts
+{
+    TQStringList rcpt;
+    TQStringList cc;
+    TQStringList bcc;
+    TQString subj;
+    TQString body;
+    TQStringList attach;
+};
+
+class TDEEmailPortal : public TQObject,
+                       public org::freedesktop::impl::portal::EmailInterface
+{
+    public:
+        INTERFACE("org.freedesktop.impl.portal.Email")
+
+        TDEEmailPortal(TQT_DBusConnection &connection);
+        virtual ~TDEEmailPortal();
+
+    protected:
+        virtual void handleMethodReply(const TQT_DBusMessage& reply);
+        virtual bool handleSignalSend(const TQT_DBusMessage& reply);
+
+        virtual bool ComposeEmail(const TQT_DBusObjectPath& handle,
+                                  const TQString& app_id,
+                                  const TQString& parent_window,
+                                  const TQT_DBusVariantMap& options,
+                                  TQ_UINT32& response,
+                                  TQT_DBusVariantMap &results,
+                                  TQT_DBusError& error);
+    private:
+        TQT_DBusConnection m_connection;
+};
+
+#endif // __EMAIL_PORTAL_H
+
+// kate: replace-tabs true; tab-width 4; indent-width 4;
\ No newline at end of file
diff --git a/src/file_chooser_portal.cpp b/src/file_chooser_portal.cpp
index ee8b0f6..4668abd 100644
--- a/src/file_chooser_portal.cpp
+++ b/src/file_chooser_portal.cpp
@@ -33,11 +33,6 @@
 // Portal
 #include "file_chooser_portal.h"
 #include "file_chooser_portal.moc"
-#include "util.h"
-
-#define OPTION_VALID(opt, sig) \
-    options.keys().contains(opt) && check_variant(options[opt], sig)
-
 
 TDEFileChooserPortal::TDEFileChooserPortal(TQT_DBusConnection &connection)
     : m_connection(connection)
@@ -135,8 +130,8 @@ bool TDEFileChooserPortal::SaveFiles(const TQT_DBusObjectPath& handle,
         return false;
     }
 
-    TQValueList<TQT_DBusData> filelist = options["files"].value.toTQValueList();
-    TQValueList<TQT_DBusData>::iterator fi;
+    TQT_DBusValueList filelist = options["files"].value.toTQValueList();
+    TQT_DBusValueList::iterator fi;
     TQStringList files;
     for (fi = filelist.begin(); fi != filelist.end(); ++fi)
     {
@@ -279,15 +274,15 @@ TQString TDEFileChooserPortal::parseFilter(const TQT_DBusData data)
 {
     TQStringList patternList;
 
-    TQValueList<TQT_DBusData> filterData = data.toStruct();
+    TQT_DBusValueList filterData = data.toStruct();
 
     TQString label = filterData[0].toString();
-    TQValueList<TQT_DBusData> patterns = filterData[1].toTQValueList();
+    TQT_DBusValueList patterns = filterData[1].toTQValueList();
 
-    TQValueList<TQT_DBusData>::iterator fp;
+    TQT_DBusValueList::iterator fp;
     for (fp = patterns.begin(); fp != patterns.end(); ++fp)
     {
-        TQValueList<TQT_DBusData> patternData = (*fp).toStruct();
+        TQT_DBusValueList patternData = (*fp).toStruct();
         bool isMime = (patternData[0].toUInt32() == 1);
         if (isMime) {
             // KFileDialog cannot handle both a mime and a simple
@@ -326,9 +321,9 @@ TQString TDEFileChooserPortal::parseFilterList(const TQT_DBusVariant filterData,
                                                const TQT_DBusVariant currentFilterData)
 {
     TQStringList filterList;
-    TQValueList<TQT_DBusData> filters = filterData.value.toTQValueList();
+    TQT_DBusValueList filters = filterData.value.toTQValueList();
     if (filters.count() > 0) {
-        TQValueList<TQT_DBusData>::iterator f;
+        TQT_DBusValueList::iterator f;
         for (f = filters.begin(); f != filters.end(); ++f)
                 filterList += parseFilter((*f));
     }
diff --git a/src/file_chooser_portal.h b/src/file_chooser_portal.h
index ef7b43a..9732b8d 100644
--- a/src/file_chooser_portal.h
+++ b/src/file_chooser_portal.h
@@ -22,18 +22,12 @@
 #ifndef __FILE_CHOOSER_PORTAL_H
 #define __FILE_CHOOSER_PORTAL_H
 
-// TQt
-#include <tqdbusconnection.h>
-#include <tqdbusmessage.h>
-#include <tqdbusvariant.h>
-#include <tqdbuserror.h>
-#include <tqobject.h>
-
 // TDE
 #include <tdefile.h>
 
 // Portal
 #include "interfaces/filechooserInterface.h"
+#include "interface.h"
 
 struct FileDialogOpts
 {
@@ -60,44 +54,43 @@ class KFileDialog;
 class TDEFileChooserPortal : public TQObject,
                              public org::freedesktop::impl::portal::FileChooserInterface
 {
+    INTERFACE("org.freedesktop.impl.portal.FileChooser")
+
     public:
         TDEFileChooserPortal(TQT_DBusConnection &connection);
         virtual ~TDEFileChooserPortal();
 
-        static const TQString interface() { return "org.freedesktop.impl.portal.FileChooser"; }
-
     protected:
         virtual bool OpenFile(const TQT_DBusObjectPath& handle,
                               const TQString& app_id,
                               const TQString& parent_window,
                               const TQString& title,
-                              const TQMap<TQString, TQT_DBusVariant> &options,
+                              const TQT_DBusVariantMap &options,
                               TQ_UINT32& response,
-                              TQMap<TQString, TQT_DBusVariant> &results,
+                              TQT_DBusVariantMap &results,
                               TQT_DBusError& error);
 
         virtual bool SaveFile(const TQT_DBusObjectPath& handle,
                               const TQString& app_id,
                               const TQString& parent_window,
                               const TQString& title,
-                              const TQMap<TQString, TQT_DBusVariant> &options,
+                              const TQT_DBusVariantMap &options,
                               TQ_UINT32& response,
-                              TQMap<TQString, TQT_DBusVariant> &results,
+                              TQT_DBusVariantMap &results,
                               TQT_DBusError& error);
 
         virtual bool SaveFiles(const TQT_DBusObjectPath& handle,
                                const TQString& app_id,
                                const TQString& parent_window,
                                const TQString& title,
-                               const TQMap<TQString, TQT_DBusVariant> &options,
+                               const TQT_DBusVariantMap &options,
                                TQ_UINT32& response,
-                               TQMap<TQString, TQT_DBusVariant> &results,
+                               TQT_DBusVariantMap &results,
                                TQT_DBusError& error);
 
         virtual void handleMethodReply(const TQT_DBusMessage& reply);
         virtual bool handleSignalSend(const TQT_DBusMessage& reply);
 
-
     private:
         TQT_DBusConnection m_connection;
 
@@ -109,7 +102,7 @@ class TDEFileChooserPortal : public TQObject,
         bool execFileDialog(FileDialogOpts options,
                             const TQT_DBusObjectPath& handle,
                             TQ_UINT32& response,
-                            TQMap<TQString, TQT_DBusVariant> &results,
+                            TQT_DBusVariantMap &results,
                             TQT_DBusError& error);
 };
 
diff --git a/src/interface.h b/src/interface.h
new file mode 100644
index 0000000..48ce942
--- /dev/null
+++ b/src/interface.h
@@ -0,0 +1,46 @@
+/*******************************************************************************
+  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!
+*******************************************************************************/
+
+/* Common definitions and includes for portal interfaces */
+#ifndef __INTERFACE_H_
+#define __INTERFACE_H_
+
+// TQt
+#include <tqdbusconnection.h>
+#include <tqdbusmessage.h>
+#include <tqdbusvariant.h>
+#include <tqdbusdatalist.h>
+#include <tqdbusdata.h>
+#include <tqdbuserror.h>
+#include <tqobject.h>
+
+// Portal
+#include "util.h"
+
+#define INTERFACE(x) \
+    public: \
+        static const TQCString interface() { return x; }
+
+
+#define OPTION_VALID(opt, sig) \
+    options.keys().contains(opt) && check_variant(options[opt], sig)
+
+#endif // __INTERFACE_H_
\ No newline at end of file
diff --git a/src/portal_service.cpp b/src/portal_service.cpp
index 4e0eae3..280078d 100644
--- a/src/portal_service.cpp
+++ b/src/portal_service.cpp
@@ -31,6 +31,7 @@
 
 // Portal
 #include "file_chooser_portal.h"
+#include "email_portal.h"
 #include "portal_service.h"
 
 
@@ -44,6 +45,7 @@ DesktopNodeService::DesktopNodeService(TQT_DBusConnection &connection)
     m_interfaces.insert("org.freedesktop.DBus.Introspectable", this);
 
     REGISTER_PORTAL(TDEFileChooserPortal)
+    REGISTER_PORTAL(TDEEmailPortal)
 
     registerObject(connection, dbusObjectPath);
 }
@@ -51,6 +53,7 @@ DesktopNodeService::DesktopNodeService(TQT_DBusConnection &connection)
 DesktopNodeService::~DesktopNodeService()
 {
     DESTROY_PORTAL(TDEFileChooserPortal)
+    DESTROY_PORTAL(TDEEmailPortal)
 }
 
 TQT_DBusObjectBase* DesktopNodeService::createInterface(const TQString& iface)
diff --git a/src/util.cpp b/src/util.cpp
new file mode 100644
index 0000000..7474fa1
--- /dev/null
+++ b/src/util.cpp
@@ -0,0 +1,117 @@
+/*******************************************************************************
+  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!
+*******************************************************************************/
+
+// TDE
+#include <kdebug.h>
+
+// Portal
+#include "util.h"
+
+bool check_variant(TQT_DBusVariant variant, TQString signature)
+{
+    return !variant.signature.isNull() && variant.signature == signature;
+}
+
+TQString bytelist_to_string(TQT_DBusDataList list)
+{
+    if (list.type() != TQT_DBusData::Byte) return TQString::null;
+    TQCString bytes;
+    TQValueList<TQ_UINT8> vl = list.toByteList();
+    TQValueList<TQ_UINT8>::iterator vlit;
+    for (vlit = vl.begin(); vlit != vl.end(); ++vlit)
+    {
+        bytes += (*vlit);
+    }
+    return TQString::fromLocal8Bit(bytes.data(), bytes.size());
+}
+
+TQT_DBusDataList string_to_bytelist(TQString str)
+{
+    TQCString bytes = str.latin1();
+    TQValueList<TQ_UINT8> vl;
+    char *bit;
+    for (bit = bytes.begin(); bit != bytes.end(); ++bit)
+    {
+        vl << (TQ_UINT8)(*bit);
+    }
+    return TQT_DBusDataList(vl);
+}
+
+TQT_DBusDataList kurl_list_to_datalist(KURL::List urls)
+{
+    return TQT_DBusDataList(urls.toStringList());
+}
+
+bool make_variant(TQVariant variant, TQT_DBusVariant &other)
+{
+    TQString signature;
+    switch (variant.type()) {
+        case TQVariant::String:
+        case TQVariant::Color:
+        case TQVariant::Font:
+        case TQVariant::Date:
+        case TQVariant::DateTime:
+        case TQVariant::Time:
+        case TQVariant::KeySequence:
+            other.signature = "s";
+            other.value = TQT_DBusData::fromString(variant.toString());
+            break;
+
+        case TQVariant::Int:
+            other.signature = "i";
+            other.value = TQT_DBusData::fromInt32(variant.toInt());
+            break;
+
+        case TQVariant::UInt:
+            other.signature = "u";
+            other.value = TQT_DBusData::fromUInt32(variant.toUInt());
+            break;
+
+        case TQVariant::Double:
+        case TQVariant::LongLong:
+        case TQVariant::ULongLong:
+            other.signature = "d";
+            other.value = TQT_DBusData::fromDouble(variant.toDouble());
+            break;
+
+        case TQVariant::Bool:
+            other.signature = "b";
+            other.value = TQT_DBusData::fromBool(variant.toBool());
+            break;
+
+        case TQVariant::StringList:
+            other.signature = "as";
+            other.value = TQT_DBusData::fromList(TQT_DBusDataList(variant.toStringList()));
+            break;
+
+        default:
+            if (variant.canCast(TQVariant::String)) {
+                other.signature = "s";
+                other.value = TQT_DBusData::fromString(variant.toString());
+            }
+            else {
+                kdDebug() << "Cannot cast TQVariant of type " << variant.type()
+                          << "to TQT_DBusVariant!" << endl;
+                return false;
+            }
+    }
+    return true;
+}
\ No newline at end of file
diff --git a/src/util.h b/src/util.h
index 656bfff..f27b7b8 100644
--- a/src/util.h
+++ b/src/util.h
@@ -30,96 +30,18 @@
 // TDE
 #include <kurl.h>
 
-inline bool check_variant(TQT_DBusVariant variant, TQString signature)
-{
-    return !variant.signature.isNull() && variant.signature == signature;
-}
+typedef TQMap<TQString, TQT_DBusVariant> TQT_DBusVariantMap;
+typedef TQValueList<TQT_DBusData> TQT_DBusValueList;
 
-inline TQString bytelist_to_string(TQT_DBusDataList list)
-{
-    if (list.type() != TQT_DBusData::Byte) return TQString::null;
-    TQCString bytes;
-    TQValueList<TQ_UINT8> vl = list.toByteList();
-    TQValueList<TQ_UINT8>::iterator vlit;
-    for (vlit = vl.begin(); vlit != vl.end(); ++vlit)
-    {
-        bytes += (*vlit);
-    }
-    return TQString::fromLocal8Bit(bytes.data(), bytes.size());
-}
+extern bool check_variant(TQT_DBusVariant variant, TQString signature);
 
-inline TQT_DBusDataList string_to_bytelist(TQString str)
-{
-    TQCString bytes = str.latin1();
-    TQValueList<TQ_UINT8> vl;
-    char *bit;
-    for (bit = bytes.begin(); bit != bytes.end(); ++bit)
-    {
-        vl << (TQ_UINT8)(*bit);
-    }
-    return TQT_DBusDataList(vl);
-}
+extern TQString bytelist_to_string(TQT_DBusDataList list);
 
-inline TQT_DBusDataList kurl_list_to_datalist(KURL::List urls)
-{
-    return TQT_DBusDataList(urls.toStringList());
-}
+extern TQT_DBusDataList string_to_bytelist(TQString str);
 
-inline bool make_variant(TQVariant variant, TQT_DBusVariant &other)
-{
-    TQString signature;
-    switch (variant.type()) {
-        case TQVariant::String:
-        case TQVariant::Color:
-        case TQVariant::Font:
-        case TQVariant::Date:
-        case TQVariant::DateTime:
-        case TQVariant::Time:
-        case TQVariant::KeySequence:
-            other.signature = "s";
-            other.value = TQT_DBusData::fromString(variant.toString());
-            break;
+extern TQT_DBusDataList kurl_list_to_datalist(KURL::List urls);
 
-        case TQVariant::Int:
-            other.signature = "i";
-            other.value = TQT_DBusData::fromInt32(variant.toInt());
-            break;
-
-        case TQVariant::UInt:
-            other.signature = "u";
-            other.value = TQT_DBusData::fromUInt32(variant.toUInt());
-            break;
-
-        case TQVariant::Double:
-        case TQVariant::LongLong:
-        case TQVariant::ULongLong:
-            other.signature = "d";
-            other.value = TQT_DBusData::fromDouble(variant.toDouble());
-            break;
-
-        case TQVariant::Bool:
-            other.signature = "b";
-            other.value = TQT_DBusData::fromBool(variant.toBool());
-            break;
-
-        case TQVariant::StringList:
-            other.signature = "as";
-            other.value = TQT_DBusData::fromList(TQT_DBusDataList(variant.toStringList()));
-            break;
-
-        default:
-            if (variant.canCast(TQVariant::String)) {
-                other.signature = "s";
-                other.value = TQT_DBusData::fromString(variant.toString());
-            }
-            else {
-                kdDebug() << "Cannot cast TQVariant of type " << variant.type()
-                          << "to TQT_DBusVariant!" << endl;
-                return false;
-            }
-    }
-    return true;
-}
+extern bool make_variant(TQVariant variant, TQT_DBusVariant &other);
 
 #endif // __UTIL_H
 
-- 
cgit v1.2.3

