File indexing completed on 2024-02-25 17:30:59

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 AppChooserPortal::~AppChooserPortal()
0026 {
0027 }
0028 
0029 uint AppChooserPortal::ChooseApplication(const QDBusObjectPath &handle,
0030                                          const QString &app_id,
0031                                          const QString &parent_window,
0032                                          const QStringList &choices,
0033                                          const QVariantMap &options,
0034                                          QVariantMap &results)
0035 {
0036     qCDebug(XdgDesktopPortalKdeAppChooser) << "ChooseApplication called with parameters:";
0037     qCDebug(XdgDesktopPortalKdeAppChooser) << "    handle: " << handle.path();
0038     qCDebug(XdgDesktopPortalKdeAppChooser) << "    app_id: " << app_id;
0039     qCDebug(XdgDesktopPortalKdeAppChooser) << "    parent_window: " << parent_window;
0040     qCDebug(XdgDesktopPortalKdeAppChooser) << "    choices: " << choices;
0041     qCDebug(XdgDesktopPortalKdeAppChooser) << "    options: " << options;
0042 
0043     QString latestChoice;
0044 
0045     if (options.contains(QStringLiteral("last_choice"))) {
0046         latestChoice = options.value(QStringLiteral("last_choice")).toString();
0047     }
0048 
0049     QVariant itemName = options.value(QStringLiteral("filename"));
0050     if (!itemName.isValid()) {
0051         itemName = options.value(QStringLiteral("content_type"));
0052     }
0053     AppChooserDialog *appDialog = new AppChooserDialog(choices, latestChoice, itemName.toString(), options.value(QStringLiteral("content_type")).toString());
0054     m_appChooserDialogs.insert(handle.path(), appDialog);
0055     Utils::setParentWindow(appDialog->windowHandle(), parent_window);
0056     Request::makeClosableDialogRequest(handle, appDialog);
0057 
0058     int result = appDialog->exec();
0059 
0060     if (result) {
0061         results.insert(QStringLiteral("choice"), appDialog->selectedApplication());
0062     }
0063 
0064     m_appChooserDialogs.remove(handle.path());
0065     appDialog->deleteLater();
0066 
0067     return !result;
0068 }
0069 
0070 void AppChooserPortal::UpdateChoices(const QDBusObjectPath &handle, const QStringList &choices)
0071 {
0072     qCDebug(XdgDesktopPortalKdeAppChooser) << "UpdateChoices called with parameters:";
0073     qCDebug(XdgDesktopPortalKdeAppChooser) << "    handle: " << handle.path();
0074     qCDebug(XdgDesktopPortalKdeAppChooser) << "    choices: " << choices;
0075 
0076     if (m_appChooserDialogs.contains(handle.path())) {
0077         m_appChooserDialogs.value(handle.path())->updateChoices(choices);
0078     }
0079 }
0080 
0081 uint AppChooserPortal::ChooseApplicationPrivate(const QString &parent_window,
0082                                                 const QStringList &urls,
0083                                                 const QVariantMap &options,
0084                                                 const QDBusMessage &msg,
0085                                                 QVariantMap &results)
0086 {
0087     qCDebug(XdgDesktopPortalKdeAppChooser) << "ChooseApplicationPrivate called with parameters:";
0088     qCDebug(XdgDesktopPortalKdeAppChooser) << "    parent_window: " << parent_window;
0089     qCDebug(XdgDesktopPortalKdeAppChooser) << "    urls: " << urls;
0090     qCDebug(XdgDesktopPortalKdeAppChooser) << "    options: " << options;
0091 
0092     if (urls.isEmpty()) {
0093         return 1;
0094     }
0095 
0096     const QString itemName = urls.size() == 1 ? urls.at(0) : i18nc("count of files to open", "%1 files", urls.size());
0097 
0098     AppChooserDialog appDialog({}, {}, itemName, options.value(QStringLiteral("content_type")).toString());
0099     Utils::setParentWindow(appDialog.windowHandle(), parent_window);
0100 
0101     QDBusServiceWatcher watcher(msg.service(), QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForUnregistration);
0102     connect(&watcher, &QDBusServiceWatcher::serviceUnregistered, &appDialog, [&appDialog] {
0103         appDialog.reject();
0104     });
0105 
0106     const bool result = appDialog.exec();
0107     if (result) {
0108         results.insert(QStringLiteral("choice"), appDialog.selectedApplication());
0109     }
0110     return result ? 0 : 1;
0111 }