ac2d7732a3fa4b7b0651870e1fb18a842aa1fc56
[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 General Public License as published by  *
8  *   the Free Software Foundation; either version 2 of the License, or     *
9  *   (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  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, 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 // Marshall the ImageStruct data into a D-BUS argument
43 const QDBusArgument &operator<<(QDBusArgument &argument, const DBusImageStruct &icon)
44 {
45     argument.beginStructure();
46     argument << icon.width;
47     argument << icon.height;
48     argument << icon.data;
49     argument.endStructure();
50     return argument;
51 }
52
53 // Retrieve the ImageStruct data from the D-BUS argument
54 const QDBusArgument &operator>>(const QDBusArgument &argument, DBusImageStruct &icon)
55 {
56     qint32 width;
57     qint32 height;
58     QByteArray data;
59
60     argument.beginStructure();
61     argument >> width;
62     argument >> height;
63     argument >> data;
64     argument.endStructure();
65
66     icon.width = width;
67     icon.height = height;
68     icon.data = data;
69
70     return argument;
71 }
72
73
74 // Marshall the ImageVector data into a D-BUS argument
75 const QDBusArgument &operator<<(QDBusArgument &argument, const DBusImageVector &iconVector)
76 {
77     argument.beginArray(qMetaTypeId<DBusImageStruct>());
78     for (int i=0; i<iconVector.size(); ++i) {
79         argument << iconVector[i];
80     }
81     argument.endArray();
82     return argument;
83 }
84
85 // Retrieve the ImageVector data from the D-BUS argument
86 const QDBusArgument &operator>>(const QDBusArgument &argument, DBusImageVector &iconVector)
87 {
88     argument.beginArray();
89     iconVector.clear();
90
91     while ( !argument.atEnd() ) {
92        DBusImageStruct element;
93        argument >> element;
94        iconVector.append(element);
95     }
96
97     argument.endArray();
98
99
100     return argument;
101 }
102
103 // Marshall the ToolTipStruct data into a D-BUS argument
104 const QDBusArgument &operator<<(QDBusArgument &argument, const DBusToolTipStruct &toolTip)
105 {
106     argument.beginStructure();
107     argument << toolTip.icon;
108     argument << toolTip.image;
109     argument << toolTip.title;
110     argument << toolTip.subTitle;
111     argument.endStructure();
112     return argument;
113 }
114
115 // Retrieve the ToolTipStruct data from the D-BUS argument
116 const QDBusArgument &operator>>(const QDBusArgument &argument, DBusToolTipStruct &toolTip)
117 {
118     QString icon;
119     DBusImageVector image;
120     QString title;
121     QString subTitle;
122
123     argument.beginStructure();
124     argument >> icon;
125     argument >> image;
126     argument >> title;
127     argument >> subTitle;
128     argument.endStructure();
129
130     toolTip.icon = icon;
131     toolTip.image = image;
132     toolTip.title = title;
133     toolTip.subTitle = subTitle;
134
135     return argument;
136 }
137
138
139 int StatusNotifierItemDBus::s_serviceCount = 0;
140
141 StatusNotifierItemDBus::StatusNotifierItemDBus(StatusNotifierItem *parent)
142   : QObject(parent),
143     m_statusNotifierItem(parent),
144     m_service(QString("org.kde.StatusNotifierItem-%1-%2")
145                       .arg(QCoreApplication::applicationPid())
146                       .arg(++s_serviceCount)),
147     m_dbus(QDBusConnection::connectToBus(QDBusConnection::SessionBus, m_service))
148 {
149    new StatusNotifierItemAdaptor(this);
150    qDebug() << "service is" << m_service;
151    m_dbus.registerService(m_service);
152    m_dbus.registerObject("/StatusNotifierItem", this);
153 }
154
155 StatusNotifierItemDBus::~StatusNotifierItemDBus()
156 {
157     m_dbus.unregisterService(m_service);
158 }
159
160 QString StatusNotifierItemDBus::service() const
161 {
162     return m_service;
163 }
164
165 //DBUS slots
166 //Values and calls have been adapted to Quassel
167
168 QString StatusNotifierItemDBus::Category() const
169 {
170     return QString("Communications"); // no need to make this configurable for Quassel
171 }
172
173 QString StatusNotifierItemDBus::Title() const
174 {
175     return m_statusNotifierItem->title();
176 }
177
178 QString StatusNotifierItemDBus::Id() const
179 {
180     return QString("QuasselIRC");
181 }
182
183 QString StatusNotifierItemDBus::Status() const
184  {
185     return m_statusNotifierItem->metaObject()->enumerator(m_statusNotifierItem->metaObject()->indexOfEnumerator("State")).valueToKey(m_statusNotifierItem->state());
186 }
187
188 int StatusNotifierItemDBus::WindowId() const
189 {
190     return (int)QtUi::mainWindow()->winId();
191 }
192
193
194 //Icon
195 //We don't need to support serialized icon data in Quassel
196
197 QString StatusNotifierItemDBus::IconName() const
198 {
199     return m_statusNotifierItem->iconName();
200 }
201
202 DBusImageVector StatusNotifierItemDBus::IconPixmap() const
203 {
204     return DBusImageVector();
205 }
206
207 QString StatusNotifierItemDBus::OverlayIconName() const
208 {
209     return QString();
210 }
211
212 DBusImageVector StatusNotifierItemDBus::OverlayIconPixmap() const
213 {
214     return DBusImageVector();
215 }
216
217 //Requesting attention icon and movie
218
219 QString StatusNotifierItemDBus::AttentionIconName() const
220 {
221     return m_statusNotifierItem->attentionIconName();
222 }
223
224 DBusImageVector StatusNotifierItemDBus::AttentionIconPixmap() const
225 {
226     return DBusImageVector();
227 }
228
229 QString StatusNotifierItemDBus::AttentionMovieName() const
230 {
231     return QString();
232 }
233
234
235 //ToolTip
236
237 DBusToolTipStruct StatusNotifierItemDBus::ToolTip() const
238 {
239     DBusToolTipStruct toolTip;
240     toolTip.icon = m_statusNotifierItem->toolTipIconName();
241     toolTip.image = DBusImageVector();
242     toolTip.title = m_statusNotifierItem->toolTipTitle();
243     toolTip.subTitle = m_statusNotifierItem->toolTipSubTitle();
244
245     return toolTip;
246 }
247
248 //Interaction
249
250 void StatusNotifierItemDBus::ContextMenu(int x, int y)
251 {
252     if (!m_statusNotifierItem->trayMenu()) {
253         return;
254     }
255
256     //TODO: nicer placement, possible?
257     if (!m_statusNotifierItem->trayMenu()->isVisible()) {
258 #ifdef HAVE_KDE
259         m_statusNotifierItem->trayMenu()->setWindowFlags(Qt::Window|Qt::FramelessWindowHint);
260 #endif
261         m_statusNotifierItem->trayMenu()->popup(QPoint(x,y));
262 #ifdef HAVE_KDE
263         KWindowSystem::setState(m_statusNotifierItem->trayMenu()->winId(), NET::SkipTaskbar|NET::SkipPager|NET::KeepAbove);
264         KWindowSystem::setType(m_statusNotifierItem->trayMenu()->winId(), NET::PopupMenu);
265         KWindowSystem::forceActiveWindow(m_statusNotifierItem->trayMenu()->winId());
266 #endif
267     } else {
268         m_statusNotifierItem->trayMenu()->hide();
269     }
270 }
271
272 void StatusNotifierItemDBus::Activate(int x, int y)
273 {
274     m_statusNotifierItem->activated(QPoint(x,y));
275 }
276
277 void StatusNotifierItemDBus::SecondaryActivate(int x, int y)
278 {
279     Q_UNUSED(x)
280     Q_UNUSED(y)
281     // emit m_statusNotifierItem->secondaryActivateRequested(QPoint(x,y));
282 }
283
284 void StatusNotifierItemDBus::Scroll(int delta, const QString &orientation)
285 {
286     Q_UNUSED(delta)
287     Q_UNUSED(orientation)
288     // Qt::Orientation dir = (orientation.toLower() == "horizontal" ? Qt::Horizontal : Qt::Vertical);
289     // emit m_statusNotifierItem->scrollRequested(delta, dir);
290 }