1/***************************************************************************
2 * Copyright 2009 by Marco Martin <notmart@gmail.com> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
18 ***************************************************************************/
19
20#include "statusnotifierwatcher.h"
21
22#include <QDBusConnection>
23#include <QDBusServiceWatcher>
24
25#include <kglobal.h>
26#include <kaboutdata.h>
27#include <kdebug.h>
28
29#include <kpluginfactory.h>
30#include <kpluginloader.h>
31#include "statusnotifierwatcheradaptor.h"
32#include "statusnotifieritem_interface.h"
33#include <config-workspace.h>
34
35
36static inline KAboutData aboutData()
37{
38 return KAboutData("statusnotifierwatcher", 0, ki18n("statusnotifierwatcher"), WORKSPACE_VERSION_STRING);
39}
40
41K_PLUGIN_FACTORY(StatusNotifierWatcherFactory,
42 registerPlugin<StatusNotifierWatcher>();
43 )
44K_EXPORT_PLUGIN(StatusNotifierWatcherFactory(aboutData()))
45
46StatusNotifierWatcher::StatusNotifierWatcher(QObject *parent, const QList<QVariant>&)
47 : KDEDModule(parent)
48{
49 setModuleName("StatusNotifierWatcher");
50 new StatusNotifierWatcherAdaptor(this);
51 QDBusConnection dbus = QDBusConnection::sessionBus();
52 dbus.registerService("org.kde.StatusNotifierWatcher");
53 dbus.registerObject("/StatusNotifierWatcher", this);
54
55 m_serviceWatcher = new QDBusServiceWatcher(this);
56 m_serviceWatcher->setConnection(dbus);
57 m_serviceWatcher->setWatchMode(QDBusServiceWatcher::WatchForUnregistration);
58
59 connect(m_serviceWatcher, SIGNAL(serviceUnregistered(QString)), this, SLOT(serviceUnregistered(QString)));
60}
61
62StatusNotifierWatcher::~StatusNotifierWatcher()
63{
64 QDBusConnection dbus = QDBusConnection::sessionBus();
65 dbus.unregisterService("org.kde.StatusNotifierWatcher");
66}
67
68
69void StatusNotifierWatcher::RegisterStatusNotifierItem(const QString &serviceOrPath)
70{
71 QString service;
72 QString path;
73 if (serviceOrPath.startsWith('/')) {
74 service = message().service();
75 path = serviceOrPath;
76 } else {
77 service = serviceOrPath;
78 path = "/StatusNotifierItem";
79 }
80 QString notifierItemId = service + path;
81 if (QDBusConnection::sessionBus().interface()->isServiceRegistered(service).value() &&
82 !m_registeredServices.contains(notifierItemId)) {
83 kDebug()<<"Registering" << notifierItemId << "to system tray";
84
85 //check if the service has registered a SystemTray object
86 org::kde::StatusNotifierItem trayclient(service, path,
87 QDBusConnection::sessionBus());
88 if (trayclient.isValid()) {
89 m_registeredServices.append(notifierItemId);
90 m_serviceWatcher->addWatchedService(service);
91 emit StatusNotifierItemRegistered(notifierItemId);
92 }
93 }
94}
95
96QStringList StatusNotifierWatcher::RegisteredStatusNotifierItems() const
97{
98 return m_registeredServices;
99}
100
101
102void StatusNotifierWatcher::serviceUnregistered(const QString& name)
103{
104 kDebug()<<"Service "<< name << "unregistered";
105 m_serviceWatcher->removeWatchedService(name);
106
107 QString match = name + '/';
108 QStringList::Iterator it = m_registeredServices.begin();
109 while (it != m_registeredServices.end()) {
110 if (it->startsWith(match)) {
111 QString name = *it;
112 it = m_registeredServices.erase(it);
113 emit StatusNotifierItemUnregistered(name);
114 } else {
115 ++it;
116 }
117 }
118
119 if (m_statusNotifierHostServices.contains(name)) {
120 m_statusNotifierHostServices.remove(name);
121 emit StatusNotifierHostUnregistered();
122 }
123}
124
125void StatusNotifierWatcher::RegisterStatusNotifierHost(const QString &service)
126{
127 if (service.contains("org.kde.StatusNotifierHost-") &&
128 QDBusConnection::sessionBus().interface()->isServiceRegistered(service).value() &&
129 !m_statusNotifierHostServices.contains(service)) {
130 kDebug()<<"Registering"<<service<<"as system tray";
131
132 m_statusNotifierHostServices.insert(service);
133 m_serviceWatcher->addWatchedService(service);
134 emit StatusNotifierHostRegistered();
135 }
136}
137
138bool StatusNotifierWatcher::IsStatusNotifierHostRegistered() const
139{
140 return !m_statusNotifierHostServices.isEmpty();
141}
142
143int StatusNotifierWatcher::ProtocolVersion() const
144{
145 return 0;
146}
147
148#include "statusnotifierwatcher.moc"
149