Commit bfaedcf6 authored by David Faure's avatar David Faure
Browse files

Add PimUniqueApplication::activateApplication

Summary:
This allows one PIM application to ensure another one is started, either
standalone or in kontact, and in the latter case, select the
corresponding plugin to make it visible.

This implementation relies on DBus activation, recently added for the
PIM apps.

+ cleanup unused "bool unique = true" in start() method, they are all unique
+ fix docu

Test Plan: see kdepim-addons change request using this

Reviewers: vkrause, dvratil, mlaurent

Reviewed By: vkrause

Subscribers: kde-pim

Tags: #kde_pim

Differential Revision: https://phabricator.kde.org/D22621
parent eb39ea1c
......@@ -101,12 +101,38 @@ void PimUniqueApplication::setAboutData(KAboutData &aboutData)
QDBusConnection::ExportAdaptors);
}
bool PimUniqueApplication::start(const QStringList &arguments, bool unique)
static bool callNewInstance(const QString &appName, const QString &serviceName, const QByteArray &asn_id, const QStringList &arguments)
{
const QString objectName = QLatin1Char('/') + appName + QLatin1String("_PimApplication");
QDBusInterface iface(serviceName,
objectName,
QStringLiteral("org.kde.PIMUniqueApplication"),
QDBusConnection::sessionBus());
if (iface.isValid()) {
QDBusReply<int> reply = iface.call(QStringLiteral("newInstance"),
asn_id,
arguments,
QDir::currentPath());
if (reply.isValid()) {
return true;
}
}
return false;
}
int PimUniqueApplication::newInstance()
{
return newInstance(KStartupInfo::startupId(), QStringList() << QApplication::applicationName(), QDir::currentPath());
}
bool PimUniqueApplication::start(const QStringList &arguments)
{
const QString appName = QApplication::applicationName();
// Try talking to /appName_PimApplication in org.kde.appName,
// (which could be kontact or the standalone application),
// otherwise fall back to starting a new app
// otherwise the current app being started will register to DBus.
const QString serviceName = QLatin1String("org.kde.") + appName;
if (QDBusConnection::sessionBus().interface()->isServiceRegistered(serviceName)) {
......@@ -125,28 +151,14 @@ bool PimUniqueApplication::start(const QStringList &arguments, bool unique)
KWindowSystem::allowExternalProcessWindowActivation();
const QString objectName = QLatin1Char('/') + appName + QLatin1String("_PimApplication");
qCDebug(KONTACTINTERFACE_LOG) << objectName;
QDBusInterface iface(serviceName,
objectName,
QStringLiteral("org.kde.PIMUniqueApplication"),
QDBusConnection::sessionBus());
if (iface.isValid()) {
QDBusReply<int> reply = iface.call(QStringLiteral("newInstance"),
new_asn_id,
arguments,
QDir::currentPath());
if (reply.isValid()) {
return false; // success means that main() can exist now.
}
if (callNewInstance(appName, serviceName, new_asn_id, arguments)) {
return false; // success means that main() can exit now.
}
}
qCDebug(KONTACTINTERFACE_LOG) << "kontact not running -- start standalone application";
if (unique) {
QDBusConnection::sessionBus().registerService(serviceName);
}
QDBusConnection::sessionBus().registerService(serviceName);
// Make sure we have DrKonqi
Private::disableChromiumCrashHandler();
......@@ -155,9 +167,15 @@ bool PimUniqueApplication::start(const QStringList &arguments, bool unique)
return true;
}
int PimUniqueApplication::newInstance()
bool PimUniqueApplication::activateApplication(const QString &appName, const QStringList &additionalArguments)
{
return newInstance(KStartupInfo::startupId(), QStringList() << QApplication::applicationName(), QDir::currentPath());
const QString serviceName = QLatin1String("org.kde.") + appName;
QStringList arguments{ appName };
arguments += additionalArguments;
// Start it standalone if not already running (if kontact is running, then this will do nothing)
QDBusConnection::sessionBus().interface()->startService(serviceName);
return callNewInstance(appName, serviceName, KStartupInfo::createNewStartupId(), arguments);
}
// This is called via DBus either by another instance that has just been
......
......@@ -33,7 +33,7 @@ namespace KontactInterface
/**
* KDEPIM applications which can be integrated into kontact should use
* PimUniqueApplication instead of Qapplication + Dbus unique.
* PimUniqueApplication instead of QApplication + Dbus unique.
* This makes command-line handling work, i.e. you can launch "korganizer"
* and if kontact is already running, it will load the korganizer part and
* switch to it.
......@@ -49,8 +49,19 @@ public:
~PimUniqueApplication();
void setAboutData(KAboutData &aboutData);
static bool start(const QStringList &arguments,
bool unique = true);
/**
* Register this process as a unique application, if not already running.
* Typically called in main().
* @param arguments should start with the appname, as QCoreApplication::arguments() does.
*/
static bool start(const QStringList &arguments);
/**
* Ensure that another PIM application is running.
*/
static bool activateApplication(const QString &application,
const QStringList &additionalArguments = {});
Q_REQUIRED_RESULT QCommandLineParser *cmdArgs() const;
......
......@@ -40,7 +40,7 @@ namespace KontactInterface
class KONTACTINTERFACE_EXPORT UniqueAppHandler : public QObject
{
Q_OBJECT
// We implement the KUniqueApplication interface
// We implement the PIMUniqueApplication interface
Q_CLASSINFO("D-Bus Interface", "org.kde.PIMUniqueApplication")
public:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment