~ubuntu-branches/ubuntu/quantal/psi/quantal

« back to all changes in this revision

Viewing changes to src/activeprofiles_dbus.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jan Niehusmann
  • Date: 2008-08-28 18:46:52 UTC
  • mfrom: (1.2.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20080828184652-iiik12dl91nq7cdi
Tags: 0.12-2
Uploading to unstable (Closes: Bug#494352)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * activeprofiles_dbus.cpp - Class for interacting with other psi instances
 
3
 * Copyright (C) 2006-2007  Martin Hostettler
 
4
 *
 
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.
 
9
 *
 
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.
 
14
 *
 
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
 
18
 *
 
19
 */
 
20
 
 
21
#include "activeprofiles.h"
 
22
 
 
23
#include <QCoreApplication>
 
24
#include <QString>
 
25
#include <QStringList>
 
26
#include <QByteArray>
 
27
#include <QDBusConnection>
 
28
#include <QDBusConnectionInterface>
 
29
#include <QDBusInterface>
 
30
 
 
31
 
 
32
#include <QLabel>
 
33
#include <QTimer>
 
34
 
 
35
 
 
36
#include "applicationinfo.h"
 
37
#include "dbus.h"
 
38
 
 
39
 
 
40
 
 
41
 
 
42
 
 
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]
 
45
 * / -> _
 
46
 * everything else to "-XX" with XX hex code of char
 
47
 * (slow)
 
48
 */
 
49
static QString encodeAlNumD(QString in)
 
50
{
 
51
        QString out;
 
52
        QByteArray chars = in.toUtf8();
 
53
        bool first = true;
 
54
        foreach(char c, chars) {
 
55
                if (('A' <= c) && (c <= 'z')) {
 
56
                        out += (char)c;
 
57
                } else if (('0' <= c) && (c <= '9') && !first) {
 
58
                        out += (char)c;
 
59
                } else if ('/' == c) {
 
60
                        out += "_";
 
61
                } else {
 
62
                        out += QString("-%1").arg(c, 2, 16, QChar('0'));
 
63
                }
 
64
                first = false;
 
65
        }
 
66
        return out;
 
67
}
 
68
 
 
69
 
 
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?
 
75
 */
 
76
static bool registerBusname(QDBusConnectionInterface *dbusIface, QString name, bool queue)
 
77
{
 
78
        bool ok = false;
 
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); 
 
87
                                break;
 
88
                        case QDBusConnectionInterface::ServiceQueued:
 
89
                                qDebug("dbus name %s already taken, queueing", (const char*)name);
 
90
                                break;
 
91
                        case QDBusConnectionInterface::ServiceRegistered:
 
92
                                ok = true;
 
93
                }
 
94
        } else {
 
95
                qWarning("failed to register dbus name %s: %s", (const char*)name,  (const char*)reply.error().message());
 
96
        }
 
97
        return ok;
 
98
}
 
99
 
 
100
 
 
101
class ActiveProfiles::Private {
 
102
public:
 
103
        QString profile;
 
104
        QStringList busNames;
 
105
        bool registerBusnames(QString prof);
 
106
 
 
107
        QString dbusName(QString prof);
 
108
};
 
109
 
 
110
 
 
111
QString ActiveProfiles::Private::dbusName(QString prof)
 
112
{
 
113
        QString name = PSIDBUSNAME;
 
114
        name += ".";
 
115
        name += encodeAlNumD(ApplicationInfo::homeDir()).right(qMax(0,200-name.size()));
 
116
        if (!prof.isEmpty()) {
 
117
                name += ".";
 
118
                name += encodeAlNumD(prof).right(qMax(0,250-name.size()));
 
119
        }
 
120
        return name;
 
121
}
 
122
 
 
123
 
 
124
 
 
125
bool ActiveProfiles::Private::registerBusnames(QString prof)
 
126
{
 
127
        // FIXME move where?
 
128
        if (!QDBusConnection::sessionBus().isConnected()) {
 
129
                qWarning("can't connect to dbus");
 
130
                return true;
 
131
        }
 
132
 
 
133
 
 
134
        QDBusConnectionInterface *dbusIface = QDBusConnection::sessionBus().interface ();
 
135
 
 
136
        QString name = PSIDBUSNAME;
 
137
        registerBusname(dbusIface, name, true);
 
138
        busNames << name;
 
139
        name = dbusName(QString());
 
140
        registerBusname(dbusIface, name, true);
 
141
        busNames << name;
 
142
        name = dbusName(prof);
 
143
        busNames << name;
 
144
        return registerBusname(dbusIface, name, false);
 
145
 
 
146
}
 
147
 
 
148
 
 
149
bool ActiveProfiles::isActive(const QString &profile) const
 
150
{
 
151
        QDBusConnectionInterface *dbusIface = QDBusConnection::sessionBus().interface ();
 
152
        return dbusIface->isServiceRegistered(d->dbusName(profile));
 
153
}
 
154
 
 
155
bool ActiveProfiles::setThisProfile(const QString &profile)
 
156
{
 
157
        if (profile == d->profile)
 
158
                return true;
 
159
 
 
160
        if (profile.isEmpty()) {
 
161
                unsetThisProfile();
 
162
                return true;
 
163
        }
 
164
        bool ok = d->registerBusnames(profile);
 
165
        if (ok) {
 
166
                d->profile = profile;
 
167
        } else {
 
168
                unsetThisProfile();
 
169
        }
 
170
        return ok;
 
171
}
 
172
 
 
173
void ActiveProfiles::unsetThisProfile()
 
174
{
 
175
        QDBusConnectionInterface *dbusIface = QDBusConnection::sessionBus().interface ();
 
176
        foreach(QString name, d->busNames) {
 
177
                dbusIface->unregisterService(name);
 
178
        }
 
179
        d->busNames.clear();
 
180
        d->profile = QString::null;
 
181
}
 
182
 
 
183
QString ActiveProfiles::thisProfile() const
 
184
{
 
185
        return d->profile;
 
186
}
 
187
 
 
188
ActiveProfiles::ActiveProfiles()
 
189
        : QObject(QCoreApplication::instance())
 
190
{
 
191
        d = new ActiveProfiles::Private;
 
192
}
 
193
 
 
194
ActiveProfiles::~ActiveProfiles()
 
195
{
 
196
        delete d;
 
197
        d = 0;
 
198
}
 
199
 
 
200
 
 
201
 
 
202
 
 
203
bool ActiveProfiles::sendOpenUri(const QString &uri, const QString &profile) const
 
204
{
 
205
        QDBusInterface(d->dbusName(profile), "/Main", PSIDBUSMAINIF).call(QDBus::NoBlock, 
 
206
                        "openURI", uri);
 
207
        return true;
 
208
        
 
209
        // FIXME
 
210
        return false; //  isActive(profile)? profile : pickProfile();
 
211
}
 
212
 
 
213
 
 
214
 
 
215
bool ActiveProfiles::raiseOther(QString profile, bool withUI) const
 
216
{
 
217
        QLabel *lab=0;
 
218
        QDBusMessage msg = QDBusMessage::createMethodCall ( d->dbusName(profile), "/Main", PSIDBUSMAINIF, "raise" );
 
219
        if (withUI) {
 
220
                lab = new QLabel(tr("This psi profile is already running...<br>please wait..."));
 
221
                QTimer::singleShot(250, lab, SLOT(show()));
 
222
        }
 
223
        QDBusMessage rmsg = QDBusConnection::sessionBus().call(msg, QDBus::BlockWithGui, 10000);
 
224
        if (withUI) {
 
225
                lab->hide();
 
226
                delete lab;
 
227
        }
 
228
        if (rmsg.type() == QDBusMessage::ReplyMessage) {
 
229
                return true;
 
230
        } else return false;
 
231
}