File indexing completed on 2024-04-28 05:36:49

0001 /*
0002  * SPDX-FileCopyrightText: 2016-2018 Red Hat Inc
0003  * SPDX-License-Identifier: LGPL-2.0-or-later
0004  *
0005  * SPDX-FileCopyrightText: 2016-2018 Jan Grulich <jgrulich@redhat.com>
0006  * SPDX-FileCopyrightText: 2022 Harald Sitter <sitter@kde.org>
0007  */
0008 
0009 #include "appchooser.h"
0010 #include "appchooser_debug.h"
0011 #include "appchooserdialog.h"
0012 #include "request.h"
0013 #include "utils.h"
0014 
0015 #include <KLocalizedString>
0016 #include <QDBusConnection>
0017 #include <QDBusMessage>
0018 #include <QDBusServiceWatcher>
0019 
0020 AppChooserPortal::AppChooserPortal(QObject *parent)
0021     : QDBusAbstractAdaptor(parent)
0022 {
0023 }
0024 
0025 uint AppChooserPortal::ChooseApplication(const QDBusObjectPath &handle,
0026                                          const QString &app_id,
0027                                          const QString &parent_window,
0028                                          const QStringList &choices,
0029                                          const QVariantMap &options,
0030                                          QVariantMap &results)
0031 {
0032     qCDebug(XdgDesktopPortalKdeAppChooser) << "ChooseApplication called with parameters:";
0033     qCDebug(XdgDesktopPortalKdeAppChooser) << "    handle: " << handle.path();
0034     qCDebug(XdgDesktopPortalKdeAppChooser) << "    app_id: " << app_id;
0035     qCDebug(XdgDesktopPortalKdeAppChooser) << "    parent_window: " << parent_window;
0036     qCDebug(XdgDesktopPortalKdeAppChooser) << "    choices: " << choices;
0037     qCDebug(XdgDesktopPortalKdeAppChooser) << "    options: " << options;
0038 
0039     QString latestChoice;
0040 
0041     if (options.contains(QStringLiteral("last_choice"))) {
0042         latestChoice = options.value(QStringLiteral("last_choice")).toString();
0043     }
0044 
0045     QVariant itemName = options.value(QStringLiteral("filename"));
0046     if (!itemName.isValid()) {
0047         itemName = options.value(QStringLiteral("content_type"));
0048     }
0049     AppChooserDialog *appDialog = new AppChooserDialog(choices, latestChoice, itemName.toString(), options.value(QStringLiteral("content_type")).toString());
0050     m_appChooserDialogs.insert(handle.path(), appDialog);
0051     Utils::setParentWindow(appDialog->windowHandle(), parent_window);
0052     Request::makeClosableDialogRequest(handle, appDialog);
0053 
0054     int result = appDialog->exec();
0055 
0056     if (result) {
0057         results.insert(QStringLiteral("choice"), appDialog->selectedApplication());
0058     }
0059 
0060     m_appChooserDialogs.remove(handle.path());
0061     appDialog->deleteLater();
0062 
0063     return !result;
0064 }
0065 
0066 void AppChooserPortal::UpdateChoices(const QDBusObjectPath &handle, const QStringList &choices)
0067 {
0068     qCDebug(XdgDesktopPortalKdeAppChooser) << "UpdateChoices called with parameters:";
0069     qCDebug(XdgDesktopPortalKdeAppChooser) << "    handle: " << handle.path();
0070     qCDebug(XdgDesktopPortalKdeAppChooser) << "    choices: " << choices;
0071 
0072     if (m_appChooserDialogs.contains(handle.path())) {
0073         m_appChooserDialogs.value(handle.path())->updateChoices(choices);
0074     }
0075 }
0076 
0077 uint AppChooserPortal::ChooseApplicationPrivate(const QString &parent_window,
0078                                                 const QStringList &urls,
0079                                                 const QVariantMap &options,
0080                                                 const QDBusMessage &msg,
0081                                                 QVariantMap &results)
0082 {
0083     qCDebug(XdgDesktopPortalKdeAppChooser) << "ChooseApplicationPrivate called with parameters:";
0084     qCDebug(XdgDesktopPortalKdeAppChooser) << "    parent_window: " << parent_window;
0085     qCDebug(XdgDesktopPortalKdeAppChooser) << "    urls: " << urls;
0086     qCDebug(XdgDesktopPortalKdeAppChooser) << "    options: " << options;
0087 
0088     if (urls.isEmpty()) {
0089         return 1;
0090     }
0091 
0092     const QString itemName = urls.size() == 1 ? urls.at(0) : i18nc("count of files to open", "%1 files", urls.size());
0093 
0094     AppChooserDialog appDialog({}, options.value(QStringLiteral("last_choice")).toString(), itemName, options.value(QStringLiteral("content_type")).toString());
0095     Utils::setParentWindow(appDialog.windowHandle(), parent_window);
0096 
0097     QDBusServiceWatcher watcher(msg.service(), QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForUnregistration);
0098     connect(&watcher, &QDBusServiceWatcher::serviceUnregistered, &appDialog, [&appDialog] {
0099         appDialog.reject();
0100     });
0101 
0102     const bool result = appDialog.exec();
0103     if (result) {
0104         results.insert(QStringLiteral("choice"), appDialog.selectedApplication());
0105     }
0106     return result ? 0 : 1;
0107 }