KIO

krun.cpp
1 /* This file is part of the KDE libraries
2  Copyright (C) 2000 Torben Weis <[email protected]>
3  Copyright (C) 2006 David Faure <[email protected]>
4  Copyright (C) 2009 Michael Pyne <[email protected]>
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 #include "krun.h"
23 
24 #if KIOWIDGETS_BUILD_DEPRECATED_SINCE(5, 71)
25 #include "krun_p.h"
26 #include "kio_widgets_debug.h"
27 
28 #include <assert.h>
29 #include <string.h>
30 #include <typeinfo>
31 #include <qplatformdefs.h>
32 
33 #include <QDialog>
34 #include <QDialogButtonBox>
35 #include <QWidget>
36 #include <QApplication>
37 #include <QDesktopWidget>
38 #include <QMimeDatabase>
39 #include <QDebug>
40 #include <QHostInfo>
41 #include <QDesktopServices>
42 
43 #include <KIconLoader>
44 #include <KJobUiDelegate>
45 #include <KMimeTypeTrader>
46 #include "kio/job.h"
47 #include "kio/global.h"
48 #include "kio/scheduler.h"
49 #include "kopenwithdialog.h"
50 #include "krecentdocument.h"
51 #include "kdesktopfileactions.h"
52 #include <kio/desktopexecparser.h>
53 #include "kprocessrunner_p.h" // for KIOGuiPrivate::checkStartupNotify
54 #include "applicationlauncherjob.h"
55 #include "jobuidelegate.h"
56 #include "widgetsuntrustedprogramhandler.h"
57 
58 #include <kurlauthorized.h>
59 #include <KMessageBox>
60 #include <KLocalizedString>
61 #include <kprotocolmanager.h>
62 #include <KProcess>
63 #include <KJobWidgets>
64 #include <KSharedConfig>
65 #include <commandlauncherjob.h>
66 
67 #include <QFile>
68 #include <QFileInfo>
69 #include <KDesktopFile>
70 #include <KShell>
71 #include <KConfigGroup>
72 #include <KStandardGuiItem>
73 #include <KGuiItem>
74 
75 #include <KIO/OpenUrlJob>
76 #include <QStandardPaths>
77 #include <KIO/JobUiDelegate>
78 
79 #ifdef Q_OS_WIN
80 #include "widgetsopenwithhandler_win.cpp" // displayNativeOpenWithDialog
81 #endif
82 
83 KRunPrivate::KRunPrivate(KRun *parent)
84  : q(parent),
85  m_showingDialog(false)
86 {
87 }
88 
89 void KRunPrivate::startTimer()
90 {
91  m_timer->start(0);
92 }
93 
94 // ---------------------------------------------------------------------------
95 
96 
97 static KService::Ptr schemeService(const QString &protocol)
98 {
99  return KMimeTypeTrader::self()->preferredService(QLatin1String("x-scheme-handler/") + protocol);
100 }
101 
102 static bool checkNeedPortalSupport()
103 {
105  QLatin1String("flatpak-info")).isEmpty() ||
106  qEnvironmentVariableIsSet("SNAP");
107 }
108 
109 qint64 KRunPrivate::runCommandLauncherJob(KIO::CommandLauncherJob *job, QWidget *widget)
110 {
111  QObject *receiver = widget ? static_cast<QObject *>(widget) : static_cast<QObject *>(qApp);
112  QObject::connect(job, &KJob::result, receiver, [widget](KJob *job) {
113  if (job->error()) {
114  QEventLoopLocker locker;
115  KMessageBox::sorry(widget, job->errorString());
116  }
117  });
118  job->start();
119  job->waitForStarted();
120  return job->error() ? 0 : job->pid();
121 }
122 
123 // ---------------------------------------------------------------------------
124 
125 // Helper function that returns whether a file has the execute bit set or not.
126 static bool hasExecuteBit(const QString &fileName)
127 {
128  QFileInfo file(fileName);
129  return file.isExecutable();
130 }
131 
132 bool KRun::isExecutableFile(const QUrl &url, const QString &mimetype)
133 {
134  if (!url.isLocalFile()) {
135  return false;
136  }
137 
138  // While isExecutable performs similar check to this one, some users depend on
139  // this method not returning true for application/x-desktop
140  QMimeDatabase db;
141  QMimeType mimeType = db.mimeTypeForName(mimetype);
142  if (!mimeType.inherits(QStringLiteral("application/x-executable"))
143  && !mimeType.inherits(QStringLiteral("application/x-ms-dos-executable"))
144  && !mimeType.inherits(QStringLiteral("application/x-executable-script"))
145  && !mimeType.inherits(QStringLiteral("application/x-sharedlib"))) {
146  return false;
147  }
148 
149  if (!hasExecuteBit(url.toLocalFile()) && !mimeType.inherits(QStringLiteral("application/x-ms-dos-executable"))) {
150  return false;
151  }
152 
153  return true;
154 }
155 
156 void KRun::handleInitError(int kioErrorCode, const QString &errorMsg)
157 {
158  Q_UNUSED(kioErrorCode);
159  d->m_showingDialog = true;
160  KMessageBox::error(d->m_window, errorMsg);
161  d->m_showingDialog = false;
162 }
163 
165 {
166  Q_ASSERT(job);
167  if (job) {
168  d->m_showingDialog = true;
169  job->uiDelegate()->showErrorMessage();
170  d->m_showingDialog = false;
171  }
172 }
173 
174 #if KIOWIDGETS_BUILD_DEPRECATED_SINCE(5, 31)
175 bool KRun::runUrl(const QUrl &url, const QString &mimetype, QWidget *window, bool tempFile, bool runExecutables, const QString &suggestedFileName, const QByteArray &asn)
176 {
177  RunFlags flags = tempFile ? KRun::DeleteTemporaryFiles : RunFlags();
178  if (runExecutables) {
179  flags |= KRun::RunExecutables;
180  }
181 
182  return runUrl(url, mimetype, window, flags, suggestedFileName, asn);
183 }
184 #endif
185 
186 #if KIOWIDGETS_BUILD_DEPRECATED_SINCE(5, 71)
187 // This is called by foundMimeType, since it knows the mimetype of the URL
188 bool KRun::runUrl(const QUrl &u, const QString &_mimetype, QWidget *window, RunFlags flags, const QString &suggestedFileName, const QByteArray &asn)
189 {
190  const bool runExecutables = flags.testFlag(KRun::RunExecutables);
191  const bool tempFile = flags.testFlag(KRun::DeleteTemporaryFiles);
192 
193  KIO::OpenUrlJob *job = new KIO::OpenUrlJob(u, _mimetype);
194  job->setSuggestedFileName(suggestedFileName);
195  job->setStartupId(asn);
197  job->setDeleteTemporaryFile(tempFile);
198  job->setRunExecutables(runExecutables);
199  job->start();
200  return true;
201 }
202 #endif
203 
204 #if KIOWIDGETS_BUILD_DEPRECATED_SINCE(5, 71)
205 bool KRun::displayOpenWithDialog(const QList<QUrl> &lst, QWidget *window, bool tempFiles,
206  const QString &suggestedFileName, const QByteArray &asn)
207 {
208  if (!KAuthorized::authorizeAction(QStringLiteral("openwith"))) {
209  KMessageBox::sorry(window,
210  i18n("You are not authorized to select an application to open this file."));
211  return false;
212  }
213 
214 #ifdef Q_OS_WIN
215  KConfigGroup cfgGroup(KSharedConfig::openConfig(), QStringLiteral("KOpenWithDialog Settings"));
216  if (cfgGroup.readEntry("Native", true)) {
217  return displayNativeOpenWithDialog(lst, window);
218  }
219 #endif
220 
221  // TODO : pass the mimetype as a parameter, to show it (comment field) in the dialog !
222  // Note KOpenWithDialog::setMimeTypeFromUrls already guesses the mimetype if lst.size() == 1
223  KOpenWithDialog dialog(lst, QString(), QString(), window);
225  if (dialog.exec()) {
226  KService::Ptr service = dialog.service();
227  if (!service) {
228  //qDebug() << "No service set, running " << dialog.text();
229  service = KService::Ptr(new KService(QString() /*name*/, dialog.text(), QString() /*icon*/));
230  }
231  const RunFlags flags = tempFiles ? KRun::DeleteTemporaryFiles : RunFlags();
232  return KRun::runApplication(*service, lst, window, flags, suggestedFileName, asn);
233  }
234  return false;
235 }
236 #endif
237 
238 #if KIOWIDGETS_BUILD_DEPRECATED_SINCE(4, 0)
240 {
241  // Credits to Walter, says Bernd G. :)
242  if (_str.isEmpty()) { // Don't create an explicit empty parameter
243  return;
244  }
245  const QChar q = QLatin1Char('\'');
246  _str.replace(q, QLatin1String("'\\''")).prepend(q).append(q);
247 }
248 #endif
249 
250 #if KIOWIDGETS_BUILD_DEPRECATED_SINCE(5, 0)
251 QStringList KRun::processDesktopExec(const KService &_service, const QList<QUrl> &_urls, bool tempFiles, const QString &suggestedFileName)
252 {
253  KIO::DesktopExecParser parser(_service, _urls);
254  parser.setUrlsAreTempFiles(tempFiles);
255  parser.setSuggestedFileName(suggestedFileName);
256  return parser.resultingArguments();
257 }
258 #endif
259 
260 #if KIOWIDGETS_BUILD_DEPRECATED_SINCE(5, 0)
261 QString KRun::binaryName(const QString &execLine, bool removePath)
262 {
263  return removePath ? KIO::DesktopExecParser::executableName(execLine) : KIO::DesktopExecParser::executablePath(execLine);
264 }
265 #endif
266 
267 // This code is also used in klauncher.
268 // TODO: port klauncher to KIOGuiPrivate::checkStartupNotify once this lands
269 // TODO: then deprecate this method, and remove in KF6
270 bool KRun::checkStartupNotify(const QString & /*binName*/, const KService *service, bool *silent_arg, QByteArray *wmclass_arg)
271 {
272  return KIOGuiPrivate::checkStartupNotify(service, silent_arg, wmclass_arg);
273 }
274 
275 #if KIOWIDGETS_BUILD_DEPRECATED_SINCE(5, 6)
276 bool KRun::run(const KService &_service, const QList<QUrl> &_urls, QWidget *window,
277  bool tempFiles, const QString &suggestedFileName, const QByteArray &asn)
278 {
279  const RunFlags flags = tempFiles ? KRun::DeleteTemporaryFiles : RunFlags();
280  return runApplication(_service, _urls, window, flags, suggestedFileName, asn) != 0;
281 }
282 #endif
283 
284 #if KIOWIDGETS_BUILD_DEPRECATED_SINCE(5, 71)
285 qint64 KRun::runApplication(const KService &service, const QList<QUrl> &urls, QWidget *window,
286  RunFlags flags, const QString &suggestedFileName,
287  const QByteArray &asn)
288 {
289  KService::Ptr servicePtr(new KService(service)); // clone
290  // QTBUG-59017 Calling winId() on an embedded widget will break interaction
291  // with it on high-dpi multi-screen setups (cf. also Bug 363548), hence using
292  // its parent window instead
293  if (window) {
294  window = window->window();
295  }
296 
298  job->setUrls(urls);
299  if (flags & DeleteTemporaryFiles) {
301  }
302  job->setSuggestedFileName(suggestedFileName);
303  job->setStartupId(asn);
305  job->start();
306  job->waitForStarted();
307  return job->error() ? 0 : job->pid();
308 }
309 #endif
310 
311 #if KIOWIDGETS_BUILD_DEPRECATED_SINCE(5, 71)
312 qint64 KRun::runService(const KService &_service, const QList<QUrl> &_urls, QWidget *window,
313  bool tempFiles, const QString &suggestedFileName, const QByteArray &asn)
314 {
315  return runApplication(_service,
316  _urls,
317  window,
318  tempFiles ? RunFlags(DeleteTemporaryFiles) : RunFlags(),
319  suggestedFileName,
320  asn);
321 }
322 #endif
323 
324 #if KIOWIDGETS_BUILD_DEPRECATED_SINCE(5, 71)
325 bool KRun::run(const QString &_exec, const QList<QUrl> &_urls, QWidget *window, const QString &_name,
326  const QString &_icon, const QByteArray &asn)
327 {
328  KService::Ptr service(new KService(_name, _exec, _icon));
329 
330  return runApplication(*service, _urls, window, RunFlags{}, QString(), asn);
331 }
332 #endif
333 
334 #if KIOWIDGETS_BUILD_DEPRECATED_SINCE(5, 71)
335 bool KRun::runCommand(const QString &cmd, QWidget *window, const QString &workingDirectory)
336 {
337  if (cmd.isEmpty()) {
338  qCWarning(KIO_WIDGETS) << "Command was empty, nothing to run";
339  return false;
340  }
341 
342  const QStringList args = KShell::splitArgs(cmd);
343  if (args.isEmpty()) {
344  qCWarning(KIO_WIDGETS) << "Command could not be parsed.";
345  return false;
346  }
347 
348  const QString &bin = args.first();
349  return KRun::runCommand(cmd, bin, bin /*iconName*/, window, QByteArray(), workingDirectory);
350 }
351 #endif
352 
353 #if KIOWIDGETS_BUILD_DEPRECATED_SINCE(5, 71)
354 bool KRun::runCommand(const QString &cmd, const QString &execName, const QString &iconName, QWidget *window, const QByteArray &asn)
355 {
356  return runCommand(cmd, execName, iconName, window, asn, QString());
357 }
358 #endif
359 
360 #if KIOWIDGETS_BUILD_DEPRECATED_SINCE(5, 71)
361 bool KRun::runCommand(const QString &cmd, const QString &execName, const QString &iconName,
362  QWidget *window, const QByteArray &asn, const QString &workingDirectory)
363 {
364  auto *job = new KIO::CommandLauncherJob(cmd);
365  job->setExecutable(execName);
366  job->setIcon(iconName);
367  job->setStartupId(asn);
368  job->setWorkingDirectory(workingDirectory);
369 
370  if (window) {
371  window = window->window();
372  }
373  return KRunPrivate::runCommandLauncherJob(job, window);
374 }
375 #endif
376 
377 KRun::KRun(const QUrl &url, QWidget *window,
378  bool showProgressInfo, const QByteArray &asn)
379  : d(new KRunPrivate(this))
380 {
381  d->m_timer = new QTimer(this);
382  d->m_timer->setObjectName(QStringLiteral("KRun::timer"));
383  d->m_timer->setSingleShot(true);
384  d->init(url, window, showProgressInfo, asn);
385 }
386 
387 void KRunPrivate::init(const QUrl &url, QWidget *window,
388  bool showProgressInfo, const QByteArray &asn)
389 {
390  m_bFault = false;
391  m_bAutoDelete = true;
392  m_bProgressInfo = showProgressInfo;
393  m_bFinished = false;
394  m_job = nullptr;
395  m_strURL = url;
396  m_bScanFile = false;
397  m_bIsDirectory = false;
398  m_runExecutables = true;
399  m_followRedirections = true;
400  m_window = window;
401  m_asn = asn;
402  q->setEnableExternalBrowser(true);
403 
404  // Start the timer. This means we will return to the event
405  // loop and do initialization afterwards.
406  // Reason: We must complete the constructor before we do anything else.
407  m_bCheckPrompt = false;
408  m_bInit = true;
409  q->connect(m_timer, &QTimer::timeout, q, &KRun::slotTimeout);
410  startTimer();
411  //qDebug() << "new KRun" << q << url << "timer=" << m_timer;
412 }
413 
415 {
416  //qDebug() << "INIT called";
417  if (!d->m_strURL.isValid() || d->m_strURL.scheme().isEmpty()) {
418  const QString error = !d->m_strURL.isValid() ? d->m_strURL.errorString() : d->m_strURL.toString();
419  handleInitError(KIO::ERR_MALFORMED_URL, i18n("Malformed URL\n%1", error));
420  qCWarning(KIO_WIDGETS) << "Malformed URL:" << error;
421  d->m_bFault = true;
422  d->m_bFinished = true;
423  d->startTimer();
424  return;
425  }
426  if (!KUrlAuthorized::authorizeUrlAction(QStringLiteral("open"), QUrl(), d->m_strURL)) {
427  QString msg = KIO::buildErrorString(KIO::ERR_ACCESS_DENIED, d->m_strURL.toDisplayString());
428  handleInitError(KIO::ERR_ACCESS_DENIED, msg);
429  d->m_bFault = true;
430  d->m_bFinished = true;
431  d->startTimer();
432  return;
433  }
434 
435  if (d->m_externalBrowserEnabled && checkNeedPortalSupport()) {
436  // use the function from QDesktopServices as it handles portals correctly
437  d->m_bFault = !QDesktopServices::openUrl(d->m_strURL);
438  d->m_bFinished = true;
439  d->startTimer();
440  return;
441  }
442 
443  if (!d->m_externalBrowser.isEmpty() && d->m_strURL.scheme().startsWith(QLatin1String("http"))) {
444  if (d->runExternalBrowser(d->m_externalBrowser)) {
445  return;
446  }
447  } else if (d->m_strURL.isLocalFile() &&
448  (d->m_strURL.host().isEmpty() ||
449  (d->m_strURL.host() == QLatin1String("localhost")) ||
450  (d->m_strURL.host().compare(QHostInfo::localHostName(), Qt::CaseInsensitive) == 0))) {
451  const QString localPath = d->m_strURL.toLocalFile();
452  if (!QFile::exists(localPath)) {
453  handleInitError(KIO::ERR_DOES_NOT_EXIST,
454  i18n("<qt>Unable to run the command specified. "
455  "The file or folder <b>%1</b> does not exist.</qt>",
456  localPath.toHtmlEscaped()));
457  d->m_bFault = true;
458  d->m_bFinished = true;
459  d->startTimer();
460  return;
461  }
462 
463  QMimeDatabase db;
464  QMimeType mime = db.mimeTypeForUrl(d->m_strURL);
465  //qDebug() << "MIME TYPE is " << mime.name();
466  if (mime.isDefault() && !QFileInfo(localPath).isReadable()) {
467  // Unknown mimetype because the file is unreadable, no point in showing an open-with dialog (#261002)
468  const QString msg = KIO::buildErrorString(KIO::ERR_ACCESS_DENIED, localPath);
469  handleInitError(KIO::ERR_ACCESS_DENIED, msg);
470  d->m_bFault = true;
471  d->m_bFinished = true;
472  d->startTimer();
473  return;
474  } else {
475  mimeTypeDetermined(mime.name());
476  return;
477  }
478  } else if (KIO::DesktopExecParser::hasSchemeHandler(d->m_strURL)) {
479  // looks for an application associated with x-scheme-handler/<protocol>
480  const KService::Ptr service = schemeService(d->m_strURL.scheme());
481  if (service) {
482  // if there's one...
483  if (runApplication(*service, QList<QUrl>() << d->m_strURL, d->m_window, RunFlags{}, QString(), d->m_asn)) {
484  d->m_bFinished = true;
485  d->startTimer();
486  return;
487  }
488  } else {
489  // fallback, look for associated helper protocol
490  Q_ASSERT(KProtocolInfo::isHelperProtocol(d->m_strURL.scheme()));
491  const auto exec = KProtocolInfo::exec(d->m_strURL.scheme());
492  if (exec.isEmpty()) {
493  // use default mimetype opener for file
495  return;
496  } else {
497  if (run(exec, QList<QUrl>() << d->m_strURL, d->m_window, QString(), QString(), d->m_asn)) {
498  d->m_bFinished = true;
499  d->startTimer();
500  return;
501  }
502  }
503  }
504 
505  }
506 
507 #if 0 // removed for KF5 (for portability). Reintroduce a bool or flag if useful.
508  // Did we already get the information that it is a directory ?
509  if ((d->m_mode & QT_STAT_MASK) == QT_STAT_DIR) {
510  mimeTypeDetermined("inode/directory");
511  return;
512  }
513 #endif
514 
515  // Let's see whether it is a directory
516 
517  if (!KProtocolManager::supportsListing(d->m_strURL)) {
518  // No support for listing => it can't be a directory (example: http)
519 
520  if (!KProtocolManager::supportsReading(d->m_strURL)) {
521  // No support for reading files either => we can't do anything (example: mailto URL, with no associated app)
522  handleInitError(KIO::ERR_UNSUPPORTED_ACTION, i18n("Could not find any application or handler for %1", d->m_strURL.toDisplayString()));
523  d->m_bFault = true;
524  d->m_bFinished = true;
525  d->startTimer();
526  return;
527  }
528  scanFile();
529  return;
530  }
531 
532  //qDebug() << "Testing directory (stating)";
533 
534  // It may be a directory or a file, let's stat
535  KIO::JobFlags flags = d->m_bProgressInfo ? KIO::DefaultFlags : KIO::HideProgressInfo;
536  KIO::StatJob *job = KIO::statDetails(d->m_strURL, KIO::StatJob::SourceSide, KIO::StatBasic, flags);
537  KJobWidgets::setWindow(job, d->m_window);
538  connect(job, &KJob::result,
539  this, &KRun::slotStatResult);
540  d->m_job = job;
541  //qDebug() << "Job" << job << "is about stating" << d->m_strURL;
542 }
543 
545 {
546  //qDebug() << this;
547  d->m_timer->stop();
548  killJob();
549  //qDebug() << this << "done";
550  delete d;
551 }
552 
553 bool KRunPrivate::runExternalBrowser(const QString &_exec)
554 {
555  QList<QUrl> urls;
556  urls.append(m_strURL);
557  if (_exec.startsWith(QLatin1Char('!'))) {
558  // Literal command
559  const QString exec = _exec.midRef(1) + QLatin1String(" %u");
560  if (KRun::run(exec, urls, m_window, QString(), QString(), m_asn)) {
561  m_bFinished = true;
562  startTimer();
563  return true;
564  }
565  } else {
567  if (service && KRun::runApplication(*service, urls, m_window, KRun::RunFlags{}, QString(), m_asn)) {
568  m_bFinished = true;
569  startTimer();
570  return true;
571  }
572  }
573  return false;
574 }
575 
576 void KRunPrivate::showPrompt()
577 {
578  ExecutableFileOpenDialog *dialog = new ExecutableFileOpenDialog(promptMode(), q->window());
579  dialog->setAttribute(Qt::WA_DeleteOnClose);
580  QObject::connect(dialog, &ExecutableFileOpenDialog::finished, q, [this, dialog](int result){
581  onDialogFinished(result, dialog->isDontAskAgainChecked());
582  });
583  dialog->show();
584 }
585 
586 bool KRunPrivate::isPromptNeeded()
587 {
588  if (m_strURL == QUrl(QStringLiteral("remote:/x-wizard_service.desktop"))) {
589  return false;
590  }
591  const QMimeDatabase db;
592  const QMimeType mime = db.mimeTypeForUrl(m_strURL);
593 
594  const bool isFileExecutable = (KRun::isExecutableFile(m_strURL, mime.name()) ||
595  mime.inherits(QStringLiteral("application/x-desktop")));
596 
597  if (isFileExecutable) {
598  KConfigGroup cfgGroup(KSharedConfig::openConfig(QStringLiteral("kiorc")), "Executable scripts");
599  const QString value = cfgGroup.readEntry("behaviourOnLaunch", "alwaysAsk");
600 
601  if (value == QLatin1String("alwaysAsk")) {
602  return true;
603  } else {
604  q->setRunExecutables(value == QLatin1String("execute"));
605  }
606  }
607 
608  return false;
609 }
610 
611 ExecutableFileOpenDialog::Mode KRunPrivate::promptMode()
612 {
613  const QMimeDatabase db;
614  const QMimeType mime = db.mimeTypeForUrl(m_strURL);
615 
616  if (mime.inherits(QStringLiteral("text/plain"))) {
617  return ExecutableFileOpenDialog::OpenOrExecute;
618  }
619 #ifndef Q_OS_WIN
620  if (mime.inherits(QStringLiteral("application/x-ms-dos-executable"))) {
621  return ExecutableFileOpenDialog::OpenAsExecute;
622  }
623 #endif
624  return ExecutableFileOpenDialog::OnlyExecute;
625 }
626 
627 void KRunPrivate::onDialogFinished(int result, bool isDontAskAgainSet)
628 {
629  if (result == ExecutableFileOpenDialog::Rejected) {
630  m_bFinished = true;
631  m_bInit = false;
632  startTimer();
633  return;
634  }
635  q->setRunExecutables(result == ExecutableFileOpenDialog::ExecuteFile);
636 
637  if (isDontAskAgainSet) {
638  QString output = result == ExecutableFileOpenDialog::OpenFile ? QStringLiteral("open") : QStringLiteral("execute");
639  KConfigGroup cfgGroup(KSharedConfig::openConfig(QStringLiteral("kiorc")), "Executable scripts");
640  cfgGroup.writeEntry("behaviourOnLaunch", output);
641  }
642  startTimer();
643 }
644 
646 {
647  //qDebug() << d->m_strURL;
648  // First, let's check for well-known extensions
649  // Not when there is a query in the URL, in any case.
650  if (!d->m_strURL.hasQuery()) {
651  QMimeDatabase db;
652  QMimeType mime = db.mimeTypeForUrl(d->m_strURL);
653  if (!mime.isDefault() || d->m_strURL.isLocalFile()) {
654  //qDebug() << "Scanfile: MIME TYPE is " << mime.name();
655  mimeTypeDetermined(mime.name());
656  return;
657  }
658  }
659 
660  // No mimetype found, and the URL is not local (or fast mode not allowed).
661  // We need to apply the 'KIO' method, i.e. either asking the server or
662  // getting some data out of the file, to know what mimetype it is.
663 
664  if (!KProtocolManager::supportsReading(d->m_strURL)) {
665  qCWarning(KIO_WIDGETS) << "#### NO SUPPORT FOR READING!";
666  d->m_bFault = true;
667  d->m_bFinished = true;
668  d->startTimer();
669  return;
670  }
671  //qDebug() << this << "Scanning file" << d->m_strURL;
672 
673  KIO::JobFlags flags = d->m_bProgressInfo ? KIO::DefaultFlags : KIO::HideProgressInfo;
674  KIO::TransferJob *job = KIO::get(d->m_strURL, KIO::NoReload /*reload*/, flags);
675  KJobWidgets::setWindow(job, d->m_window);
676  connect(job, &KJob::result,
677  this, &KRun::slotScanFinished);
678  connect(job, QOverload<KIO::Job*,const QString&>::of(&KIO::TransferJob::mimetype),
679  this, &KRun::slotScanMimeType);
680  d->m_job = job;
681  //qDebug() << "Job" << job << "is about getting from" << d->m_strURL;
682 }
683 
684 // When arriving in that method there are 6 possible states:
685 // must_show_prompt, must_init, must_scan_file, found_dir, done+error or done+success.
687 {
688  if (d->m_bCheckPrompt) {
689  d->m_bCheckPrompt = false;
690  if (d->isPromptNeeded()) {
691  d->showPrompt();
692  return;
693  }
694  }
695  if (d->m_bInit) {
696  d->m_bInit = false;
697  init();
698  return;
699  }
700 
701  if (d->m_bFault) {
702  emit error();
703  }
704  if (d->m_bFinished) {
705  emit finished();
706  } else {
707  if (d->m_bScanFile) {
708  d->m_bScanFile = false;
709  scanFile();
710  return;
711  } else if (d->m_bIsDirectory) {
712  d->m_bIsDirectory = false;
713  mimeTypeDetermined(QStringLiteral("inode/directory"));
714  return;
715  }
716  }
717 
718  if (d->m_bAutoDelete) {
719  deleteLater();
720  return;
721  }
722 }
723 
725 {
726  d->m_job = nullptr;
727  const int errCode = job->error();
728  if (errCode) {
729  // ERR_NO_CONTENT is not an error, but an indication no further
730  // actions needs to be taken.
731  if (errCode != KIO::ERR_NO_CONTENT) {
732  qCWarning(KIO_WIDGETS) << this << "ERROR" << job->error() << job->errorString();
733  handleError(job);
734  //qDebug() << this << " KRun returning from showErrorDialog, starting timer to delete us";
735  d->m_bFault = true;
736  }
737 
738  d->m_bFinished = true;
739 
740  // will emit the error and autodelete this
741  d->startTimer();
742  } else {
743  //qDebug() << "Finished";
744 
745  KIO::StatJob *statJob = qobject_cast<KIO::StatJob *>(job);
746  if (!statJob) {
747  qFatal("Fatal Error: job is a %s, should be a StatJob", typeid(*job).name());
748  }
749 
750  // Update our URL in case of a redirection
751  setUrl(statJob->url());
752 
753  const KIO::UDSEntry entry = statJob->statResult();
754  const mode_t mode = entry.numberValue(KIO::UDSEntry::UDS_FILE_TYPE);
755  if ((mode & QT_STAT_MASK) == QT_STAT_DIR) {
756  d->m_bIsDirectory = true; // it's a dir
757  } else {
758  d->m_bScanFile = true; // it's a file
759  }
760 
761  d->m_localPath = entry.stringValue(KIO::UDSEntry::UDS_LOCAL_PATH);
762 
763  // mimetype already known? (e.g. print:/manager)
764  const QString knownMimeType = entry.stringValue(KIO::UDSEntry::UDS_MIME_TYPE);
765 
766  if (!knownMimeType.isEmpty()) {
767  mimeTypeDetermined(knownMimeType);
768  d->m_bFinished = true;
769  }
770 
771  // We should have found something
772  assert(d->m_bScanFile || d->m_bIsDirectory);
773 
774  // Start the timer. Once we get the timer event this
775  // protocol server is back in the pool and we can reuse it.
776  // This gives better performance than starting a new slave
777  d->startTimer();
778  }
779 }
780 
781 void KRun::slotScanMimeType(KIO::Job *, const QString &mimetype)
782 {
783  if (mimetype.isEmpty()) {
784  qCWarning(KIO_WIDGETS) << "get() didn't emit a mimetype! Probably a kioslave bug, please check the implementation of" << url().scheme();
785  }
786  mimeTypeDetermined(mimetype);
787  d->m_job = nullptr;
788 }
789 
791 {
792  d->m_job = nullptr;
793  const int errCode = job->error();
794  if (errCode) {
795  // ERR_NO_CONTENT is not an error, but an indication no further
796  // actions needs to be taken.
797  if (errCode != KIO::ERR_NO_CONTENT) {
798  qCWarning(KIO_WIDGETS) << this << "ERROR (stat):" << job->error() << ' ' << job->errorString();
799  handleError(job);
800 
801  d->m_bFault = true;
802  }
803 
804  d->m_bFinished = true;
805  // will emit the error and autodelete this
806  d->startTimer();
807  }
808 }
809 
810 void KRun::mimeTypeDetermined(const QString &mimeType)
811 {
812  // foundMimeType reimplementations might show a dialog box;
813  // make sure some timer doesn't kill us meanwhile (#137678, #156447)
814  Q_ASSERT(!d->m_showingDialog);
815  d->m_showingDialog = true;
816 
817  foundMimeType(mimeType);
818 
819  d->m_showingDialog = false;
820 
821  // We cannot assume that we're finished here. Some reimplementations
822  // start a KIO job and call setFinished only later.
823 }
824 
825 void KRun::foundMimeType(const QString &type)
826 {
827  //qDebug() << "Resulting mime type is " << type;
828 
829  QMimeDatabase db;
830 
831  KIO::TransferJob *job = qobject_cast<KIO::TransferJob *>(d->m_job);
832  if (job) {
833  // Update our URL in case of a redirection
834  if (d->m_followRedirections) {
835  setUrl(job->url());
836  }
837 
838  job->putOnHold();
840  d->m_job = nullptr;
841  }
842 
843  Q_ASSERT(!d->m_bFinished);
844 
845  // Support for preferred service setting, see setPreferredService
846  if (!d->m_preferredService.isEmpty()) {
847  //qDebug() << "Attempting to open with preferred service: " << d->m_preferredService;
848  KService::Ptr serv = KService::serviceByDesktopName(d->m_preferredService);
849  if (serv && serv->hasMimeType(type)) {
850  QList<QUrl> lst;
851  lst.append(d->m_strURL);
852  if (KRun::runApplication(*serv, lst, d->m_window, RunFlags{}, QString(), d->m_asn)) {
853  setFinished(true);
854  return;
855  }
860  }
861  }
862 
863  // Resolve .desktop files from media:/, remote:/, applications:/ etc.
864  QMimeType mime = db.mimeTypeForName(type);
865  if (!mime.isValid()) {
866  qCWarning(KIO_WIDGETS) << "Unknown mimetype" << type;
867  } else if (mime.inherits(QStringLiteral("application/x-desktop")) && !d->m_localPath.isEmpty()) {
868  d->m_strURL = QUrl::fromLocalFile(d->m_localPath);
869  }
870 
871  KRun::RunFlags runFlags;
872  if (d->m_runExecutables) {
873  runFlags |= KRun::RunExecutables;
874  }
875  if (!KRun::runUrl(d->m_strURL, type, d->m_window, runFlags, d->m_suggestedFileName, d->m_asn)) {
876  d->m_bFault = true;
877  }
878  setFinished(true);
879 }
880 
882 {
883  if (d->m_job) {
884  //qDebug() << this << "m_job=" << d->m_job;
885  d->m_job->kill();
886  d->m_job = nullptr;
887  }
888 }
889 
891 {
892  if (d->m_bFinished) {
893  return;
894  }
895  //qDebug() << this << "m_showingDialog=" << d->m_showingDialog;
896  killJob();
897  // If we're showing an error message box, the rest will be done
898  // after closing the msgbox -> don't autodelete nor emit signals now.
899  if (d->m_showingDialog) {
900  return;
901  }
902  d->m_bFault = true;
903  d->m_bFinished = true;
904  d->m_bInit = false;
905  d->m_bScanFile = false;
906 
907  // will emit the error and autodelete this
908  d->startTimer();
909 }
910 
912 {
913  return d->m_window;
914 }
915 
916 bool KRun::hasError() const
917 {
918  return d->m_bFault;
919 }
920 
921 bool KRun::hasFinished() const
922 {
923  return d->m_bFinished;
924 }
925 
926 bool KRun::autoDelete() const
927 {
928  return d->m_bAutoDelete;
929 }
930 
932 {
933  d->m_bAutoDelete = b;
934 }
935 
937 {
938  d->m_externalBrowserEnabled = b;
939  if (d->m_externalBrowserEnabled) {
940  d->m_externalBrowser = KConfigGroup(KSharedConfig::openConfig(), "General").readEntry("BrowserApplication");
941 
942  // If a default browser isn't set in kdeglobals, fall back to mimeapps.list
943  if (!d->m_externalBrowser.isEmpty()) {
944  return;
945  }
946 
947  KSharedConfig::Ptr profile = KSharedConfig::openConfig(QStringLiteral("mimeapps.list"), KConfig::NoGlobals, QStandardPaths::GenericConfigLocation);
948  KConfigGroup defaultApps(profile, "Default Applications");
949 
950  d->m_externalBrowser = defaultApps.readEntry("x-scheme-handler/https");
951  if (d->m_externalBrowser.isEmpty()) {
952  d->m_externalBrowser = defaultApps.readEntry("x-scheme-handler/http");
953  }
954  } else {
955  d->m_externalBrowser.clear();
956  }
957 }
958 
959 void KRun::setPreferredService(const QString &desktopEntryName)
960 {
961  d->m_preferredService = desktopEntryName;
962 }
963 
965 {
966  d->m_runExecutables = b;
967 }
968 
969 void KRun::setSuggestedFileName(const QString &fileName)
970 {
971  d->m_suggestedFileName = fileName;
972 }
973 
975 {
976  d->m_bCheckPrompt = showPrompt;
977 }
978 
979 void KRun::setFollowRedirections(bool followRedirections)
980 {
981  d->m_followRedirections = followRedirections;
982 }
983 
985 {
986  return d->m_suggestedFileName;
987 }
988 
989 bool KRun::isExecutable(const QString &mimeTypeName)
990 {
991  QMimeDatabase db;
992  QMimeType mimeType = db.mimeTypeForName(mimeTypeName);
993  return (mimeType.inherits(QStringLiteral("application/x-desktop")) ||
994  mimeType.inherits(QStringLiteral("application/x-executable")) ||
995  /* See https://bugs.freedesktop.org/show_bug.cgi?id=97226 */
996  mimeType.inherits(QStringLiteral("application/x-sharedlib")) ||
997  mimeType.inherits(QStringLiteral("application/x-ms-dos-executable")) ||
998  mimeType.inherits(QStringLiteral("application/x-shellscript")));
999 }
1000 
1001 void KRun::setUrl(const QUrl &url)
1002 {
1003  d->m_strURL = url;
1004 }
1005 
1007 {
1008  return d->m_strURL;
1009 }
1010 
1012 {
1013  d->m_bFault = error;
1014 }
1015 
1017 {
1018  d->m_bProgressInfo = progressInfo;
1019 }
1020 
1022 {
1023  return d->m_bProgressInfo;
1024 }
1025 
1027 {
1028  d->m_bFinished = finished;
1029  if (finished) {
1030  d->startTimer();
1031  }
1032 }
1033 
1035 {
1036  d->m_job = job;
1037 }
1038 
1040 {
1041  return d->m_job;
1042 }
1043 
1044 #if KIOWIDGETS_BUILD_DEPRECATED_SINCE(4, 4)
1046 {
1047  return *d->m_timer;
1048 }
1049 #endif
1050 
1051 #if KIOWIDGETS_BUILD_DEPRECATED_SINCE(4, 1)
1053 {
1054  d->m_bScanFile = scanFile;
1055 }
1056 #endif
1057 
1058 #if KIOWIDGETS_BUILD_DEPRECATED_SINCE(4, 1)
1059 bool KRun::doScanFile() const
1060 {
1061  return d->m_bScanFile;
1062 }
1063 #endif
1064 
1065 #if KIOWIDGETS_BUILD_DEPRECATED_SINCE(4, 1)
1067 {
1068  d->m_bIsDirectory = isDirectory;
1069 }
1070 #endif
1071 
1072 bool KRun::isDirectory() const
1073 {
1074  return d->m_bIsDirectory;
1075 }
1076 
1077 #if KIOWIDGETS_BUILD_DEPRECATED_SINCE(4, 1)
1078 void KRun::setInitializeNextAction(bool initialize)
1079 {
1080  d->m_bInit = initialize;
1081 }
1082 #endif
1083 
1084 #if KIOWIDGETS_BUILD_DEPRECATED_SINCE(4, 1)
1086 {
1087  return d->m_bInit;
1088 }
1089 #endif
1090 
1091 bool KRun::isLocalFile() const
1092 {
1093  return d->m_strURL.isLocalFile();
1094 }
1095 
1096 #include "moc_krun.cpp"
1097 #endif
KJOBWIDGETS_EXPORT void setWindow(KJob *job, QWidget *widget)
bool isReadable() const const
QByteArray fileName(const QUrl &url) const
Converts the given URL into 8-bit form and retrieve the filename.
static bool run(const KService &service, const QList< QUrl > &urls, QWidget *window, bool tempFiles=false, const QString &suggestedFileName=QString(), const QByteArray &asn=QByteArray())
Open a list of URLs with a certain service (application).
Definition: krun.cpp:276
void setEnableExternalBrowser(bool b)
Sets whether the external webbrowser setting should be honoured.
Definition: krun.cpp:936
static bool displayOpenWithDialog(const QList< QUrl > &lst, QWidget *window, bool tempFiles=false, const QString &suggestedFileName=QString(), const QByteArray &asn=QByteArray())
Display the Open-With dialog for those URLs, and run the chosen application.
Definition: krun.cpp:205
QString & append(QChar ch)
static bool supportsReading(const QUrl &url)
Returns whether the protocol can retrieve data from URLs.
void slotTimeout()
All following protected slots are used by subclasses of KRun!
Definition: krun.cpp:686
virtual void foundMimeType(const QString &type)
Called if the mimetype has been detected.
Definition: krun.cpp:825
void abort()
Abort this KRun.
Definition: krun.cpp:890
void setDoScanFile(bool scanFile)
Indicate that the next action is to scan the file.
Definition: krun.cpp:1052
bool progressInfo() const
Returns whether progress information are shown.
Definition: krun.cpp:1021
OpenUrlJob finds out the right way to "open" a URL.
Definition: openurljob.h:52
void setIsDirecory(bool isDirectory)
Sets whether it is a directory.
Definition: krun.cpp:1066
void setUiDelegate(KJobUiDelegate *delegate)
QWidget * window() const const
const QUrl & url() const
Returns the SimpleJob&#39;s URL.
Definition: simplejob.cpp:82
Universal Directory Service.
Definition: udsentry.h:88
static Ptr serviceByDesktopName(const QString &_name)
void setWindowModality(Qt::WindowModality windowModality)
void start() override
Starts the job.
Definition: openurljob.cpp:163
QString & prepend(QChar ch)
virtual QString errorString() const
void setRunExecutables(bool b)
Sets whether executables, .desktop files or shell scripts should be run by KRun.
Definition: krun.cpp:964
Hide progress information dialog, i.e.
Definition: job_base.h:287
static bool isExecutableFile(const QUrl &url, const QString &mimetype)
Returns whether the url of mimetype is executable.
Definition: krun.cpp:132
void setUrl(const QUrl &url)
Sets the url.
Definition: krun.cpp:1001
File type, part of the mode returned by stat (for a link, this returns the file type of the pointed i...
Definition: udsentry.h:279
QUrl url() const
Returns the url.
Definition: krun.cpp:1006
bool isDirectory() const
Returns whether it is a directory.
Definition: krun.cpp:1072
bool inherits(const QString &mimeTypeName) const const
virtual int exec()
void writeEntry(const QString &key, const QVariant &value, WriteConfigFlags pFlags=Normal)
A KIO job that retrieves information about a file or directory.
Definition: statjob.h:38
static qint64 runService(const KService &service, const QList< QUrl > &urls, QWidget *window, bool tempFiles=false, const QString &suggestedFileName=QString(), const QByteArray &asn=QByteArray())
Open a list of URLs with a certain service (application).
Definition: krun.cpp:312
A local file path if the ioslave display files sitting on the local filesystem (but in another hierar...
Definition: udsentry.h:264
static bool runUrl(const QUrl &url, const QString &mimetype, QWidget *window, bool tempFile=false, bool runExecutables=true, const QString &suggestedFileName=QString(), const QByteArray &asn=QByteArray())
Open the given URL.
Definition: krun.cpp:175
bool hasError() const
Returns true if the KRun instance has an error.
Definition: krun.cpp:916
QExplicitlySharedDataPointer< KService > Ptr
bool exists() const const
void setSuggestedFileName(const QString &suggestedFileName)
Sets the file name to use in the case of downloading the file to a tempfile in order to give to a non...
bool initializeNextAction() const
Definition: krun.cpp:1085
virtual void scanFile()
Start scanning a file.
Definition: krun.cpp:645
static bool checkStartupNotify(const QString &binName, const KService *service, bool *silent_arg, QByteArray *wmclass_arg)
Definition: krun.cpp:270
void start() override
Starts the job.
void setSuggestedFileName(const QString &suggestedFileName)
Sets the file name to use in the case of downloading the file to a tempfile in order to give to a non...
To open files with their associated applications in KDE, use KRun.
Definition: krun.h:64
void slotScanMimeType(KIO::Job *, const QString &type)
This slot is called when the scan job has found out the mime type.
Definition: krun.cpp:781
static QStringList processDesktopExec(const KService &_service, const QList< QUrl > &_urls, bool tempFiles=false, const QString &suggestedFileName=QString())
Processes a Exec= line as found in .desktop files.
Definition: krun.cpp:251
Show the progress info GUI, no Resume and no Overwrite.
Definition: job_base.h:282
void timeout()
void setError(bool error)
Sets whether an error has occurred.
Definition: krun.cpp:1011
QString mimetype() const
Call this in the slot connected to result, and only after making sure no error happened.
QStringList resultingArguments() const
void append(const T &value)
the URLs passed to the service will be deleted when it exits (if the URLs are local files) ...
Definition: krun.h:285
void finished()
Emitted when the operation finished.
long long numberValue(uint field, long long defaultValue=0) const
Definition: udsentry.cpp:370
void setStartupId(const QByteArray &startupId)
Sets the startup notification id of the application launch.
QMimeType mimeTypeForUrl(const QUrl &url) const const
static QString defaultMimetype(const QUrl &url)
Returns default mimetype for this URL based on the protocol.
bool hasMimeType(const QString &mimeType) const
A UI delegate tuned to be used with KIO Jobs.
Definition: jobuidelegate.h:42
CaseInsensitive
QWidget * window() const
Associated window, as passed to the constructor.
Definition: krun.cpp:911
Filename, access, type, size, linkdest.
Definition: global.h:325
bool isEmpty() const const
virtual void killJob()
Kills the file scanning job.
Definition: krun.cpp:881
static bool supportsListing(const QUrl &url)
Returns whether the protocol can list files/objects.
bool isEmpty() const const
KService::Ptr preferredService(const QString &mimeType, const QString &genericServiceType=QStringLiteral("Application"))
virtual void slotStatResult(KJob *)
This slot is called when the &#39;stat&#39; job has finished.
Definition: krun.cpp:724
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
KIOCORE_EXPORT QString buildErrorString(int errorCode, const QString &errorText)
Returns a translated error message for errorCode using the additional error information provided by e...
Definition: job_error.cpp:38
void error(QWidget *parent, const QString &text, const QString &caption=QString(), Options options=Notify)
bool autoDelete() const
Checks whether auto delete is activated.
Definition: krun.cpp:926
KIO::Job * job()
Returns the job.
Definition: krun.cpp:1039
virtual void handleInitError(int kioErrorCode, const QString &errorMsg)
Called when KRun detects an error during the init phase.
Definition: krun.cpp:156
"Open With" dialog box.
static KMimeTypeTrader * self()
bool doScanFile() const
Returns whether the file shall be scanned.
Definition: krun.cpp:1059
void setRunExecutables(bool allow)
Set this to true if this class should allow the user to run executables.
Definition: openurljob.cpp:137
void setSuggestedFileName(const QString &fileName)
Sets the file name to use in the case of downloading the file to a tempfile in order to give to a non...
Definition: krun.cpp:969
void deleteLater()
T & first()
void slotScanFinished(KJob *)
This slot is called when the scan job is finished.
Definition: krun.cpp:790
void setUrlsAreTempFiles(bool tempFiles)
If tempFiles is set to true and the urls given to the constructor are local files, they will be deleted when the application exits.
KCOREADDONS_EXPORT QStringList splitArgs(const QString &cmd, Options flags=NoOptions, Errors *err=nullptr)
KJobUiDelegate * uiDelegate() const
QString scheme() const const
QMimeType mimeTypeForName(const QString &nameOrAlias) const const
QString toLocalFile() const const
void setRunFlags(RunFlags runFlags)
Specifies various flags.
KIOCORE_EXPORT TransferJob * get(const QUrl &url, LoadType reload=NoReload, JobFlags flags=DefaultFlags)
Get (means: read).
void mimeTypeDetermined(const QString &mimeType)
Call this from subclasses when you have determined the mimetype.
Definition: krun.cpp:810
QString toHtmlEscaped() const const
bool isValid() const const
QStringRef midRef(int position, int n) const const
static QString exec(const QString &protocol)
Returns the library / executable to open for the protocol protocol Example : "kio_ftp", meaning either the executable "kio_ftp" or the library "kio_ftp.la" (recommended), whichever is available.
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
the URLs passed to the service will be deleted when it exits (if the URLs are local files) ...
WA_DeleteOnClose
QString text() const
QString i18n(const char *text, const TYPE &arg...)
QString & replace(int position, int n, QChar after)
Whether to run URLs that are executable scripts or binaries.
Definition: krun.h:286
virtual void handleError(KJob *job)
Called when a KIO job started by KRun gives an error.
Definition: krun.cpp:164
int startTimer(int interval, Qt::TimerType timerType)
void setStartupId(const QByteArray &startupId)
Sets the startup notification id of the application launch.
Definition: openurljob.cpp:132
void setInitializeNextAction(bool initialize)
Definition: krun.cpp:1078
void setPreferredService(const QString &desktopEntryName)
Set the preferred service for opening this URL, after its mimetype will have been found by KRun...
Definition: krun.cpp:959
bool isLocalFile() const
Returns whether it is a local file.
Definition: krun.cpp:1091
QString suggestedFileName() const
Suggested file name given by the server (e.g.
Definition: krun.cpp:984
void setAutoDelete(bool b)
Enables or disabled auto deletion.
Definition: krun.cpp:931
virtual void showErrorMessage()
static qint64 runApplication(const KService &service, const QList< QUrl > &urls, QWidget *window, RunFlags flags=RunFlags(), const QString &suggestedFileName=QString(), const QByteArray &asn=QByteArray())
Run an application (known from its .desktop file, i.e.
Definition: krun.cpp:285
void setUrls(const QList< QUrl > &urls)
Specifies the URLs to be passed to the application.
static QString executablePath(const QString &execLine)
Given a full command line (e.g.
static bool isHelperProtocol(const QUrl &url)
Returns whether the protocol can act as a helper protocol.
void error()
Emitted when the operation had an error.
void setJob(KIO::Job *job)
Sets the job.
Definition: krun.cpp:1034
QTimer & timer()
Returns the timer object.
Definition: krun.cpp:1045
virtual Q_SCRIPTABLE void start()=0
void setFinished(bool finished)
Marks this &#39;KRun&#39; instance as finished.
Definition: krun.cpp:1026
The base class for all jobs.
Definition: job_base.h:57
void setFollowRedirections(bool b)
Sets whether KRun should follow URLs redirections.
Definition: krun.cpp:979
Action succeeded but no content will follow.
Definition: global.h:261
virtual void init()
All following protected methods are used by subclasses of KRun!
Definition: krun.cpp:414
QString localHostName()
void setSuggestedFileName(const QString &suggestedFileName)
Sets the file name to use in the case of downloading the file to a tempfile, in order to give it to a...
Definition: openurljob.cpp:127
CommandLauncherJob runs a command and watches it while running.
virtual void putOnHold()
Abort job.
Definition: simplejob.cpp:87
virtual ~KRun()
Destructor.
Definition: krun.cpp:544
A mime type; the slave should set it if it&#39;s known.
Definition: udsentry.h:290
void result(KJob *job)
Parses the Exec= line from a .desktop file, and process all the &#39;%&#39; placeholders, e...
KRun(const QUrl &url, QWidget *window, bool showProgressInfo=true, const QByteArray &asn=QByteArray())
Definition: krun.cpp:377
The transfer job pumps data into and/or out of a Slave.
Definition: transferjob.h:38
void setProgressInfo(bool progressInfo)
Sets whether progress information shall be shown.
Definition: krun.cpp:1016
bool openUrl(const QUrl &url)
static void publishSlaveOnHold()
Send the slave that was put on hold back to KLauncher.
Definition: scheduler.cpp:847
WindowModal
const UDSEntry & statResult() const
Result of the stat operation.
Definition: statjob.cpp:123
ApplicationLauncherJob runs an application and watches it while running.
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
T qobject_cast(QObject *object)
void setDeleteTemporaryFile(bool b)
Specifies that the URL passed to the application will be deleted when it exits (if the URL is a local...
Definition: openurljob.cpp:122
bool testFlag(Enum flag) const const
T readEntry(const QString &key, const T &aDefault) const
static QString binaryName(const QString &execLine, bool removePath)
Given a full command line (e.g.
Definition: krun.cpp:261
static void shellQuote(QString &str)
Quotes a string for the shell.
Definition: krun.cpp:239
KIOCORE_EXPORT StatJob * statDetails(const QUrl &url, KIO::StatJob::StatSide side, KIO::StatDetails details=KIO::StatDefaultDetails, JobFlags flags=DefaultFlags)
Find all details for one file or directory.
Definition: statjob.cpp:237
void setShowScriptExecutionPrompt(bool showPrompt)
Sets whether a prompt should be shown before executing scripts or desktop files.
Definition: krun.cpp:974
static bool hasSchemeHandler(const QUrl &url)
Returns true if protocol should be opened by a "handler" application, i.e.
QUrl fromLocalFile(const QString &localFile)
void sorry(QWidget *parent, const QString &text, const QString &caption=QString(), Options options=Notify)
KService::Ptr service() const
static bool isExecutable(const QString &mimeType)
Returns whether mimeType refers to an executable program instead of a data file.
Definition: krun.cpp:989
QString locate(QStandardPaths::StandardLocation type, const QString &fileName, QStandardPaths::LocateOptions options)
static QString executableName(const QString &execLine)
Given a full command line (e.g.
bool authorizeUrlAction(const QString &action, const QUrl &baseURL, const QUrl &destURL)
Returns whether a certain URL related action is authorized.
int error() const
static Ptr serviceByStorageId(const QString &_storageId)
static bool runCommand(const QString &cmd, QWidget *window, const QString &workingDirectory=QString())
Run the given shell command and notifies KDE of the starting of the application.
Definition: krun.cpp:335
bool hasFinished() const
Returns true if the KRun instance has finished.
Definition: krun.cpp:921
bool isLocalFile() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Sun Aug 2 2020 22:59:47 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.