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