summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMavridis Philippe <mavridisf@gmail.com>2024-10-02 20:39:12 +0300
committerMavridis Philippe <mavridisf@gmail.com>2024-10-02 20:39:12 +0300
commitb0aeeeb9669438db204b88711ab318a5dcab8f98 (patch)
tree8a7e74c15899b67343cda288e01b449ccd9db60b
parent2397c7e9cb9eba2b2b7934ef7d59e1bd3035c67d (diff)
downloadxdg-desktop-portal-tde-b0aeeeb9669438db204b88711ab318a5dcab8f98.tar.gz
xdg-desktop-portal-tde-b0aeeeb9669438db204b88711ab318a5dcab8f98.zip
Port TDEFileChooserPortal::SaveFiles and TDEAccountPortal to DialogResultSender
Signed-off-by: Mavridis Philippe <mavridisf@gmail.com>
-rw-r--r--interfaces/interfaces.xml2
-rw-r--r--src/account_portal.cpp165
-rw-r--r--src/account_portal.h20
-rw-r--r--src/dialog_result_sender.cpp39
-rw-r--r--src/dialog_result_sender.h85
-rw-r--r--src/file_chooser_portal.cpp200
-rw-r--r--src/file_chooser_portal.h25
-rw-r--r--src/request.cpp70
-rw-r--r--src/request.h58
9 files changed, 483 insertions, 181 deletions
diff --git a/interfaces/interfaces.xml b/interfaces/interfaces.xml
index e86379f..7b9c2c8 100644
--- a/interfaces/interfaces.xml
+++ b/interfaces/interfaces.xml
@@ -3,6 +3,7 @@
<!-- Account -->
<interface name="org.freedesktop.impl.portal.Account">
<method name="GetUserInformation">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
<arg type="o" name="handle" direction="in"/>
<arg type="s" name="app_id" direction="in"/>
<arg type="s" name="window" direction="in"/>
@@ -48,6 +49,7 @@
<arg name="results" type="a{sv}" direction="out" />
</method>
<method name="SaveFiles">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
<arg name="handle" type="o" direction="in" />
<arg name="app_id" type="s" direction="in" />
<arg name="parent_window" type="s" direction="in" />
diff --git a/src/account_portal.cpp b/src/account_portal.cpp
index a20559b..ba45b83 100644
--- a/src/account_portal.cpp
+++ b/src/account_portal.cpp
@@ -48,87 +48,14 @@
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;
+ // Get account information
KUser user;
- info.userId = TQString::number(user.uid());
- info.loginName = user.loginName();
- info.realName = user.fullName();
- info.homeDirectory = user.homeDir();
- findUserAvatar(info);
- return info;
-}
+ m_info.userId = TQString::number(user.uid());
+ m_info.loginName = user.loginName();
+ m_info.realName = user.fullName();
+ m_info.homeDirectory = user.homeDir();
-void TDEAccountPortal::findUserAvatar(AccountInfo &info)
-{
+ // -- Find user avatar
// Parse tdmrc settings to determine face source and system location
const int fAdminOnly = 1;
const int fAdminFirst = fAdminOnly + 1;
@@ -156,7 +83,7 @@ void TDEAccountPortal::findUserAvatar(AccountInfo &info)
// Faces provided by administrator (default and per user)
const TQString systemDefault(userPicsDir + ".default.face.icon");
- const TQString systemUser(userPicsDir + info.loginName + ".face.icon");
+ const TQString systemUser(userPicsDir + m_info.loginName + ".face.icon");
TQString avatar;
if (faceSource == fAdminFirst)
@@ -168,7 +95,7 @@ void TDEAccountPortal::findUserAvatar(AccountInfo &info)
if (faceSource >= fUserFirst)
{
- avatar = info.homeDirectory + "/.face.icon";
+ avatar = m_info.homeDirectory + "/.face.icon";
if (!TQFile::exists(avatar) && faceSource == fUserFirst)
avatar = systemUser;
@@ -183,7 +110,81 @@ void TDEAccountPortal::findUserAvatar(AccountInfo &info)
avatar = systemDefault;
}
- info.avatarPath = avatar;
+ m_info.avatarPath = avatar;
+}
+
+TDEAccountPortal::~TDEAccountPortal()
+{
+}
+
+void TDEAccountPortal::handleMethodReply(const TQT_DBusMessage &reply)
+{
+ m_connection.send(reply);
+}
+
+bool TDEAccountPortal::handleSignalSend(const TQT_DBusMessage& reply) {
+ handleMethodReply(reply);
+ return true;
+}
+
+void TDEAccountPortal::GetUserInformationAsync(int asyncCallId,
+ const TQT_DBusObjectPath& handle,
+ const TQString& app_id,
+ const TQString& window,
+ const TQT_DBusVariantMap& options)
+{
+ 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
+ );
+ appendDataPreview(dialog, m_info);
+
+ if (wid > 0) KWin::setMainWindow(dialog, wid);
+
+ auto *sender = new DialogResultSender<TDEAccountPortal>
+ (this, asyncCallId, dialog,
+ &TDEAccountPortal::prepareReply,
+ &TDEAccountPortal::GetUserInformationAsyncReply);
+ dialog->show();
+ sender->start();
+}
+
+DialogResult TDEAccountPortal::prepareReply(TQDialog *dlg)
+{
+ DialogResult res;
+ if (dlg->result() == KDialogBase::Yes)
+ {
+ res.response = 0;
+ res.results.insert("id", TQSTRING_TO_DBUS_VARIANT(m_info.userId));
+ res.results.insert("name", TQSTRING_TO_DBUS_VARIANT(m_info.realName));
+ res.results.insert("image", TQSTRING_TO_DBUS_VARIANT(m_info.avatarPath));
+ }
+ else
+ {
+ res.response = 1;
+ }
+ return res;
}
void TDEAccountPortal::appendDataPreview(TDEPermissionDialog *dlg, AccountInfo info)
diff --git a/src/account_portal.h b/src/account_portal.h
index b75fe26..f59fb71 100644
--- a/src/account_portal.h
+++ b/src/account_portal.h
@@ -23,6 +23,7 @@
#define __ACCOUNT_PORTAL_H
// Portal
+#include "dialog_result_sender.h"
#include "interfaces/accountInterface.h"
#include "interface.h"
@@ -50,22 +51,21 @@ class TDEAccountPortal : public TQObject,
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);
+ void GetUserInformationAsync(int asyncCallId,
+ const TQT_DBusObjectPath& handle,
+ const TQString& app_id,
+ const TQString& window,
+ const TQT_DBusVariantMap& options);
- AccountInfo getAccountInfo();
void appendDataPreview(TDEPermissionDialog *dlg, AccountInfo info);
- private:
- void findUserAvatar(AccountInfo &info);
+ DialogResult prepareReply(TQDialog *dlg);
private:
+ AccountInfo m_info;
TQT_DBusConnection m_connection;
+
+ friend class DialogResultSender<TDEAccountPortal>;
};
#endif // __ACCOUNT_PORTAL_H
diff --git a/src/dialog_result_sender.cpp b/src/dialog_result_sender.cpp
new file mode 100644
index 0000000..21fffaa
--- /dev/null
+++ b/src/dialog_result_sender.cpp
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ 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!
+*******************************************************************************/
+
+// Portal
+#include "dialog_result_sender.h"
+
+template <class T>
+DialogResultSender<T>::DialogResultSender(T* portal, int asyncCallId, TQDialog *dlg,
+ ResultPrepareCallback<T> prepareCb, ResultSendCallback<T> sendCb)
+{}
+
+template <class T>
+DialogResultSender<T>::~DialogResultSender()
+{
+}
+
+template <class T>
+void DialogResultSender<T>::run()
+{
+
+} \ No newline at end of file
diff --git a/src/dialog_result_sender.h b/src/dialog_result_sender.h
new file mode 100644
index 0000000..0c14e78
--- /dev/null
+++ b/src/dialog_result_sender.h
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ 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 __DIALOG_RESULT_SENDER_H
+#define __DIALOG_RESULT_SENDER_H
+
+// TQt
+#include <tqthread.h>
+#include <tqdialog.h>
+
+// Portal
+#include "util.h"
+
+struct DialogResult
+{
+ TQ_UINT32 response;
+ TQT_DBusVariantMap results;
+};
+
+template <class T>
+using ResultPrepareCallback = DialogResult(T::*)(TQDialog*);
+
+template <class T>
+using ResultSendCallback = void(T::*)(int, TQ_UINT32, const TQT_DBusVariantMap&);
+
+template <class T>
+class DialogResultSender : public TQThread
+{
+ public:
+ DialogResultSender(T* portal, int asyncCallId, TQDialog *dlg, ResultPrepareCallback<T> prepareCb, ResultSendCallback<T> sendCb)
+ : TQThread(),
+ m_portal(portal),
+ m_asyncCallId(asyncCallId),
+ m_dlg(dlg),
+ m_prepareCb(prepareCb),
+ m_sendCb(sendCb)
+ {}
+
+ ~DialogResultSender()
+ {
+ wait();
+ }
+
+ void run()
+ {
+ if (!m_dlg) return;
+
+ while (m_dlg->isVisible())
+ {
+ usleep(1000);
+ }
+
+ DialogResult res = (m_portal->*m_prepareCb)(m_dlg);
+ (m_portal->*m_sendCb)(m_asyncCallId, res.response, res.results);
+
+ m_dlg->deleteLater();
+ }
+
+ private:
+ T *m_portal;
+ int m_asyncCallId;
+ TQDialog *m_dlg;
+ ResultPrepareCallback<T> m_prepareCb;
+ ResultSendCallback<T> m_sendCb;
+};
+
+#endif // __DIALOG_RESULT_SENDER_H \ No newline at end of file
diff --git a/src/file_chooser_portal.cpp b/src/file_chooser_portal.cpp
index 246ad1a..7d6eb02 100644
--- a/src/file_chooser_portal.cpp
+++ b/src/file_chooser_portal.cpp
@@ -35,46 +35,76 @@
#include "file_chooser_portal.h"
#include "file_chooser_portal.moc"
-class DialogResultSender : public TQThread
+class KMultiFileSaveDialog : public KFileDialog
{
public:
- DialogResultSender(KFileDialog *dlg, int asyncCallId, TDEFileChooserPortal *portal, TQT_DBusAsyncCallback callback)
- : TQThread(), m_dlg(dlg), m_asyncCallId(asyncCallId), m_portal(portal), m_callback(callback)
+ KMultiFileSaveDialog(TQString startDir, TQStringList filelist,
+ const char *name, bool modal)
+ : KFileDialog(startDir, TQString::null, nullptr, name, modal),
+ m_files(filelist)
{}
- ~DialogResultSender()
+ KURL::List urls()
{
- wait();
+ return m_urls;
}
- void run()
+ protected slots:
+ // The below is a workaround to prevent the dialog from disappearing
+ // until we are done handling conflicting files.
+ // Don't kick it, it works.
+ void done(int) {}
+ void actuallyDone(int r) { KFileDialog::done(r); }
+
+ void slotCancel()
+ {
+ actuallyDone(KFileDialog::Rejected);
+ }
+
+ void slotOk()
{
- if (!m_dlg) return;
+ KFileDialog::slotOk();
+ m_urls.clear();
- while (m_dlg->isVisible())
+ // Check if there are conflicting files in the target directory
+ // and prompt for action
+ TQDir d(selectedURL().path());
+ for (TQStringList::Iterator it = m_files.begin(); it != m_files.end(); ++it)
{
- usleep(1000);
+ TQString filename(*it);
+ TQFileInfo fi(d, filename);
+ KURL url(fi.absFilePath());
+ if (fi.exists())
+ {
+ TDEIO::RenameDlg rename(nullptr, caption(), TQString::null,
+ fi.absFilePath(), TDEIO::M_OVERWRITE);
+ int result = rename.exec();
+
+ switch (result)
+ {
+ case TDEIO::R_RENAME:
+ m_urls << rename.newDestURL();
+ break;
+ case TDEIO::R_OVERWRITE:
+ m_urls << url.url();
+ break;
+ case TDEIO::R_CANCEL:
+ default:
+ actuallyDone(KFileDialog::Rejected);
+ break;
+ }
+ }
+ else
+ {
+ m_urls << url.url();
+ }
}
-
- KURL::List urllist = m_dlg->selectedURLs();
-
- TQMap<TQString, TQT_DBusVariant> results;
- TQT_DBusDataList urls = kurl_list_to_datalist(urllist);
- TQT_DBusVariant var = TQT_DBusData::fromList(urls).getAsVariantData().toVariant();
- results.insert("uris", var);
-
- TQ_UINT32 response = urllist.isEmpty() ? 1 : 0;
-
- (m_portal->*m_callback)(m_asyncCallId, response, results);
-
- m_dlg->deleteLater();
+ actuallyDone(KFileDialog::Accepted);
}
private:
- KFileDialog *m_dlg;
- int m_asyncCallId;
- TDEFileChooserPortal *m_portal;
- TQT_DBusAsyncCallback m_callback;
+ TQStringList m_files;
+ KURL::List m_urls;
};
TDEFileChooserPortal::TDEFileChooserPortal(TQT_DBusConnection &connection)
@@ -153,21 +183,22 @@ void TDEFileChooserPortal::SaveFileAsync(int asyncCallId,
execFileDialog(&TDEFileChooserPortal::SaveFileAsyncReply, asyncCallId, opts, handle);
}
-bool TDEFileChooserPortal::SaveFiles(const TQT_DBusObjectPath& handle,
- const TQString& app_id,
- const TQString& parent_window,
- const TQString& title,
- const TQMap<TQString, TQT_DBusVariant> &options,
- TQ_UINT32& response,
- TQMap<TQString, TQT_DBusVariant> &results,
- TQT_DBusError& error)
+// TODO move some of the dialog handling stuff to execFileDialog()
+void TDEFileChooserPortal::SaveFilesAsync(int asyncCallId,
+ const TQT_DBusObjectPath& handle,
+ const TQString& app_id,
+ const TQString& parent_window,
+ const TQString& title,
+ const TQMap<TQString, TQT_DBusVariant> &options)
{
// Get list of files to save
if (!OPTION_VALID("files", "aay"))
{
kdWarning() << "TDEFileChooserPortal::SaveFiles: "
- << "Invalid or misssing files option" << endl;
- return false;
+ << "Invalid or missing files option" << endl;
+
+ SaveFilesAsyncReply(asyncCallId, 0, TQT_DBusVariantMap());
+ return;
}
TQT_DBusValueList filelist = options["files"].value.toTQValueList();
@@ -192,9 +223,9 @@ bool TDEFileChooserPortal::SaveFiles(const TQT_DBusObjectPath& handle,
opts.startDir = bytelist_to_string(options["current_folder"].value.toList().toByteList());
// We can't just use execFileDialog because we need to do some special processing
- KFileDialog *dialog = new KFileDialog(opts.startDir, TQString::null,
- nullptr, "xdg-tde-file-chooser",
- opts.modal);
+ KMultiFileSaveDialog *dialog = new KMultiFileSaveDialog(opts.startDir, files,
+ "xdg-tde-file-chooser",
+ opts.modal);
dialog->setMode(KFile::LocalOnly | KFile::Directory);
@@ -206,40 +237,13 @@ bool TDEFileChooserPortal::SaveFiles(const TQT_DBusObjectPath& handle,
if (opts.windowId > 0) KWin::setMainWindow(dialog, opts.windowId);
- if (dialog->exec() == TQDialog::Accepted)
- {
- TQDir d(dialog->selectedURL().path());
- KURL::List urllist;
- for (TQStringList::Iterator it = files.begin(); it != files.end(); ++it)
- {
- TQString filename = (*it);
- TQFileInfo fi(d, filename);
- KURL url(fi.absFilePath());
- if (fi.exists())
- {
- TDEIO::RenameDlg rename(dialog, opts.caption, TQString::null,
- fi.absFilePath(), TDEIO::M_OVERWRITE);
- int result = rename.exec();
- switch (result)
- {
- case TDEIO::R_RENAME:
- url = rename.newDestURL();
- break;
- case TDEIO::R_CANCEL:
- url = KURL();
- break;
- }
- }
- urllist << url.url();
- }
+ auto *sender = new DialogResultSender<TDEFileChooserPortal>
+ (this, asyncCallId, dialog,
+ &TDEFileChooserPortal::prepareSaveFilesReply,
+ &TDEFileChooserPortal::SaveFilesAsyncReply);
+ dialog->show();
+ sender->start();
- response = 0;
- TQT_DBusDataList urls = kurl_list_to_datalist(urllist);
- TQT_DBusVariant var = TQT_DBusData::fromList(urls).getAsVariantData().toVariant();
- results.insert("uris", var);
- }
- else response = 1;
- return true;
}
void TDEFileChooserPortal::handleMethodReply(const TQT_DBusMessage &reply)
@@ -252,7 +256,7 @@ bool TDEFileChooserPortal::handleSignalSend(const TQT_DBusMessage& reply) {
return true;
}
-void TDEFileChooserPortal::execFileDialog(TQT_DBusAsyncCallback callback,
+void TDEFileChooserPortal::execFileDialog(ResultSendCallback<TDEFileChooserPortal> callback,
int asyncCallId,
FileDialogOpts options,
const TQT_DBusObjectPath& handle)
@@ -271,25 +275,63 @@ void TDEFileChooserPortal::execFileDialog(TQT_DBusAsyncCallback callback,
dialog->setMode(mode | options.mode());
if (!options.caption.isNull())
- dialog->setPlainCaption(options.caption);
+ {
+ dialog->setPlainCaption(options.caption);
+ }
if (!options.okButtonText.isNull())
- dialog->okButton()->setText(options.okButtonText);
+ {
+ dialog->okButton()->setText(options.okButtonText);
+ }
if (!options.filters.isNull())
- dialog->setFilter(options.filters);
+ {
+ dialog->setFilter(options.filters);
+ }
dialog->setSelection(options.startName);
if (options.windowId > 0) KWin::setMainWindow(dialog, options.windowId);
-// return dialog->selectedURLs();
-
- DialogResultSender *sender = new DialogResultSender(dialog, asyncCallId, this, callback);
+ auto *sender = new DialogResultSender<TDEFileChooserPortal>
+ (this, asyncCallId, dialog, &TDEFileChooserPortal::prepareReply, callback);
dialog->show();
sender->start();
}
+DialogResult TDEFileChooserPortal::prepareReply(TQDialog *dlg)
+{
+ KFileDialog *fd = static_cast<KFileDialog*>(dlg);
+ KURL::List urllist = fd->selectedURLs();
+
+ DialogResult res;
+ TQT_DBusDataList urls = kurl_list_to_datalist(urllist);
+ TQT_DBusVariant var = TQT_DBusData::fromList(urls).getAsVariantData().toVariant();
+ res.results.insert("uris", var);
+ res.response = urllist.isEmpty() ? 1 : 0;
+ return res;
+}
+
+// Special treatment for SaveFiles()
+// TODO revise this and possibly merge with prepareReply()
+DialogResult TDEFileChooserPortal::prepareSaveFilesReply(TQDialog *dlg)
+{
+ DialogResult res;
+ if (dlg->result() == TQDialog::Accepted)
+ {
+ KMultiFileSaveDialog *fd = static_cast<KMultiFileSaveDialog*>(dlg);
+
+ TQT_DBusDataList urls = kurl_list_to_datalist(fd->urls());
+ TQT_DBusVariant var = TQT_DBusData::fromList(urls).getAsVariantData().toVariant();
+
+ res.response = 0;
+ res.results.insert("uris", var);
+ }
+ else res.response = 1;
+
+ return res;
+}
+
TQString TDEFileChooserPortal::parseFilter(const TQT_DBusData data)
{
TQStringList patternList;
diff --git a/src/file_chooser_portal.h b/src/file_chooser_portal.h
index 383d219..8377fc9 100644
--- a/src/file_chooser_portal.h
+++ b/src/file_chooser_portal.h
@@ -28,9 +28,9 @@
// Portal
#include "interfaces/filechooserInterface.h"
#include "interface.h"
+#include "dialog_result_sender.h"
class TDEFileChooserPortal;
-typedef void(TDEFileChooserPortal::*TQT_DBusAsyncCallback)(int, TQ_UINT32, const TQT_DBusVariantMap&);
struct FileDialogOpts
{
@@ -78,14 +78,12 @@ class TDEFileChooserPortal : public TQObject,
const TQString& title,
const TQT_DBusVariantMap &options);
- virtual bool SaveFiles(const TQT_DBusObjectPath& handle,
- const TQString& app_id,
- const TQString& parent_window,
- const TQString& title,
- const TQT_DBusVariantMap &options,
- TQ_UINT32& response,
- TQT_DBusVariantMap &results,
- TQT_DBusError& error);
+ void SaveFilesAsync(int asyncCallId,
+ const TQT_DBusObjectPath& handle,
+ const TQString& app_id,
+ const TQString& parent_window,
+ const TQString& title,
+ const TQT_DBusVariantMap &options);
virtual void handleMethodReply(const TQT_DBusMessage& reply);
virtual bool handleSignalSend(const TQT_DBusMessage& reply);
@@ -94,14 +92,21 @@ class TDEFileChooserPortal : public TQObject,
TQT_DBusConnection m_connection;
WId parseWindowId(const TQString data);
+
+ protected:
TQString parseFilter(const TQT_DBusData data);
TQString parseFilterList(const TQT_DBusVariant filterData,
const TQT_DBusVariant currentFilterData);
- void execFileDialog(TQT_DBusAsyncCallback callback,
+ void execFileDialog(ResultSendCallback<TDEFileChooserPortal> callback,
int asyncCallId,
FileDialogOpts options,
const TQT_DBusObjectPath& handle);
+
+ DialogResult prepareReply(TQDialog *dlg);
+ DialogResult prepareSaveFilesReply(TQDialog *dlg);
+
+ friend class DialogResultSender<TDEFileChooserPortal>;
};
#endif // __FILE_CHOOSER_PORTAL_H
diff --git a/src/request.cpp b/src/request.cpp
new file mode 100644
index 0000000..e3d043d
--- /dev/null
+++ b/src/request.cpp
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ 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>
+#include <tdemessagebox.h>
+
+// Portal
+#include "request.h"
+#include "request.moc"
+
+Request::Request(TQT_DBusConnection connection, const TQT_DBusObjectPath &handle,
+ TQObject *parent, const TQVariant data)
+: TQObject(parent),
+ m_connection(connection),
+ m_handle(handle),
+ m_data(data),
+ m_registered(false)
+{
+ if (!m_connection.registerObject(m_handle, this))
+ {
+ kdWarning() << "Could not register Request object on " << m_handle << endl;
+ deleteLater();
+ return;
+ }
+ m_registered = true;
+}
+
+Request::~Request()
+{
+ if (m_registered) m_connection.unregisterObject(m_handle);
+}
+
+bool Request::handleMethodCall(const TQT_DBusMessage &message)
+{
+ if (message.interface() != "org.freedesktop.impl.portal.Request"
+ || message.member() != "Close")
+ {
+ return false;
+ }
+
+ TQT_DBusMessage reply = TQT_DBusMessage::methodReply(message);
+ m_connection.send(reply);
+
+ emit closeRequested();
+ emit closeRequested(m_data);
+
+ deleteLater();
+ return true;
+}
+
+// kate: replace-tabs true; tab-width 4; indent-width 4; \ No newline at end of file
diff --git a/src/request.h b/src/request.h
new file mode 100644
index 0000000..9552869
--- /dev/null
+++ b/src/request.h
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ 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 __REQUEST_H
+#define __REQUEST_H
+
+// TQt
+#include <tqobject.h>
+#include <tqvariant.h>
+#include <tqdbusconnection.h>
+#include <tqdbusmessage.h>
+#include <tqdbusobject.h>
+#include <tqdbusobjectpath.h>
+
+class Request : public TQObject, TQT_DBusObjectBase
+{
+ TQ_OBJECT
+
+ public:
+ Request(TQT_DBusConnection connection, const TQT_DBusObjectPath &handle,
+ TQObject *parent, const TQVariant data = TQVariant());
+ virtual ~Request();
+
+ protected:
+ virtual bool handleMethodCall(const TQT_DBusMessage& message);
+
+ signals:
+ void closeRequested(); // when we don't care about data
+ void closeRequested(const TQVariant &data);
+
+ private:
+ TQT_DBusConnection m_connection;
+ const TQT_DBusObjectPath &m_handle;
+ const TQVariant m_data;
+ bool m_registered;
+};
+
+#endif // __REQUEST_H
+
+// kate: replace-tabs true; tab-width 4; indent-width 4; \ No newline at end of file