Use QSslCertificate::isNull() instead of isValid() in IdentityEditWidget
[quassel.git] / src / qtui / statusnotifieritemdbus.cpp
1 /***************************************************************************
2  *   The original file is part of the KDE libraries                        *
3  *   Copyright (C) 2009 by Marco Martin <notmart@gmail.com>                *
4  *   Quasselfied 2010 by Manuel Nickschas <sputnick@quassel-irc.org>       *
5  *                                                                         *
6  *   This file is free software; you can redistribute it and/or modify     *
7  *   it under the terms of the GNU Library General Public License (LGPL)   *
8  *   as published by the Free Software Foundation; either version 2 of the *
9  *   License, or (at your option) any later version.                       *
10  *                                                                         *
11  *   This program is distributed in the hope that it will be useful,       *
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14  *   GNU General Public License for more details.                          *
15  *                                                                         *
16  *   You should have received a copy of the GNU General Public License     *
17  *   along with this program; if not, write to the                         *
18  *   Free Software Foundation, Inc.,                                       *
19  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
20  ***************************************************************************/
21
22 #include "mainwin.h"
23 #include "qtui.h"
24 #include "statusnotifieritemdbus.h"
25 #include "statusnotifieritem.h"
26
27 #include <QDBusConnection>
28 #include <QPixmap>
29 #include <QImage>
30 #include <QApplication>
31 #include <QMenu>
32 #include <QMovie>
33
34 #ifdef HAVE_KDE
35 #  include <KWindowInfo>
36 #  include <KWindowSystem>
37 #endif
38
39 #include "statusnotifierwatcher.h"
40 #include "statusnotifieritemadaptor.h"
41
42 #ifdef Q_OS_WIN64
43 __inline int toInt(WId wid)
44 {
45     return (int)((__int64)wid);
46 }
47
48
49 #else
50 __inline int toInt(WId wid)
51 {
52     return (int)wid;
53 }
54
55
56 #endif
57
58 // Marshall the ImageStruct data into a D-BUS argument
59 const QDBusArgument &operator<<(QDBusArgument &argument, const DBusImageStruct &icon)
60 {
61     argument.beginStructure();
62     argument << icon.width;
63     argument << icon.height;
64     argument << icon.data;
65     argument.endStructure();
66     return argument;
67 }
68
69
70 // Retrieve the ImageStruct data from the D-BUS argument
71 const QDBusArgument &operator>>(const QDBusArgument &argument, DBusImageStruct &icon)
72 {
73     qint32 width;
74     qint32 height;
75     QByteArray data;
76
77     argument.beginStructure();
78     argument >> width;
79     argument >> height;
80     argument >> data;
81     argument.endStructure();
82
83     icon.width = width;
84     icon.height = height;
85     icon.data = data;
86
87     return argument;
88 }
89
90
91 // Marshall the ImageVector data into a D-BUS argument
92 const QDBusArgument &operator<<(QDBusArgument &argument, const DBusImageVector &iconVector)
93 {
94     argument.beginArray(qMetaTypeId<DBusImageStruct>());
95     for (int i = 0; i < iconVector.size(); ++i) {
96         argument << iconVector[i];
97     }
98     argument.endArray();
99     return argument;
100 }
101
102
103 // Retrieve the ImageVector data from the D-BUS argument
104 const QDBusArgument &operator>>(const QDBusArgument &argument, DBusImageVector &iconVector)
105 {
106     argument.beginArray();
107     iconVector.clear();
108
109     while (!argument.atEnd()) {
110         DBusImageStruct element;
111         argument >> element;
112         iconVector.append(element);
113     }
114
115     argument.endArray();
116
117     return argument;
118 }
119
120
121 // Marshall the ToolTipStruct data into a D-BUS argument
122 const QDBusArgument &operator<<(QDBusArgument &argument, const DBusToolTipStruct &toolTip)
123 {
124     argument.beginStructure();
125     argument << toolTip.icon;
126     argument << toolTip.image;
127     argument << toolTip.title;
128     argument << toolTip.subTitle;
129     argument.endStructure();
130     return argument;
131 }
132
133
134 // Retrieve the ToolTipStruct data from the D-BUS argument
135 const QDBusArgument &operator>>(const QDBusArgument &argument, DBusToolTipStruct &toolTip)
136 {
137     QString icon;
138     DBusImageVector image;
139     QString title;
140     QString subTitle;
141
142     argument.beginStructure();
143     argument >> icon;
144     argument >> image;
145     argument >> title;
146     argument >> subTitle;
147     argument.endStructure();
148
149     toolTip.icon = icon;
150     toolTip.image = image;
151     toolTip.title = title;
152     toolTip.subTitle = subTitle;
153
154     return argument;
155 }
156
157
158 int StatusNotifierItemDBus::s_serviceCount = 0;
159
160 StatusNotifierItemDBus::StatusNotifierItemDBus(StatusNotifierItem *parent)
161     : QObject(parent),
162     m_statusNotifierItem(parent),
163     m_service(QString("org.kde.StatusNotifierItem-%1-%2")
164         .arg(QCoreApplication::applicationPid())
165         .arg(++s_serviceCount)),
166     m_dbus(QDBusConnection::connectToBus(QDBusConnection::SessionBus, m_service))
167 {
168     new StatusNotifierItemAdaptor(this);
169     //qDebug() << "service is" << m_service;
170     registerService();
171 }
172
173
174 StatusNotifierItemDBus::~StatusNotifierItemDBus()
175 {
176     unregisterService();
177 }
178
179
180 QDBusConnection StatusNotifierItemDBus::dbusConnection() const
181 {
182     return m_dbus;
183 }
184
185
186 // FIXME: prevent double registrations, also test this on platforms != KDE
187 //
188 void StatusNotifierItemDBus::registerService()
189 {
190     //qDebug() << "registering to" << m_service;
191     m_dbus.registerService(m_service);
192     m_dbus.registerObject("/StatusNotifierItem", this);
193 }
194
195
196 // FIXME: see above
197 void StatusNotifierItemDBus::unregisterService()
198 {
199     //qDebug() << "unregistering from" << m_service;
200     if (m_dbus.isConnected()) {
201         m_dbus.unregisterObject("/StatusNotifierItem");
202         m_dbus.unregisterService(m_service);
203     }
204 }
205
206
207 QString StatusNotifierItemDBus::service() const
208 {
209     return m_service;
210 }
211
212
213 //DBUS slots
214 //Values and calls have been adapted to Quassel
215
216 QString StatusNotifierItemDBus::Category() const
217 {
218     return QString("Communications"); // no need to make this configurable for Quassel
219 }
220
221
222 QString StatusNotifierItemDBus::Title() const
223 {
224     return m_statusNotifierItem->title();
225 }
226
227
228 QString StatusNotifierItemDBus::Id() const
229 {
230     return QString("QuasselIRC");
231 }
232
233
234 QString StatusNotifierItemDBus::Status() const
235 {
236     return m_statusNotifierItem->metaObject()->enumerator(m_statusNotifierItem->metaObject()->indexOfEnumerator("State")).valueToKey(m_statusNotifierItem->state());
237 }
238
239
240 int StatusNotifierItemDBus::WindowId() const
241 {
242     return toInt(QtUi::mainWindow()->winId());
243 }
244
245
246 //Icon
247 //We don't need to support serialized icon data in Quassel
248
249 QString StatusNotifierItemDBus::IconName() const
250 {
251     return m_statusNotifierItem->iconName();
252 }
253
254
255 DBusImageVector StatusNotifierItemDBus::IconPixmap() const
256 {
257     return DBusImageVector();
258 }
259
260
261 QString StatusNotifierItemDBus::OverlayIconName() const
262 {
263     return QString();
264 }
265
266
267 DBusImageVector StatusNotifierItemDBus::OverlayIconPixmap() const
268 {
269     return DBusImageVector();
270 }
271
272
273 //Requesting attention icon and movie
274
275 QString StatusNotifierItemDBus::AttentionIconName() const
276 {
277     return m_statusNotifierItem->attentionIconName();
278 }
279
280
281 DBusImageVector StatusNotifierItemDBus::AttentionIconPixmap() const
282 {
283     return DBusImageVector();
284 }
285
286
287 QString StatusNotifierItemDBus::AttentionMovieName() const
288 {
289     return QString();
290 }
291
292
293 //ToolTip
294
295 DBusToolTipStruct StatusNotifierItemDBus::ToolTip() const
296 {
297     DBusToolTipStruct toolTip;
298     toolTip.icon = m_statusNotifierItem->toolTipIconName();
299     toolTip.image = DBusImageVector();
300     toolTip.title = m_statusNotifierItem->toolTipTitle();
301     toolTip.subTitle = m_statusNotifierItem->toolTipSubTitle();
302
303     return toolTip;
304 }
305
306
307 QString StatusNotifierItemDBus::IconThemePath() const
308 {
309     return m_statusNotifierItem->iconThemePath();
310 }
311
312
313 //Menu
314
315 QDBusObjectPath StatusNotifierItemDBus::Menu() const
316 {
317     return QDBusObjectPath(m_statusNotifierItem->menuObjectPath());
318 }
319
320
321 //Interaction
322
323 void StatusNotifierItemDBus::ContextMenu(int x, int y)
324 {
325     if (!m_statusNotifierItem->trayMenu()) {
326         return;
327     }
328
329     //TODO: nicer placement, possible?
330     if (!m_statusNotifierItem->trayMenu()->isVisible()) {
331 #ifdef HAVE_KDE
332         m_statusNotifierItem->trayMenu()->setWindowFlags(Qt::Window|Qt::FramelessWindowHint);
333 #endif
334         m_statusNotifierItem->trayMenu()->popup(QPoint(x, y));
335 #ifdef HAVE_KDE
336         KWindowSystem::setState(m_statusNotifierItem->trayMenu()->winId(), NET::SkipTaskbar|NET::SkipPager|NET::KeepAbove);
337         KWindowSystem::setType(m_statusNotifierItem->trayMenu()->winId(), NET::PopupMenu);
338         KWindowSystem::forceActiveWindow(m_statusNotifierItem->trayMenu()->winId());
339 #endif
340     }
341     else {
342         m_statusNotifierItem->trayMenu()->hide();
343     }
344 }
345
346
347 void StatusNotifierItemDBus::Activate(int x, int y)
348 {
349     m_statusNotifierItem->activated(QPoint(x, y));
350 }
351
352
353 void StatusNotifierItemDBus::SecondaryActivate(int x, int y)
354 {
355     Q_UNUSED(x)
356     Q_UNUSED(y)
357     // emit m_statusNotifierItem->secondaryActivateRequested(QPoint(x,y));
358 }
359
360
361 void StatusNotifierItemDBus::Scroll(int delta, const QString &orientation)
362 {
363     Q_UNUSED(delta)
364     Q_UNUSED(orientation)
365     // Qt::Orientation dir = (orientation.toLower() == "horizontal" ? Qt::Horizontal : Qt::Vertical);
366     // emit m_statusNotifierItem->scrollRequested(delta, dir);
367 }