KIO

commandlauncherjob.cpp
1 /*
2  This file is part of the KDE libraries
3  SPDX-FileCopyrightText: 2020 David Faure <[email protected]>
4 
5  SPDX-License-Identifier: LGPL-2.0-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6 */
7 
8 #include "commandlauncherjob.h"
9 #include "kprocessrunner_p.h"
10 #include "kiogui_debug.h"
11 #include <KShell>
12 #include <KLocalizedString>
13 
14 class KIO::CommandLauncherJobPrivate
15 {
16 public:
17  QString m_command;
18  QString m_desktopName;
19  QString m_executable;
20  QString m_iconName;
21  QString m_workingDirectory;
22  QByteArray m_startupId;
23  QPointer<KProcessRunner> m_processRunner;
24  qint64 m_pid = 0;
25 };
26 
28  : KJob(parent), d(new CommandLauncherJobPrivate())
29 {
30  d->m_command = command;
31 }
32 
34  : KJob(parent), d(new CommandLauncherJobPrivate())
35 {
36  d->m_executable = executable;
37  d->m_command = KShell::quoteArg(executable) + QLatin1Char(' ') + KShell::joinArgs(args);
38 }
39 
41 {
42  // Do *NOT* delete the KProcessRunner instances here.
43  // We need it to keep running so it can terminate startup notification on process exit.
44 }
45 
47 {
48  d->m_executable = executable;
49 }
50 
52 {
53  d->m_iconName = iconName;
54 }
55 
57 {
58  d->m_desktopName = desktopName;
59 }
60 
62 {
63  d->m_startupId = startupId;
64 }
65 
67 {
68  d->m_workingDirectory = workingDirectory;
69 }
70 
72 {
73  // Some fallback for lazy callers, not 100% accurate though
74  if (d->m_executable.isEmpty()) {
75  const QStringList args = KShell::splitArgs(d->m_command);
76  if (!args.isEmpty()) {
77  d->m_executable = args.first();
78  }
79  }
80 
81  QString displayName = d->m_executable;
82  KService::Ptr service = KService::serviceByDesktopName(d->m_desktopName);
83  if (service) {
84  displayName = service->name();
85  }
86  Q_EMIT description(this, i18nc("Launching application", "Launching %1", displayName), {}, {});
87 
88  if (d->m_iconName.isEmpty()) {
89  d->m_iconName = d->m_executable;
90  }
91  d->m_processRunner = KProcessRunner::fromCommand(d->m_command, d->m_desktopName, d->m_executable,
92  d->m_iconName, d->m_startupId,
93  d->m_workingDirectory);
94  connect(d->m_processRunner, &KProcessRunner::error, this, [this](const QString &errorText) {
95  setError(KJob::UserDefinedError);
96  setErrorText(errorText);
97  emitResult();
98  });
99  connect(d->m_processRunner, &KProcessRunner::processStarted, this, [this](qint64 pid) {
100  d->m_pid = pid;
101  emitResult();
102  });
103 }
104 
105 bool KIO::CommandLauncherJob::waitForStarted()
106 {
107  if (d->m_processRunner.isNull()) {
108  return false;
109  }
110  const bool ret = d->m_processRunner->waitForStarted();
111  if (!d->m_processRunner.isNull()) {
112  qApp->sendPostedEvents(d->m_processRunner); // so slotStarted gets called
113  }
114  return ret;
115 }
116 
118 {
119  return d->m_pid;
120 }
static Ptr serviceByDesktopName(const QString &_name)
CommandLauncherJob(const QString &command, QObject *parent=nullptr)
Creates a CommandLauncherJob.
void description(KJob *job, const QString &title, const QPair< QString, QString > &field1=QPair< QString, QString >(), const QPair< QString, QString > &field2=QPair< QString, QString >())
void start() override
Starts the job.
void setStartupId(const QByteArray &startupId)
Sets the startup notification id of the command launch.
QString i18nc(const char *context, const char *text, const TYPE &arg...)
bool isEmpty() const const
void setDesktopName(const QString &desktopName)
Set the name of the desktop file (e.g. "org.kde.dolphin", the extension is optional).
T & first()
KCOREADDONS_EXPORT QStringList splitArgs(const QString &cmd, Options flags=NoOptions, Errors *err=nullptr)
void setWorkingDirectory(const QString &workingDirectory)
Sets the working directory from which to run the command.
KCOREADDONS_EXPORT QString quoteArg(const QString &arg)
bool isNull() const const
~CommandLauncherJob() override
Destructor.
KCOREADDONS_EXPORT QString joinArgs(const QStringList &args)
void setIcon(const QString &iconName)
Sets the icon for the startup notification.
void setExecutable(const QString &executable)
Sets the name of the executable, used in the startup notification (see KStartupInfoData::setBin()).
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const const
QString name() const
Q_EMITQ_EMIT
QString errorText() const
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Wed Jan 27 2021 23:00:04 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.