qtui: Don't show config for DockManager if not available
[quassel.git] / src / qtui / dockmanagernotificationbackend.cpp
1 /***************************************************************************
2  *   Copyright (C) 2013-2018 by the Quassel Project                        *
3  *   devel@quassel-irc.org                                                 *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) version 3.                                           *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
19  ***************************************************************************/
20
21 #include "dockmanagernotificationbackend.h"
22
23 #include <QHBoxLayout>
24 #include <QCheckBox>
25 #include <QDBusReply>
26
27 #include "client.h"
28 #include "clientsettings.h"
29 #include "coreconnection.h"
30 #include "clientbacklogmanager.h"
31
32 DockManagerNotificationBackend::DockManagerNotificationBackend(QObject *parent)
33     : AbstractNotificationBackend(parent), _bus(QDBusConnection::sessionBus()), _dock(0), _item(0), _count(0)
34 {
35     NotificationSettings notificationSettings;
36     _enabled = notificationSettings.value("DockManager/Enabled", false).toBool();
37
38     notificationSettings.notify("DockManager/Enabled", this, SLOT(enabledChanged(const QVariant &)));
39
40     _dock = new QDBusInterface("net.launchpad.DockManager", "/net/launchpad/DockManager", "net.launchpad.DockManager", _bus, this);
41     if (_dock->isValid()) {
42         _bus.connect("net.launchpad.DockManager", "/net/launchpad/DockManager", "net.launchpad.DockManager", "ItemAdded", this, SLOT(itemAdded(QDBusObjectPath)));
43     } else {
44         // evil implementations (awn) use fd.o
45         _dock = new QDBusInterface("org.freedesktop.DockManager", "/org/freedesktop/DockManager", "org.freedesktop.DockManager", _bus, this);
46         if (_dock->isValid()) {
47             _bus.connect("org.freedesktop.DockManager", "/org/freedesktop/DockManager", "org.freedesktop.DockManager", "ItemAdded", this, SLOT(itemAdded(QDBusObjectPath)));
48         } else {
49             _available = _enabled = false;
50             return;
51         }
52     }
53     _available = true;
54
55     itemAdded(QDBusObjectPath());
56
57     connect(Client::coreConnection(), SIGNAL(progressValueChanged(int)), this, SLOT(updateProgress(int)));
58     connect(Client::coreConnection(), SIGNAL(synchronized()), this, SLOT(synchronized()));
59 }
60
61
62 void DockManagerNotificationBackend::itemAdded(QDBusObjectPath p)
63 {
64     Q_UNUSED(p);
65
66     if (_item)
67         return;
68
69     // stupid implementations (awn; kde?) use wrong casing of PID, but proper type
70     QDBusReply<QList<QDBusObjectPath> > paths = _dock->call("GetItemsByPid", (int)QCoreApplication::applicationPid());
71     if (!paths.isValid()) {
72         // stupid implementations (i.e. docky) use uint, but proper casing
73         paths = _dock->call("GetItemsByPID", (unsigned int)QCoreApplication::applicationPid());
74         if (!paths.isValid()) {
75             qDebug() << "DBus error:" << paths.error().message();
76             return;
77         }
78     }
79     if (paths.value().count() == 0) { // no icon for this instance
80         return;
81     }
82
83     QString path = paths.value()[0].path(); // no sense in using multiple icons for one instance
84     _item = new QDBusInterface("org.freedesktop.DockManager", path, "org.freedesktop.DockItem", _bus, this);
85 }
86
87
88 void DockManagerNotificationBackend::updateProgress(int progress)
89 {
90     if (!_enabled || !_item)
91         return;
92
93     CoreConnection *c = Client::instance()->coreConnection();
94     int perc = 0;
95     if (c->progressMaximum() == c->progressMinimum())
96         perc = 0;
97     else
98         perc = (progress - c->progressMinimum()) * 100 / (c->progressMaximum() - c->progressMinimum());
99
100     QHash<QString, QVariant> args;
101     args["progress"] = perc;
102     _item->call("UpdateDockItem", args);
103 }
104
105
106 void DockManagerNotificationBackend::updateProgress(int done, int total)
107 {
108     if (!_enabled || !_item)
109         return;
110
111     int perc = 0;
112     if (done == total) {
113         disconnect(Client::backlogManager(), 0, this, 0);
114         perc = -1;
115     } else
116         perc = (done * 100) / total;
117
118     QHash<QString, QVariant> args;
119     args["progress"] = perc;
120     _item->call("UpdateDockItem", args);
121 }
122
123
124 void DockManagerNotificationBackend::synchronized()
125 {
126     connect(Client::backlogManager(), SIGNAL(updateProgress(int, int)), this, SLOT(updateProgress(int, int)));
127 }
128
129
130 void DockManagerNotificationBackend::notify(const Notification &notification)
131 {
132     if (!_enabled || !_item) {
133         return;
134     }
135     if (notification.type != Highlight && notification.type != PrivMsg) {
136         return;
137     }
138
139     QHash<QString, QVariant> args;
140     args["attention"] = true;
141     args["badge"] = QString::number(++_count);
142     _item->call("UpdateDockItem", args);
143 }
144
145
146 void DockManagerNotificationBackend::close(uint notificationId)
147 {
148     Q_UNUSED(notificationId);
149     if (!_item)
150         return;
151
152     QHash<QString, QVariant> args;
153     args["attention"] = false;
154     args["badge"] = --_count == 0 ? QString() : QString::number(_count);
155     _item->call("UpdateDockItem", args);
156 }
157
158
159 void DockManagerNotificationBackend::enabledChanged(const QVariant &v)
160 {
161     _enabled = v.toBool();
162
163     if (!_enabled && _item) {
164         QHash<QString, QVariant> args;
165         args["attention"] = false;
166         args["badge"] = QString();
167         _item->call("UpdateDockItem", args);
168     }
169 }
170
171
172 SettingsPage *DockManagerNotificationBackend::createConfigWidget() const
173 {
174     return new ConfigWidget(_available);
175 }
176
177
178 /***************************************************************************/
179
180 DockManagerNotificationBackend::ConfigWidget::ConfigWidget(bool enabled, QWidget *parent)
181     : SettingsPage("Internal", "DockManagerNotification", parent)
182 {
183     QHBoxLayout *layout = new QHBoxLayout(this);
184     layout->addWidget(enabledBox = new QCheckBox(tr("Mark dockmanager entry"), this));
185     enabledBox->setVisible(enabled);
186
187     connect(enabledBox, SIGNAL(toggled(bool)), SLOT(widgetChanged()));
188 }
189
190
191 void DockManagerNotificationBackend::ConfigWidget::widgetChanged()
192 {
193     bool changed = enabled != enabledBox->isChecked();
194
195     if (changed != hasChanged()) setChangedState(changed);
196 }
197
198
199 bool DockManagerNotificationBackend::ConfigWidget::hasDefaults() const
200 {
201     return true;
202 }
203
204
205 void DockManagerNotificationBackend::ConfigWidget::defaults()
206 {
207     enabledBox->setChecked(false);
208     widgetChanged();
209 }
210
211
212 void DockManagerNotificationBackend::ConfigWidget::load()
213 {
214     NotificationSettings s;
215     enabled = s.value("DockManager/Enabled", false).toBool();
216
217     enabledBox->setChecked(enabled);
218     setChangedState(false);
219 }
220
221
222 void DockManagerNotificationBackend::ConfigWidget::save()
223 {
224     NotificationSettings s;
225     s.setValue("DockManager/Enabled", enabledBox->isChecked());
226     load();
227 }