mirror of
https://bitbucket.org/smil3y/kdelibs.git
synced 2025-02-23 10:22:48 +00:00
kio: move most of the KRun bits to KLauncher
two things doing the same thing - one has to go away. also KRun does not fork and the launched service/application lifetime was bound to the process launching it, that is not the case with klauncher - it is bound to the session (in the usual case) a few things on the TODO list but mostly for services/applications lacking features Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
parent
ceaddee1dd
commit
b90f90905b
24 changed files with 414 additions and 2892 deletions
|
@ -693,11 +693,11 @@ QString KService::docPath() const
|
|||
return it->toString();
|
||||
}
|
||||
|
||||
bool KService::allowMultipleFiles() const {
|
||||
bool KService::allowMultipleFiles() const
|
||||
{
|
||||
Q_D(const KService);
|
||||
// Can we pass multiple files on the command line or do we have to start the application for every single file ?
|
||||
return (d->m_strExec.contains( QLatin1String("%F") ) || d->m_strExec.contains( QLatin1String("%U") ) ||
|
||||
d->m_strExec.contains( QLatin1String("%N") ) || d->m_strExec.contains( QLatin1String("%D") ));
|
||||
return (d->m_strExec.contains( QLatin1String("%F") ) || d->m_strExec.contains( QLatin1String("%U") ));
|
||||
}
|
||||
|
||||
QStringList KService::categories() const
|
||||
|
|
|
@ -43,36 +43,6 @@
|
|||
|
||||
#define KTOOLINVOCATION_TIMEOUT 250
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
K_GLOBAL_STATIC(KToolInvocation, kToolInvocation)
|
||||
|
||||
KToolInvocation* KToolInvocation::self()
|
||||
|
@ -104,113 +74,27 @@ void KToolInvocation::setLaunchEnv(const QString &name, const QString &value)
|
|||
klauncherIface->asyncCall(QString::fromLatin1("setLaunchEnv"), name, value);
|
||||
}
|
||||
|
||||
int KToolInvocation::startServiceInternal(const char *_function,
|
||||
const QString &name, const QStringList &URLs,
|
||||
QString *error,
|
||||
const QByteArray &startup_id,
|
||||
const QString &workdir)
|
||||
bool KToolInvocation::startServiceForUrl(const QString &url, QWidget *window, bool temp)
|
||||
{
|
||||
QString function = QString::fromLatin1(_function);
|
||||
// make sure there is id, so that user timestamp exists
|
||||
QStringList envs;
|
||||
if (QX11Info::display()) {
|
||||
const QString dpystring = QString::fromLatin1(XDisplayString(QX11Info::display()));
|
||||
envs << QLatin1String("DISPLAY=") + dpystring;
|
||||
} else {
|
||||
const QString dpystring = QString::fromLocal8Bit(qgetenv("DISPLAY"));
|
||||
if (!dpystring.isEmpty()) {
|
||||
envs << QLatin1String("DISPLAY=") + dpystring;
|
||||
}
|
||||
}
|
||||
|
||||
QDBusPendingReply<int> reply;
|
||||
if (qstrcmp(_function, "kdeinit_exec_with_workdir") == 0) {
|
||||
reply = klauncherIface->asyncCall(
|
||||
function, name, URLs, envs, QString::fromLatin1(startup_id, startup_id.size()), workdir
|
||||
return startServiceInternal(
|
||||
"start_service_by_url", QString(), QStringList() << url, window, temp
|
||||
);
|
||||
} else {
|
||||
reply = klauncherIface->asyncCall(
|
||||
function, name, URLs, envs, QString::fromLatin1(startup_id, startup_id.size())
|
||||
);
|
||||
}
|
||||
kDebug() << "Waiting for klauncher call to finish" << function;
|
||||
while (!reply.isFinished()) {
|
||||
QCoreApplication::processEvents(QEventLoop::AllEvents, KTOOLINVOCATION_TIMEOUT);
|
||||
}
|
||||
kDebug() << "Done waiting for klauncher call to finish" << function;
|
||||
if (!reply.isValid()) {
|
||||
printError(
|
||||
i18n("KLauncher error: %1.", reply.error().message()),
|
||||
error
|
||||
);
|
||||
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;
|
||||
}
|
||||
|
||||
int KToolInvocation::startServiceByDesktopPath(const QString &name, const QString &URL,
|
||||
QString *error, const QByteArray &startup_id)
|
||||
bool KToolInvocation::startServiceByStorageId(const QString &name, const QStringList &URLs,
|
||||
QWidget *window, bool temp)
|
||||
{
|
||||
QStringList URLs;
|
||||
if (!URL.isEmpty()) {
|
||||
URLs.append(URL);
|
||||
}
|
||||
return startServiceInternal("start_service_by_desktop_path", name, URLs, error, startup_id);
|
||||
return startServiceInternal("start_service_by_storage_id", name, URLs, window, temp);
|
||||
}
|
||||
|
||||
int KToolInvocation::startServiceByDesktopPath(const QString &name, const QStringList &URLs,
|
||||
QString *error, const QByteArray &startup_id)
|
||||
bool KToolInvocation::startProgram(const QString &name, const QStringList &args, QWidget *window,
|
||||
bool temp)
|
||||
{
|
||||
return startServiceInternal("start_service_by_desktop_path", name, URLs, error, startup_id);
|
||||
}
|
||||
|
||||
int KToolInvocation::startServiceByDesktopName(const QString &name, const QString &URL,
|
||||
QString *error, const QByteArray &startup_id)
|
||||
{
|
||||
QStringList URLs;
|
||||
if (!URL.isEmpty()) {
|
||||
URLs.append(URL);
|
||||
}
|
||||
return startServiceInternal("start_service_by_desktop_name", name, URLs, error, startup_id);
|
||||
}
|
||||
|
||||
int KToolInvocation::startServiceByDesktopName(const QString &name, const QStringList &URLs,
|
||||
QString *error, const QByteArray &startup_id)
|
||||
{
|
||||
return startServiceInternal("start_service_by_desktop_name", name, URLs, error, startup_id);
|
||||
}
|
||||
|
||||
int KToolInvocation::kdeinitExec(const QString &name, const QStringList &args, QString *error,
|
||||
const QByteArray &startup_id)
|
||||
{
|
||||
return startServiceInternal("kdeinit_exec", name, args, error, startup_id);
|
||||
}
|
||||
|
||||
|
||||
int KToolInvocation::kdeinitExecWait(const QString &name, const QStringList &args, QString *error,
|
||||
const QByteArray &startup_id)
|
||||
{
|
||||
return startServiceInternal("kdeinit_exec_wait", name, args, error, startup_id);
|
||||
return startServiceInternal("start_program", name, args, window, temp);
|
||||
}
|
||||
|
||||
void KToolInvocation::invokeHelp(const QString &anchor,
|
||||
const QString &_appname,
|
||||
const QByteArray &startup_id)
|
||||
const QString &_appname)
|
||||
{
|
||||
KUrl url;
|
||||
QString appname;
|
||||
|
@ -235,14 +119,12 @@ void KToolInvocation::invokeHelp(const QString &anchor,
|
|||
invokeBrowser(url.url());
|
||||
}
|
||||
|
||||
void KToolInvocation::invokeMailer(const QString &address, const QString &subject,
|
||||
const QByteArray &startup_id)
|
||||
void KToolInvocation::invokeMailer(const QString &address, const QString &subject)
|
||||
{
|
||||
invokeMailer(address, QString(), subject, QString(), QStringList(), startup_id);
|
||||
invokeMailer(address, QString(), subject, QString(), QStringList());
|
||||
}
|
||||
|
||||
void KToolInvocation::invokeMailer(const KUrl &mailtoURL, const QByteArray &startup_id,
|
||||
bool allowAttachments)
|
||||
void KToolInvocation::invokeMailer(const KUrl &mailtoURL, bool allowAttachments)
|
||||
{
|
||||
QString address = mailtoURL.path();
|
||||
QString subject;
|
||||
|
@ -274,7 +156,50 @@ void KToolInvocation::invokeMailer(const KUrl &mailtoURL, const QByteArray &star
|
|||
address = address.isEmpty()? KUrl::fromPercentEncoding((*it).mid(3).toLatin1()): address + comma + KUrl::fromPercentEncoding((*it).mid(3).toLatin1());
|
||||
}
|
||||
|
||||
invokeMailer(address, cc, subject, body, attachURLs, startup_id);
|
||||
invokeMailer(address, cc, subject, body, attachURLs);
|
||||
}
|
||||
|
||||
bool KToolInvocation::startServiceInternal(const char *_function,
|
||||
const QString &name, const QStringList &URLs,
|
||||
QWidget *window, bool temp, const QString &workdir)
|
||||
{
|
||||
QString function = QString::fromLatin1(_function);
|
||||
// make sure there is id, so that user timestamp exists
|
||||
QStringList envs;
|
||||
if (QX11Info::display()) {
|
||||
const QString dpystring = QString::fromLatin1(XDisplayString(QX11Info::display()));
|
||||
envs << QLatin1String("DISPLAY=") + dpystring;
|
||||
} else {
|
||||
const QString dpystring = QString::fromLocal8Bit(qgetenv("DISPLAY"));
|
||||
if (!dpystring.isEmpty()) {
|
||||
envs << QLatin1String("DISPLAY=") + dpystring;
|
||||
}
|
||||
}
|
||||
|
||||
QDBusPendingReply<bool> reply;
|
||||
if (qstrcmp(_function, "start_service_by_url") == 0) {
|
||||
reply = klauncherIface->asyncCall(
|
||||
function, URLs.first(), envs, window ? quint64(window->winId()) : 0, temp
|
||||
);
|
||||
} else if (qstrcmp(_function, "start_program_with_workdir") == 0) {
|
||||
reply = klauncherIface->asyncCall(
|
||||
function, name, URLs, envs, window ? quint64(window->winId()) : 0, temp, workdir
|
||||
);
|
||||
} else {
|
||||
reply = klauncherIface->asyncCall(
|
||||
function, name, URLs, envs, window ? quint64(window->winId()) : 0, temp
|
||||
);
|
||||
}
|
||||
kDebug() << "Waiting for klauncher call to finish" << function;
|
||||
while (!reply.isFinished()) {
|
||||
QCoreApplication::processEvents(QEventLoop::AllEvents, KTOOLINVOCATION_TIMEOUT);
|
||||
}
|
||||
kDebug() << "Done waiting for klauncher call to finish" << function;
|
||||
if (!reply.isValid()) {
|
||||
kError() << "KLauncher error" << reply.error().message();
|
||||
return false;
|
||||
}
|
||||
return reply.value();
|
||||
}
|
||||
|
||||
#include "moc_ktoolinvocation.cpp"
|
||||
|
|
|
@ -47,16 +47,14 @@ public:
|
|||
|
||||
public Q_SLOTS:
|
||||
/**
|
||||
* Invokes the KHelpCenter HTML help viewer from docbook sources.
|
||||
* Invokes the help viewer.
|
||||
*
|
||||
* @param anchor This has to be a defined anchor in your docbook sources. If empty the
|
||||
* main index is loaded
|
||||
* @param appname This allows you to show the help of another application. If empty the
|
||||
* current name() is used
|
||||
* @param startup_id For app startup notification, "0" for none
|
||||
*/
|
||||
void invokeHelp(const QString &anchor = QString(), const QString &appname = QString(),
|
||||
const QByteArray &startup_id = QByteArray());
|
||||
void invokeHelp(const QString &anchor = QString(), const QString &appname = QString());
|
||||
|
||||
/**
|
||||
* Convenience method; invokes the standard email application.
|
||||
|
@ -65,19 +63,16 @@ public Q_SLOTS:
|
|||
* @param subject Subject string. Can be QString().
|
||||
* @param startup_id Ffor app startup notification, "0" for none
|
||||
*/
|
||||
void invokeMailer(const QString &address, const QString &subject,
|
||||
const QByteArray &startup_id = QByteArray());
|
||||
void invokeMailer(const QString &address, const QString &subject);
|
||||
|
||||
/**
|
||||
* Invokes the standard email application.
|
||||
*
|
||||
* @param mailtoURL A mailto URL.
|
||||
* @param startup_id For app startup notification, "0" for none
|
||||
* @param allowAttachments Whether attachments specified in mailtoURL should be honoured. The
|
||||
* default is false; do not honor requests for attachments.
|
||||
*/
|
||||
void invokeMailer(const KUrl &mailtoURL, const QByteArray &startup_id = QByteArray(),
|
||||
bool allowAttachments = false);
|
||||
void invokeMailer(const KUrl &mailtoURL, bool allowAttachments = false);
|
||||
|
||||
/**
|
||||
* Convenience method; invokes the standard email application.
|
||||
|
@ -89,11 +84,9 @@ public Q_SLOTS:
|
|||
* @param subject Subject string
|
||||
* @param body A string containing the body of the mail
|
||||
* @param attachURLs List of URLs to be attached to the mail.
|
||||
* @param startup_id For app startup notification, "0" for none
|
||||
*/
|
||||
void invokeMailer(const QString &to, const QString &cc, const QString &subject,
|
||||
const QString &body, const QStringList &attachURLs = QStringList(),
|
||||
const QByteArray &startup_id = QByteArray());
|
||||
const QString &body, const QStringList &attachURLs = QStringList());
|
||||
|
||||
/**
|
||||
* Invokes the user's preferred browser. Note that you should only do this when you know for
|
||||
|
@ -101,21 +94,18 @@ public Q_SLOTS:
|
|||
* to an image or anything else than HTML, prefer to use KRun.
|
||||
*
|
||||
* @param url The destination address
|
||||
* @param startup_id For app startup notification, "0" for none
|
||||
*/
|
||||
void invokeBrowser(const QString &url, const QByteArray &startup_id = QByteArray());
|
||||
void invokeBrowser(const QString &url);
|
||||
|
||||
/**
|
||||
* Invokes the standard terminal application.
|
||||
*
|
||||
* @param command The command to execute, can be empty.
|
||||
* @param workdir The initial working directory, can be empty.
|
||||
* @param startup_id For app startup notification, "0" for none
|
||||
*
|
||||
* @since 4.1
|
||||
*/
|
||||
void invokeTerminal(const QString &command, const QString &workdir = QString(),
|
||||
const QByteArray &startup_id = QByteArray());
|
||||
void invokeTerminal(const QString &command, const QString &workdir = QString());
|
||||
|
||||
public:
|
||||
/**
|
||||
|
@ -127,89 +117,39 @@ public:
|
|||
void setLaunchEnv(const QString &name, const QString &value);
|
||||
|
||||
/**
|
||||
* Starts a service based on the desktop path of the service, e.g.
|
||||
* "Applications/konqueror.desktop" or "/home/user/bla/myfile.desktop"
|
||||
* Starts a service based on the MIME type of the URL, the MIME type is automatically
|
||||
* determined
|
||||
*
|
||||
* @param name The path of the desktop file
|
||||
* @param URL If not empty this URL is passed to the service
|
||||
* @param error On failure, @p error contains a description of the error that occurred.
|
||||
* If the pointer is null, the argument will be ignored
|
||||
* @param startup_id For app startup notification, "0" for none
|
||||
* @param url The URL to start service for
|
||||
* @param window Window to use for error reporting and job delegation
|
||||
* @param temp Whether the URL is temporary file or not
|
||||
* @return an error code indicating success (== 0) or failure (> 0).
|
||||
*/
|
||||
int startServiceByDesktopPath(const QString &name, const QString &URL,
|
||||
QString *error = nullptr,
|
||||
const QByteArray &startup_id = QByteArray());
|
||||
bool startServiceForUrl(const QString &url, QWidget *window = nullptr, bool temp = false);
|
||||
|
||||
/**
|
||||
* Starts a service based on the desktop path of the service, e..g.
|
||||
* "Applications/konqueror.desktop" or "/home/user/bla/myfile.desktop"
|
||||
*
|
||||
* @param name The path of the desktop file
|
||||
* @param URLs If not empty these URLs will be passed to the service
|
||||
* @param error On failure, @p error contains a description of the error that occurred.
|
||||
* If the pointer is null, the argument will be ignored
|
||||
* @param startup_id For app startup notification, "0" for none
|
||||
* @return an error code indicating success (== 0) or failure (> 0).
|
||||
*/
|
||||
int startServiceByDesktopPath(const QString &name, const QStringList &URLs = QStringList(),
|
||||
QString *error = nullptr,
|
||||
const QByteArray &startup_id = QByteArray());
|
||||
|
||||
/**
|
||||
* Starts a service based on the desktop name of the service, e.g. "konqueror"
|
||||
* Starts a service based on the desktop name or entry path of the service, e.g. "konqueror"
|
||||
*
|
||||
* @param name The desktop name of the service
|
||||
* @param URL If not empty this URL is passed to the service
|
||||
* @param error On failure, @p error contains a description of the error that occurred.
|
||||
* If the pointer is null, the argument will be ignored
|
||||
* @param startup_id For app startup notification, "0" for none
|
||||
* @param urls If not empty these URLs will be passed to the service
|
||||
* @param window Window to use for error reporting and job delegation
|
||||
* @param temp Whether any of the URLs is temporary file or not
|
||||
* @return an error code indicating success (== 0) or failure (> 0)
|
||||
*/
|
||||
int startServiceByDesktopName(const QString &name, const QString &URL,
|
||||
QString *error = nullptr,
|
||||
const QByteArray &startup_id = QByteArray());
|
||||
bool startServiceByStorageId(const QString &name, const QStringList &urls = QStringList(),
|
||||
QWidget *window = nullptr, bool temp = false);
|
||||
|
||||
/**
|
||||
* Starts a service based on the desktop name of the service, e.g. "konqueror"
|
||||
*
|
||||
* @param name The desktop name of the service
|
||||
* @param URLs If not empty these URLs will be passed to the service
|
||||
* @param error On failure, @p error contains a description of the error that occurred.
|
||||
* If the pointer is null, the argument will be ignored
|
||||
* @param startup_id For app startup notification, "0" for none
|
||||
* @return an error code indicating success (== 0) or failure (> 0)
|
||||
*/
|
||||
int startServiceByDesktopName(const QString &name, const QStringList &URLs = QStringList(),
|
||||
QString *error = nullptr,
|
||||
const QByteArray &startup_id = QByteArray());
|
||||
|
||||
/**
|
||||
* Starts a program via kdeinit.
|
||||
* Starts a program.
|
||||
*
|
||||
* @param name Name of the program to start
|
||||
* @param args Arguments to pass to the program
|
||||
* @param error On failure, @p error contains a description of the error that occurred
|
||||
* If the pointer is null, the argument will be ignored
|
||||
* @param startup_id For app startup notification, "0" for none
|
||||
* @param window Window to use for error reporting and job delegation
|
||||
* @param temp Whether argument is temporary file or not
|
||||
* @return an error code indicating success (== 0) or failure (> 0)
|
||||
*/
|
||||
int kdeinitExec(const QString &name, const QStringList &args = QStringList(),
|
||||
QString *error = nullptr, const QByteArray &startup_id = QByteArray());
|
||||
|
||||
/**
|
||||
* Starts a program via kdeinit and wait for it to finish, it behaves similar to the system()
|
||||
* function.
|
||||
*
|
||||
* @param name Name of the program to start
|
||||
* @param args Arguments to pass to the program
|
||||
* @param error On failure, @p error contains a description of the error that occurred
|
||||
* If the pointer is null, the argument will be ignored
|
||||
* @param startup_id For app startup notification, "0" for none
|
||||
* @return an error code indicating success (== 0) or failure (> 0)
|
||||
*/
|
||||
int kdeinitExecWait(const QString &name, const QStringList &args = QStringList(),
|
||||
QString *error = nullptr, const QByteArray &startup_id = QByteArray());
|
||||
bool startProgram(const QString &name, const QStringList &args = QStringList(),
|
||||
QWidget *window = nullptr, bool temp = false);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(KToolInvocation);
|
||||
|
@ -217,10 +157,9 @@ private:
|
|||
/**
|
||||
* @internal
|
||||
*/
|
||||
int startServiceInternal(const char *_function,
|
||||
const QString &name, const QStringList &URLs,
|
||||
QString *error,
|
||||
const QByteArray &startup_id,
|
||||
bool startServiceInternal(const char *_function,
|
||||
const QString &name, const QStringList &urls,
|
||||
QWidget *window, const bool temp,
|
||||
const QString &workdir = QString());
|
||||
|
||||
QDBusInterface *klauncherIface;
|
||||
|
|
|
@ -110,8 +110,7 @@ static QStringList splitEmailAddressList( const QString & aStr )
|
|||
|
||||
void KToolInvocation::invokeMailer(const QString &to, const QString &cc,
|
||||
const QString &subject, const QString &body,
|
||||
const QStringList &attachURLs,
|
||||
const QByteArray &startup_id)
|
||||
const QStringList &attachURLs)
|
||||
{
|
||||
KConfig config(QString::fromLatin1("emaildefaults"));
|
||||
KConfigGroup profileGrp(&config, "General");
|
||||
|
@ -202,90 +201,43 @@ void KToolInvocation::invokeMailer(const QString &to, const QString &cc,
|
|||
}
|
||||
}
|
||||
|
||||
QString error;
|
||||
// TODO this should check if cmd has a .desktop file, and use data from it, together
|
||||
// with sending more ASN data
|
||||
if (kdeinitExec(cmd, cmdTokens, &error, startup_id) != 0) {
|
||||
KMessageBox::queuedMessageBox(
|
||||
nullptr, KMessageBox::Error,
|
||||
i18n("Could not launch the mail client:\n\n%1", error),
|
||||
i18n("Could not launch Mail Client")
|
||||
);
|
||||
}
|
||||
startProgram(cmd, cmdTokens);
|
||||
}
|
||||
|
||||
void KToolInvocation::invokeBrowser(const QString &url, const QByteArray& startup_id)
|
||||
void KToolInvocation::invokeBrowser(const QString &url)
|
||||
{
|
||||
QStringList args;
|
||||
args << url;
|
||||
QString error;
|
||||
|
||||
// This method should launch a webbrowser, preferably without doing a mimetype
|
||||
// check first, like KRun (i.e. kde-open) would do.
|
||||
// check first like kde-open would do.
|
||||
const KService::Ptr htmlApp = KMimeTypeTrader::self()->preferredService(QLatin1String("text/html"));
|
||||
if (htmlApp) {
|
||||
QString error;
|
||||
const int err = startServiceByDesktopPath(htmlApp->entryPath(), url, &error, startup_id);
|
||||
if (err != 0) {
|
||||
KMessageBox::queuedMessageBox(
|
||||
nullptr, KMessageBox::Error,
|
||||
// TODO: i18n("Could not launch %1:\n\n%2", htmlApp->exec(), error),
|
||||
i18n("Could not launch the browser:\n\n%1", error),
|
||||
i18n("Could not launch Browser")
|
||||
);
|
||||
}
|
||||
startServiceByStorageId(htmlApp->entryPath(), QStringList() << url);
|
||||
return;
|
||||
}
|
||||
|
||||
QString exe = KStandardDirs::findExe(QString::fromLatin1("kde-open"));
|
||||
if (exe.isEmpty()) {
|
||||
exe = KStandardDirs::findExe(QString::fromLatin1("xdg-open"));
|
||||
}
|
||||
|
||||
if (kdeinitExec(exe, args, &error, startup_id) != 0) {
|
||||
KMessageBox::queuedMessageBox(
|
||||
nullptr, KMessageBox::Error,
|
||||
// TODO: i18n("Could not launch %1:\n\n%2", exe, error),
|
||||
i18n("Could not launch the browser:\n\n%1", error),
|
||||
i18n("Could not launch Browser")
|
||||
);
|
||||
}
|
||||
// if one cannot be found then launch the service for the URL MIME type
|
||||
startServiceForUrl(url);
|
||||
}
|
||||
|
||||
void KToolInvocation::invokeTerminal(const QString &command,
|
||||
const QString &workdir,
|
||||
const QByteArray &startup_id)
|
||||
const QString &workdir)
|
||||
{
|
||||
KConfigGroup confGroup( KGlobal::config(), "General" );
|
||||
QString exec = confGroup.readPathEntry("TerminalApplication", QString::fromLatin1("konsole"));
|
||||
|
||||
QStringList cmdTokens = KShell::splitArgs(exec);
|
||||
if (!command.isEmpty()) {
|
||||
if (exec == QLatin1String("konsole")) {
|
||||
exec += QString::fromLatin1(" --noclose");
|
||||
} else if (exec == QLatin1String("xterm")) {
|
||||
exec += QString::fromLatin1(" -hold");
|
||||
cmdTokens << QString::fromLatin1("--noclose");
|
||||
} else if (exec.startsWith(QLatin1String("xterm"))) {
|
||||
cmdTokens << QString::fromLatin1("-hold");
|
||||
}
|
||||
|
||||
exec += QString::fromLatin1(" -e ") + command;
|
||||
cmdTokens << QString::fromLatin1("-e") << command;
|
||||
}
|
||||
|
||||
QStringList cmdTokens = KShell::splitArgs(exec);
|
||||
|
||||
QString cmd = cmdTokens.takeFirst();
|
||||
|
||||
if (exec == QLatin1String("konsole") && !workdir.isEmpty()) {
|
||||
cmdTokens << QString::fromLatin1("--workdir");
|
||||
cmdTokens << workdir;
|
||||
// For other terminals like xterm, we'll simply change the working
|
||||
// directory before launching them, see below.
|
||||
}
|
||||
|
||||
QString error;
|
||||
if (self()->startServiceInternal("kdeinit_exec_with_workdir",
|
||||
cmd, cmdTokens, &error, startup_id, workdir)) {
|
||||
KMessageBox::queuedMessageBox(
|
||||
nullptr, KMessageBox::Error,
|
||||
i18n("Could not launch the terminal client:\n\n%1", error),
|
||||
i18n("Could not launch Terminal Client")
|
||||
startServiceInternal(
|
||||
"start_program_with_workdir", cmd, cmdTokens, nullptr, false, workdir
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,47 +22,50 @@
|
|||
#include "kautostart.h"
|
||||
#include "kshell.h"
|
||||
#include "kconfiggroup.h"
|
||||
#include "kmessagebox.h"
|
||||
#include "kmimetype.h"
|
||||
#include "kmimetypetrader.h"
|
||||
#include "kprotocolmanager.h"
|
||||
#include "kio/netaccess.h"
|
||||
#include "kio/udsentry.h"
|
||||
#include "kdebug.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QApplication>
|
||||
#include <QThread>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <signal.h>
|
||||
|
||||
static const int s_eventstime = 250;
|
||||
static const int s_sleeptime = 50;
|
||||
// NOTE: keep in sync with:
|
||||
// kde-workspace/kwin/effects/startupfeedback/startupfeedback.cpp
|
||||
// kde-workspace/kcontrol/launch/kcmlaunch.cpp
|
||||
static const qint64 s_startuptimeout = 10; // 10sec
|
||||
// klauncher is the last process to quit in a session (see kde-workspace/startkde.cmake) so 5sec
|
||||
// for each child process is more than enough
|
||||
// klauncher is the last process to quit in a session so 5sec for each child process is more than
|
||||
// enough
|
||||
static const qint64 s_processtimeout = 5000; // 5sec
|
||||
|
||||
static inline bool isPIDAlive(const pid_t pid)
|
||||
static inline void removeTemp(const bool temp, const QStringList &args)
|
||||
{
|
||||
return (::kill(pid, 0) >= 0);
|
||||
if (temp) {
|
||||
foreach (const QString &arg, args) {
|
||||
if (QFile::exists(arg)) {
|
||||
kDebug() << "removing temporary file" << arg;
|
||||
QFile::remove(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline int getExitStatus(const pid_t pid)
|
||||
static inline void showError(const QString &error, const quint64 window)
|
||||
{
|
||||
int pidstate = 0;
|
||||
::waitpid(pid, &pidstate, WNOHANG);
|
||||
return WEXITSTATUS(pidstate);
|
||||
}
|
||||
|
||||
static inline bool isASNValid(const QByteArray &asn)
|
||||
{
|
||||
return (!asn.isEmpty() && asn != "0");
|
||||
KMessageBox::errorWId(static_cast<WId>(window), error);
|
||||
}
|
||||
|
||||
KLauncherProcess::KLauncherProcess(QObject *parent)
|
||||
: QProcess(parent),
|
||||
m_kstartupinfo(nullptr),
|
||||
m_startuptimer(nullptr)
|
||||
m_startuptimer(nullptr),
|
||||
m_temp(false)
|
||||
{
|
||||
connect(
|
||||
this, SIGNAL(stateChanged(QProcess::ProcessState)),
|
||||
|
@ -70,13 +73,18 @@ KLauncherProcess::KLauncherProcess(QObject *parent)
|
|||
);
|
||||
}
|
||||
|
||||
void KLauncherProcess::setupStartup(const QByteArray &startup_id, const QString &appexe,
|
||||
const KService::Ptr kservice, const qint64 timeout)
|
||||
KLauncherProcess::~KLauncherProcess()
|
||||
{
|
||||
removeTemp(m_temp, m_args);
|
||||
}
|
||||
|
||||
void KLauncherProcess::setupStartup(const QString &appexe, const KService::Ptr kservice,
|
||||
const qint64 timeout, const bool temp, const QStringList &args)
|
||||
{
|
||||
Q_ASSERT(m_kstartupinfoid.none() == true);
|
||||
QByteArray startupwmclass;
|
||||
if (KRun::checkStartupNotify(kservice.data(), &startupwmclass)) {
|
||||
m_kstartupinfoid.initId(!isASNValid(startup_id) ? KStartupInfo::createNewStartupId() : startup_id);
|
||||
m_kstartupinfoid.initId(KStartupInfo::createNewStartupId());
|
||||
kDebug() << "setting up ASN for" << kservice->entryPath() << m_kstartupinfoid.id();
|
||||
m_kstartupinfodata.setHostname();
|
||||
m_kstartupinfodata.setBin(QFileInfo(appexe).fileName());
|
||||
|
@ -88,19 +96,11 @@ void KLauncherProcess::setupStartup(const QByteArray &startup_id, const QString
|
|||
processenv.insert(QString::fromLatin1("DESKTOP_STARTUP_ID"), m_kstartupinfoid.id());
|
||||
QProcess::setProcessEnvironment(processenv);
|
||||
sendSIStart(timeout);
|
||||
} else if (isASNValid(startup_id)) {
|
||||
kDebug() << "setting up ASN for" << startup_id;
|
||||
m_kstartupinfoid.initId(startup_id);
|
||||
m_kstartupinfodata.setHostname();
|
||||
m_kstartupinfodata.setBin(QFileInfo(appexe).fileName());
|
||||
m_kstartupinfodata.setDescription(i18n("Launching %1", m_kstartupinfodata.bin()));
|
||||
QProcessEnvironment processenv = QProcess::processEnvironment();
|
||||
processenv.insert(QString::fromLatin1("DESKTOP_STARTUP_ID"), QString::fromLatin1(startup_id.constData(), startup_id.size()));
|
||||
QProcess::setProcessEnvironment(processenv);
|
||||
sendSIStart(timeout);
|
||||
} else {
|
||||
kDebug() << "no ASN for" << appexe;
|
||||
}
|
||||
m_temp = temp;
|
||||
m_args = args;
|
||||
}
|
||||
|
||||
void KLauncherProcess::slotProcessStateChanged(QProcess::ProcessState state)
|
||||
|
@ -282,32 +282,18 @@ void KLauncherAdaptor::cleanup()
|
|||
}
|
||||
}
|
||||
|
||||
int KLauncherAdaptor::kdeinit_exec(const QString &app, const QStringList &args, const QStringList &envs, const QString& startup_id)
|
||||
bool KLauncherAdaptor::start_program(const QString &app, const QStringList &args,
|
||||
const QStringList &envs, quint64 window, bool temp)
|
||||
{
|
||||
return kdeinit_exec_with_workdir(app, args, envs, startup_id, QDir::currentPath());
|
||||
return start_program_with_workdir(app, args, envs, window, temp, QDir::currentPath());
|
||||
}
|
||||
|
||||
int KLauncherAdaptor::kdeinit_exec_wait(const QString &app, const QStringList &args, const QStringList &envs, const QString &startup_id)
|
||||
bool KLauncherAdaptor::start_program_with_workdir(const QString &app, const QStringList &args,
|
||||
const QStringList &envs, quint64 window,
|
||||
bool temp, const QString &workdir)
|
||||
{
|
||||
qint64 pid = 0;
|
||||
int result = startProgram(app, args, envs, startup_id, QDir::currentPath(), pid, m_startuptimeout);
|
||||
if (result != KLauncherAdaptor::NoError) {
|
||||
return result;
|
||||
}
|
||||
kDebug() << "waiting for" << pid;
|
||||
while (isPIDAlive(pid)) {
|
||||
QApplication::processEvents(QEventLoop::AllEvents, s_eventstime);
|
||||
QThread::msleep(s_sleeptime);
|
||||
}
|
||||
result = getExitStatus(pid);
|
||||
kDebug() << "done waiting for" << pid << ", exit status" << result;
|
||||
return result;
|
||||
}
|
||||
|
||||
int KLauncherAdaptor::kdeinit_exec_with_workdir(const QString &app, const QStringList &args, const QStringList &envs, const QString &startup_id, const QString &workdir)
|
||||
{
|
||||
qint64 pid = 0;
|
||||
return startProgram(app, args, envs, startup_id, workdir, pid, m_startuptimeout);
|
||||
return startProgram(app, args, envs, window, temp, workdir, pid, m_startuptimeout);
|
||||
}
|
||||
|
||||
void KLauncherAdaptor::setLaunchEnv(const QString &name, const QString &value)
|
||||
|
@ -320,31 +306,31 @@ void KLauncherAdaptor::setLaunchEnv(const QString &name, const QString &value)
|
|||
m_environment.insert(name, value);
|
||||
}
|
||||
|
||||
int KLauncherAdaptor::start_service_by_desktop_name(const QString &serviceName, const QStringList &urls, const QStringList &envs, const QString &startup_id)
|
||||
{
|
||||
KService::Ptr kservice = KService::serviceByDesktopName(serviceName);
|
||||
if (!kservice) {
|
||||
kWarning() << "invalid service name" << serviceName;
|
||||
return KLauncherAdaptor::ServiceError;
|
||||
}
|
||||
return start_service_by_desktop_path(kservice->entryPath(), urls, envs, startup_id);
|
||||
}
|
||||
|
||||
int KLauncherAdaptor::start_service_by_desktop_path(const QString &serviceName, const QStringList &urls, const QStringList &envs, const QString &startup_id)
|
||||
bool KLauncherAdaptor::start_service_by_storage_id(const QString &serviceName,
|
||||
const QStringList &urls,
|
||||
const QStringList &envs, quint64 window,
|
||||
bool temp)
|
||||
{
|
||||
KService::Ptr kservice = KService::serviceByStorageId(serviceName);
|
||||
if (!kservice) {
|
||||
kWarning() << "invalid service path" << serviceName;
|
||||
return KLauncherAdaptor::ServiceError;
|
||||
kError() << "invalid service path" << serviceName;
|
||||
showError(i18n("Invalid service: %1", serviceName), window);
|
||||
removeTemp(temp, urls);
|
||||
return false;
|
||||
}
|
||||
// TODO: start one service for each
|
||||
if (urls.size() > 1 && !kservice->allowMultipleFiles()) {
|
||||
kWarning() << "service does not support multiple files" << serviceName;
|
||||
return KLauncherAdaptor::ServiceError;
|
||||
kError() << "service does not support multiple files" << serviceName;
|
||||
showError(i18n("Service does not support multiple files: %1", serviceName), window);
|
||||
return false;
|
||||
}
|
||||
// TODO: for applications which do not support URLs - download
|
||||
QStringList programandargs = KRun::processDesktopExec(*kservice, urls);
|
||||
if (programandargs.isEmpty()) {
|
||||
kWarning() << "could not process service" << kservice->entryPath();
|
||||
return KLauncherAdaptor::ArgumentsError;
|
||||
kError() << "could not process service" << kservice->entryPath();
|
||||
showError(i18n("Could not process service: %1", serviceName), window);
|
||||
removeTemp(temp, urls);
|
||||
return false;
|
||||
}
|
||||
QString programworkdir = kservice->path();
|
||||
if (programworkdir.isEmpty()) {
|
||||
|
@ -353,7 +339,52 @@ int KLauncherAdaptor::start_service_by_desktop_path(const QString &serviceName,
|
|||
kDebug() << "starting" << kservice->entryPath() << urls;
|
||||
const QString program = programandargs.takeFirst();
|
||||
qint64 pid = 0;
|
||||
return startProgram(program, programandargs, envs, QString(), programworkdir, pid, m_startuptimeout, kservice);
|
||||
return startProgram(program, programandargs, envs, window, temp, programworkdir, pid, m_startuptimeout, kservice);
|
||||
}
|
||||
|
||||
bool KLauncherAdaptor::start_service_by_url(const QString &url, const QStringList &envs,
|
||||
quint64 window, bool temp)
|
||||
{
|
||||
const KUrl realurl = KUrl(url);
|
||||
QString urlmimetype;
|
||||
if (realurl.isLocalFile()) {
|
||||
KMimeType::Ptr kmimetype = KMimeType::findByUrl(realurl);
|
||||
if (kmimetype) {
|
||||
urlmimetype = kmimetype->name();
|
||||
}
|
||||
} else {
|
||||
KIO::UDSEntry kioudsentry;
|
||||
// TODO: unless WId is passed around QWidget::find() will not find external windows
|
||||
if (!KIO::NetAccess::stat(realurl, kioudsentry, QWidget::find(static_cast<WId>(window)))) {
|
||||
kWarning() << "could not stat URL for MIME type" << url;
|
||||
urlmimetype = KProtocolManager::defaultMimetype(realurl);
|
||||
} else {
|
||||
urlmimetype = kioudsentry.stringValue(KIO::UDSEntry::UDS_MIME_TYPE);
|
||||
}
|
||||
}
|
||||
if (urlmimetype.isEmpty()) {
|
||||
kError() << "invalid MIME type for path" << url;
|
||||
showError(i18n("Could not determine the MIME type of: %1", url), window);
|
||||
removeTemp(temp, QStringList() << url);
|
||||
return false;
|
||||
}
|
||||
kDebug() << "MIME type of" << url << "is" << urlmimetype;
|
||||
if (KRun::isExecutableFile(realurl, urlmimetype)) {
|
||||
kDebug() << "execuable file" << url;
|
||||
KMessageBox::sorryWId(
|
||||
static_cast<WId>(window),
|
||||
i18n("The file <tt>%1</tt> is an executable program.<br/>For safety it will not be started.", Qt::escape(realurl.prettyUrl()))
|
||||
);
|
||||
return false;
|
||||
}
|
||||
KService::Ptr kservice = KMimeTypeTrader::self()->preferredService(urlmimetype);
|
||||
if (!kservice) {
|
||||
kError() << "invalid service for MIME type" << urlmimetype;
|
||||
showError(i18n("No service can handle: %1", urlmimetype), window);
|
||||
removeTemp(temp, QStringList() << url);
|
||||
return false;
|
||||
}
|
||||
return start_service_by_storage_id(kservice->entryPath(), QStringList() << url, envs, window, temp);
|
||||
}
|
||||
|
||||
#ifdef KLAUNCHER_DEBUG
|
||||
|
@ -384,14 +415,16 @@ QString KLauncherAdaptor::findExe(const QString &app) const
|
|||
return KStandardDirs::findExe(app, environmentpath);
|
||||
}
|
||||
|
||||
int KLauncherAdaptor::startProgram(const QString &app, const QStringList &args, const QStringList &envs,
|
||||
const QString &startup_id, const QString &workdir, qint64 &pid,
|
||||
const qint64 timeout, const KService::Ptr kservice)
|
||||
bool KLauncherAdaptor::startProgram(const QString &app, const QStringList &args, const QStringList &envs,
|
||||
const quint64 window, const bool temp, const QString &workdir,
|
||||
qint64 &pid, const qint64 timeout, const KService::Ptr kservice)
|
||||
{
|
||||
const QString appexe = findExe(app);
|
||||
if (appexe.isEmpty()) {
|
||||
kWarning() << "could not find" << app;
|
||||
return KLauncherAdaptor::FindError;
|
||||
kError() << "could not find" << app;
|
||||
showError(i18n("Could not find the application: %1", app), window);
|
||||
removeTemp(temp, args);
|
||||
return false;
|
||||
}
|
||||
|
||||
KLauncherProcess* process = new KLauncherProcess(this);
|
||||
|
@ -411,7 +444,7 @@ int KLauncherAdaptor::startProgram(const QString &app, const QStringList &args,
|
|||
}
|
||||
process->setProcessEnvironment(processenv);
|
||||
process->setWorkingDirectory(workdir);
|
||||
process->setupStartup(startup_id.toLatin1(), appexe, kservice, timeout);
|
||||
process->setupStartup(appexe, kservice, timeout, temp, args);
|
||||
kDebug() << "starting" << appexe << args << envs << workdir;
|
||||
process->start(appexe, args);
|
||||
while (process->state() == QProcess::Starting) {
|
||||
|
@ -420,11 +453,11 @@ int KLauncherAdaptor::startProgram(const QString &app, const QStringList &args,
|
|||
}
|
||||
if (process->error() == QProcess::FailedToStart || process->error() == QProcess::Crashed) {
|
||||
kWarning() << "could not start" << appexe;
|
||||
return KLauncherAdaptor::ExecError;
|
||||
return false;
|
||||
}
|
||||
|
||||
pid = process->pid();
|
||||
return KLauncherAdaptor::NoError;
|
||||
return true;
|
||||
}
|
||||
|
||||
#include "moc_klauncher_adaptor.cpp"
|
||||
|
|
|
@ -33,9 +33,10 @@ class KLauncherProcess : public QProcess
|
|||
Q_OBJECT
|
||||
public:
|
||||
explicit KLauncherProcess(QObject *parent);
|
||||
~KLauncherProcess();
|
||||
|
||||
void setupStartup(const QByteArray &startup_id, const QString &appexe,
|
||||
const KService::Ptr kservice, const qint64 timeout);
|
||||
void setupStartup(const QString &appexe, const KService::Ptr kservice, const qint64 timeout,
|
||||
const bool temp, const QStringList &args);
|
||||
|
||||
private Q_SLOTS:
|
||||
void slotProcessStateChanged(QProcess::ProcessState state);
|
||||
|
@ -53,6 +54,8 @@ private:
|
|||
QTimer* m_startuptimer;
|
||||
KStartupInfoId m_kstartupinfoid;
|
||||
KStartupInfoData m_kstartupinfodata;
|
||||
bool m_temp;
|
||||
QStringList m_args;
|
||||
};
|
||||
|
||||
// Adaptor class for interface org.kde.KLauncher
|
||||
|
@ -61,14 +64,6 @@ class KLauncherAdaptor: public QDBusAbstractAdaptor
|
|||
Q_OBJECT
|
||||
Q_CLASSINFO("D-Bus Interface", "org.kde.KLauncher")
|
||||
public:
|
||||
enum KLauncherError {
|
||||
NoError = 0,
|
||||
ServiceError = -1,
|
||||
FindError = -2,
|
||||
ArgumentsError = -3,
|
||||
ExecError = -4
|
||||
};
|
||||
|
||||
KLauncherAdaptor(QObject *parent);
|
||||
~KLauncherAdaptor();
|
||||
|
||||
|
@ -83,11 +78,15 @@ public Q_SLOTS:
|
|||
|
||||
// used by KToolInvocation
|
||||
void setLaunchEnv(const QString &name, const QString &value);
|
||||
int kdeinit_exec(const QString &app, const QStringList &args, const QStringList &envs, const QString &startup_id);
|
||||
int kdeinit_exec_wait(const QString &app, const QStringList &args, const QStringList &envs, const QString &startup_id);
|
||||
int kdeinit_exec_with_workdir(const QString &app, const QStringList &args, const QStringList &envs, const QString &startup_id, const QString &workdir);
|
||||
int start_service_by_desktop_name(const QString &serviceName, const QStringList &urls, const QStringList &envs, const QString &startup_id);
|
||||
int start_service_by_desktop_path(const QString &serviceName, const QStringList &urls, const QStringList &envs, const QString &startup_id);
|
||||
bool start_program(const QString &app, const QStringList &args, const QStringList &envs,
|
||||
quint64 window, bool temp);
|
||||
bool start_program_with_workdir(const QString &app, const QStringList &args,
|
||||
const QStringList &envs, quint64 window, bool temp,
|
||||
const QString &workdir);
|
||||
bool start_service_by_storage_id(const QString &serviceName, const QStringList &urls,
|
||||
const QStringList &envs, quint64 window, bool temp);
|
||||
bool start_service_by_url(const QString &url, const QStringList &envs, quint64 window,
|
||||
bool temp);
|
||||
|
||||
// for debugging
|
||||
#ifdef KLAUNCHER_DEBUG
|
||||
|
@ -104,8 +103,8 @@ private Q_SLOTS:
|
|||
|
||||
private:
|
||||
QString findExe(const QString &app) const;
|
||||
int startProgram(const QString &app, const QStringList &args, const QStringList &envs,
|
||||
const QString &startup_id, const QString &workdir, qint64 &pid,
|
||||
bool startProgram(const QString &app, const QStringList &args, const QStringList &envs,
|
||||
const quint64 window, const bool temp, const QString &workdir, qint64 &pid,
|
||||
const qint64 timeout, const KService::Ptr kservice = KService::Ptr(nullptr));
|
||||
|
||||
QProcessEnvironment m_environment;
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include <kmenu.h>
|
||||
#include <kstandardshortcut.h>
|
||||
#include <kstandardaction.h>
|
||||
#include <krun.h>
|
||||
#include <ktoolinvocation.h>
|
||||
#include <kactioncollection.h>
|
||||
|
||||
/********************************************************************/
|
||||
|
@ -638,7 +638,7 @@ KBookmarkAction::KBookmarkAction(const KBookmark &bk, KBookmarkOwner *owner, QOb
|
|||
void KBookmarkAction::slotSelected(Qt::MouseButtons mb, Qt::KeyboardModifiers km)
|
||||
{
|
||||
if (!m_pOwner) {
|
||||
new KRun(bookmark().url(), (QWidget*)0);
|
||||
KToolInvocation::self()->startServiceForUrl(bookmark().url().url());
|
||||
} else {
|
||||
m_pOwner->openBookmark(bookmark(), mb, km);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "kfileitem.h"
|
||||
#include "kimagefilepreview.h"
|
||||
#include "knewfilemenu.h"
|
||||
#include "ktoolinvocation.h"
|
||||
|
||||
#include <config-kfile.h>
|
||||
|
||||
|
@ -71,7 +72,6 @@
|
|||
#include <kio/previewjob.h>
|
||||
#include <kio/renamedialog.h>
|
||||
#include <kfilepreviewgenerator.h>
|
||||
#include <krun.h>
|
||||
#include <kpropertiesdialog.h>
|
||||
#include <kstandardshortcut.h>
|
||||
#include <kde_file.h>
|
||||
|
@ -649,7 +649,7 @@ void KDirOperator::Private::_k_toggleInlinePreviews(bool show)
|
|||
|
||||
void KDirOperator::Private::_k_slotOpenFileManager()
|
||||
{
|
||||
new KRun(currUrl, parent);
|
||||
KToolInvocation::self()->startServiceForUrl(currUrl.url(), parent);
|
||||
}
|
||||
|
||||
void KDirOperator::Private::_k_slotSortByName()
|
||||
|
|
|
@ -78,6 +78,7 @@
|
|||
#include "kpreviewprops.h"
|
||||
#include "kmetaprops.h"
|
||||
#include "krun.h"
|
||||
#include "ktoolinvocation.h"
|
||||
#include "kvbox.h"
|
||||
#include "kacl.h"
|
||||
#include "kconfiggroup.h"
|
||||
|
@ -1100,14 +1101,11 @@ void KFilePropsPlugin::slotEditFileType()
|
|||
} else {
|
||||
mime = d->mimeType;
|
||||
}
|
||||
QString keditfiletype = QString::fromLatin1("keditfiletype");
|
||||
KRun::runCommand(keditfiletype
|
||||
#ifdef Q_WS_X11
|
||||
+ " --parent " + QString::number( (ulong)properties->window()->winId())
|
||||
#endif
|
||||
+ " --caption " + KShell::quoteArg(KGlobal::caption())
|
||||
+ ' ' + KShell::quoteArg(mime),
|
||||
keditfiletype, keditfiletype /*unused*/, properties->window());
|
||||
QStringList args;
|
||||
args << "--parent" << QString::number( (ulong)properties->window()->winId());
|
||||
args << "--caption" << KGlobal::caption();
|
||||
args << mime;
|
||||
KToolInvocation::self()->startProgram(QLatin1String("keditfiletype"), args, properties->window());
|
||||
}
|
||||
|
||||
void KFilePropsPlugin::slotIconChanged()
|
||||
|
@ -3256,9 +3254,7 @@ void KDesktopPropsPlugin::slotBrowseExec()
|
|||
return;
|
||||
}
|
||||
|
||||
QString path = f.toLocalFile();
|
||||
path = KShell::quoteArg(path);
|
||||
d->w->commandEdit->setText(path);
|
||||
d->w->commandEdit->setText(KShell::quoteArg(f.toLocalFile()));
|
||||
}
|
||||
|
||||
void KDesktopPropsPlugin::slotAdvanced()
|
||||
|
|
|
@ -18,10 +18,11 @@
|
|||
|
||||
#include "kautomount.h"
|
||||
|
||||
#include <krun.h>
|
||||
#include <ktoolinvocation.h>
|
||||
#include <kdirnotify.h>
|
||||
#include <kmessagebox.h>
|
||||
#include <klocale.h>
|
||||
#include <kurl.h>
|
||||
#include <kdebug.h>
|
||||
|
||||
#include <QDBusInterface>
|
||||
|
@ -112,10 +113,9 @@ void KAutoMountPrivate::slotFinished(QDBusPendingCallWatcher *watcher)
|
|||
return;
|
||||
}
|
||||
|
||||
const KUrl url(m_mountPoint);
|
||||
// kDebug(7015) << "KAutoMount: m_strDevice=" << m_strDevice << " -> mountpoint=" << m_mountPoint;
|
||||
if (m_bShowFilemanagerWindow) {
|
||||
KRun::runUrl(url, "inode/directory", nullptr /*TODO - window*/);
|
||||
KToolInvocation::self()->startServiceForUrl(m_mountPoint);
|
||||
}
|
||||
|
||||
// Update the desktop file which is used for mount/unmount (icon change)
|
||||
|
|
|
@ -21,24 +21,24 @@
|
|||
|
||||
#include "krun.h"
|
||||
#include "kautomount.h"
|
||||
#include "kmimetype.h"
|
||||
#include "kmessagebox.h"
|
||||
#include "kdirnotify.h"
|
||||
#include "kmountpoint.h"
|
||||
#include "kstandarddirs.h"
|
||||
#include "kdesktopfile.h"
|
||||
#include "kconfiggroup.h"
|
||||
#include "ktoolinvocation.h"
|
||||
#include "klocale.h"
|
||||
#include "kservice.h"
|
||||
#include "kdebug.h"
|
||||
|
||||
#include <QtDBus/QDBusInterface>
|
||||
#include <QtDBus/QDBusReply>
|
||||
|
||||
#include <kmessagebox.h>
|
||||
#include <kdirnotify.h>
|
||||
#include <kmountpoint.h>
|
||||
#include <kstandarddirs.h>
|
||||
#include <kdesktopfile.h>
|
||||
#include <kconfiggroup.h>
|
||||
#include <klocale.h>
|
||||
#include <kservice.h>
|
||||
#include <kdebug.h>
|
||||
|
||||
enum BuiltinServiceType { ST_MOUNT = 0x0E1B05B0, ST_UNMOUNT = 0x0E1B05B1 }; // random numbers
|
||||
|
||||
static bool runFSDevice( const KUrl& _url, const KDesktopFile &cfg );
|
||||
static bool runApplication( const KUrl& _url, const QString & _serviceFile );
|
||||
static bool runLink( const KUrl& _url, const KDesktopFile &cfg );
|
||||
|
||||
bool KDesktopFileActions::run( const KUrl& u, bool _is_local )
|
||||
|
@ -64,7 +64,7 @@ bool KDesktopFileActions::run( const KUrl& u, bool _is_local )
|
|||
return runFSDevice( u, cfg );
|
||||
else if ( cfg.hasApplicationType()
|
||||
|| (cfg.readType() == "Service" && !cfg.desktopGroup().readEntry("Exec").isEmpty())) // for kio_settings
|
||||
return runApplication( u, u.toLocalFile() );
|
||||
return KToolInvocation::self()->startServiceByStorageId( u.toLocalFile() );
|
||||
else if ( cfg.hasLinkType() )
|
||||
return runLink( u, cfg );
|
||||
|
||||
|
@ -94,9 +94,8 @@ static bool runFSDevice( const KUrl& _url, const KDesktopFile &cfg )
|
|||
KMountPoint::Ptr mp = KMountPoint::currentMountPoints().findByDevice( dev );
|
||||
// Is the device already mounted ?
|
||||
if (mp) {
|
||||
KUrl mpURL(mp->mountPoint());
|
||||
// Open a new window
|
||||
retval = KRun::runUrl( mpURL, QLatin1String("inode/directory"), 0 /*TODO - window*/ );
|
||||
retval = KToolInvocation::self()->startServiceForUrl(mp->mountPoint());
|
||||
} else {
|
||||
KConfigGroup cg = cfg.desktopGroup();
|
||||
bool ro = cg.readEntry("ReadOnly", false);
|
||||
|
@ -108,18 +107,6 @@ static bool runFSDevice( const KUrl& _url, const KDesktopFile &cfg )
|
|||
return retval;
|
||||
}
|
||||
|
||||
static bool runApplication( const KUrl& , const QString & _serviceFile )
|
||||
{
|
||||
KService s( _serviceFile );
|
||||
if ( !s.isValid() )
|
||||
// The error message was already displayed, so we can just quit here
|
||||
// ### KDE4: is this still the case?
|
||||
return false;
|
||||
|
||||
KUrl::List lst;
|
||||
return KRun::run( s, lst, 0 /*TODO - window*/ );
|
||||
}
|
||||
|
||||
static bool runLink( const KUrl& _url, const KDesktopFile &cfg )
|
||||
{
|
||||
QString u = cfg.readUrl();
|
||||
|
@ -132,17 +119,19 @@ static bool runLink( const KUrl& _url, const KDesktopFile &cfg )
|
|||
return false;
|
||||
}
|
||||
|
||||
KUrl url ( u );
|
||||
KRun* run = new KRun(url,(QWidget*)0);
|
||||
|
||||
// X-KDE-LastOpenedWith holds the service desktop entry name that
|
||||
// was should be preferred for opening this URL if possible.
|
||||
// should be preferred for opening this URL if possible.
|
||||
// This is used by the Recent Documents menu for instance.
|
||||
QString lastOpenedWidth = cfg.desktopGroup().readEntry( "X-KDE-LastOpenedWith" );
|
||||
if ( !lastOpenedWidth.isEmpty() )
|
||||
run->setPreferredService( lastOpenedWidth );
|
||||
|
||||
return false;
|
||||
if ( !lastOpenedWidth.isEmpty() ) {
|
||||
KService::Ptr service = KService::serviceByStorageId(lastOpenedWidth);
|
||||
if (!service.isNull()) {
|
||||
return KToolInvocation::self()->startServiceByStorageId(service->entryPath(), QStringList() << u, nullptr);
|
||||
} else {
|
||||
kWarning() << "Last opened with service is not valid" << lastOpenedWidth;
|
||||
}
|
||||
}
|
||||
return KToolInvocation::self()->startServiceForUrl(u, nullptr);
|
||||
}
|
||||
|
||||
QList<KServiceAction> KDesktopFileActions::builtinServices( const KUrl& _url )
|
||||
|
@ -291,7 +280,14 @@ void KDesktopFileActions::executeService( const KUrl::List& urls, const KService
|
|||
}
|
||||
} else {
|
||||
kDebug() << action.name() << "first url's path=" << urls.first().toLocalFile() << "exec=" << action.exec();
|
||||
KRun::run( action.exec(), urls, 0, action.text(), action.icon());
|
||||
KService actionService(action.text(), action.exec(), action.icon());
|
||||
QStringList actionArgs = KRun::processDesktopExec(actionService, urls);
|
||||
if (actionArgs.isEmpty()) {
|
||||
kWarning() << "empty service command" << action.text() << action.exec();
|
||||
} else {
|
||||
const QString actionProgram = actionArgs.takeFirst();
|
||||
KToolInvocation::self()->startProgram(actionProgram, actionArgs);
|
||||
}
|
||||
// The action may update the desktop file. Example: eject unmounts (#5129).
|
||||
org::kde::KDirNotify::emitFilesChanged( urls.toStringList() );
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ namespace KDesktopFileActions
|
|||
* @param _url the url to run
|
||||
* @param _is_local true if the URL is local, false otherwise
|
||||
* @return true on success and false on failure.
|
||||
* @see KRun::runUrl
|
||||
* @see KRun, KToolInvocation
|
||||
*/
|
||||
KIO_EXPORT bool run( const KUrl& _url, bool _is_local );
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include <kmountpoint.h>
|
||||
#include <kconfiggroup.h>
|
||||
#include <kuser.h>
|
||||
#include <ktoolinvocation.h>
|
||||
#include <kfilesystemtype_p.h>
|
||||
|
||||
static bool isKDirShare(const QString &dirpath)
|
||||
|
@ -993,7 +994,7 @@ void KFileItem::run(QWidget *parentWidget) const
|
|||
kWarning() << "null item";
|
||||
return;
|
||||
}
|
||||
(void) new KRun(targetUrl(), parentWidget, d->m_fileMode, d->m_bIsLocalUrl);
|
||||
KToolInvocation::self()->startServiceForUrl(targetUrl().url(), parentWidget);
|
||||
}
|
||||
|
||||
bool KFileItem::cmp(const KFileItem &item) const
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include <kaction.h>
|
||||
#include <krun.h>
|
||||
#include <kmimetypetrader.h>
|
||||
#include <kdebug.h>
|
||||
#include <kdesktopfileactions.h>
|
||||
#include <kmenu.h>
|
||||
#include <klocale.h>
|
||||
|
@ -33,6 +32,8 @@
|
|||
#include <kicon.h>
|
||||
#include <kstandarddirs.h>
|
||||
#include <kservicetypetrader.h>
|
||||
#include <ktoolinvocation.h>
|
||||
#include <kdebug.h>
|
||||
|
||||
#include <QFile>
|
||||
#include <QtCore/qalgorithms.h>
|
||||
|
@ -577,7 +578,7 @@ void KFileItemActionsPrivate::slotRunPreferredApplications()
|
|||
const QStringList mimeTypeList = listMimeTypes(fileItems);
|
||||
const QStringList serviceIdList = listPreferredServiceIds(mimeTypeList, m_traderConstraint);
|
||||
|
||||
foreach (const QString serviceId, serviceIdList) {
|
||||
foreach (const QString &serviceId, serviceIdList) {
|
||||
KFileItemList serviceItems;
|
||||
foreach (const KFileItem& item, fileItems) {
|
||||
const KService::Ptr serv = preferredService(item.mimetype(), m_traderConstraint);
|
||||
|
@ -597,7 +598,9 @@ void KFileItemActionsPrivate::slotRunPreferredApplications()
|
|||
KRun::displayOpenWithDialog(serviceItems.urlList(), m_parentWidget);
|
||||
continue;
|
||||
}
|
||||
KRun::run(*servicePtr, serviceItems.urlList(), m_parentWidget);
|
||||
KToolInvocation::self()->startServiceByStorageId(
|
||||
servicePtr->entryPath(), serviceItems.urlList().toStringList(), m_parentWidget
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -628,7 +631,9 @@ void KFileItemActionsPrivate::slotRunApplication(QAction* act)
|
|||
KService::Ptr app = act->data().value<KService::Ptr>();
|
||||
Q_ASSERT(app);
|
||||
if (app) {
|
||||
KRun::run(*app, m_props.urlList(), m_parentWidget);
|
||||
KToolInvocation::self()->startServiceByStorageId(
|
||||
app->entryPath(), m_props.urlList().toStringList(), m_parentWidget
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include <klocale.h>
|
||||
#include <kmimetype.h>
|
||||
#include <kshell.h>
|
||||
#include <krun.h>
|
||||
#include <ktoolinvocation.h>
|
||||
#include <ksycoca.h>
|
||||
|
||||
#include <QLabel>
|
||||
|
@ -201,14 +201,13 @@ void KMimeTypeChooserPrivate::_k_editMimeType()
|
|||
return;
|
||||
QString mt = (item->parent())->text(0) + '/' + item->text(0);
|
||||
// thanks to libkonq/konq_operations.cc
|
||||
q->connect( KSycoca::self(), SIGNAL(databaseChanged(QStringList)),
|
||||
q, SLOT(_k_slotSycocaDatabaseChanged(QStringList)) );
|
||||
QString keditfiletype = QString::fromLatin1("keditfiletype");
|
||||
KRun::runCommand( keditfiletype
|
||||
+ " --parent " + QString::number( (ulong)q->window()->winId())
|
||||
+ " --caption " + KShell::quoteArg(KGlobal::caption())
|
||||
+ ' ' + KShell::quoteArg(mt),
|
||||
keditfiletype, keditfiletype /*unused*/, q->window());
|
||||
q->connect(KSycoca::self(), SIGNAL(databaseChanged(QStringList)),
|
||||
q, SLOT(_k_slotSycocaDatabaseChanged(QStringList)));
|
||||
QStringList args;
|
||||
args << "--parent" << QString::number((ulong)q->window()->winId());
|
||||
args << "--caption" << KGlobal::caption();
|
||||
args << mt;
|
||||
KToolInvocation::self()->startProgram(QLatin1String("keditfiletype"), args, q->window());
|
||||
}
|
||||
|
||||
void KMimeTypeChooserPrivate::_k_slotCurrentChanged(QTreeWidgetItem* item)
|
||||
|
|
1636
kio/kio/krun.cpp
1636
kio/kio/krun.cpp
File diff suppressed because it is too large
Load diff
413
kio/kio/krun.h
413
kio/kio/krun.h
|
@ -1,12 +1,10 @@
|
|||
// -*- mode: c++; c-basic-offset: 2 -*-
|
||||
/* This file is part of the KDE project
|
||||
Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
|
||||
Copyright (C) 2006 David Faure <faure@kde.org>
|
||||
/*
|
||||
This file is part of the KDE libraries
|
||||
Copyright (C) 2024 Ivailo Monev <xakepa10@gmail.com>
|
||||
|
||||
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.
|
||||
License version 2, as published by the Free Software Foundation.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
|
@ -24,19 +22,11 @@
|
|||
|
||||
#include <kio/kio_export.h>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QString>
|
||||
#include <sys/types.h>
|
||||
#include <QString>
|
||||
#include <kurl.h>
|
||||
#include <kservice.h>
|
||||
|
||||
class KService;
|
||||
class KStartupInfo;
|
||||
class KJob;
|
||||
namespace KIO
|
||||
{
|
||||
class Job;
|
||||
}
|
||||
class KRunPrivate;
|
||||
|
||||
/**
|
||||
* To open files with their associated applications in KDE, use KRun.
|
||||
|
@ -56,249 +46,28 @@ class Job;
|
|||
*
|
||||
* @short Opens files with their associated applications in KDE
|
||||
*/
|
||||
class KIO_EXPORT KRun : public QObject
|
||||
class KIO_EXPORT KRun
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* @param url the URL of the file or directory to 'run'
|
||||
*
|
||||
* @param window
|
||||
* The top-level widget of the app that invoked this object.
|
||||
* It is used to make sure private information like passwords
|
||||
* are properly handled per application.
|
||||
*
|
||||
* @param mode The @p st_mode field of <tt>struct stat</tt>. If
|
||||
* you don't know this set it to 0.
|
||||
*
|
||||
* @param isLocalFile
|
||||
* If this parameter is set to @p false then @p url is
|
||||
* examined to find out whether it is a local URL or
|
||||
* not. This flag is just used to improve speed, since the
|
||||
* function KUrl::isLocalFile is a bit slow.
|
||||
*
|
||||
* @param showProgressInfo
|
||||
* Whether to show progress information when determining the
|
||||
* type of the file (i.e. when using KIO::stat and KIO::mimetype)
|
||||
* Before you set this to false to avoid a dialog box, think about
|
||||
* a very slow FTP server...
|
||||
* It is always better to provide progress info in such cases.
|
||||
* @param asn
|
||||
* Application startup notification id, if available (otherwise "").
|
||||
*/
|
||||
KRun(const KUrl& url, QWidget* window, mode_t mode = 0,
|
||||
bool isLocalFile = false, bool showProgressInfo = true,
|
||||
const QByteArray& asn = QByteArray());
|
||||
|
||||
/**
|
||||
* Destructor. Don't call it yourself, since a KRun object auto-deletes
|
||||
* itself.
|
||||
*/
|
||||
virtual ~KRun();
|
||||
|
||||
/**
|
||||
* Abort this KRun. This kills any jobs launched by it,
|
||||
* and leads to deletion if auto-deletion is on.
|
||||
* This is much safer than deleting the KRun (in case it's
|
||||
* currently showing an error dialog box, for instance)
|
||||
*/
|
||||
void abort();
|
||||
|
||||
/**
|
||||
* Returns true if the KRun instance has an error.
|
||||
* @return true when an error occurred
|
||||
* @see error()
|
||||
*/
|
||||
bool hasError() const;
|
||||
|
||||
/**
|
||||
* Returns true if the KRun instance has finished.
|
||||
* @return true if the KRun instance has finished
|
||||
* @see finished()
|
||||
*/
|
||||
bool hasFinished() const;
|
||||
|
||||
/**
|
||||
* Checks whether auto delete is activated.
|
||||
* Auto-deletion causes the KRun instance to delete itself
|
||||
* when it finished its task.
|
||||
* By default auto deletion is on.
|
||||
* @return true if auto deletion is on, false otherwise
|
||||
*/
|
||||
bool autoDelete() const;
|
||||
|
||||
/**
|
||||
* Enables or disabled auto deletion.
|
||||
* Auto deletion causes the KRun instance to delete itself
|
||||
* when it finished its task. If you allocate the KRun
|
||||
* object on the stack you must disable auto deletion.
|
||||
* By default auto deletion is on.
|
||||
* @param b true to enable auto deletion, false to disable
|
||||
*/
|
||||
void setAutoDelete(bool b);
|
||||
|
||||
/**
|
||||
* Set the preferred service for opening this URL, after
|
||||
* its mimetype will have been found by KRun. IMPORTANT: the service is
|
||||
* only used if its configuration says it can handle this mimetype.
|
||||
* This is used for instance for the X-KDE-LastOpenedWith key in
|
||||
* the recent documents list.
|
||||
* @param desktopEntryName the desktopEntryName of the service, e.g. "kate".
|
||||
*/
|
||||
void setPreferredService(const QString& desktopEntryName);
|
||||
|
||||
/**
|
||||
* Sets whether executables, .desktop files or shell scripts should
|
||||
* be run by KRun. This is enabled by default.
|
||||
* @param b whether to run executable files or not.
|
||||
* @see isExecutable()
|
||||
*/
|
||||
void setRunExecutables(bool b);
|
||||
|
||||
/**
|
||||
* Sets the file name to use in the case of downloading the file to a tempfile
|
||||
* in order to give to a non-url-aware application. Some apps rely on the extension
|
||||
* to determine the mimetype of the file. Usually the file name comes from the URL,
|
||||
* but in the case of the HTTP Content-Disposition header, we need to override the
|
||||
* file name.
|
||||
*/
|
||||
void setSuggestedFileName(const QString& fileName);
|
||||
|
||||
/**
|
||||
* Suggested file name given by the server (e.g. HTTP content-disposition)
|
||||
*/
|
||||
QString suggestedFileName() const;
|
||||
|
||||
/**
|
||||
* Associated window, as passed to the constructor
|
||||
* @since 4.9.3
|
||||
*/
|
||||
QWidget* window() const;
|
||||
|
||||
|
||||
/**
|
||||
* Open a list of URLs with a certain service (application).
|
||||
*
|
||||
* @param service the service to run
|
||||
* @param urls the list of URLs, can be empty (app launched
|
||||
* without argument)
|
||||
* @param window The top-level widget of the app that invoked this object.
|
||||
* @param tempFiles if true and urls are local files, they will be deleted
|
||||
* when the application exits.
|
||||
* @param suggestedFileName see setSuggestedFileName
|
||||
* @param asn Application startup notification id, if any (otherwise "").
|
||||
* @return @c true on success, @c false on error
|
||||
*/
|
||||
static bool run(const KService& service, const KUrl::List& urls, QWidget* window,
|
||||
bool tempFiles = false, const QString& suggestedFileName = QString(),
|
||||
const QByteArray& asn = QByteArray());
|
||||
|
||||
/**
|
||||
* Open a list of URLs with an executable.
|
||||
*
|
||||
* @param exec the name of the executable, for example
|
||||
* "/usr/bin/netscape %u".
|
||||
* Don't forget to include the %u if you know that the applications
|
||||
* supports URLs. Otherwise, non-local urls will first be downloaded
|
||||
* to a temp file (using kioexec).
|
||||
* @param urls the list of URLs to open, can be empty (app launched without argument)
|
||||
* @param window The top-level widget of the app that invoked this object.
|
||||
* @param name the logical name of the application, for example
|
||||
* "Netscape 4.06".
|
||||
* @param icon the icon which should be used by the application.
|
||||
* @param asn Application startup notification id, if any (otherwise "").
|
||||
* @return @c true on success, @c false on error
|
||||
*/
|
||||
static bool run(const QString& exec, const KUrl::List& urls, QWidget* window,
|
||||
const QString& name = QString(),
|
||||
const QString& icon = QString(),
|
||||
const QByteArray& asn = QByteArray());
|
||||
|
||||
/**
|
||||
* Open the given URL.
|
||||
*
|
||||
* This function is used after the mime type
|
||||
* is found out. It will search for all services which can handle
|
||||
* the mime type and call run() afterwards.
|
||||
* @param url the URL to open
|
||||
* @param mimetype the mime type of the resource
|
||||
* @param window The top-level widget of the app that invoked this object.
|
||||
* @param tempFile if true and url is a local file, it will be deleted
|
||||
* when the launched application exits.
|
||||
* @param runExecutables if false then local .desktop files,
|
||||
* executables and shell scripts will not be run.
|
||||
* See also isExecutable().
|
||||
* @param suggestedFileName see setSuggestedFileName
|
||||
* @param asn Application startup notification id, if any (otherwise "").
|
||||
* @return @c true on success, @c false on error
|
||||
*/
|
||||
static bool runUrl(const KUrl& url, const QString& mimetype, QWidget* window,
|
||||
bool tempFile = false , bool runExecutables = true,
|
||||
const QString& suggestedFileName = QString(), const QByteArray& asn = QByteArray());
|
||||
|
||||
/**
|
||||
* Run the given shell command and notifies KDE of the starting
|
||||
* of the application. If the program to be called doesn't exist,
|
||||
* an error box will be displayed.
|
||||
*
|
||||
* Use only when you know the full command line. Otherwise use the other
|
||||
* static methods, or KRun's constructor.
|
||||
*
|
||||
* @p cmd must be a shell command. You must not append "&"
|
||||
* to it, since the function will do that for you.
|
||||
* @param window The top-level widget of the app that invoked this object.
|
||||
* @param workingDirectory a working directory, so that a command like
|
||||
* "kwrite file.txt" finds file.txt from the right place.
|
||||
*
|
||||
* @return @c true on success, @c false on error
|
||||
*/
|
||||
static bool runCommand(const QString &cmd, QWidget* window, const QString& workingDirectory = QString());
|
||||
|
||||
/**
|
||||
* Same as the other runCommand(), but it also takes the name of the
|
||||
* binary, to display an error message in case it couldn't find it.
|
||||
*
|
||||
* @param cmd must be a shell command. You must not append "&"
|
||||
* to it, since the function will do that for you.
|
||||
* @param execName the name of the executable
|
||||
* @param icon icon for app starting notification
|
||||
* @param window The top-level widget of the app that invoked this object.
|
||||
* @param asn Application startup notification id, if any (otherwise "").
|
||||
* @param workingDirectory the working directory for the started process. The default
|
||||
* (if passing an empty string) is the user's document path.
|
||||
* @return @c true on success, @c false on error
|
||||
*/
|
||||
static bool runCommand(const QString& cmd, const QString& execName,
|
||||
const QString& icon, QWidget* window, const QByteArray& asn = QByteArray(),
|
||||
const QString& workingDirectory = QString());
|
||||
|
||||
/**
|
||||
* Display the Open-With dialog for those URLs, and run the chosen application.
|
||||
* @param lst the list of applications to run
|
||||
* @param urls the list of applications to run
|
||||
* @param window The top-level widget of the app that invoked this object.
|
||||
* @param tempFiles if true and lst are local files, they will be deleted
|
||||
* when the application exits.
|
||||
* @param suggestedFileName see setSuggestedFileName
|
||||
* @param asn Application startup notification id, if any (otherwise "").
|
||||
* @return false if the dialog was canceled
|
||||
*/
|
||||
static bool displayOpenWithDialog(const KUrl::List& lst, QWidget* window,
|
||||
bool tempFiles = false, const QString& suggestedFileName = QString(),
|
||||
const QByteArray& asn = QByteArray());
|
||||
static bool displayOpenWithDialog(const KUrl::List &urls, QWidget* window,
|
||||
bool tempFiles = false);
|
||||
|
||||
/**
|
||||
* Processes a Exec= line as found in .desktop files.
|
||||
* @param _service the service to extract information from.
|
||||
* @param _urls The urls the service should open.
|
||||
* @param tempFiles if true and urls are local files, they will be deleted
|
||||
* when the application exits.
|
||||
* @param suggestedFileName see setSuggestedFileName
|
||||
* @param service the service to extract information from.
|
||||
* @param urls The urls the service should open.
|
||||
*
|
||||
* @return a list of arguments suitable for KProcess::setProgram().
|
||||
*/
|
||||
static QStringList processDesktopExec(const KService &_service, const KUrl::List &_urls,
|
||||
bool tempFiles = false,
|
||||
const QString& suggestedFileName = QString());
|
||||
static QStringList processDesktopExec(const KService &service, const KUrl::List &urls);
|
||||
|
||||
/**
|
||||
* Given a full command line (e.g. the Exec= line from a .desktop file),
|
||||
|
@ -307,13 +76,13 @@ public:
|
|||
* @param removePath if true, remove a (relative or absolute) path. E.g. /usr/bin/ls becomes ls.
|
||||
* @return the name of the binary to run
|
||||
*/
|
||||
static QString binaryName(const QString & execLine, bool removePath);
|
||||
static QString binaryName(const QString &execLine, bool removePath);
|
||||
|
||||
/**
|
||||
* Returns whether @p serviceType refers to an executable program instead
|
||||
* of a data file.
|
||||
*/
|
||||
static bool isExecutable(const QString& serviceType);
|
||||
static bool isExecutable(const QString &serviceType);
|
||||
|
||||
/**
|
||||
* Returns whether the @p url of @p mimetype is executable.
|
||||
|
@ -330,157 +99,9 @@ public:
|
|||
static bool isExecutableFile(const KUrl &url, const QString &mimetype);
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* Returns true if startup notification should be done for the given service, false otherwise
|
||||
*/
|
||||
static bool checkStartupNotify(const KService *service, QByteArray *wmclass_arg);
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
* Emitted when the operation finished.
|
||||
* This signal is emitted in all cases of completion, whether successful or with error.
|
||||
* @see hasFinished()
|
||||
*/
|
||||
void finished();
|
||||
/**
|
||||
* Emitted when the operation had an error.
|
||||
* @see hasError()
|
||||
*/
|
||||
void error();
|
||||
|
||||
protected Q_SLOTS:
|
||||
/**
|
||||
* All following protected slots are used by subclasses of KRun!
|
||||
*/
|
||||
|
||||
/**
|
||||
* This slot is called whenever the internal timer fired,
|
||||
* in order to move on to the next step.
|
||||
*/
|
||||
void slotTimeout(); // KDE5: rename to slotNextStep() or something like that
|
||||
|
||||
/**
|
||||
* This slot is called when the scan job is finished.
|
||||
*/
|
||||
void slotScanFinished(KJob *);
|
||||
|
||||
/**
|
||||
* Call this from subclasses when you have determined the mimetype.
|
||||
* It will call foundMimeType, but also sets up protection against deletion during message boxes.
|
||||
* @since 4.0.2
|
||||
*/
|
||||
void mimeTypeDetermined(const QString& mimeType);
|
||||
|
||||
/**
|
||||
* This slot is called when the 'stat' job has finished.
|
||||
*/
|
||||
virtual void slotStatResult(KJob *);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* All following protected methods are used by subclasses of KRun!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Initializes the krun object.
|
||||
*/
|
||||
virtual void init();
|
||||
|
||||
/**
|
||||
* Start scanning a file.
|
||||
*/
|
||||
virtual void scanFile();
|
||||
|
||||
/**
|
||||
* Called if the mimetype has been detected. The function runs
|
||||
* the application associated with this mimetype.
|
||||
* Reimplement this method to implement a different behavior,
|
||||
* like opening the component for displaying the URL embedded.
|
||||
*
|
||||
* Important: call setFinished(true) once you are done!
|
||||
* Usually at the end of the foundMimeType reimplementation, but if the
|
||||
* reimplementation is asynchronous (e.g. uses KIO jobs) then
|
||||
* it can be called later instead.
|
||||
*/
|
||||
virtual void foundMimeType(const QString& type);
|
||||
|
||||
/**
|
||||
* Called if error occurres.
|
||||
*/
|
||||
virtual void error(const QString& message);
|
||||
|
||||
/**
|
||||
* Kills the file scanning job.
|
||||
*/
|
||||
virtual void killJob();
|
||||
|
||||
/**
|
||||
* Sets the url.
|
||||
*/
|
||||
void setUrl(const KUrl &url);
|
||||
|
||||
/**
|
||||
* Returns the url.
|
||||
*/
|
||||
KUrl url() const;
|
||||
|
||||
/**
|
||||
* Sets whether an error has occurred.
|
||||
*/
|
||||
void setError(bool error);
|
||||
|
||||
/**
|
||||
* Sets whether progress information shall be shown.
|
||||
*/
|
||||
void setProgressInfo(bool progressInfo);
|
||||
|
||||
/**
|
||||
* Returns whether progress information are shown.
|
||||
*/
|
||||
bool progressInfo() const;
|
||||
|
||||
/**
|
||||
* Marks this 'KRun' instance as finished.
|
||||
*/
|
||||
void setFinished(bool finished);
|
||||
|
||||
/**
|
||||
* Sets the job.
|
||||
*/
|
||||
void setJob(KIO::Job *job);
|
||||
|
||||
/**
|
||||
* Returns the job.
|
||||
*/
|
||||
KIO::Job* job();
|
||||
|
||||
/**
|
||||
* Returns whether it is a directory.
|
||||
*/
|
||||
bool isDirectory() const;
|
||||
|
||||
/**
|
||||
* Sets whether it is a local file.
|
||||
*/
|
||||
void setIsLocalFile(bool isLocalFile);
|
||||
|
||||
/**
|
||||
* Returns whether it is a local file.
|
||||
*/
|
||||
bool isLocalFile() const;
|
||||
|
||||
/**
|
||||
* Sets the file mode.
|
||||
*/
|
||||
void setMode(mode_t mode);
|
||||
|
||||
/**
|
||||
* Returns the file mode.
|
||||
*/
|
||||
mode_t mode() const;
|
||||
|
||||
private:
|
||||
class KRunPrivate;
|
||||
KRunPrivate* const d;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
127
kio/kio/krun_p.h
127
kio/kio/krun_p.h
|
@ -1,127 +0,0 @@
|
|||
// -*- mode: c++; c-basic-offset: 2 -*-
|
||||
/* This file is part of the KDE project
|
||||
Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
|
||||
Copyright (C) 2006 David Faure <faure@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.
|
||||
*/
|
||||
|
||||
#ifndef KRUN_P_H
|
||||
#define KRUN_P_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QPointer>
|
||||
|
||||
#include "kprocess.h"
|
||||
#include "kstartupinfo.h"
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* This class watches a process launched by KRun.
|
||||
* It sends a notification when the process exits (for the taskbar)
|
||||
* and it will show an error message if necessary (e.g. "program not found").
|
||||
*/
|
||||
class KProcessRunner : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
#ifndef Q_WS_X11
|
||||
static qint64 run(KProcess *, const QString & executable);
|
||||
#else
|
||||
static qint64 run(KProcess *, const QString & executable, const KStartupInfoId& id);
|
||||
#endif
|
||||
|
||||
virtual ~KProcessRunner();
|
||||
|
||||
qint64 pid() const;
|
||||
|
||||
protected Q_SLOTS:
|
||||
|
||||
void slotProcessExited(int, QProcess::ExitStatus);
|
||||
|
||||
private:
|
||||
#ifndef Q_WS_X11
|
||||
KProcessRunner(KProcess *, const QString & binName);
|
||||
#else
|
||||
KProcessRunner(KProcess *, const QString & binName, const KStartupInfoId& id);
|
||||
#endif
|
||||
|
||||
void terminateStartupNotification();
|
||||
|
||||
KProcess *m_process;
|
||||
QString m_executable; // can be a full path
|
||||
KStartupInfoId m_id;
|
||||
qint64 m_pid;
|
||||
|
||||
Q_DISABLE_COPY(KProcessRunner)
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class KRun::KRunPrivate
|
||||
{
|
||||
public:
|
||||
KRunPrivate(KRun *parent);
|
||||
|
||||
void init (const KUrl& url, QWidget* window, mode_t mode,
|
||||
bool isLocalFile, bool showProgressInfo, const QByteArray& asn);
|
||||
|
||||
// This helper method makes debugging easier: a single breakpoint for all
|
||||
// the code paths that start the timer - at least from KRun itself.
|
||||
// TODO: add public method startTimer() and deprecate timer() accessor,
|
||||
// starting is the only valid use of the timer in subclasses
|
||||
void startTimer();
|
||||
|
||||
bool runExecutable(const QString& _exec);
|
||||
|
||||
KRun *q;
|
||||
bool m_showingDialog;
|
||||
bool m_runExecutables;
|
||||
|
||||
QString m_preferredService;
|
||||
QString m_localPath;
|
||||
QString m_suggestedFileName;
|
||||
QPointer <QWidget> m_window;
|
||||
QByteArray m_asn;
|
||||
KUrl m_strURL;
|
||||
bool m_bFault;
|
||||
bool m_bAutoDelete;
|
||||
bool m_bProgressInfo;
|
||||
bool m_bFinished;
|
||||
KIO::Job * m_job;
|
||||
QTimer m_timer;
|
||||
|
||||
/**
|
||||
* Used to indicate that the next action is to scan the file.
|
||||
* This action is invoked from slotTimeout.
|
||||
*/
|
||||
bool m_bScanFile;
|
||||
bool m_bIsDirectory;
|
||||
|
||||
/**
|
||||
* Used to indicate that the next action is to initialize.
|
||||
* This action is invoked from slotTimeout
|
||||
*/
|
||||
bool m_bInit;
|
||||
|
||||
bool m_bIsLocalFile;
|
||||
mode_t m_mode;
|
||||
};
|
||||
|
||||
#endif // KRUN_P_H
|
|
@ -38,7 +38,7 @@ int main( int argc, char **argv )
|
|||
if ( args->count() != 1 )
|
||||
return 1;
|
||||
|
||||
KToolInvocation::self()->invokeMailer(KUrl(args->arg(0)), QByteArray(), true);
|
||||
KToolInvocation::self()->invokeMailer(KUrl(args->arg(0)), true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ int main(int argc, char **argv)
|
|||
cmd << QString::number(url.port());
|
||||
}
|
||||
|
||||
KToolInvocation::self()->kdeinitExec(terminal, cmd);
|
||||
KToolInvocation::self()->startProgram(terminal, cmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@ ENDMACRO(KIO_UNIT_TESTS)
|
|||
# jobtest seems to trigger a ctest problem; jobtest finishes and ctest waits for ever
|
||||
|
||||
KIO_UNIT_TESTS(
|
||||
krununittest
|
||||
kprotocolinfotest
|
||||
jobtest
|
||||
jobguitest
|
||||
|
|
|
@ -1,266 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2003 Waldo Bastian <bastian@kde.org>
|
||||
* Copyright (C) 2007, 2009 David Faure <faure@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 "krununittest.h"
|
||||
#include "moc_krununittest.cpp"
|
||||
#include <qtest_kde.h>
|
||||
QTEST_KDEMAIN( KRunUnitTest, NoGUI )
|
||||
|
||||
#include "krun.h"
|
||||
#include <kshell.h>
|
||||
#include <kservice.h>
|
||||
#include <kstandarddirs.h>
|
||||
#include <kconfiggroup.h>
|
||||
#include <kprocess.h>
|
||||
#include "kiotesthelper.h" // createTestFile etc.
|
||||
|
||||
void KRunUnitTest::initTestCase()
|
||||
{
|
||||
// testProcessDesktopExec works only if your terminal application is set to "x-term"
|
||||
KConfigGroup cg(KGlobal::config(), "General");
|
||||
cg.writeEntry("TerminalApplication", "x-term");
|
||||
|
||||
// Determine the full path of sh - this is needed to make testProcessDesktopExecNoFile()
|
||||
// pass on systems where KStandardDirs::findExe("sh") is not "/bin/sh".
|
||||
m_sh = KStandardDirs::findExe("sh");
|
||||
if (m_sh.isEmpty()) m_sh = "/bin/sh";
|
||||
}
|
||||
|
||||
void KRunUnitTest::testBinaryName_data()
|
||||
{
|
||||
QTest::addColumn<QString>("execLine");
|
||||
QTest::addColumn<bool>("removePath");
|
||||
QTest::addColumn<QString>("expected");
|
||||
|
||||
QTest::newRow("/usr/bin/ls true") << "/usr/bin/ls" << true << "ls";
|
||||
QTest::newRow("/usr/bin/ls false") << "/usr/bin/ls" << false << "/usr/bin/ls";
|
||||
QTest::newRow("/path/to/wine \"long argument with path\"") << "/path/to/wine \"long argument with path\"" << true << "wine";
|
||||
QTest::newRow("/path/with/a/sp\\ ace/exe arg1 arg2") << "/path/with/a/sp\\ ace/exe arg1 arg2" << true << "exe";
|
||||
QTest::newRow("\"progname\" \"arg1\"") << "\"progname\" \"arg1\"" << true << "progname";
|
||||
QTest::newRow("'quoted' \"arg1\"") << "'quoted' \"arg1\"" << true << "quoted";
|
||||
QTest::newRow(" 'leading space' arg1") << " 'leading space' arg1" << true << "leading space";
|
||||
}
|
||||
|
||||
void KRunUnitTest::testBinaryName()
|
||||
{
|
||||
QFETCH(QString, execLine);
|
||||
QFETCH(bool, removePath);
|
||||
QFETCH(QString, expected);
|
||||
QCOMPARE(KRun::binaryName(execLine, removePath), expected);
|
||||
}
|
||||
|
||||
//static const char *bt(bool tr) { return tr?"true":"false"; }
|
||||
static void checkPDE(const char* exec, const char* term, const char* sus,
|
||||
const KUrl::List &urls, bool tf, const QString& b)
|
||||
{
|
||||
QFile out( "kruntest.desktop" );
|
||||
if ( !out.open( QIODevice::WriteOnly ) )
|
||||
abort();
|
||||
QByteArray str ( "[Desktop Entry]\n"
|
||||
"Type=Application\n"
|
||||
"Name=just_a_test\n"
|
||||
"Icon=~/icon.png\n");
|
||||
str += QByteArray(exec) + '\n';
|
||||
str += QByteArray(term) + '\n';
|
||||
str += QByteArray(sus) + '\n';
|
||||
out.write( str );
|
||||
out.close();
|
||||
|
||||
KService service(QDir::currentPath() + "/kruntest.desktop");
|
||||
/*qDebug() << QString().sprintf(
|
||||
"processDesktopExec( "
|
||||
"service = {\nexec = %s\nterminal = %s, terminalOptions = %s\nsubstituteUid = %s, user = %s },"
|
||||
"\nURLs = { %s },\ntemp_files = %s )",
|
||||
service.exec().toLatin1().constData(), bt(service.terminal()), service.terminalOptions().toLatin1().constData(), bt(service.substituteUid()), service.username().toLatin1().constData(),
|
||||
KShell::joinArgs(urls.toStringList()).toLatin1().constData(), bt(tf));
|
||||
*/
|
||||
QCOMPARE(KShell::joinArgs(KRun::processDesktopExec(service,urls,tf)), b);
|
||||
|
||||
QFile::remove("kruntest.desktop");
|
||||
}
|
||||
|
||||
void KRunUnitTest::testProcessDesktopExec()
|
||||
{
|
||||
KUrl::List l0;
|
||||
static const char
|
||||
* const execs[] = { "Exec=date -u", "Exec=echo $PWD" },
|
||||
* const terms[] = { "Terminal=false", "Terminal=true\nTerminalOptions=-T \"%f - %c\"" },
|
||||
* const sus[] = { "X-KDE-SubstituteUID=false", "X-KDE-SubstituteUID=true\nX-KDE-Username=sprallo" },
|
||||
* const rslts[] = {
|
||||
"/bin/date -u", // 0
|
||||
"/bin/sh -c 'echo $PWD '", // 1
|
||||
"x-term -T ' - just_a_test' -e /bin/date -u", // 2
|
||||
"x-term -T ' - just_a_test' -e /bin/sh -c 'echo $PWD '", // 3
|
||||
/* kdesudo */ " -u sprallo -c '/bin/date -u'", // 4
|
||||
/* kdesudo */ " -u sprallo -c '/bin/sh -c '\\''echo $PWD '\\'''", // 5
|
||||
"x-term -T ' - just_a_test' -e su sprallo -c '/bin/date -u'", // 6
|
||||
"x-term -T ' - just_a_test' -e su sprallo -c '/bin/sh -c '\\''echo $PWD '\\'''", // 7
|
||||
};
|
||||
|
||||
// Find out the full path of the shell which will be used to execute shell commands
|
||||
KProcess process;
|
||||
process.setShellCommand("");
|
||||
const QString shellPath = process.program().at(0);
|
||||
|
||||
// Arch moved /bin/date to /usr/bin/date...
|
||||
const QString datePath = KStandardDirs::findExe("date");
|
||||
|
||||
for (int su = 0; su < 2; su++)
|
||||
for (int te = 0; te < 2; te++)
|
||||
for (int ex = 0; ex < 2; ex++) {
|
||||
int pt = ex+te*2+su*4;
|
||||
QString exe;
|
||||
if (pt == 4 || pt == 5) {
|
||||
exe = KStandardDirs::findExe("kdesudo");
|
||||
if (exe.isEmpty()) {
|
||||
qWarning() << "kdesudo not found, skipping test";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
const QString result = QString::fromLatin1(rslts[pt])
|
||||
.replace("/bin/sh", shellPath)
|
||||
.replace("/bin/date", datePath);
|
||||
checkPDE( execs[ex], terms[te], sus[su], l0, false, exe + result);
|
||||
}
|
||||
}
|
||||
|
||||
void KRunUnitTest::testProcessDesktopExecNoFile_data()
|
||||
{
|
||||
QTest::addColumn<QString>("execLine");
|
||||
QTest::addColumn<KUrl::List>("urls");
|
||||
QTest::addColumn<bool>("tempfiles");
|
||||
QTest::addColumn<QString>("expected");
|
||||
|
||||
KUrl::List l0;
|
||||
KUrl::List l1; l1 << KUrl( "file:/tmp" );
|
||||
KUrl::List l2; l2 << KUrl( "http://localhost/foo" );
|
||||
KUrl::List l3; l3 << KUrl( "file:/local/file" ) << KUrl( "http://remotehost.org/bar" );
|
||||
KUrl::List l4; l4 << KUrl( "http://login:password@www.kde.org" );
|
||||
|
||||
// A real-world use case would be kate.
|
||||
// But I picked klauncher4 since it's installed by kdelibs
|
||||
QString klauncher = KStandardDirs::findExe("klauncher4");
|
||||
if (klauncher.isEmpty()) klauncher = "klauncher4";
|
||||
|
||||
QString kioexec = KStandardDirs::findExe("kioexec");
|
||||
if (kioexec.isEmpty())
|
||||
QSKIP("kioexec not found, kdebase needed", SkipAll);
|
||||
|
||||
QString kmailservice = KStandardDirs::findExe("kmailservice");
|
||||
if (kmailservice.isEmpty()) kmailservice = "kmailservice";
|
||||
if (!klauncher.isEmpty()) {
|
||||
QVERIFY(!kmailservice.isEmpty());
|
||||
}
|
||||
|
||||
// NOTE: using QString() for concats to avoid QStringBuilder metatype, which is not valid
|
||||
QTest::newRow("%U l0") << "klauncher4 %U" << l0 << false << klauncher;
|
||||
QTest::newRow("%U l1") << "klauncher4 %U" << l1 << false << QString(klauncher + " /tmp");
|
||||
QTest::newRow("%U l2") << "klauncher4 %U" << l2 << false << QString(klauncher + " http://localhost/foo");
|
||||
QTest::newRow("%U l3") << "klauncher4 %U" << l3 << false << QString(klauncher + " /local/file http://remotehost.org/bar");
|
||||
|
||||
//QTest::newRow("%u l0") << "klauncher4 %u" << l0 << false << klauncher; // gives runtime warning
|
||||
QTest::newRow("%u l1") << "klauncher4 %u" << l1 << false << QString(klauncher + " /tmp");
|
||||
QTest::newRow("%u l2") << "klauncher4 %u" << l2 << false << QString(klauncher + " http://localhost/foo");
|
||||
//QTest::newRow("%u l3") << "klauncher4 %u" << l3 << false << klauncher; // gives runtime warning
|
||||
|
||||
QTest::newRow("%F l0") << "klauncher4 %F" << l0 << false << klauncher;
|
||||
QTest::newRow("%F l1") << "klauncher4 %F" << l1 << false << QString(klauncher + " /tmp");
|
||||
QTest::newRow("%F l2") << "klauncher4 %F" << l2 << false << QString(kioexec + " 'klauncher4 %F' http://localhost/foo");
|
||||
QTest::newRow("%F l3") << "klauncher4 %F" << l3 << false << QString(kioexec + " 'klauncher4 %F' /local/file http://remotehost.org/bar");
|
||||
|
||||
QTest::newRow("%F l1 tempfile") << "klauncher4 %F" << l1 << true << QString(kioexec + " --tempfiles 'klauncher4 %F' /tmp");
|
||||
|
||||
QTest::newRow("sh -c klauncher4 %F") << "sh -c \"klauncher4 \"'\\\"'\"%F\"'\\\"'"
|
||||
<< l1 << false << QString(m_sh + " -c 'klauncher4 \\\"/tmp\\\"'");
|
||||
|
||||
QTest::newRow("kmailservice %u l1") << "kmailservice %u" << l1 << false << QString(kmailservice + " /tmp");
|
||||
QTest::newRow("kmailservice %u l4") << "kmailservice %u" << l4 << false << QString(kmailservice + " http://login:password@www.kde.org");
|
||||
}
|
||||
|
||||
void KRunUnitTest::testProcessDesktopExecNoFile()
|
||||
{
|
||||
QFETCH(QString, execLine);
|
||||
KService service("dummy", execLine, "app");
|
||||
QFETCH(KUrl::List, urls);
|
||||
QFETCH(bool, tempfiles);
|
||||
QFETCH(QString, expected);
|
||||
QCOMPARE(KShell::joinArgs(KRun::processDesktopExec(service,urls,tempfiles)), expected);
|
||||
}
|
||||
|
||||
class KRunImpl : public KRun
|
||||
{
|
||||
public:
|
||||
KRunImpl(const KUrl& url, bool isLocalFile = false)
|
||||
: KRun(url, 0, 0, isLocalFile, false) {}
|
||||
|
||||
void foundMimeType(const QString& type) final {
|
||||
m_mimeType = type;
|
||||
// don't call KRun::foundMimeType, we don't want to start an app ;-)
|
||||
setFinished(true);
|
||||
}
|
||||
|
||||
void error(const QString& message) final {
|
||||
// don't show message box, this is unit test
|
||||
Q_UNUSED(message);
|
||||
}
|
||||
|
||||
QString mimeTypeFound() const { return m_mimeType; }
|
||||
|
||||
private:
|
||||
QString m_mimeType;
|
||||
};
|
||||
|
||||
void KRunUnitTest::testMimeTypeFile()
|
||||
{
|
||||
const QString filePath = homeTmpDir() + "file";
|
||||
createTestFile(filePath, true);
|
||||
KRunImpl* krun = new KRunImpl(filePath, true);
|
||||
QTest::kWaitForSignal(krun, SIGNAL(finished()), 1000);
|
||||
QCOMPARE(krun->mimeTypeFound(), QString::fromLatin1("text/plain"));
|
||||
}
|
||||
|
||||
void KRunUnitTest::testMimeTypeDirectory()
|
||||
{
|
||||
const QString dir = homeTmpDir() + "dir";
|
||||
createTestDirectory(dir);
|
||||
KRunImpl* krun = new KRunImpl(dir, true);
|
||||
QTest::kWaitForSignal(krun, SIGNAL(finished()), 1000);
|
||||
QCOMPARE(krun->mimeTypeFound(), QString::fromLatin1("inode/directory"));
|
||||
}
|
||||
|
||||
void KRunUnitTest::testMimeTypeBrokenLink()
|
||||
{
|
||||
const QString dir = homeTmpDir() + "dir";
|
||||
createTestDirectory(dir);
|
||||
KRunImpl* krun = new KRunImpl(KUrl(dir + "/testlink"), true);
|
||||
QSignalSpy spyError(krun, SIGNAL(error()));
|
||||
QTest::kWaitForSignal(krun, SIGNAL(finished()), 1000);
|
||||
QVERIFY(krun->mimeTypeFound().isEmpty());
|
||||
QCOMPARE(spyError.count(), 1);
|
||||
}
|
||||
|
||||
void KRunUnitTest::testMimeTypeDoesNotExist()
|
||||
{
|
||||
KRunImpl* krun = new KRunImpl(KUrl("/does/not/exist"));
|
||||
QSignalSpy spyError(krun, SIGNAL(error()));
|
||||
QTest::kWaitForSignal(krun, SIGNAL(finished()), 1000);
|
||||
QVERIFY(krun->mimeTypeFound().isEmpty());
|
||||
QCOMPARE(spyError.count(), 1);
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2005, 2009 David Faure <faure@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.
|
||||
*/
|
||||
|
||||
#ifndef KRUNUNITTEST_H
|
||||
#define KRUNUNITTEST_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
class KRunUnitTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
void testBinaryName_data();
|
||||
void testBinaryName();
|
||||
void testProcessDesktopExec();
|
||||
void testProcessDesktopExecNoFile_data();
|
||||
void testProcessDesktopExecNoFile();
|
||||
|
||||
void testMimeTypeFile();
|
||||
void testMimeTypeDirectory();
|
||||
void testMimeTypeBrokenLink();
|
||||
void testMimeTypeDoesNotExist();
|
||||
|
||||
private:
|
||||
QString m_sh;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif /* KRUNUNITTEST_H */
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
#include <kstandarddirs.h>
|
||||
#include <kicon.h>
|
||||
#include <krun.h>
|
||||
#include <ktoolinvocation.h>
|
||||
|
||||
namespace Plasma
|
||||
{
|
||||
|
@ -79,7 +79,7 @@ AssociatedApplicationManager *AssociatedApplicationManager::self()
|
|||
|
||||
void AssociatedApplicationManager::setApplication(Plasma::Applet *applet, const QString &application)
|
||||
{
|
||||
KService::Ptr service = KService::serviceByDesktopName(application);
|
||||
KService::Ptr service = KService::serviceByStorageId(application);
|
||||
if (service || !KStandardDirs::findExe(application).isNull() || QFile::exists(application)) {
|
||||
d->applicationNames[applet] = application;
|
||||
if (!d->urlLists.contains(applet)) {
|
||||
|
@ -106,14 +106,15 @@ KUrl::List AssociatedApplicationManager::urls(const Plasma::Applet *applet) cons
|
|||
void AssociatedApplicationManager::run(Plasma::Applet *applet)
|
||||
{
|
||||
if (d->applicationNames.contains(applet)) {
|
||||
bool success = KRun::run(d->applicationNames.value(applet), d->urlLists.value(applet), 0);
|
||||
bool success = KToolInvocation::self()->startServiceByStorageId(
|
||||
d->applicationNames.value(applet), d->urlLists.value(applet).toStringList()
|
||||
);
|
||||
if (!success) {
|
||||
applet->showMessage(KIcon("application-exit"), i18n("There was an error attempting to exec the associated application with this widget."), ButtonOk);
|
||||
}
|
||||
|
||||
} else if (d->urlLists.contains(applet) && !d->urlLists.value(applet).isEmpty()) {
|
||||
KRun *krun = new KRun(d->urlLists.value(applet).first(), 0);
|
||||
krun->setAutoDelete(true);
|
||||
KToolInvocation::self()->startServiceForUrl(d->urlLists.value(applet).first().url());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue