1/***************************************************************************
2 * Copyright (C) 2005-2014 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 <QApplication>
22#include <QCheckBox>
23#include <QGroupBox>
24#include <QHBoxLayout>
25
26#include "systraynotificationbackend.h"
27
28#include "client.h"
29#include "clientsettings.h"
30#include "icon.h"
31#include "iconloader.h"
32#include "mainwin.h"
33#include "networkmodel.h"
34#include "qtui.h"
35#include "systemtray.h"
36
37SystrayNotificationBackend::SystrayNotificationBackend(QObject *parent)
38 : AbstractNotificationBackend(parent),
39 _blockActivation(false)
40{
41 NotificationSettings notificationSettings;
42 notificationSettings.initAndNotify("Systray/ShowBubble", this, SLOT(showBubbleChanged(QVariant)), true);
43 notificationSettings.initAndNotify("Systray/Animate", this, SLOT(animateChanged(QVariant)), true);
44
45 connect(QtUi::mainWindow()->systemTray(), SIGNAL(messageClicked(uint)), SLOT(notificationActivated(uint)));
46 connect(QtUi::mainWindow()->systemTray(), SIGNAL(activated(SystemTray::ActivationReason)),
47 SLOT(notificationActivated(SystemTray::ActivationReason)));
48
49 QApplication::instance()->installEventFilter(this);
50
51 updateToolTip();
52}
53
54
55void SystrayNotificationBackend::notify(const Notification &n)
56{
57 if (n.type != Highlight && n.type != PrivMsg)
58 return;
59
60 _notifications.append(n);
61 if (_showBubble) {
62 QString title = Client::networkModel()->networkName(n.bufferId) + " - " + Client::networkModel()->bufferName(n.bufferId);
63 QString message = QString("<%1> %2").arg(n.sender, n.message);
64 QtUi::mainWindow()->systemTray()->showMessage(title, message, SystemTray::Information, 10000, n.notificationId);
65 }
66
67 if (_animate)
68 QtUi::mainWindow()->systemTray()->setAlert(true);
69
70 updateToolTip();
71}
72
73
74void SystrayNotificationBackend::close(uint notificationId)
75{
76 QList<Notification>::iterator i = _notifications.begin();
77 while (i != _notifications.end()) {
78 if (i->notificationId == notificationId)
79 i = _notifications.erase(i);
80 else
81 ++i;
82 }
83
84 QtUi::mainWindow()->systemTray()->closeMessage(notificationId);
85
86 //if(!_notifications.count()) //FIXME make configurable
87 QtUi::mainWindow()->systemTray()->setAlert(false);
88
89 updateToolTip();
90}
91
92
93void SystrayNotificationBackend::notificationActivated(uint notificationId)
94{
95 if (!_blockActivation) {
96 if (_notifications.count()) {
97 if (QtUi::mainWindow()->systemTray()->mode() == SystemTray::Legacy)
98 _blockActivation = true; // prevent double activation because both tray icon and bubble might send a signal
99 if (!notificationId)
100 notificationId = _notifications.count() ? _notifications.last().notificationId : 0;
101 emit activated(notificationId);
102 }
103 else
104 GraphicalUi::toggleMainWidget();
105 }
106}
107
108
109void SystrayNotificationBackend::notificationActivated(SystemTray::ActivationReason reason)
110{
111 if (reason == SystemTray::Trigger) {
112 notificationActivated(0);
113 }
114}
115
116
117// moving the mouse or releasing the button means that we're not dealing with a double activation
118bool SystrayNotificationBackend::eventFilter(QObject *obj, QEvent *event)
119{
120 if (event->type() == QEvent::MouseMove || event->type() == QEvent::MouseButtonRelease) {
121 _blockActivation = false;
122 }
123 return AbstractNotificationBackend::eventFilter(obj, event);
124}
125
126
127void SystrayNotificationBackend::showBubbleChanged(const QVariant &v)
128{
129 _showBubble = v.toBool();
130}
131
132
133void SystrayNotificationBackend::animateChanged(const QVariant &v)
134{
135 _animate = v.toBool();
136}
137
138
139void SystrayNotificationBackend::updateToolTip()
140{
141 QtUi::mainWindow()->systemTray()->setToolTip("Quassel IRC",
142 _notifications.count() ? tr("%n pending highlight(s)", "", _notifications.count()) : QString());
143}
144
145
146SettingsPage *SystrayNotificationBackend::createConfigWidget() const
147{
148 return new ConfigWidget();
149}
150
151
152/***************************************************************************/
153
154SystrayNotificationBackend::ConfigWidget::ConfigWidget(QWidget *parent) : SettingsPage("Internal", "SystrayNotification", parent)
155{
156 _showBubbleBox = new QCheckBox(tr("Show a message in a popup"));
157 _showBubbleBox->setIcon(SmallIcon("dialog-information"));
158 connect(_showBubbleBox, SIGNAL(toggled(bool)), this, SLOT(widgetChanged()));
159 QHBoxLayout *layout = new QHBoxLayout(this);
160 layout->addWidget(_showBubbleBox);
161}
162
163
164void SystrayNotificationBackend::ConfigWidget::widgetChanged()
165{
166 bool changed = (_showBubble != _showBubbleBox->isChecked());
167 if (changed != hasChanged())
168 setChangedState(changed);
169}
170
171
172bool SystrayNotificationBackend::ConfigWidget::hasDefaults() const
173{
174 return true;
175}
176
177
178void SystrayNotificationBackend::ConfigWidget::defaults()
179{
180 _showBubbleBox->setChecked(false);
181 widgetChanged();
182}
183
184
185void SystrayNotificationBackend::ConfigWidget::load()
186{
187 NotificationSettings s;
188 _showBubble = s.value("Systray/ShowBubble", false).toBool();
189 _showBubbleBox->setChecked(_showBubble);
190 setChangedState(false);
191}
192
193
194void SystrayNotificationBackend::ConfigWidget::save()
195{
196 NotificationSettings s;
197 s.setValue("Systray/ShowBubble", _showBubbleBox->isChecked());
198 load();
199}
200