1 /*
2     This file is part of the KDE project
3 
4     SPDX-FileCopyrightText: 2002 David Faure <faure@kde.org>
5     SPDX-License-Identifier: LGPL-2.0-only
6 */
7 
8 #ifndef kparts_browserrun_h
9 #define kparts_browserrun_h
10 
11 #include <kparts/browserextension.h>
12 
13 #include <KRun>
14 #include <KService>
15 #include <memory>
16 
17 #if KIOWIDGETS_ENABLE_DEPRECATED_SINCE(5, 71)
18 namespace KParts
19 {
20 /**
21  * @class BrowserRun browserrun.h <KParts/BrowserRun>
22  *
23  * @short This class extends KRun to provide additional functionality for browsers:
24  * - "save or open" dialog boxes
25  * - "save" functionality
26  * - support for HTTP POST (including saving the result to a temp file if
27  *   opening a separate application)
28  * - warning before launching executables off the web
29  * - custom error handling (i.e. treating errors as HTML pages)
30  * - generation of SSL metadata depending on the previous URL shown by the part
31  * @author David Faure <faure@kde.org>
32  */
33 class KPARTS_EXPORT BrowserRun : public KRun
34 {
35     Q_OBJECT
36 public:
37     /**
38      * @param url the URL we're probing
39      * @param args URL args - includes reload, metaData, etc.
40      * @param browserArgs browser-related args - includes data for a HTTP POST, etc.
41      * @param part the part going to open this URL - can be @c nullptr if not created yet
42      * @param window the mainwindow - passed to KIO::Job::setWindow()
43      * @param removeReferrer if true, the "referrer" metadata from @p args isn't passed on
44      * @param trustedSource if false, a warning will be shown before launching an executable.
45       Always pass false for @p trustedSource, except for local directory views.
46      * @param hideErrorDialog if true, no dialog will be shown in case of errors.
47      */
48     BrowserRun(const QUrl &url,
49                const KParts::OpenUrlArguments &args,
50                const KParts::BrowserArguments &browserArgs,
51                KParts::ReadOnlyPart *part,
52                QWidget *window,
53                bool removeReferrer,
54                bool trustedSource,
55                bool hideErrorDialog = false);
56 
57     ~BrowserRun() override;
58 
59     KParts::OpenUrlArguments &arguments();
60     KParts::BrowserArguments &browserArguments();
61     KParts::ReadOnlyPart *part() const;
62     QUrl url() const;
63 
64     bool hideErrorDialog() const;
65 
66     /**
67      * @return Suggested disposition by the server (e.g. HTTP content-disposition)
68      */
69     QString contentDisposition() const;
70 
71     /**
72      * @return Whether the returned disposition suggests saving or opening inline
73      */
74     bool serverSuggestsSave() const;
75 
76 #if KPARTS_ENABLE_DEPRECATED_SINCE(5, 0)
77     enum AskSaveResult { Save, Open, Cancel };
78     /**
79      * Ask the user whether to save or open a url in another application.
80      * @param url the URL in question
81      * @param offer the application that will be used to open the URL
82      * @param mimeType the mimetype of the URL
83      * @param suggestedFileName optional file name suggested by the server
84      * @return Save, Open or Cancel.
85      * @deprecated Since 5.0, use BrowserOpenOrSaveQuestion
86      * @code
87      *  BrowserOpenOrSaveQuestion dlg(parent, url, mimeType, suggestedFileName);
88      *  const BrowserOpenOrSaveQuestion::Result res = dlg.askOpenOrSave();
89      * @endcode
90      */
91     KPARTS_DEPRECATED_VERSION(5, 0, "Use KParts::BrowserOpenOrSaveQuestion")
92     static AskSaveResult askSave(const QUrl &url, KService::Ptr offer, const QString &mimeType, const QString &suggestedFileName = QString());
93 #endif
94 
95 #if KPARTS_ENABLE_DEPRECATED_SINCE(5, 65)
96     /** @deprecated Since 5.65, use BrowserOpenOrSaveQuestion::AskEmbedOrSaveFlags */
97     enum AskEmbedOrSaveFlags { InlineDisposition = 0, AttachmentDisposition = 1 };
98 #endif
99 
100 #if KPARTS_ENABLE_DEPRECATED_SINCE(5, 0)
101     /**
102      * Similar to askSave but for the case where the current application is
103      * able to embed the url itself (instead of passing it to another app).
104      * @param url the URL in question
105      * @param mimeType the mimetype of the URL
106      * @param suggestedFileName optional filename suggested by the server
107      * @param flags set to AttachmentDisposition if suggested by the server
108      * @return Save, Open or Cancel.
109      * @deprecated Since 5.0, use BrowserOpenOrSaveQuestion
110      * @code
111      *  BrowserOpenOrSaveQuestion dlg(parent, url, mimeType, suggestedFileName);
112      *  const BrowserOpenOrSaveQuestion::Result res = dlg.askEmbedOrSave(flags);
113      *  // Important: returns Embed now, not Open!
114      * @endcode
115      */
116     KPARTS_DEPRECATED_VERSION(5, 0, "Use KParts::BrowserOpenOrSaveQuestion")
117     static AskSaveResult askEmbedOrSave(const QUrl &url, const QString &mimeType, const QString &suggestedFileName = QString(), int flags = 0);
118 #endif
119 
120     // virtual so that KHTML can implement differently (HTML cache)
121     virtual void save(const QUrl &url, const QString &suggestedFileName);
122 
123 #if KPARTS_ENABLE_DEPRECATED_SINCE(4, 4)
124     /**
125      * static so that it can be called from other classes
126      * @deprecated Since 4.4, use saveUrl(const QUrl &, const QString &, QWidget *, const KParts::OpenUrlArguments &)
127      */
128     KPARTS_DEPRECATED_VERSION(4, 4, "Use BrowserRun::saveUrl(const QUrl &, const QString &, QWidget *, const KParts::OpenUrlArguments &)")
129     static void simpleSave(const QUrl &url, const QString &suggestedFileName, QWidget *window = nullptr);
130 #endif
131 
132     /**
133      * If kget integration is enabled, passes the url to kget.
134      * Otherwise, asks the user for a destination url, and calls saveUrlUsingKIO.
135      * @since 4.4
136      */
137     static void saveUrl(const QUrl &url, const QString &suggestedFileName, QWidget *window, const KParts::OpenUrlArguments &args);
138 
139     /**
140      * Starts the KIO file copy job to download @p srcUrl into @p destUrl.
141      * @since 4.4
142      */
143     static void saveUrlUsingKIO(const QUrl &srcUrl, const QUrl &destUrl, QWidget *window, const QMap<QString, QString> &metaData);
144 
145     static bool allowExecution(const QString &mimeType, const QUrl &url);
146 
147     static bool isTextExecutable(const QString &mimeType);
148 
149     /**
150      * KDE webbrowsing kparts support error urls to display errors in-line in the browser component.
151      * This helper method creates the error URL from its parameters.
152      * @param error the KIO error code (or KIO::ERR_SLAVE_DEFINED if not from KIO)
153      * @param errorText the text of the error message
154      * @param initialUrl the URL that we were trying to open (as a string, so that this can
155      *                   support invalid URLs as well) (changed from QString to QUrl in KF5)
156      * @since 4.6
157      */
158     static QUrl makeErrorUrl(int error, const QString &errorText, const QUrl &initialUrl);
159 
160 protected:
161     /**
162      * Reimplemented from KRun
163      */
164     void scanFile() override;
165     /**
166      * Reimplemented from KRun
167      */
168     void init() override;
169     /**
170      * Reimplemented from KRun
171      */
172     void handleError(KJob *job) override;
173 
174     /**
175      * NotHandled means that foundMimeType should call KRun::foundMimeType,
176      * i.e. launch an external app.
177      */
178     enum NonEmbeddableResult { Handled, NotHandled, Delayed };
179 
180     /**
181      * Helper for foundMimeType: call this if the mimetype couldn't be embedded
182      */
183     NonEmbeddableResult handleNonEmbeddable(const QString &mimeType); // TODO KDE5: remove, and add =0 to the other overload
184 
185     /**
186      * Helper for foundMimeType: call this if the mimetype couldn't be embedded
187      * @param mimeType the mimetype found for the URL
188      * @param pSelectedService Output variable: pointer to a KService::Ptr, which will be set
189      *        to the service selected in the BrowserOpenOrSaveQuestion dialog, if any.
190      *
191      * How to handle this properly: if pSelectedService is non-zero, then the dialog will show
192      * additional "open with" buttons. In your code, you should write:
193      * @code
194         if (selectedService) {
195             KRun::setPreferredService(selectedService->desktopEntryName()); // not necessary since 4.9.3
196             KRun::foundMimeType(mimeType);
197         } else { // the user requested an open-with dialog
198             KRun::displayOpenWithDialog(url(), m_window, false, suggestedFileName());
199             setFinished(true);
200         }
201      * @endcode
202      *
203      * @since 4.5
204      */
205     NonEmbeddableResult handleNonEmbeddable(const QString &mimeType, KService::Ptr *pSelectedService);
206 
207 protected Q_SLOTS:
208     void slotBrowserScanFinished(KJob *job);
209     void slotBrowserMimetype(KIO::Job *job, const QString &type);
210     void slotCopyToTempFileResult(KJob *job);
211 
212 private:
213     void redirectToError(int error, const QString &errorText);
214 
215 private:
216     std::unique_ptr<class BrowserRunPrivate> const d;
217 };
218 }
219 
220 #endif
221 
222 #endif
223