modernize: Use ranged-for loops in some obvious cases
[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 <QApplication>
28 #include <QDBusConnection>
29 #include <QImage>
30 #include <QMenu>
31 #include <QPixmap>
32
33 #include "statusnotifierwatcher.h"
34 #include "statusnotifieritemadaptor.h"
35
36 #ifdef Q_OS_WIN64
37 __inline int toInt(WId wid)
38 {
39     return (int)((__int64)wid);
40 }
41
42 #else
43 __inline int toInt(WId wid)
44 {
45     return (int)wid;
46 }
47
48
49 #endif
50
51 // Marshall the ImageStruct data into a D-BUS argument
52 const QDBusArgument &operator<<(QDBusArgument &argument, const DBusImageStruct &icon)
53 {
54     argument.beginStructure();
55     argument << icon.width;
56     argument << icon.height;
57     argument << icon.data;
58     argument.endStructure();
59     return argument;
60 }
61
62
63 // Retrieve the ImageStruct data from the D-BUS argument
64 const QDBusArgument &operator>>(const QDBusArgument &argument, DBusImageStruct &icon)
65 {
66     qint32 width;
67     qint32 height;
68     QByteArray data;
69
70     argument.beginStructure();
71     argument >> width;
72     argument >> height;
73     argument >> data;
74     argument.endStructure();
75
76     icon.width = width;
77     icon.height = height;
78     icon.data = data;
79
80     return argument;
81 }
82
83
84 // Marshall the ImageVector data into a D-BUS argument
85 const QDBusArgument &operator<<(QDBusArgument &argument, const DBusImageVector &iconVector)
86 {
87     argument.beginArray(qMetaTypeId<DBusImageStruct>());
88     for (const auto &i : iconVector) {
89         argument << i;
90     }
91     argument.endArray();
92     return argument;
93 }
94
95
96 // Retrieve the ImageVector data from the D-BUS argument
97 const QDBusArgument &operator>>(const QDBusArgument &argument, DBusImageVector &iconVector)
98 {
99     argument.beginArray();
100     iconVector.clear();
101
102     while (!argument.atEnd()) {
103         DBusImageStruct element;
104         argument >> element;
105         iconVector.append(element);
106     }
107
108     argument.endArray();
109
110     return argument;
111 }
112
113
114 // Marshall the ToolTipStruct data into a D-BUS argument
115 const QDBusArgument &operator<<(QDBusArgument &argument, const DBusToolTipStruct &toolTip)
116 {
117     argument.beginStructure();
118     argument << toolTip.icon;
119     argument << toolTip.image;
120     argument << toolTip.title;
121     argument << toolTip.subTitle;
122     argument.endStructure();
123     return argument;
124 }
125
126
127 // Retrieve the ToolTipStruct data from the D-BUS argument
128 const QDBusArgument &operator>>(const QDBusArgument &argument, DBusToolTipStruct &toolTip)
129 {
130     QString icon;
131     DBusImageVector image;
132     QString title;
133     QString subTitle;
134
135     argument.beginStructure();
136     argument >> icon;
137     argument >> image;
138     argument >> title;
139     argument >> subTitle;
140     argument.endStructure();
141
142     toolTip.icon = icon;
143     toolTip.image = image;
144     toolTip.title = title;
145     toolTip.subTitle = subTitle;
146
147     return argument;
148 }
149
150
151 int StatusNotifierItemDBus::s_serviceCount = 0;
152
153 StatusNotifierItemDBus::StatusNotifierItemDBus(StatusNotifierItem *parent)
154     : QObject(parent),
155     m_statusNotifierItem(parent),
156     m_dbus(QDBusConnection::connectToBus(QDBusConnection::SessionBus,
157                                          QString("org.kde.StatusNotifierItem-%1-%2").arg(QCoreApplication::applicationPid()).arg(++s_serviceCount)))
158 {
159     new StatusNotifierItemAdaptor(this);
160 }
161
162
163 StatusNotifierItemDBus::~StatusNotifierItemDBus()
164 {
165     unregisterTrayIcon();
166 }
167
168
169 QDBusConnection StatusNotifierItemDBus::dbusConnection() const
170 {
171     return m_dbus;
172 }
173
174
175 // FIXME: prevent double registrations, also test this on platforms != KDE
176 //
177 void StatusNotifierItemDBus::registerTrayIcon()
178 {
179     m_dbus.registerObject("/StatusNotifierItem", this);
180 }
181
182
183 // FIXME: see above
184 void StatusNotifierItemDBus::unregisterTrayIcon()
185 {
186     if (m_dbus.isConnected()) {
187         m_dbus.unregisterObject("/StatusNotifierItem");
188     }
189 }
190
191
192 QString StatusNotifierItemDBus::service() const
193 {
194     return m_dbus.baseService();
195 }
196
197
198 //DBUS slots
199 //Values and calls have been adapted to Quassel
200
201 QString StatusNotifierItemDBus::Category() const
202 {
203     return QString("Communications"); // no need to make this configurable for Quassel
204 }
205
206
207 QString StatusNotifierItemDBus::Title() const
208 {
209     return m_statusNotifierItem->title();
210 }
211
212
213 QString StatusNotifierItemDBus::Id() const
214 {
215     return QString("QuasselIRC");
216 }
217
218
219 QString StatusNotifierItemDBus::Status() const
220 {
221     return m_statusNotifierItem->metaObject()->enumerator(m_statusNotifierItem->metaObject()->indexOfEnumerator("State")).valueToKey(m_statusNotifierItem->state());
222 }
223
224
225 int StatusNotifierItemDBus::WindowId() const
226 {
227     return toInt(QtUi::mainWindow()->winId());
228 }
229
230
231 //Icon
232 //We don't need to support serialized icon data in Quassel
233
234 QString StatusNotifierItemDBus::IconName() const
235 {
236     return m_statusNotifierItem->iconName();
237 }
238
239
240 DBusImageVector StatusNotifierItemDBus::IconPixmap() const
241 {
242     return DBusImageVector();
243 }
244
245
246 QString StatusNotifierItemDBus::OverlayIconName() const
247 {
248     return QString();
249 }
250
251
252 DBusImageVector StatusNotifierItemDBus::OverlayIconPixmap() const
253 {
254     return DBusImageVector();
255 }
256
257
258 //Requesting attention icon and movie
259
260 QString StatusNotifierItemDBus::AttentionIconName() const
261 {
262     return m_statusNotifierItem->attentionIconName();
263 }
264
265
266 DBusImageVector StatusNotifierItemDBus::AttentionIconPixmap() const
267 {
268     return DBusImageVector();
269 }
270
271
272 QString StatusNotifierItemDBus::AttentionMovieName() const
273 {
274     return QString();
275 }
276
277
278 //ToolTip
279
280 DBusToolTipStruct StatusNotifierItemDBus::ToolTip() const
281 {
282     DBusToolTipStruct toolTip;
283     toolTip.icon = m_statusNotifierItem->toolTipIconName();
284     toolTip.image = DBusImageVector();
285     toolTip.title = m_statusNotifierItem->toolTipTitle();
286     toolTip.subTitle = m_statusNotifierItem->toolTipSubTitle();
287
288     return toolTip;
289 }
290
291
292 QString StatusNotifierItemDBus::IconThemePath() const
293 {
294     return m_statusNotifierItem->iconThemePath();
295 }
296
297
298 //Menu
299
300 QDBusObjectPath StatusNotifierItemDBus::Menu() const
301 {
302     return QDBusObjectPath(m_statusNotifierItem->menuObjectPath());
303 }
304
305
306 //Interaction
307
308 void StatusNotifierItemDBus::ContextMenu(int x, int y)
309 {
310     if (!m_statusNotifierItem->trayMenu()) {
311         return;
312     }
313
314     //TODO: nicer placement, possible?
315     if (!m_statusNotifierItem->trayMenu()->isVisible()) {
316         m_statusNotifierItem->trayMenu()->popup(QPoint(x, y));
317     }
318     else {
319         m_statusNotifierItem->trayMenu()->hide();
320     }
321 }
322
323
324 void StatusNotifierItemDBus::Activate(int x, int y)
325 {
326     m_statusNotifierItem->activated(QPoint(x, y));
327 }
328
329
330 void StatusNotifierItemDBus::SecondaryActivate(int x, int y)
331 {
332     Q_UNUSED(x)
333     Q_UNUSED(y)
334     // emit m_statusNotifierItem->secondaryActivateRequested(QPoint(x,y));
335 }
336
337
338 void StatusNotifierItemDBus::Scroll(int delta, const QString &orientation)
339 {
340     Q_UNUSED(delta)
341     Q_UNUSED(orientation)
342     // Qt::Orientation dir = (orientation.toLower() == "horizontal" ? Qt::Horizontal : Qt::Vertical);
343     // emit m_statusNotifierItem->scrollRequested(delta, dir);
344 }