kdelibs/kdecore/kernel/ktoolinvocation.cpp

282 lines
9.8 KiB
C++
Raw Normal View History

2014-11-13 01:04:59 +02:00
/* This file is part of the KDE libraries
Copyright (C) 2005 Brad Hards <bradh@frogmouth.net>
Copyright (C) 2006 Thiago Macieira <thiago@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "ktoolinvocation.h"
#include "kdebug.h"
#include "kglobal.h"
#include "kstandarddirs.h"
#include "kcomponentdata.h"
#include "kurl.h"
#include "kmessage.h"
#include "kservice.h"
#include "klocale.h"
#include "kglobalsettings.h"
2014-11-13 01:04:59 +02:00
2015-09-27 01:19:30 +00:00
#include <QtCore/QThread>
#include <QtCore/QProcess>
#include <QtCore/QCoreApplication>
#include <QtDBus/QDBusInterface>
#include <QtDBus/QDBusConnectionInterface>
2014-11-13 01:04:59 +02:00
#define KTOOLINVOCATION_TIMEOUT 250
#define KTOOLINVOCATION_SLEEPTIME 150
// NOTE: keep in sync with:
// kdelibs/kinit/klauncher_adaptor.h
static inline QString getKLauncherError(const int result, const QString &app)
{
switch (result) {
case -1: {
return i18n("Application service is not valid or does not support multiple files: %1.", app);
}
case -2: {
return i18n("Application not found: %1.", app);
}
case -3: {
return i18n("Application could not be processed: %1.", app);
}
case -4: {
return i18n("Application failed to start: %1.", app);
}
case -5: {
return i18n("D-Bus error occured while starting application: %1.", app);
}
}
return i18n("Unknown KLauncher error for application: %1.", app);
}
static inline void printError(const QString &text, QString *error)
{
if (error)
*error = text;
else
kError() << text;
}
2014-11-13 01:04:59 +02:00
KToolInvocation *KToolInvocation::self()
{
K_GLOBAL_STATIC(KToolInvocation, s_self)
return s_self;
}
KToolInvocation::KToolInvocation()
: QObject(0),
klauncherIface(nullptr)
2014-11-13 01:04:59 +02:00
{
klauncherIface = new QDBusInterface(
QString::fromLatin1("org.kde.klauncher"),
QString::fromLatin1("/KLauncher"),
QString::fromLatin1("org.kde.KLauncher"),
QDBusConnection::sessionBus(),
this
);
2014-11-13 01:04:59 +02:00
}
KToolInvocation::~KToolInvocation()
{
delete klauncherIface;
2014-11-13 01:04:59 +02:00
}
void KToolInvocation::setLaunchEnv(const QString &name, const QString &value)
2014-11-13 01:04:59 +02:00
{
self()->klauncherIface->asyncCall(QString::fromLatin1("setLaunchEnv"), name, value);
2014-11-13 01:04:59 +02:00
}
int KToolInvocation::startServiceInternal(const char *_function,
const QString &name, const QStringList &URLs,
QString *error,
const QByteArray &startup_id,
const QString &workdir)
2014-11-13 01:04:59 +02:00
{
QString function = QString::fromLatin1(_function);
2014-11-13 01:04:59 +02:00
// make sure there is id, so that user timestamp exists
QStringList envs;
QByteArray asn = startup_id;
emit kapplication_hook(envs, asn);
QDBusPendingReply<int> reply;
if (qstrcmp(_function, "kdeinit_exec_with_workdir") == 0) {
reply = klauncherIface->asyncCall(
function, name, URLs, envs, QString::fromLatin1(asn, asn.size()), workdir
);
} else {
reply = klauncherIface->asyncCall(
function, name, URLs, envs, QString::fromLatin1(asn, asn.size())
);
}
kDebug() << "Waiting for klauncher call to finish" << function;
while (!reply.isFinished()) {
QCoreApplication::processEvents(QEventLoop::AllEvents, KTOOLINVOCATION_TIMEOUT);
QThread::msleep(KTOOLINVOCATION_SLEEPTIME);
}
kDebug() << "Done waiting for klauncher call to finish" << function;
if (!reply.isValid()) {
printError(
i18n("KLauncher error: %1.", reply.error().message()),
error
);
2014-11-13 01:04:59 +02:00
return EINVAL;
}
const int result = reply.value();
if (result < 0) {
printError(
getKLauncherError(result, name),
error
);
// compat
return -result;
} else if (result != 0) {
printError(
i18n("Application failed to start: %1.", name),
error
);
}
return result;
2014-11-13 01:04:59 +02:00
}
int KToolInvocation::startServiceByDesktopPath(const QString &name, const QString &URL,
QString *error,
const QByteArray &startup_id)
2014-11-13 01:04:59 +02:00
{
QStringList URLs;
if (!URL.isEmpty())
URLs.append(URL);
return self()->startServiceInternal("start_service_by_desktop_path",
name, URLs, error, startup_id);
2014-11-13 01:04:59 +02:00
}
int KToolInvocation::startServiceByDesktopPath(const QString &name, const QStringList &URLs,
QString *error,
const QByteArray &startup_id)
2014-11-13 01:04:59 +02:00
{
return self()->startServiceInternal("start_service_by_desktop_path",
name, URLs, error, startup_id);
2014-11-13 01:04:59 +02:00
}
int KToolInvocation::startServiceByDesktopName(const QString &name, const QString &URL,
QString *error,
const QByteArray &startup_id)
2014-11-13 01:04:59 +02:00
{
QStringList URLs;
if (!URL.isEmpty())
URLs.append(URL);
return self()->startServiceInternal("start_service_by_desktop_name",
name, URLs, error, startup_id);
2014-11-13 01:04:59 +02:00
}
int KToolInvocation::startServiceByDesktopName(const QString &name, const QStringList &URLs,
QString *error,
const QByteArray &startup_id)
2014-11-13 01:04:59 +02:00
{
return self()->startServiceInternal("start_service_by_desktop_name",
name, URLs, error, startup_id);
2014-11-13 01:04:59 +02:00
}
int KToolInvocation::kdeinitExec(const QString &name, const QStringList &args,
QString *error,
const QByteArray &startup_id)
2014-11-13 01:04:59 +02:00
{
return self()->startServiceInternal("kdeinit_exec",
name, args, error, startup_id);
2014-11-13 01:04:59 +02:00
}
int KToolInvocation::kdeinitExecWait(const QString &name, const QStringList &args,
QString *error,
const QByteArray &startup_id)
2014-11-13 01:04:59 +02:00
{
return self()->startServiceInternal("kdeinit_exec_wait",
name, args, error, startup_id);
2014-11-13 01:04:59 +02:00
}
void KToolInvocation::invokeHelp(const QString &anchor,
const QString &_appname,
const QByteArray &startup_id)
2014-11-13 01:04:59 +02:00
{
KUrl url;
QString appname;
QString docPath;
if (_appname.isEmpty()) {
appname = QCoreApplication::instance()->applicationName();
} else {
2014-11-13 01:04:59 +02:00
appname = _appname;
}
2014-11-13 01:04:59 +02:00
KService::Ptr service(KService::serviceByDesktopName(appname));
if (service) {
docPath = service->docPath();
}
if (!docPath.isEmpty()) {
url = KUrl(KUrl(QString::fromLatin1(KDE_HELP_URL)), docPath);
2014-11-13 01:04:59 +02:00
} else {
url = QString::fromLatin1(KDE_HELP_URL);
2014-11-13 01:04:59 +02:00
}
if (!anchor.isEmpty()) {
url.addQueryItem(QString::fromLatin1("anchor"), anchor);
}
invokeBrowser(url.url());
2014-11-13 01:04:59 +02:00
}
void KToolInvocation::invokeMailer(const QString &address, const QString &subject, const QByteArray &startup_id)
2014-11-13 01:04:59 +02:00
{
invokeMailer(address, QString(), subject, QString(), QStringList(), startup_id );
2014-11-13 01:04:59 +02:00
}
void KToolInvocation::invokeMailer(const KUrl &mailtoURL, const QByteArray& startup_id, bool allowAttachments)
2014-11-13 01:04:59 +02:00
{
QString address = mailtoURL.path();
QString subject;
QString cc;
QString body;
const QStringList queries = mailtoURL.query().mid(1).split(QLatin1Char('&'));
const QChar comma = QChar::fromLatin1(',');
QStringList attachURLs;
for (QStringList::ConstIterator it = queries.begin(); it != queries.end(); ++it)
{
QString q = (*it).toLower();
if (q.startsWith(QLatin1String("subject=")))
subject = KUrl::fromPercentEncoding((*it).mid(8).toLatin1());
else
if (q.startsWith(QLatin1String("cc=")))
cc = cc.isEmpty()? KUrl::fromPercentEncoding((*it).mid(3).toLatin1()): cc + comma + KUrl::fromPercentEncoding((*it).mid(3).toLatin1());
else
if (q.startsWith(QLatin1String("body=")))
body = KUrl::fromPercentEncoding((*it).mid(5).toLatin1());
2014-11-13 01:04:59 +02:00
else
if (allowAttachments && q.startsWith(QLatin1String("attach=")))
attachURLs.push_back(KUrl::fromPercentEncoding((*it).mid(7).toLatin1()));
2014-11-13 01:04:59 +02:00
else
if (allowAttachments && q.startsWith(QLatin1String("attachment=")))
attachURLs.push_back(KUrl::fromPercentEncoding((*it).mid(11).toLatin1()));
2014-11-13 01:04:59 +02:00
else
if (q.startsWith(QLatin1String("to=")))
address = address.isEmpty()? KUrl::fromPercentEncoding((*it).mid(3).toLatin1()): address + comma + KUrl::fromPercentEncoding((*it).mid(3).toLatin1());
2014-11-13 01:04:59 +02:00
}
invokeMailer(address, cc, subject, body, attachURLs, startup_id);
2014-11-13 01:04:59 +02:00
}
#include "moc_ktoolinvocation.cpp"