e3cb0e311eada9876f4493e0c4ee4cc36992696f
[quassel.git] / src / qtui / indicatornotificationbackend.cpp
1 /***************************************************************************
2  *   Copyright (C) 2005-09 Canonical Ltd                                   *
3  *   author: aurelien.gateau@canonical.com                                 *
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 "indicatornotificationbackend.h"
22
23 #include <QIcon>
24 #include <QImage>
25
26 #include <qindicateserver.h>
27 #include <qindicateindicator.h>
28
29 #include "client.h"
30 #include "clientsettings.h"
31 #include "mainwin.h"
32 #include "networkmodel.h"
33 #include "qtui.h"
34
35 #define STR(x) #x
36 #define XSTR(x) STR(x)
37
38 class Indicator : public QIndicate::Indicator
39 {
40 public:
41     uint lastNotificationId;
42 };
43
44
45 IndicatorNotificationBackend::IndicatorNotificationBackend(QObject *parent)
46     : AbstractNotificationBackend(parent)
47 {
48     NotificationSettings notificationSettings;
49     _enabled = notificationSettings.value("Indicator/Enabled", false).toBool();
50
51     notificationSettings.notify("Indicator/Enabled", this, SLOT(enabledChanged(const QVariant &)));
52
53     _server = QIndicate::Server::defaultInstance();
54     _server->setType("message.irc");
55     QString desktopFile = QString("%1/%2.desktop")
56                           .arg(XSTR(XDG_APPS_INSTALL_DIR))
57                           .arg(QCoreApplication::applicationFilePath().section('/', -1));
58     _server->setDesktopFile(desktopFile);
59     connect(_server, SIGNAL(serverDisplay()), SLOT(activateMainWidget()));
60
61     if (_enabled) {
62         _server->show();
63     }
64 }
65
66
67 IndicatorNotificationBackend::~IndicatorNotificationBackend()
68 {
69     qDeleteAll(_indicatorHash);
70 }
71
72
73 void IndicatorNotificationBackend::activateMainWidget()
74 {
75     GraphicalUi::activateMainWidget();
76 }
77
78
79 void IndicatorNotificationBackend::notify(const Notification &notification)
80 {
81     if (!_enabled) {
82         return;
83     }
84     if (notification.type != Highlight && notification.type != PrivMsg) {
85         return;
86     }
87     BufferId bufferId = notification.bufferId;
88     Indicator *indicator = _indicatorHash.value(bufferId);
89     if (!indicator) {
90         indicator = new Indicator;
91         _indicatorHash.insert(bufferId, indicator);
92         connect(indicator, SIGNAL(display(QIndicate::Indicator *)),
93             SLOT(indicatorDisplayed(QIndicate::Indicator *)));
94     }
95     indicator->lastNotificationId = notification.notificationId;
96
97     BufferInfo::Type type = Client::networkModel()->bufferType(bufferId);
98     QString name;
99     if (type == BufferInfo::QueryBuffer) {
100         name = notification.sender;
101     }
102     else {
103         name = QString("%1 (%2)")
104                .arg(Client::networkModel()->bufferName(bufferId))
105                .arg(notification.sender);
106     }
107     indicator->setNameProperty(name);
108
109     indicator->setTimeProperty(QDateTime::currentDateTime());
110
111     QModelIndex index = Client::networkModel()->bufferIndex(bufferId);
112     QVariant icon = QtUi::style()->bufferViewItemData(index, Qt::DecorationRole);
113     if (icon.canConvert<QIcon>()) {
114         QImage image = icon.value<QIcon>().pixmap(16).toImage();
115         indicator->setIconProperty(image);
116     }
117
118     indicator->setDrawAttentionProperty(true);
119     indicator->show();
120 }
121
122
123 void IndicatorNotificationBackend::close(uint notificationId)
124 {
125     // If we find an indicator whose lastNotificationId is notificationId, we
126     // delete it
127
128     IndicatorHash::Iterator
129         it = _indicatorHash.begin(),
130         end = _indicatorHash.end();
131     for (; it != end; ++it) {
132         if (it.value()->lastNotificationId == notificationId) {
133             break;
134         }
135     }
136     if (it == end) {
137         // Not found, maybe there was no indicator for this notification or another
138         // notification happened after
139         return;
140     }
141     _indicatorHash.erase(it);
142     delete it.value();
143 }
144
145
146 void IndicatorNotificationBackend::enabledChanged(const QVariant &v)
147 {
148     _enabled = v.toBool();
149     if (_enabled) {
150         _server->show();
151         // TODO: Create indicators for existing highlighted buffers?
152     }
153     else {
154         _server->hide();
155         qDeleteAll(_indicatorHash);
156     }
157 }
158
159
160 void IndicatorNotificationBackend::indicatorDisplayed(QIndicate::Indicator *_indicator)
161 {
162     Indicator *indicator = static_cast<Indicator *>(_indicator);
163     emit activated(indicator->lastNotificationId);
164 }
165
166
167 SettingsPage *IndicatorNotificationBackend::createConfigWidget() const
168 {
169     return new ConfigWidget();
170 }
171
172
173 /***************************************************************************/
174
175 IndicatorNotificationBackend::ConfigWidget::ConfigWidget(QWidget *parent)
176     : SettingsPage("Internal", "IndicatorNotification", parent)
177 {
178     ui.setupUi(this);
179     // FIXME find proper icon (this one is used by the plasmoid as well)
180     ui.enabled->setIcon(QIcon::fromTheme("mail-message-new"));
181
182     connect(ui.enabled, SIGNAL(toggled(bool)), SLOT(widgetChanged()));
183 }
184
185
186 IndicatorNotificationBackend::ConfigWidget::~ConfigWidget()
187 {
188 }
189
190
191 void IndicatorNotificationBackend::ConfigWidget::widgetChanged()
192 {
193     bool changed = enabled != ui.enabled->isChecked();
194
195     if (changed != hasChanged()) setChangedState(changed);
196 }
197
198
199 bool IndicatorNotificationBackend::ConfigWidget::hasDefaults() const
200 {
201     return true;
202 }
203
204
205 void IndicatorNotificationBackend::ConfigWidget::defaults()
206 {
207     ui.enabled->setChecked(false);
208     widgetChanged();
209 }
210
211
212 void IndicatorNotificationBackend::ConfigWidget::load()
213 {
214     NotificationSettings s;
215     enabled = s.value("Indicator/Enabled", false).toBool();
216
217     ui.enabled->setChecked(enabled);
218     setChangedState(false);
219 }
220
221
222 void IndicatorNotificationBackend::ConfigWidget::save()
223 {
224     NotificationSettings s;
225     s.setValue("Indicator/Enabled", ui.enabled->isChecked());
226     load();
227 }