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