File indexing completed on 2024-04-21 03:55:27

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2020 David Faure <faure@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006 */
0007 
0008 #ifndef KIO_APPLICATIONLAUNCHERJOB_H
0009 #define KIO_APPLICATIONLAUNCHERJOB_H
0010 
0011 #include "kiogui_export.h"
0012 #include <KJob>
0013 #include <KService>
0014 #include <QUrl>
0015 
0016 class ApplicationLauncherJobTest;
0017 class KDesktopFileAction;
0018 
0019 namespace KIO
0020 {
0021 class ApplicationLauncherJobPrivate;
0022 
0023 /**
0024  * @class ApplicationLauncherJob applicationlauncherjob.h <KIO/ApplicationLauncherJob>
0025  *
0026  * @brief ApplicationLauncherJob runs an application and watches it while running.
0027  *
0028  * It creates a startup notification and finishes it on success or on error (for the taskbar).
0029  * It also emits an error message if necessary (e.g. "program not found").
0030  *
0031  * When passing multiple URLs to an application that doesn't support opening
0032  * multiple files, the application will be launched once for each URL.
0033  *
0034  * The job finishes when the application is successfully started. At that point you can
0035  * query the PID(s).
0036  *
0037  * For error handling, either connect to the result() signal, or for a simple messagebox on error,
0038  * you can use:
0039  * @code
0040  *    // Since 5.98 use:
0041  *    job->setUiDelegate(KIO::createDefaultJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, this));
0042  *    // For older releases use:
0043  *    job->setUiDelegate(new KIO::JobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, this));
0044  * @endcode
0045  * Using JobUiDelegate (which is widgets based) also enables the feature of asking the user
0046  * in case the executable or desktop file isn't marked as executable. Otherwise the job will
0047  * just refuse executing such files.
0048  *
0049  * To invoke the open-with dialog (from KIOWidgets), construct an ApplicationLauncherJob without
0050  * any arguments or with a null KService.
0051  *
0052  * @since 5.69
0053  */
0054 class KIOGUI_EXPORT ApplicationLauncherJob : public KJob
0055 {
0056 public:
0057     /**
0058      * Creates an ApplicationLauncherJob.
0059      * @param service the service (application desktop file) to run
0060      * @param parent the parent QObject
0061      */
0062     explicit ApplicationLauncherJob(const KService::Ptr &service, QObject *parent = nullptr);
0063 
0064     /**
0065      * Creates an ApplicationLauncherJob.
0066      * @param serviceAction the service action to run
0067      * @param parent the parent QObject
0068      */
0069     explicit ApplicationLauncherJob(const KServiceAction &serviceAction, QObject *parent = nullptr);
0070 
0071     /**
0072      * @overload
0073      * @since 6.0
0074      */
0075     explicit ApplicationLauncherJob(const KDesktopFileAction &desktopFileAction, QObject *parent = nullptr);
0076 
0077     /**
0078      * Creates an ApplicationLauncherJob which will prompt the user for which application to use
0079      * (via the open-with dialog from KIOWidgets).
0080      * @param parent the parent QObject
0081      * @since 5.71
0082      */
0083     explicit ApplicationLauncherJob(QObject *parent = nullptr);
0084 
0085     /**
0086      * Destructor
0087      *
0088      * Note that jobs auto-delete themselves after emitting result.
0089      * Deleting/killing the job will not stop the started application.
0090      */
0091     ~ApplicationLauncherJob() override;
0092 
0093     /**
0094      * Specifies the URLs to be passed to the application.
0095      * @param urls list of files (local or remote) to open
0096      *
0097      * Note that when passing multiple URLs to an application that doesn't support opening
0098      * multiple files, the application will be launched once for each URL.
0099      */
0100     void setUrls(const QList<QUrl> &urls);
0101 
0102     /**
0103      * @see RunFlag
0104      */
0105     enum RunFlag {
0106         DeleteTemporaryFiles = 0x1, ///< the URLs passed to the service will be deleted when it exits (if the URLs are local files)
0107     };
0108     /**
0109      * Stores a combination of #RunFlag values.
0110      */
0111     Q_DECLARE_FLAGS(RunFlags, RunFlag)
0112 
0113     /**
0114      * Specifies various flags.
0115      * @param runFlags the flags to be set. For instance, whether the URLs are temporary files that should be deleted after execution.
0116      */
0117     void setRunFlags(RunFlags runFlags);
0118 
0119     /**
0120      * Sets the file name to use in the case of downloading the file to a tempfile
0121      * in order to give to a non-URL-aware application.
0122      * Some apps rely on the extension to determine the MIME type of the file.
0123      * Usually the file name comes from the URL, but in the case of the
0124      * HTTP Content-Disposition header, we need to override the file name.
0125      * @param suggestedFileName the file name
0126      */
0127     void setSuggestedFileName(const QString &suggestedFileName);
0128 
0129     /**
0130      * Sets the platform-specific startup id of the application launch.
0131      * @param startupId startup id, if any (otherwise "").
0132      * For X11, this would be the id for the Startup Notification protocol.
0133      * For Wayland, this would be the token for the XDG Activation protocol.
0134      */
0135     void setStartupId(const QByteArray &startupId);
0136 
0137     /**
0138      * Starts the job.
0139      * You must call this, after having done all the setters.
0140      * This is (potentially) a GUI job, never use exec(), it would block user interaction.
0141      */
0142     void start() override;
0143 
0144     /**
0145      * @return the PID of the application that was started
0146      *
0147      * Convenience method for pids().at(0). You should only use this when specifying zero or one URL,
0148      * or when you are sure that the application supports opening multiple files. Otherwise use pids().
0149      * Available after the job emits result().
0150      */
0151     qint64 pid() const;
0152 
0153     /**
0154      * @return the PIDs of the applications that were started
0155      *
0156      * Available after the job emits result().
0157      */
0158     QList<qint64> pids() const;
0159 
0160 private:
0161     friend class ::ApplicationLauncherJobTest;
0162     /**
0163      * Blocks until the process has started.
0164      */
0165     bool waitForStarted();
0166     KIOGUI_NO_EXPORT void emitUnauthorizedError();
0167     KIOGUI_NO_EXPORT void proceedAfterSecurityChecks();
0168 
0169     friend class ApplicationLauncherJobPrivate;
0170     QScopedPointer<ApplicationLauncherJobPrivate> d;
0171 };
0172 
0173 } // namespace KIO
0174 
0175 #endif