2
* activeprofiles_dbus.cpp - Class for interacting with other psi instances
3
* Copyright (C) 2006-2007 Martin Hostettler
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License
7
* as published by the Free Software Foundation; either version 2
8
* of the License, or (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this library; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
#include "activeprofiles.h"
23
#include <QCoreApplication>
25
#include <QStringList>
27
#include <QDBusConnection>
28
#include <QDBusConnectionInterface>
29
#include <QDBusInterface>
36
#include "applicationinfo.h"
43
/** \brief encodes a string to "[A-Z][a-z][0-9]_-" ascii subset
44
* [A-Z][a-z][0-9] -> [A-Z][a-z][0-9]
46
* everything else to "-XX" with XX hex code of char
49
static QString encodeAlNumD(QString in)
52
QByteArray chars = in.toUtf8();
54
foreach(char c, chars) {
55
if (('A' <= c) && (c <= 'z')) {
57
} else if (('0' <= c) && (c <= '9') && !first) {
59
} else if ('/' == c) {
62
out += QString("-%1").arg(c, 2, 16, QChar('0'));
70
/** \brief DBus busname registration helper
71
* \param dbusIface interface of bus
72
* \param name busname to register
73
* \param queue try queueing?
74
* \return got dbus name?
76
static bool registerBusname(QDBusConnectionInterface *dbusIface, QString name, bool queue)
79
QDBusReply<QDBusConnectionInterface::RegisterServiceReply> reply;
80
reply = dbusIface->registerService(name,
81
queue ? QDBusConnectionInterface::QueueService : QDBusConnectionInterface::DontQueueService,
82
QDBusConnectionInterface::AllowReplacement);
83
if (reply.isValid()) {
84
switch (reply.value()) {
85
case QDBusConnectionInterface::ServiceNotRegistered:
86
qWarning("failed to register dbus name %s:", (const char*)name);
88
case QDBusConnectionInterface::ServiceQueued:
89
qDebug("dbus name %s already taken, queueing", (const char*)name);
91
case QDBusConnectionInterface::ServiceRegistered:
95
qWarning("failed to register dbus name %s: %s", (const char*)name, (const char*)reply.error().message());
101
class ActiveProfiles::Private {
104
QStringList busNames;
105
bool registerBusnames(QString prof);
107
QString dbusName(QString prof);
111
QString ActiveProfiles::Private::dbusName(QString prof)
113
QString name = PSIDBUSNAME;
115
name += encodeAlNumD(ApplicationInfo::homeDir()).right(qMax(0,200-name.size()));
116
if (!prof.isEmpty()) {
118
name += encodeAlNumD(prof).right(qMax(0,250-name.size()));
125
bool ActiveProfiles::Private::registerBusnames(QString prof)
128
if (!QDBusConnection::sessionBus().isConnected()) {
129
qWarning("can't connect to dbus");
134
QDBusConnectionInterface *dbusIface = QDBusConnection::sessionBus().interface ();
136
QString name = PSIDBUSNAME;
137
registerBusname(dbusIface, name, true);
139
name = dbusName(QString());
140
registerBusname(dbusIface, name, true);
142
name = dbusName(prof);
144
return registerBusname(dbusIface, name, false);
149
bool ActiveProfiles::isActive(const QString &profile) const
151
QDBusConnectionInterface *dbusIface = QDBusConnection::sessionBus().interface ();
152
return dbusIface->isServiceRegistered(d->dbusName(profile));
155
bool ActiveProfiles::setThisProfile(const QString &profile)
157
if (profile == d->profile)
160
if (profile.isEmpty()) {
164
bool ok = d->registerBusnames(profile);
166
d->profile = profile;
173
void ActiveProfiles::unsetThisProfile()
175
QDBusConnectionInterface *dbusIface = QDBusConnection::sessionBus().interface ();
176
foreach(QString name, d->busNames) {
177
dbusIface->unregisterService(name);
180
d->profile = QString::null;
183
QString ActiveProfiles::thisProfile() const
188
ActiveProfiles::ActiveProfiles()
189
: QObject(QCoreApplication::instance())
191
d = new ActiveProfiles::Private;
194
ActiveProfiles::~ActiveProfiles()
203
bool ActiveProfiles::sendOpenUri(const QString &uri, const QString &profile) const
205
QDBusInterface(d->dbusName(profile), "/Main", PSIDBUSMAINIF).call(QDBus::NoBlock,
210
return false; // isActive(profile)? profile : pickProfile();
215
bool ActiveProfiles::raiseOther(QString profile, bool withUI) const
218
QDBusMessage msg = QDBusMessage::createMethodCall ( d->dbusName(profile), "/Main", PSIDBUSMAINIF, "raise" );
220
lab = new QLabel(tr("This psi profile is already running...<br>please wait..."));
221
QTimer::singleShot(250, lab, SLOT(show()));
223
QDBusMessage rmsg = QDBusConnection::sessionBus().call(msg, QDBus::BlockWithGui, 10000);
228
if (rmsg.type() == QDBusMessage::ReplyMessage) {