File indexing completed on 2024-04-28 15:26:51

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 KRun; // KF6 REMOVE
0017 class ApplicationLauncherJobTest; // KF6 REMOVE
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      * Creates an ApplicationLauncherJob which will prompt the user for which application to use
0073      * (via the open-with dialog from KIOWidgets).
0074      * @param parent the parent QObject
0075      * @since 5.71
0076      */
0077     explicit ApplicationLauncherJob(QObject *parent = nullptr);
0078 
0079     /**
0080      * Destructor
0081      *
0082      * Note that jobs auto-delete themselves after emitting result.
0083      * Deleting/killing the job will not stop the started application.
0084      */
0085     ~ApplicationLauncherJob() override;
0086 
0087     /**
0088      * Specifies the URLs to be passed to the application.
0089      * @param urls list of files (local or remote) to open
0090      *
0091      * Note that when passing multiple URLs to an application that doesn't support opening
0092      * multiple files, the application will be launched once for each URL.
0093      */
0094     void setUrls(const QList<QUrl> &urls);
0095 
0096     /**
0097      * @see RunFlag
0098      */
0099     enum RunFlag {
0100         DeleteTemporaryFiles = 0x1, ///< the URLs passed to the service will be deleted when it exits (if the URLs are local files)
0101     };
0102     /**
0103      * Stores a combination of #RunFlag values.
0104      */
0105     Q_DECLARE_FLAGS(RunFlags, RunFlag)
0106 
0107     /**
0108      * Specifies various flags.
0109      * @param runFlags the flags to be set. For instance, whether the URLs are temporary files that should be deleted after execution.
0110      */
0111     void setRunFlags(RunFlags runFlags);
0112 
0113     /**
0114      * Sets the file name to use in the case of downloading the file to a tempfile
0115      * in order to give to a non-URL-aware application.
0116      * Some apps rely on the extension to determine the MIME type of the file.
0117      * Usually the file name comes from the URL, but in the case of the
0118      * HTTP Content-Disposition header, we need to override the file name.
0119      * @param suggestedFileName the file name
0120      */
0121     void setSuggestedFileName(const QString &suggestedFileName);
0122 
0123     /**
0124      * Sets the platform-specific startup id of the application launch.
0125      * @param startupId startup id, if any (otherwise "").
0126      * For X11, this would be the id for the Startup Notification protocol.
0127      * For Wayland, this would be the token for the XDG Activation protocol.
0128      */
0129     void setStartupId(const QByteArray &startupId);
0130 
0131     /**
0132      * Starts the job.
0133      * You must call this, after having done all the setters.
0134      * This is (potentially) a GUI job, never use exec(), it would block user interaction.
0135      */
0136     void start() override;
0137 
0138     /**
0139      * @return the PID of the application that was started
0140      *
0141      * Convenience method for pids().at(0). You should only use this when specifying zero or one URL,
0142      * or when you are sure that the application supports opening multiple files. Otherwise use pids().
0143      * Available after the job emits result().
0144      */
0145     qint64 pid() const;
0146 
0147     /**
0148      * @return the PIDs of the applications that were started
0149      *
0150      * Available after the job emits result().
0151      */
0152     QVector<qint64> pids() const;
0153 
0154 private:
0155     friend class ::KRun; // KF6 REMOVE
0156     friend class ::ApplicationLauncherJobTest; // KF6 REMOVE
0157     /**
0158      * Blocks until the process has started. Only exists for KRun, will disappear in KF6.
0159      */
0160     bool waitForStarted();
0161     KIOGUI_NO_EXPORT void emitUnauthorizedError();
0162     KIOGUI_NO_EXPORT void proceedAfterSecurityChecks();
0163 
0164     friend class ApplicationLauncherJobPrivate;
0165     QScopedPointer<ApplicationLauncherJobPrivate> d;
0166 };
0167 
0168 } // namespace KIO
0169 
0170 #endif