1 | // -*- mode: c++; c-basic-offset: 2 -*- |
2 | /* This file is part of the KDE project |
3 | Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> |
4 | Copyright (C) 2006 David Faure <faure@kde.org> |
5 | |
6 | This library is free software; you can redistribute it and/or |
7 | modify it under the terms of the GNU Library General Public |
8 | License as published by the Free Software Foundation; either |
9 | version 2 of the License, or (at your option) any later version. |
10 | |
11 | This library is distributed in the hope that it will be useful, |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | Library General Public License for more details. |
15 | |
16 | You should have received a copy of the GNU Library General Public License |
17 | along with this library; see the file COPYING.LIB. If not, write to |
18 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
19 | Boston, MA 02110-1301, USA. |
20 | */ |
21 | |
22 | #ifndef KRUN_H |
23 | #define KRUN_H |
24 | |
25 | #include <kio/kio_export.h> |
26 | |
27 | #include <QtCore/QObject> |
28 | #include <QtCore/QTimer> |
29 | #include <QtCore/QString> |
30 | #include <sys/types.h> |
31 | #include <kurl.h> |
32 | |
33 | class KService; |
34 | class KStartupInfo; |
35 | class KJob; |
36 | namespace KIO |
37 | { |
38 | class Job; |
39 | } |
40 | |
41 | /** |
42 | * To open files with their associated applications in KDE, use KRun. |
43 | * |
44 | * It can execute any desktop entry, as well as any file, using |
45 | * the default application or another application "bound" to the file type |
46 | * (or URL protocol). |
47 | * |
48 | * In that example, the mimetype of the file is not known by the application, |
49 | * so a KRun instance must be created. It will determine the mimetype by itself. |
50 | * If the mimetype is known, or if you even know the service (application) to |
51 | * use for this file, use one of the static methods. |
52 | * |
53 | * By default KRun uses auto deletion. It causes the KRun instance to delete |
54 | * itself when the it finished its task. If you allocate the KRun |
55 | * object on the stack you must disable auto deletion, otherwise it will crash. |
56 | * |
57 | * @short Opens files with their associated applications in KDE |
58 | */ |
59 | class KIO_EXPORT KRun : public QObject |
60 | { |
61 | Q_OBJECT |
62 | public: |
63 | /** |
64 | * @param url the URL of the file or directory to 'run' |
65 | * |
66 | * @param window |
67 | * The top-level widget of the app that invoked this object. |
68 | * It is used to make sure private information like passwords |
69 | * are properly handled per application. |
70 | * |
71 | * @param mode The @p st_mode field of <tt>struct stat</tt>. If |
72 | * you don't know this set it to 0. |
73 | * |
74 | * @param isLocalFile |
75 | * If this parameter is set to @p false then @p url is |
76 | * examined to find out whether it is a local URL or |
77 | * not. This flag is just used to improve speed, since the |
78 | * function KUrl::isLocalFile is a bit slow. |
79 | * |
80 | * @param showProgressInfo |
81 | * Whether to show progress information when determining the |
82 | * type of the file (i.e. when using KIO::stat and KIO::mimetype) |
83 | * Before you set this to false to avoid a dialog box, think about |
84 | * a very slow FTP server... |
85 | * It is always better to provide progress info in such cases. |
86 | * @param asn |
87 | * Application startup notification id, if available (otherwise ""). |
88 | */ |
89 | KRun(const KUrl& url, QWidget* window, mode_t mode = 0, |
90 | bool isLocalFile = false, bool showProgressInfo = true, |
91 | const QByteArray& asn = QByteArray()); |
92 | |
93 | /** |
94 | * Destructor. Don't call it yourself, since a KRun object auto-deletes |
95 | * itself. |
96 | */ |
97 | virtual ~KRun(); |
98 | |
99 | /** |
100 | * Abort this KRun. This kills any jobs launched by it, |
101 | * and leads to deletion if auto-deletion is on. |
102 | * This is much safer than deleting the KRun (in case it's |
103 | * currently showing an error dialog box, for instance) |
104 | */ |
105 | void abort(); |
106 | |
107 | /** |
108 | * Returns true if the KRun instance has an error. |
109 | * @return true when an error occurred |
110 | * @see error() |
111 | */ |
112 | bool hasError() const; |
113 | |
114 | /** |
115 | * Returns true if the KRun instance has finished. |
116 | * @return true if the KRun instance has finished |
117 | * @see finished() |
118 | */ |
119 | bool hasFinished() const; |
120 | |
121 | /** |
122 | * Checks whether auto delete is activated. |
123 | * Auto-deletion causes the KRun instance to delete itself |
124 | * when it finished its task. |
125 | * By default auto deletion is on. |
126 | * @return true if auto deletion is on, false otherwise |
127 | */ |
128 | bool autoDelete() const; |
129 | |
130 | /** |
131 | * Enables or disabled auto deletion. |
132 | * Auto deletion causes the KRun instance to delete itself |
133 | * when it finished its task. If you allocate the KRun |
134 | * object on the stack you must disable auto deletion. |
135 | * By default auto deletion is on. |
136 | * @param b true to enable auto deletion, false to disable |
137 | */ |
138 | void setAutoDelete(bool b); |
139 | |
140 | /** |
141 | * Set the preferred service for opening this URL, after |
142 | * its mimetype will have been found by KRun. IMPORTANT: the service is |
143 | * only used if its configuration says it can handle this mimetype. |
144 | * This is used for instance for the X-KDE-LastOpenedWith key in |
145 | * the recent documents list, or for the app selection in |
146 | * KParts::BrowserOpenOrSaveQuestion. |
147 | * @param desktopEntryName the desktopEntryName of the service, e.g. "kate". |
148 | */ |
149 | void setPreferredService(const QString& desktopEntryName); |
150 | |
151 | /** |
152 | * Sets whether executables, .desktop files or shell scripts should |
153 | * be run by KRun. This is enabled by default. |
154 | * @param b whether to run executable files or not. |
155 | * @see isExecutable() |
156 | */ |
157 | void setRunExecutables(bool b); |
158 | |
159 | /** |
160 | * Sets whether the external webbrowser setting should be honoured. |
161 | * This is enabled by default. |
162 | * This should only be disabled in webbrowser applications. |
163 | * @param b whether to enable the external browser or not. |
164 | */ |
165 | void setEnableExternalBrowser(bool b); |
166 | |
167 | /** |
168 | * Sets the file name to use in the case of downloading the file to a tempfile |
169 | * in order to give to a non-url-aware application. Some apps rely on the extension |
170 | * to determine the mimetype of the file. Usually the file name comes from the URL, |
171 | * but in the case of the HTTP Content-Disposition header, we need to override the |
172 | * file name. |
173 | */ |
174 | void setSuggestedFileName(const QString& fileName); |
175 | |
176 | /** |
177 | * Suggested file name given by the server (e.g. HTTP content-disposition) |
178 | */ |
179 | QString suggestedFileName() const; |
180 | |
181 | /** |
182 | * Associated window, as passed to the constructor |
183 | * @since 4.9.3 |
184 | */ |
185 | QWidget* window() const; |
186 | |
187 | |
188 | /** |
189 | * Open a list of URLs with a certain service (application). |
190 | * |
191 | * @param service the service to run |
192 | * @param urls the list of URLs, can be empty (app launched |
193 | * without argument) |
194 | * @param window The top-level widget of the app that invoked this object. |
195 | * @param tempFiles if true and urls are local files, they will be deleted |
196 | * when the application exits. |
197 | * @param suggestedFileName see setSuggestedFileName |
198 | * @param asn Application startup notification id, if any (otherwise ""). |
199 | * @return @c true on success, @c false on error |
200 | */ |
201 | static bool run(const KService& service, const KUrl::List& urls, QWidget* window, |
202 | bool tempFiles = false, const QString& suggestedFileName = QString(), |
203 | const QByteArray& asn = QByteArray()); |
204 | |
205 | /** |
206 | * Open a list of URLs with an executable. |
207 | * |
208 | * @param exec the name of the executable, for example |
209 | * "/usr/bin/netscape %u". |
210 | * Don't forget to include the %u if you know that the applications |
211 | * supports URLs. Otherwise, non-local urls will first be downloaded |
212 | * to a temp file (using kioexec). |
213 | * @param urls the list of URLs to open, can be empty (app launched without argument) |
214 | * @param window The top-level widget of the app that invoked this object. |
215 | * @param name the logical name of the application, for example |
216 | * "Netscape 4.06". |
217 | * @param icon the icon which should be used by the application. |
218 | * @param asn Application startup notification id, if any (otherwise ""). |
219 | * @return @c true on success, @c false on error |
220 | */ |
221 | static bool run(const QString& exec, const KUrl::List& urls, QWidget* window, |
222 | const QString& name = QString(), |
223 | const QString& icon = QString(), |
224 | const QByteArray& asn = QByteArray()); |
225 | |
226 | /** |
227 | * Open the given URL. |
228 | * |
229 | * This function is used after the mime type |
230 | * is found out. It will search for all services which can handle |
231 | * the mime type and call run() afterwards. |
232 | * @param url the URL to open |
233 | * @param mimetype the mime type of the resource |
234 | * @param window The top-level widget of the app that invoked this object. |
235 | * @param tempFile if true and url is a local file, it will be deleted |
236 | * when the launched application exits. |
237 | * @param runExecutables if false then local .desktop files, |
238 | * executables and shell scripts will not be run. |
239 | * See also isExecutable(). |
240 | * @param suggestedFileName see setSuggestedFileName |
241 | * @param asn Application startup notification id, if any (otherwise ""). |
242 | * @return @c true on success, @c false on error |
243 | */ |
244 | static bool runUrl(const KUrl& url, const QString& mimetype, QWidget* window, |
245 | bool tempFile = false , bool runExecutables = true, |
246 | const QString& suggestedFileName = QString(), const QByteArray& asn = QByteArray()); |
247 | |
248 | /** |
249 | * Run the given shell command and notifies KDE of the starting |
250 | * of the application. If the program to be called doesn't exist, |
251 | * an error box will be displayed. |
252 | * |
253 | * Use only when you know the full command line. Otherwise use the other |
254 | * static methods, or KRun's constructor. |
255 | * |
256 | * @p cmd must be a shell command. You must not append "&" |
257 | * to it, since the function will do that for you. |
258 | * @param window The top-level widget of the app that invoked this object. |
259 | * |
260 | * @return @c true on success, @c false on error |
261 | */ |
262 | static bool runCommand(const QString &cmd, QWidget* window); |
263 | |
264 | /** |
265 | * Overload that also takes a working directory, so that a command like |
266 | * "kwrite file.txt" finds file.txt from the right place. |
267 | * @since 4.4 |
268 | */ |
269 | static bool runCommand(const QString &cmd, QWidget* window, const QString& workingDirectory); |
270 | // TODO KDE5: merge the above with 2-args runCommand, using QString() |
271 | |
272 | /** |
273 | * Same as the other runCommand(), but it also takes the name of the |
274 | * binary, to display an error message in case it couldn't find it. |
275 | * |
276 | * @param cmd must be a shell command. You must not append "&" |
277 | * to it, since the function will do that for you. |
278 | * @param execName the name of the executable |
279 | * @param icon icon for app starting notification |
280 | * @param window The top-level widget of the app that invoked this object. |
281 | * @param asn Application startup notification id, if any (otherwise ""). |
282 | * @return @c true on success, @c false on error |
283 | */ |
284 | static bool runCommand(const QString& cmd, const QString & execName, |
285 | const QString & icon, QWidget* window, const QByteArray& asn = QByteArray()); |
286 | |
287 | /** |
288 | * Overload that also takes a working directory, so that a command like |
289 | * "kwrite file.txt" finds file.txt from the right place. |
290 | * @param workingDirectory the working directory for the started process. The default |
291 | * (if passing an empty string) is the user's document path. |
292 | * @since 4.4 |
293 | */ |
294 | static bool runCommand(const QString& cmd, const QString & execName, |
295 | const QString & icon, QWidget* window, |
296 | const QByteArray& asn, const QString& workingDirectory); |
297 | // TODO KDE5: merge the above with 5-args runCommand, using QString() |
298 | |
299 | /** |
300 | * Display the Open-With dialog for those URLs, and run the chosen application. |
301 | * @param lst the list of applications to run |
302 | * @param window The top-level widget of the app that invoked this object. |
303 | * @param tempFiles if true and lst are local files, they will be deleted |
304 | * when the application exits. |
305 | * @param suggestedFileName see setSuggestedFileName |
306 | * @param asn Application startup notification id, if any (otherwise ""). |
307 | * @return false if the dialog was canceled |
308 | */ |
309 | static bool displayOpenWithDialog(const KUrl::List& lst, QWidget* window, |
310 | bool tempFiles = false, const QString& suggestedFileName = QString(), |
311 | const QByteArray& asn = QByteArray()); |
312 | |
313 | /** |
314 | * Quotes a string for the shell. |
315 | * An empty string will @em not be quoted. |
316 | * |
317 | * @deprecated Use KShell::quoteArg() instead. @em Note that this function |
318 | * behaves differently for empty arguments and returns the result |
319 | * differently. |
320 | * |
321 | * @param str the string to quote. The quoted string will be written here |
322 | */ |
323 | #ifndef KDE_NO_DEPRECATED |
324 | static KDE_DEPRECATED void shellQuote(QString &str); |
325 | #endif |
326 | |
327 | /** |
328 | * Processes a Exec= line as found in .desktop files. |
329 | * @param _service the service to extract information from. |
330 | * @param _urls The urls the service should open. |
331 | * @param tempFiles if true and urls are local files, they will be deleted |
332 | * when the application exits. |
333 | * @param suggestedFileName see setSuggestedFileName |
334 | * |
335 | * @return a list of arguments suitable for KProcess::setProgram(). |
336 | */ |
337 | static QStringList processDesktopExec(const KService &_service, const KUrl::List &_urls, |
338 | bool tempFiles = false, |
339 | const QString& suggestedFileName = QString()); |
340 | |
341 | /** |
342 | * Given a full command line (e.g. the Exec= line from a .desktop file), |
343 | * extract the name of the binary being run. |
344 | * @param execLine the full command line |
345 | * @param removePath if true, remove a (relative or absolute) path. E.g. /usr/bin/ls becomes ls. |
346 | * @return the name of the binary to run |
347 | */ |
348 | static QString binaryName(const QString & execLine, bool removePath); |
349 | |
350 | /** |
351 | * Returns whether @p serviceType refers to an executable program instead |
352 | * of a data file. |
353 | */ |
354 | static bool isExecutable(const QString& serviceType); |
355 | |
356 | /** |
357 | * Returns whether the @p url of @p mimetype is executable. |
358 | * To be executable the file must pass the following rules: |
359 | * -# Must reside on the local filesystem. |
360 | * -# Must be marked as executable for the user by the filesystem. |
361 | * -# The mime type must inherit application/x-executable or application/x-executable-script. |
362 | * To allow a script to run when the above rules are satisfied add the entry |
363 | * @code |
364 | * X-KDE-IsAlso=application/x-executable-script |
365 | * @endcode |
366 | * to the mimetype's desktop file. |
367 | */ |
368 | static bool isExecutableFile(const KUrl& url, const QString &mimetype); |
369 | |
370 | /** |
371 | * @internal |
372 | */ |
373 | static bool checkStartupNotify(const QString& binName, const KService* service, bool* silent_arg, |
374 | QByteArray* wmclass_arg); |
375 | |
376 | Q_SIGNALS: |
377 | /** |
378 | * Emitted when the operation finished. |
379 | * This signal is emitted in all cases of completion, whether successful or with error. |
380 | * @see hasFinished() |
381 | */ |
382 | void finished(); |
383 | /** |
384 | * Emitted when the operation had an error. |
385 | * @see hasError() |
386 | */ |
387 | void error(); |
388 | |
389 | protected Q_SLOTS: |
390 | /** |
391 | * All following protected slots are used by subclasses of KRun! |
392 | */ |
393 | |
394 | /** |
395 | * This slot is called whenever the internal timer fired, |
396 | * in order to move on to the next step. |
397 | */ |
398 | void slotTimeout(); // KDE5: rename to slotNextStep() or something like that |
399 | |
400 | /** |
401 | * This slot is called when the scan job is finished. |
402 | */ |
403 | void slotScanFinished(KJob *); |
404 | |
405 | /** |
406 | * This slot is called when the scan job has found out |
407 | * the mime type. |
408 | */ |
409 | void slotScanMimeType(KIO::Job *, const QString &type); |
410 | |
411 | /** |
412 | * Call this from subclasses when you have determined the mimetype. |
413 | * It will call foundMimeType, but also sets up protection against deletion during message boxes. |
414 | * @since 4.0.2 |
415 | */ |
416 | void mimeTypeDetermined(const QString& mimeType); |
417 | |
418 | /** |
419 | * This slot is called when the 'stat' job has finished. |
420 | */ |
421 | virtual void slotStatResult(KJob *); |
422 | |
423 | protected: |
424 | /** |
425 | * All following protected methods are used by subclasses of KRun! |
426 | */ |
427 | |
428 | /** |
429 | * Initializes the krun object. |
430 | */ |
431 | virtual void init(); |
432 | |
433 | /** |
434 | * Start scanning a file. |
435 | */ |
436 | virtual void scanFile(); |
437 | |
438 | /** |
439 | * Called if the mimetype has been detected. The function runs |
440 | * the application associated with this mimetype. |
441 | * Reimplement this method to implement a different behavior, |
442 | * like opening the component for displaying the URL embedded. |
443 | * |
444 | * Important: call setFinished(true) once you are done! |
445 | * Usually at the end of the foundMimeType reimplementation, but if the |
446 | * reimplementation is asynchronous (e.g. uses KIO jobs) then |
447 | * it can be called later instead. |
448 | */ |
449 | virtual void foundMimeType(const QString& type); |
450 | |
451 | /** |
452 | * Kills the file scanning job. |
453 | */ |
454 | virtual void killJob(); |
455 | |
456 | /** |
457 | * Sets the url. |
458 | */ |
459 | void setUrl(const KUrl &url); |
460 | |
461 | /** |
462 | * Returns the url. |
463 | */ |
464 | KUrl url() const; |
465 | |
466 | /** |
467 | * Sets whether an error has occurred. |
468 | */ |
469 | void setError(bool error); |
470 | |
471 | /** |
472 | * Sets whether progress information shall be shown. |
473 | */ |
474 | void setProgressInfo(bool progressInfo); |
475 | |
476 | /** |
477 | * Returns whether progress information are shown. |
478 | */ |
479 | bool progressInfo() const; |
480 | |
481 | /** |
482 | * Marks this 'KRun' instance as finished. |
483 | */ |
484 | void setFinished(bool finished); |
485 | |
486 | /** |
487 | * Sets the job. |
488 | */ |
489 | void setJob(KIO::Job *job); |
490 | |
491 | /** |
492 | * Returns the job. |
493 | */ |
494 | KIO::Job* job(); |
495 | |
496 | /** |
497 | * Returns the timer object. |
498 | * @deprecated setFinished(true) now takes care of the timer().start(0), |
499 | * so this can be removed. |
500 | */ |
501 | #ifndef KDE_NO_DEPRECATED |
502 | KDE_DEPRECATED QTimer& timer(); |
503 | #endif |
504 | |
505 | /** |
506 | * Indicate that the next action is to scan the file. |
507 | * @deprecated not useful in public API |
508 | */ |
509 | #ifndef KDE_NO_DEPRECATED |
510 | KDE_DEPRECATED void setDoScanFile(bool scanFile); |
511 | #endif |
512 | |
513 | /** |
514 | * Returns whether the file shall be scanned. |
515 | * @deprecated not useful in public API |
516 | */ |
517 | #ifndef KDE_NO_DEPRECATED |
518 | KDE_DEPRECATED bool doScanFile() const; |
519 | #endif |
520 | |
521 | /** |
522 | * Sets whether it is a directory. |
523 | * @deprecated typo in the name, and not useful as a public method |
524 | */ |
525 | #ifndef KDE_NO_DEPRECATED |
526 | KDE_DEPRECATED void setIsDirecory(bool isDirectory); |
527 | #endif |
528 | |
529 | /** |
530 | * Returns whether it is a directory. |
531 | */ |
532 | bool isDirectory() const; |
533 | |
534 | /** |
535 | * @deprecated not useful in public API |
536 | */ |
537 | #ifndef KDE_NO_DEPRECATED |
538 | KDE_DEPRECATED void setInitializeNextAction(bool initialize); |
539 | #endif |
540 | |
541 | /** |
542 | * @deprecated not useful in public API |
543 | */ |
544 | #ifndef KDE_NO_DEPRECATED |
545 | KDE_DEPRECATED bool initializeNextAction() const; |
546 | #endif |
547 | |
548 | /** |
549 | * Sets whether it is a local file. |
550 | */ |
551 | void setIsLocalFile(bool isLocalFile); |
552 | |
553 | /** |
554 | * Returns whether it is a local file. |
555 | */ |
556 | bool isLocalFile() const; |
557 | |
558 | /** |
559 | * Sets the file mode. |
560 | */ |
561 | void setMode(mode_t mode); |
562 | |
563 | /** |
564 | * Returns the file mode. |
565 | */ |
566 | mode_t mode() const; |
567 | |
568 | private: |
569 | class KRunPrivate; |
570 | KRunPrivate* const d; |
571 | }; |
572 | |
573 | #endif |
574 | |