diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ea1cf18..34b1954 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -27,8 +27,8 @@ tde_add_executable( SOURCES PortalService.cpp PortalServiceDaemon.cpp main.cpp LINK - tdecore-shared - tdexdgdesktopportal-shared + tdecore-shared tdeui-shared tdeio-shared + tdexdgdesktopportal-static DESTINATION ${LIBEXEC_INSTALL_DIR} ) diff --git a/src/PortalService.cpp b/src/PortalService.cpp index 47acb67..c100720 100644 --- a/src/PortalService.cpp +++ b/src/PortalService.cpp @@ -23,9 +23,21 @@ #include #include +//FileChooser +#include +#include +#include + // TDE #include +#include #include +#include + +// FileChooser +#include "util.h" +#define OPTION_VALID(opt, sig) \ + options.keys().contains(opt) && check_variant(options[opt], sig) // Portal #include "PortalService.h" @@ -289,30 +301,223 @@ TQString FileChooserService::objectPath() const { return TQString(); } -bool FileChooserService::OpenFile(const TQT_DBusObjectPath& handle, const TQString& app_id, - const TQString& parent_window, const TQString& title, - const TQMap& options, TQ_UINT32& response, - TQMap& results, TQT_DBusError& error) { - // do something - return true; +bool FileChooserService::OpenFile(const TQT_DBusObjectPath& handle, + const TQString& app_id, + const TQString& parent_window, + const TQString& title, + const TQMap &options, + TQ_UINT32& response, + TQMap &results, + TQT_DBusError& error) +{ + FileDialogOpts opts; + + opts.caption = title; + + if (OPTION_VALID("accept_label", "s")) + opts.okButtonText = options["accept_label"].value.toString(); + + if (OPTION_VALID("directory", "b")) + opts.directory = options["directory"].value.toBool(); + + if (OPTION_VALID("multiple", "b")) + opts.multiple = options["multiple"].value.toBool(); + + if (OPTION_VALID("modal", "b")) + opts.modal = options["modal"].value.toBool(); + + if (OPTION_VALID("filters", "a(sa(us))")) + opts.filters = parseFilterList(options["filters"], options["current_filter"]); + + opts.windowId = parseWindowId(parent_window); + + return execFileDialog(opts, handle, response, results, error); } -bool FileChooserService::SaveFile(const TQT_DBusObjectPath& handle, const TQString& app_id, - const TQString& parent_window, const TQString& title, - const TQMap& options, TQ_UINT32& response, - TQMap& results, TQT_DBusError& error) { - // do something - return true; +bool FileChooserService::SaveFile(const TQT_DBusObjectPath& handle, + const TQString& app_id, + const TQString& parent_window, + const TQString& title, + const TQMap &options, + TQ_UINT32& response, + TQMap &results, + TQT_DBusError& error) +{ + FileDialogOpts opts; + + opts.caption = title; + + if (OPTION_VALID("accept_label", "s")) + opts.okButtonText = options["accept_label"].value.toString(); + + if (OPTION_VALID("directory", "b")) + opts.directory = options["directory"].value.toBool(); + + if (OPTION_VALID("multiple", "b")) + opts.multiple = options["multiple"].value.toBool(); + + if (OPTION_VALID("modal", "b")) + opts.modal = options["modal"].value.toBool(); + + if (OPTION_VALID("filters", "a(sa(us))")) + opts.filters = parseFilterList(options["filters"], options["current_filter"]); + + if (OPTION_VALID("current_folder", "ay")) + opts.startDir = bytelist_to_string(options["current_folder"].value.toList().toByteList()); + + if (OPTION_VALID("current_name", "s")) + opts.startName = options["current_name"].value.toString(); + + opts.windowId = parseWindowId(parent_window); + + return execFileDialog(opts, handle, response, results, error); } -bool FileChooserService::SaveFiles(const TQT_DBusObjectPath& handle, const TQString& app_id, - const TQString& parent_window, const TQString& title, - const TQMap& options, TQ_UINT32& response, - TQMap& results, TQT_DBusError& error) { - // do something +bool FileChooserService::SaveFiles(const TQT_DBusObjectPath& handle, + const TQString& app_id, + const TQString& parent_window, + const TQString& title, + const TQMap &options, + TQ_UINT32& response, + TQMap &results, + TQT_DBusError& error) +{ + return false; +} + +bool FileChooserService::execFileDialog(FileDialogOpts options, + const TQT_DBusObjectPath& handle, + TQ_UINT32& response, + TQMap &results, + TQT_DBusError& error) +{ + KFileDialog *dialog = new KFileDialog (options.startDir, TQString::null, + nullptr, "xdg-tde-file-chooser", + options.modal); + uint mode = KFile::LocalOnly; + if (options.savingMode) + { + dialog->setOperationMode(KFileDialog::Saving); + } + else { + mode |= KFile::ExistingOnly; + } + dialog->setMode(mode | options.mode()); + + if (!options.caption.isNull()) + dialog->setPlainCaption(options.caption); + + if (!options.okButtonText.isNull()) + dialog->okButton()->setText(options.okButtonText); + + if (!options.filters.isNull()) + dialog->setFilter(options.filters); + + dialog->setSelection(options.startName); + + if (options.windowId > 0) KWin::setMainWindow(dialog, options.windowId); + + if (dialog->exec() == TQDialog::Accepted) + { + response = 0; + TQT_DBusDataList urls = kurl_list_to_datalist(dialog->selectedURLs()); + TQT_DBusVariant var = TQT_DBusData::fromList(urls).getAsVariantData().toVariant(); + results.insert("uris", var); + } + else response = 1; return true; } +WId FileChooserService::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 FileChooserService::parseFilter(const TQT_DBusData data) +{ + TQStringList patternList; + + TQValueList filterData = data.toStruct(); + + TQString label = filterData[0].toString(); + TQValueList patterns = filterData[1].toTQValueList(); + + TQValueList::iterator fp; + for (fp = patterns.begin(); fp != patterns.end(); ++fp) + { + TQValueList patternData = (*fp).toStruct(); + bool isMime = (patternData[0].toUInt32() == 1); + if (isMime) { + // KFileDialog cannot handle both a mime and a simple + // extension filter, so in case we get a mimetype, + // we just get the associated extensions from the + // MIME system + TQString mime = patternData[1].toString(); + patternList += KMimeType::mimeType(mime)->patterns(); + } + else { + TQString patternString = patternData[1].toString(); + + // Regex patterns like *.[hH][tT][mM][lL] are unnecessary for us + // and causes a problem with the save dialog's extension autoselection + TQString finalPattern = patternString; + if (TQRegExp("[*.](?:[[](?:[A-Za-z]{2})[]])+").search(patternString) != -1) + { + finalPattern = "*."; + int pos = patternString.find('['); + while (pos != -1) + { + finalPattern += patternString[pos + 1]; + pos = patternString.find('[', patternString.find(']', pos)); + } + } + patternList += finalPattern; + } + } + + TQString patternString = patternList.join(" "); + + return TQString("%1|%2 (%3)").arg(patternString, label, patternString); +} + +TQString FileChooserService::parseFilterList(const TQT_DBusVariant filterData, + const TQT_DBusVariant currentFilterData) +{ + TQStringList filterList; + TQValueList filters = filterData.value.toTQValueList(); + if (filters.count() > 0) { + TQValueList::iterator f; + for (f = filters.begin(); f != filters.end(); ++f) + filterList += parseFilter((*f)); + } + + if (check_variant(currentFilterData, "(sa(us))")) + { + TQString currentFilter = parseFilter(currentFilterData.value); + if (filterList.contains(currentFilter)) + { + // We have no way to affect the filter selection of the dialog, + // so we just move the current filter to the top of the list + // to get it selected automatically + filterList.remove(currentFilter); + filterList.prepend(currentFilter); + } + } + + return filterList.join("\n"); +} + + void FileChooserService::handleMethodReply(const TQT_DBusMessage& reply) { m_connection->send(reply); } diff --git a/src/PortalService.h b/src/PortalService.h index fb744bb..1c7500e 100644 --- a/src/PortalService.h +++ b/src/PortalService.h @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -47,6 +48,28 @@ #include #include +// FileChooser +#include +struct FileDialogOpts +{ + TQString caption; + TQString okButtonText; + TQString startDir; + TQString startName; + TQString filters; + bool multiple = false; + bool directory = false; + bool savingMode = false; + bool modal = true; + WId windowId = 0; + + inline KFile::Mode mode() + { + if (directory) return KFile::Directory; + return multiple ? KFile::Files : KFile::File; + } +}; + class PropertiesService: public org::freedesktop::DBus::PropertiesInterface { public: @@ -223,6 +246,19 @@ protected: protected: // implement sending replies virtual void handleMethodReply(const TQT_DBusMessage& reply); + +private: + WId parseWindowId(const TQString data); + TQString parseFilter(const TQT_DBusData data); + TQString parseFilterList(const TQT_DBusVariant filterData, + const TQT_DBusVariant currentFilterData); + + bool execFileDialog(FileDialogOpts options, + const TQT_DBusObjectPath& handle, + TQ_UINT32& response, + TQMap &results, + TQT_DBusError& error); + private: TQT_DBusConnection *m_connection; }; diff --git a/src/file_chooser_portal.cpp b/src/file_chooser_portal.cpp deleted file mode 100644 index 1d037ec..0000000 --- a/src/file_chooser_portal.cpp +++ /dev/null @@ -1,269 +0,0 @@ -/******************************************************************************* - XDG desktop portal implementation for TDE - Copyright © 2024 Mavridis Philippe - - 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 -#include - -// TDE -#include -#include -#include -#include - -// 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) -{} - -TDEFileChooserPortal::~TDEFileChooserPortal() -{} - -bool TDEFileChooserPortal::OpenFile(const TQT_DBusObjectPath& handle, - const TQString& app_id, - const TQString& parent_window, - const TQString& title, - const TQMap &options, - TQ_UINT32& response, - TQMap &results, - TQT_DBusError& error) -{ - FileDialogOpts opts; - - opts.caption = title; - - if (OPTION_VALID("accept_label", "s")) - opts.okButtonText = options["accept_label"].value.toString(); - - if (OPTION_VALID("directory", "b")) - opts.directory = options["directory"].value.toBool(); - - if (OPTION_VALID("multiple", "b")) - opts.multiple = options["multiple"].value.toBool(); - - if (OPTION_VALID("modal", "b")) - opts.modal = options["modal"].value.toBool(); - - if (OPTION_VALID("filters", "a(sa(us))")) - opts.filters = parseFilterList(options["filters"], options["current_filter"]); - - opts.windowId = parseWindowId(parent_window); - - return execFileDialog(opts, handle, response, results, error); -} - -bool TDEFileChooserPortal::SaveFile(const TQT_DBusObjectPath& handle, - const TQString& app_id, - const TQString& parent_window, - const TQString& title, - const TQMap &options, - TQ_UINT32& response, - TQMap &results, - TQT_DBusError& error) -{ - FileDialogOpts opts; - - opts.caption = title; - - if (OPTION_VALID("accept_label", "s")) - opts.okButtonText = options["accept_label"].value.toString(); - - if (OPTION_VALID("directory", "b")) - opts.directory = options["directory"].value.toBool(); - - if (OPTION_VALID("multiple", "b")) - opts.multiple = options["multiple"].value.toBool(); - - if (OPTION_VALID("modal", "b")) - opts.modal = options["modal"].value.toBool(); - - if (OPTION_VALID("filters", "a(sa(us))")) - opts.filters = parseFilterList(options["filters"], options["current_filter"]); - - if (OPTION_VALID("current_folder", "ay")) - opts.startDir = bytelist_to_string(options["current_folder"].value.toList().toByteList()); - - if (OPTION_VALID("current_name", "s")) - opts.startName = options["current_name"].value.toString(); - - opts.windowId = parseWindowId(parent_window); - - return execFileDialog(opts, handle, response, results, error); -} - -bool TDEFileChooserPortal::SaveFiles(const TQT_DBusObjectPath& handle, - const TQString& app_id, - const TQString& parent_window, - const TQString& title, - const TQMap &options, - TQ_UINT32& response, - TQMap &results, - TQT_DBusError& error) -{ - return false; -} - -void TDEFileChooserPortal::handleMethodReply(const TQT_DBusMessage &reply) -{ - m_connection.send(reply); -} - -bool TDEFileChooserPortal::execFileDialog(FileDialogOpts options, - const TQT_DBusObjectPath& handle, - TQ_UINT32& response, - TQMap &results, - TQT_DBusError& error) -{ - KFileDialog *dialog = new KFileDialog(options.startDir, TQString::null, - nullptr, "xdg-tde-file-chooser", - options.modal); - uint mode = KFile::LocalOnly; - if (options.savingMode) - { - dialog->setOperationMode(KFileDialog::Saving); - } - else { - mode |= KFile::ExistingOnly; - } - dialog->setMode(mode | options.mode()); - - if (!options.caption.isNull()) - dialog->setPlainCaption(options.caption); - - if (!options.okButtonText.isNull()) - dialog->okButton()->setText(options.okButtonText); - - if (!options.filters.isNull()) - dialog->setFilter(options.filters); - - dialog->setSelection(options.startName); - - if (options.windowId > 0) KWin::setMainWindow(dialog, options.windowId); - - if (dialog->exec() == TQDialog::Accepted) - { - response = 0; - TQT_DBusDataList urls = kurl_list_to_datalist(dialog->selectedURLs()); - TQT_DBusVariant var = TQT_DBusData::fromList(urls).getAsVariantData().toVariant(); - results.insert("uris", var); - } - else response = 1; - 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; - - TQValueList filterData = data.toStruct(); - - TQString label = filterData[0].toString(); - TQValueList patterns = filterData[1].toTQValueList(); - - TQValueList::iterator fp; - for (fp = patterns.begin(); fp != patterns.end(); ++fp) - { - TQValueList patternData = (*fp).toStruct(); - bool isMime = (patternData[0].toUInt32() == 1); - if (isMime) { - // KFileDialog cannot handle both a mime and a simple - // extension filter, so in case we get a mimetype, - // we just get the associated extensions from the - // MIME system - TQString mime = patternData[1].toString(); - patternList += KMimeType::mimeType(mime)->patterns(); - } - else { - TQString patternString = patternData[1].toString(); - - // Regex patterns like *.[hH][tT][mM][lL] are unnecessary for us - // and causes a problem with the save dialog's extension autoselection - TQString finalPattern = patternString; - if (TQRegExp("[*.](?:[[](?:[A-Za-z]{2})[]])+").search(patternString) != -1) - { - finalPattern = "*."; - int pos = patternString.find('['); - while (pos != -1) - { - finalPattern += patternString[pos + 1]; - pos = patternString.find('[', patternString.find(']', pos)); - } - } - patternList += finalPattern; - } - } - - TQString patternString = patternList.join(" "); - - return TQString("%1|%2 (%3)").arg(patternString, label, patternString); -} - -TQString TDEFileChooserPortal::parseFilterList(const TQT_DBusVariant filterData, - const TQT_DBusVariant currentFilterData) -{ - TQStringList filterList; - TQValueList filters = filterData.value.toTQValueList(); - if (filters.count() > 0) { - TQValueList::iterator f; - for (f = filters.begin(); f != filters.end(); ++f) - filterList += parseFilter((*f)); - } - - if (check_variant(currentFilterData, "(sa(us))")) - { - TQString currentFilter = parseFilter(currentFilterData.value); - if (filterList.contains(currentFilter)) - { - // We have no way to affect the filter selection of the dialog, - // so we just move the current filter to the top of the list - // to get it selected automatically - filterList.remove(currentFilter); - filterList.prepend(currentFilter); - } - } - - return filterList.join("\n"); -} - -// kate: replace-tabs true; tab-width 4; indent-width 4; \ No newline at end of file diff --git a/src/file_chooser_portal.h b/src/file_chooser_portal.h deleted file mode 100644 index 375b7c8..0000000 --- a/src/file_chooser_portal.h +++ /dev/null @@ -1,114 +0,0 @@ -/******************************************************************************* - XDG desktop portal implementation for TDE - Copyright © 2024 Mavridis Philippe - - 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 __FILE_CHOOSER_PORTAL_H -#define __FILE_CHOOSER_PORTAL_H - -// TQt -#include -#include -#include -#include -#include - -// TDE -#include - -// Portal -#include "filechooserInterface.h" - -struct FileDialogOpts -{ - TQString caption; - TQString okButtonText; - TQString startDir; - TQString startName; - TQString filters; - bool multiple = false; - bool directory = false; - bool savingMode = false; - bool modal = true; - WId windowId = 0; - - inline KFile::Mode mode() - { - if (directory) return KFile::Directory; - return multiple ? KFile::Files : KFile::File; - } -}; - -class KFileDialog; - -class TDEFileChooserPortal : public TQObject, - public org::freedesktop::impl::portal::FileChooserInterface -{ - public: - TDEFileChooserPortal(TQT_DBusConnection &connection); - virtual ~TDEFileChooserPortal(); - - protected: - virtual bool OpenFile(const TQT_DBusObjectPath& handle, - const TQString& app_id, - const TQString& parent_window, - const TQString& title, - const TQMap &options, - TQ_UINT32& response, - TQMap &results, - TQT_DBusError& error); - - virtual bool SaveFile(const TQT_DBusObjectPath& handle, - const TQString& app_id, - const TQString& parent_window, - const TQString& title, - const TQMap &options, - TQ_UINT32& response, - TQMap &results, - TQT_DBusError& error); - - virtual bool SaveFiles(const TQT_DBusObjectPath& handle, - const TQString& app_id, - const TQString& parent_window, - const TQString& title, - const TQMap &options, - TQ_UINT32& response, - TQMap &results, - TQT_DBusError& error); - - virtual void handleMethodReply(const TQT_DBusMessage &reply); - - private: - TQT_DBusConnection m_connection; - - WId parseWindowId(const TQString data); - TQString parseFilter(const TQT_DBusData data); - TQString parseFilterList(const TQT_DBusVariant filterData, - const TQT_DBusVariant currentFilterData); - - bool execFileDialog(FileDialogOpts options, - const TQT_DBusObjectPath& handle, - TQ_UINT32& response, - TQMap &results, - TQT_DBusError& error); -}; - -#endif // __FILE_CHOOSER_PORTAL_H - -// kate: replace-tabs true; tab-width 4; indent-width 4; \ No newline at end of file diff --git a/src/portal_service.cpp b/src/portal_service.cpp deleted file mode 100644 index 86baa63..0000000 --- a/src/portal_service.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/******************************************************************************* - XDG desktop portal implementation for TDE - Copyright © 2024 Mavridis Philippe - - 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 - -// TDE -#include -#include - -// Portal -#include "file_chooser_portal.h" -#include "portal_service.h" - - -static const char *dbusObjectPath = "/org/freedesktop/portal/desktop"; -static const char *dbusInterfaceRoot = "org.freedesktop.impl.portal"; - -TDEPortalService::TDEPortalService(TQT_DBusConnection &connection) -: m_connection(connection) -{ - if (!m_connection.registerObject(dbusObjectPath, this)) - kdFatal() << "Unable to register XDG desktop portal object " << dbusObjectPath << endl; - else - kdDebug() << "Registered XDG desktop portal object " << dbusObjectPath << endl; -} - -TDEPortalService::~TDEPortalService() -{ - m_connection.unregisterObject(dbusObjectPath); -} - -TQT_DBusObjectBase* TDEPortalService::getPortalInterface(TQCString portal) -{ - if (portal == "FileChooser") - return new TDEFileChooserPortal(m_connection); - - return nullptr; -} - -bool TDEPortalService::handleMethodCall(const TQT_DBusMessage &message) -{ - if (!message.interface().startsWith(dbusInterfaceRoot)) - return false; - - TQCString portal = message.interface().mid(TQString(dbusInterfaceRoot).length() + 1).local8Bit(); - TQT_DBusObjectBase *iface = getPortalInterface(portal); - if (!iface) - { - kdWarning() << "Unsupported XDG portal requested: " << portal << endl; - return false; - } - - return delegateMethodCall(message, iface); -} - -// kate: replace-tabs true; tab-width 4; indent-width 4; \ No newline at end of file diff --git a/src/portal_service.h b/src/portal_service.h deleted file mode 100644 index 8e7c400..0000000 --- a/src/portal_service.h +++ /dev/null @@ -1,47 +0,0 @@ -/******************************************************************************* - XDG desktop portal implementation for TDE - Copyright © 2024 Mavridis Philippe - - 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 __PORTAL_SERVICE_H -#define __PORTAL_SERVICE_H - -// TQt -#include -#include - -class TDEFileChooserPortal; - -class TDEPortalService : public TQT_DBusObjectBase -{ - public: - TDEPortalService(TQT_DBusConnection &connection); - ~TDEPortalService(); - - protected: - bool handleMethodCall(const TQT_DBusMessage &message); - - private: - TQT_DBusConnection m_connection; - TQT_DBusObjectBase* getPortalInterface(TQCString portal); -}; - -#endif // __DESTKOP_PORTAL_H - -// kate: replace-tabs true; tab-width 4; indent-width 4; \ No newline at end of file