• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KDECore

  • kdecore
  • kernel
ktoolinvocation.cpp
Go to the documentation of this file.
1/* This file is part of the KDE libraries
2 Copyright (C) 2005 Brad Hards <bradh@frogmouth.net>
3 Copyright (C) 2006 Thiago Macieira <thiago@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21#include "ktoolinvocation.h"
22#include "klauncher_iface.h"
23#include "kdebug.h"
24#include "kglobal.h"
25#include "kstandarddirs.h"
26#include "kcomponentdata.h"
27#include "kurl.h"
28#include "kmessage.h"
29#include "kservice.h"
30#include <klockfile.h>
31#include <klocale.h>
32
33#include <QMutex>
34#include <QMutexLocker>
35#include <QCoreApplication>
36#include <QThread>
37
38#include <errno.h>
39
40
41KToolInvocation *KToolInvocation::self()
42{
43 K_GLOBAL_STATIC(KToolInvocation, s_self)
44 return s_self;
45}
46
47KToolInvocation::KToolInvocation() : QObject(0), d(0)
48{
49}
50
51KToolInvocation::~KToolInvocation()
52{
53}
54
55Q_GLOBAL_STATIC_WITH_ARGS(org::kde::KLauncher, klauncherIface,
56 (QString::fromLatin1("org.kde.klauncher"), QString::fromLatin1("/KLauncher"), QDBusConnection::sessionBus()))
57
58org::kde::KLauncher *KToolInvocation::klauncher()
59{
60 if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(QString::fromLatin1("org.kde.klauncher"))) {
61 kDebug(180) << "klauncher not running... launching kdeinit";
62 KToolInvocation::startKdeinit();
63 }
64 return ::klauncherIface();
65}
66
67static void printError(const QString& text, QString* error)
68{
69 if (error)
70 *error = text;
71 else
72 kError() << text << endl;
73}
74
75bool KToolInvocation::isMainThreadActive(QString* error)
76{
77 if (QCoreApplication::instance() && QCoreApplication::instance()->thread() != QThread::currentThread())
78 {
79 printError(i18n("Function must be called from the main thread."), error);
80 return false;
81 }
82
83 return true;
84}
85
86int KToolInvocation::startServiceInternal(const char *_function,
87 const QString& _name, const QStringList &URLs,
88 QString *error, QString *serviceName, int *pid,
89 const QByteArray& startup_id, bool noWait,
90 const QString& workdir)
91{
92 QString function = QLatin1String(_function);
93 org::kde::KLauncher *launcher = KToolInvocation::klauncher();
94 QDBusMessage msg = QDBusMessage::createMethodCall(launcher->service(),
95 launcher->path(),
96 launcher->interface(),
97 function);
98 msg << _name << URLs;
99 if (function == QLatin1String("kdeinit_exec_with_workdir"))
100 msg << workdir;
101#ifdef Q_WS_X11
102 // make sure there is id, so that user timestamp exists
103 QStringList envs;
104 QByteArray s = startup_id;
105 emit kapplication_hook(envs, s);
106 msg << envs;
107 msg << QString::fromLatin1(s);
108#else
109 msg << QStringList();
110 msg << QString();
111#endif
112 if( !function.startsWith( QLatin1String("kdeinit_exec") ) )
113 msg << noWait;
114
115 QDBusMessage reply = QDBusConnection::sessionBus().call(msg, QDBus::Block, INT_MAX);
116 if ( reply.type() != QDBusMessage::ReplyMessage )
117 {
118 QDBusReply<QString> replyObj(reply);
119 if (replyObj.error().type() == QDBusError::NoReply) {
120 printError(i18n("Error launching %1. Either KLauncher is not running anymore, or it failed to start the application.", _name), error);
121 } else {
122 const QString rpl = reply.arguments().count() > 0 ? reply.arguments().at(0).toString() : reply.errorMessage();
123 printError(i18n("KLauncher could not be reached via D-Bus. Error when calling %1:\n%2\n",function, rpl), error);
124 }
125 //qDebug() << reply;
126 return EINVAL;
127 }
128
129 if (noWait)
130 return 0;
131
132 Q_ASSERT(reply.arguments().count() == 4);
133 if (serviceName)
134 *serviceName = reply.arguments().at(1).toString();
135 if (error)
136 *error = reply.arguments().at(2).toString();
137 if (pid)
138 *pid = reply.arguments().at(3).toInt();
139 return reply.arguments().at(0).toInt();
140}
141
142#ifndef KDE_NO_DEPRECATED
143int
144KToolInvocation::startServiceByName( const QString& _name, const QString &URL,
145 QString *error, QString *serviceName, int *pid,
146 const QByteArray& startup_id, bool noWait )
147{
148 if (!isMainThreadActive(error))
149 return EINVAL;
150
151 QStringList URLs;
152 if (!URL.isEmpty())
153 URLs.append(URL);
154 return self()->startServiceInternal("start_service_by_name",
155 _name, URLs, error, serviceName, pid, startup_id, noWait);
156}
157#endif
158
159#ifndef KDE_NO_DEPRECATED
160int
161KToolInvocation::startServiceByName( const QString& _name, const QStringList &URLs,
162 QString *error, QString *serviceName, int *pid,
163 const QByteArray& startup_id, bool noWait )
164{
165 if (!isMainThreadActive(error))
166 return EINVAL;
167
168 return self()->startServiceInternal("start_service_by_name",
169 _name, URLs, error, serviceName, pid, startup_id, noWait);
170}
171#endif
172
173int
174KToolInvocation::startServiceByDesktopPath( const QString& _name, const QString &URL,
175 QString *error, QString *serviceName,
176 int *pid, const QByteArray& startup_id, bool noWait )
177{
178 if (!isMainThreadActive(error))
179 return EINVAL;
180
181 QStringList URLs;
182 if (!URL.isEmpty())
183 URLs.append(URL);
184 return self()->startServiceInternal("start_service_by_desktop_path",
185 _name, URLs, error, serviceName, pid, startup_id, noWait);
186}
187
188int
189KToolInvocation::startServiceByDesktopPath( const QString& _name, const QStringList &URLs,
190 QString *error, QString *serviceName, int *pid,
191 const QByteArray& startup_id, bool noWait )
192{
193 if (!isMainThreadActive(error))
194 return EINVAL;
195
196 return self()->startServiceInternal("start_service_by_desktop_path",
197 _name, URLs, error, serviceName, pid, startup_id, noWait);
198}
199
200int
201KToolInvocation::startServiceByDesktopName( const QString& _name, const QString &URL,
202 QString *error, QString *serviceName, int *pid,
203 const QByteArray& startup_id, bool noWait )
204{
205 if (!isMainThreadActive(error))
206 return EINVAL;
207
208 QStringList URLs;
209 if (!URL.isEmpty())
210 URLs.append(URL);
211 return self()->startServiceInternal("start_service_by_desktop_name",
212 _name, URLs, error, serviceName, pid, startup_id, noWait);
213}
214
215int
216KToolInvocation::startServiceByDesktopName( const QString& _name, const QStringList &URLs,
217 QString *error, QString *serviceName, int *pid,
218 const QByteArray& startup_id, bool noWait )
219{
220 if (!isMainThreadActive(error))
221 return EINVAL;
222
223 return self()->startServiceInternal("start_service_by_desktop_name",
224 _name, URLs, error, serviceName, pid, startup_id, noWait);
225}
226
227int
228KToolInvocation::kdeinitExec( const QString& name, const QStringList &args,
229 QString *error, int *pid, const QByteArray& startup_id )
230{
231 if (!isMainThreadActive(error))
232 return EINVAL;
233
234 return self()->startServiceInternal("kdeinit_exec",
235 name, args, error, 0, pid, startup_id, false);
236}
237
238
239int
240KToolInvocation::kdeinitExecWait( const QString& name, const QStringList &args,
241 QString *error, int *pid, const QByteArray& startup_id )
242{
243 if (!isMainThreadActive(error))
244 return EINVAL;
245
246 return self()->startServiceInternal("kdeinit_exec_wait",
247 name, args, error, 0, pid, startup_id, false);
248}
249
250void KToolInvocation::invokeHelp( const QString& anchor,
251 const QString& _appname,
252 const QByteArray& startup_id )
253{
254 if (!isMainThreadActive())
255 return;
256
257 KUrl url;
258 QString appname;
259 QString docPath;
260 if (_appname.isEmpty()) {
261 appname = QCoreApplication::instance()->applicationName();
262 } else
263 appname = _appname;
264
265 KService::Ptr service(KService::serviceByDesktopName(appname));
266 if (service) {
267 docPath = service->docPath();
268 }
269
270 if (!docPath.isEmpty()) {
271 url = KUrl(KUrl("help:/"), docPath);
272 } else {
273 url = QString::fromLatin1("help:/%1/index.html").arg(appname);
274 }
275
276 if (!anchor.isEmpty()) {
277 url.addQueryItem(QString::fromLatin1("anchor"), anchor);
278 }
279
280 // launch a browser for URIs not handled by khelpcenter
281 // (following KCMultiDialog::slotHelpClicked())
282 if (!(url.protocol() == QLatin1String("help") || url.protocol() == QLatin1String("man") || url.protocol() == QLatin1String("info"))) {
283 invokeBrowser(url.url());
284 return;
285 }
286
287 QDBusInterface *iface = new QDBusInterface(QLatin1String("org.kde.khelpcenter"),
288 QLatin1String("/KHelpCenter"),
289 QLatin1String("org.kde.khelpcenter.khelpcenter"),
290 QDBusConnection::sessionBus());
291 if ( !iface->isValid() )
292 {
293 QString error;
294#ifdef Q_WS_WIN
295 // startServiceByDesktopName() does not work yet; KRun:processDesktopExec returned 'KRun: syntax error in command "khelpcenter %u" , service "KHelpCenter" '
296 if (kdeinitExec(QLatin1String("khelpcenter"), QStringList() << url.url(), &error, 0, startup_id))
297#else
298 if (startServiceByDesktopName(QLatin1String("khelpcenter"), url.url(), &error, 0, 0, startup_id, false))
299#endif
300 {
301 KMessage::message(KMessage::Error,
302 i18n("Could not launch the KDE Help Center:\n\n%1", error),
303 i18n("Could not Launch Help Center"));
304 delete iface;
305 return;
306 }
307
308 delete iface;
309 iface = new QDBusInterface(QLatin1String("org.kde.khelpcenter"),
310 QLatin1String("/KHelpCenter"),
311 QLatin1String("org.kde.khelpcenter.khelpcenter"),
312 QDBusConnection::sessionBus());
313 }
314
315 iface->call(QString::fromLatin1("openUrl"), url.url(), startup_id );
316 delete iface;
317}
318
319void KToolInvocation::invokeMailer(const QString &address, const QString &subject, const QByteArray& startup_id)
320{
321 if (!isMainThreadActive())
322 return;
323
324 invokeMailer(address, QString(), QString(), subject, QString(), QString(),
325 QStringList(), startup_id );
326}
327
328void KToolInvocation::invokeMailer(const KUrl &mailtoURL, const QByteArray& startup_id, bool allowAttachments )
329{
330 if (!isMainThreadActive())
331 return;
332
333 QString address = mailtoURL.path();
334 QString subject;
335 QString cc;
336 QString bcc;
337 QString body;
338
339 const QStringList queries = mailtoURL.query().mid(1).split(QLatin1Char('&'));
340 const QChar comma = QChar::fromLatin1(',');
341 QStringList attachURLs;
342 for (QStringList::ConstIterator it = queries.begin(); it != queries.end(); ++it)
343 {
344 QString q = (*it).toLower();
345 if (q.startsWith(QLatin1String("subject=")))
346 subject = KUrl::fromPercentEncoding((*it).mid(8).toLatin1());
347 else
348 if (q.startsWith(QLatin1String("cc=")))
349 cc = cc.isEmpty()? KUrl::fromPercentEncoding((*it).mid(3).toLatin1()): cc + comma + KUrl::fromPercentEncoding((*it).mid(3).toLatin1());
350 else
351 if (q.startsWith(QLatin1String("bcc=")))
352 bcc = bcc.isEmpty()? KUrl::fromPercentEncoding((*it).mid(4).toLatin1()): bcc + comma + KUrl::fromPercentEncoding((*it).mid(4).toLatin1());
353 else
354 if (q.startsWith(QLatin1String("body=")))
355 body = KUrl::fromPercentEncoding((*it).mid(5).toLatin1());
356 else
357 if (allowAttachments && q.startsWith(QLatin1String("attach=")))
358 attachURLs.push_back(KUrl::fromPercentEncoding((*it).mid(7).toLatin1()));
359 else
360 if (allowAttachments && q.startsWith(QLatin1String("attachment=")))
361 attachURLs.push_back(KUrl::fromPercentEncoding((*it).mid(11).toLatin1()));
362 else
363 if (q.startsWith(QLatin1String("to=")))
364 address = address.isEmpty()? KUrl::fromPercentEncoding((*it).mid(3).toLatin1()): address + comma + KUrl::fromPercentEncoding((*it).mid(3).toLatin1());
365 }
366
367 invokeMailer( address, cc, bcc, subject, body, QString(), attachURLs, startup_id );
368}
369
370void KToolInvocation::startKdeinit()
371{
372 KComponentData inst( "startkdeinitlock" );
373 KLockFile lock( KStandardDirs::locateLocal("tmp", QString::fromLatin1("startkdeinitlock"), inst ));
374 if( lock.lock( KLockFile::NoBlockFlag ) != KLockFile::LockOK ) {
375 lock.lock();
376 if( QDBusConnection::sessionBus().interface()->isServiceRegistered(QString::fromLatin1("org.kde.klauncher")))
377 return; // whoever held the lock has already started it
378 }
379 // Try to launch kdeinit.
380 QString srv = KStandardDirs::findExe(QLatin1String("kdeinit4"));
381 if (srv.isEmpty())
382 return;
383// this is disabled because we are in kdecore
384// const bool gui = qApp && qApp->type() != QApplication::Tty;
385// if ( gui )
386// qApp->setOverrideCursor( Qt::WaitCursor );
387 QStringList args;
388#ifndef Q_WS_WIN
389 args += QString::fromLatin1("--suicide");
390#endif
391 QProcess::execute(srv, args);
392// if ( gui )
393// qApp->restoreOverrideCursor();
394}
395
396#include "ktoolinvocation.moc"
KComponentData
Per component data.
Definition: kcomponentdata.h:47
KLockFile
The KLockFile class provides NFS safe lockfiles.
Definition: klockfile.h:37
KLockFile::LockOK
@ LockOK
Lock was acquired successfully.
Definition: klockfile.h:55
KLockFile::NoBlockFlag
@ NoBlockFlag
Return immediately, do not wait for the lock to become available.
Definition: klockfile.h:77
KService::serviceByDesktopName
static Ptr serviceByDesktopName(const QString &_name)
Find a service by the name of its desktop file, not depending on its actual location (as long as it's...
Definition: kservice.cpp:620
KService::docPath
QString docPath() const
The path to the documentation for this service.
Definition: kservice.cpp:744
KSharedPtr< KService >
KStandardDirs::findExe
static QString findExe(const QString &appname, const QString &pathstr=QString(), SearchOptions options=NoSearchOptions)
Finds the executable in the system path.
Definition: kstandarddirs.cpp:1334
KStandardDirs::locateLocal
static QString locateLocal(const char *type, const QString &filename, const KComponentData &cData=KGlobal::mainComponent())
This function is much like locate.
Definition: kstandarddirs.cpp:2097
KToolInvocation
KToolInvocation: for starting other programs.
Definition: ktoolinvocation.h:72
KToolInvocation::startServiceByName
static int startServiceByName(const QString &_name, const QString &URL, QString *error=0, QString *serviceName=0, int *pid=0, const QByteArray &startup_id=QByteArray(), bool noWait=false)
Starts a service based on the (translated) name of the service.
Definition: ktoolinvocation.cpp:144
KToolInvocation::klauncher
static OrgKdeKLauncherInterface * klauncher()
Returns the D-Bus interface of the service launcher.
KToolInvocation::kapplication_hook
void kapplication_hook(QStringList &env, QByteArray &startup_id)
Hook for KApplication in kdeui.
KToolInvocation::kdeinitExec
static int kdeinitExec(const QString &name, const QStringList &args=QStringList(), QString *error=0, int *pid=0, const QByteArray &startup_id=QByteArray())
Starts a program via kdeinit.
Definition: ktoolinvocation.cpp:228
KToolInvocation::invokeMailer
static void invokeMailer(const QString &address, const QString &subject, const QByteArray &startup_id=QByteArray())
Convenience method; invokes the standard email application.
Definition: ktoolinvocation.cpp:319
KToolInvocation::~KToolInvocation
~KToolInvocation()
Definition: ktoolinvocation.cpp:51
KToolInvocation::invokeHelp
static void invokeHelp(const QString &anchor=QString(), const QString &appname=QString(), const QByteArray &startup_id=QByteArray())
Invokes the KHelpCenter HTML help viewer from docbook sources.
Definition: ktoolinvocation.cpp:250
KToolInvocation::startServiceByDesktopName
static int startServiceByDesktopName(const QString &_name, const QString &URL, QString *error=0, QString *serviceName=0, int *pid=0, const QByteArray &startup_id=QByteArray(), bool noWait=false)
Starts a service based on the desktop name of the service.
Definition: ktoolinvocation.cpp:201
KToolInvocation::kdeinitExecWait
static int kdeinitExecWait(const QString &name, const QStringList &args=QStringList(), QString *error=0, int *pid=0, const QByteArray &startup_id=QByteArray())
Starts a program via kdeinit and wait for it to finish.
Definition: ktoolinvocation.cpp:240
KToolInvocation::invokeBrowser
static void invokeBrowser(const QString &url, const QByteArray &startup_id=QByteArray())
Invokes the user's preferred browser.
Definition: ktoolinvocation_win.cpp:37
KToolInvocation::self
static KToolInvocation * self()
Definition: ktoolinvocation.cpp:41
KToolInvocation::startServiceByDesktopPath
static int startServiceByDesktopPath(const QString &_name, const QString &URL, QString *error=0, QString *serviceName=0, int *pid=0, const QByteArray &startup_id=QByteArray(), bool noWait=false)
Starts a service based on the desktop path of the service.
Definition: ktoolinvocation.cpp:174
KUrl
Represents and parses a URL.
Definition: kurl.h:112
KUrl::addQueryItem
void addQueryItem(const QString &_item, const QString &_value)
Add an additional query item.
Definition: kurl.cpp:1868
KUrl::url
QString url(AdjustPathOption trailing=LeaveTrailingSlash) const
Returns the URL as string, with all escape sequences intact, encoded in a given charset.
Definition: kurl.cpp:1035
KUrl::path
QString path(AdjustPathOption trailing=LeaveTrailingSlash) const
Definition: kurl.cpp:873
KUrl::query
QString query() const
Returns the query of the URL.
Definition: kurl.cpp:1589
KUrl::protocol
QString protocol() const
Returns the protocol for the URL (i.e., file, http, etc.), lowercased.
Definition: kurl.cpp:672
OrgKdeKLauncherInterface
Definition: klauncher_iface.h:38
QObject
QStringList
QString
K_GLOBAL_STATIC
#define K_GLOBAL_STATIC(TYPE, NAME)
This macro makes it easy to use non-POD types as global statics.
Definition: kglobal.h:221
kDebug
#define kDebug
Definition: kdebug.h:316
kError
static QDebug kError(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
Definition: kdebug.h:187
pid
static pid_t pid
Definition: k3resolvermanager.cpp:249
kcomponentdata.h
kdebug.h
kglobal.h
klauncher_iface.h
klocale.h
i18n
QString i18n(const char *text)
Returns a localized version of a string.
Definition: klocalizedstring.h:630
klockfile.h
kmessage.h
kservice.h
kstandarddirs.h
printError
static void printError(const QString &text, QString *error)
Definition: ktoolinvocation.cpp:67
Q_GLOBAL_STATIC_WITH_ARGS
Q_GLOBAL_STATIC_WITH_ARGS(org::kde::KLauncher, klauncherIface,(QString::fromLatin1("org.kde.klauncher"), QString::fromLatin1("/KLauncher"), QDBusConnection::sessionBus())) org
Definition: ktoolinvocation.cpp:55
ktoolinvocation.h
kurl.h
KMessage::message
void message(KMessage::MessageType messageType, const QString &text, const QString &caption=QString())
Display a long message of a certain type.
Definition: kmessage.cpp:92
KMessage::Error
@ Error
Error message.
Definition: kmessage.h:57
org
Definition: ksslcertificatemanager_p.h:58
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDECore

Skip menu "KDECore"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal