Make the UI actually emit the required signal
[quassel.git] / src / qtui / qtui.cpp
1 /***************************************************************************
2  *   Copyright (C) 2005-2016 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 "qtui.h"
22
23 #include "abstractnotificationbackend.h"
24 #include "buffermodel.h"
25 #include "chatlinemodel.h"
26 #include "contextmenuactionprovider.h"
27 #include "mainwin.h"
28 #include "qtuimessageprocessor.h"
29 #include "qtuisettings.h"
30 #include "qtuistyle.h"
31 #include "systemtray.h"
32 #include "toolbaractionprovider.h"
33 #include "types.h"
34 #include "util.h"
35
36 #ifdef Q_WS_X11
37 #  include <QX11Info>
38 #endif
39
40 QtUi *QtUi::_instance = 0;
41 MainWin *QtUi::_mainWin = 0;
42 QList<AbstractNotificationBackend *> QtUi::_notificationBackends;
43 QList<AbstractNotificationBackend::Notification> QtUi::_notifications;
44
45 QtUi::QtUi() : GraphicalUi()
46 {
47     if (_instance != 0) {
48         qWarning() << "QtUi has been instantiated again!";
49         return;
50     }
51     _instance = this;
52
53     QtUiSettings uiSettings;
54     Quassel::loadTranslation(uiSettings.value("Locale", QLocale::system()).value<QLocale>());
55
56     setContextMenuActionProvider(new ContextMenuActionProvider(this));
57     setToolBarActionProvider(new ToolBarActionProvider(this));
58
59     setUiStyle(new QtUiStyle(this));
60     _mainWin = new MainWin();
61
62     setMainWidget(_mainWin);
63
64     connect(_mainWin, SIGNAL(connectToCore(const QVariantMap &)), this, SIGNAL(connectToCore(const QVariantMap &)));
65     connect(_mainWin, SIGNAL(disconnectFromCore()), this, SIGNAL(disconnectFromCore()));
66     connect(Client::instance(), SIGNAL(bufferMarkedAsRead(BufferId)), SLOT(closeNotifications(BufferId)));
67 }
68
69
70 QtUi::~QtUi()
71 {
72     unregisterAllNotificationBackends();
73     delete _mainWin;
74     _mainWin = 0;
75     _instance = 0;
76 }
77
78
79 void QtUi::init()
80 {
81     _mainWin->init();
82     QtUiSettings uiSettings;
83     uiSettings.initAndNotify("UseSystemTrayIcon", this, SLOT(useSystemTrayChanged(QVariant)), true);
84
85     GraphicalUi::init(); // needs to be called after the mainWin is initialized
86 }
87
88
89 MessageModel *QtUi::createMessageModel(QObject *parent)
90 {
91     return new ChatLineModel(parent);
92 }
93
94
95 AbstractMessageProcessor *QtUi::createMessageProcessor(QObject *parent)
96 {
97     return new QtUiMessageProcessor(parent);
98 }
99
100
101 void QtUi::connectedToCore()
102 {
103     _mainWin->connectedToCore();
104 }
105
106
107 void QtUi::disconnectedFromCore()
108 {
109     _mainWin->disconnectedFromCore();
110     GraphicalUi::disconnectedFromCore();
111 }
112
113
114 void QtUi::useSystemTrayChanged(const QVariant &v)
115 {
116     _useSystemTray = v.toBool();
117     SystemTray *tray = mainWindow()->systemTray();
118     if (_useSystemTray) {
119         if (tray->isSystemTrayAvailable())
120             tray->setVisible(true);
121     }
122     else {
123         if (tray->isSystemTrayAvailable() && mainWindow()->isVisible())
124             tray->setVisible(false);
125     }
126 }
127
128
129 bool QtUi::haveSystemTray()
130 {
131     return mainWindow()->systemTray()->isSystemTrayAvailable() && instance()->_useSystemTray;
132 }
133
134
135 bool QtUi::isHidingMainWidgetAllowed() const
136 {
137     return haveSystemTray();
138 }
139
140
141 void QtUi::minimizeRestore(bool show)
142 {
143     SystemTray *tray = mainWindow()->systemTray();
144     if (show) {
145         if (tray && !_useSystemTray)
146             tray->setVisible(false);
147     }
148     else {
149         if (tray && _useSystemTray)
150             tray->setVisible(true);
151     }
152     GraphicalUi::minimizeRestore(show);
153 }
154
155
156 void QtUi::registerNotificationBackend(AbstractNotificationBackend *backend)
157 {
158     if (!_notificationBackends.contains(backend)) {
159         _notificationBackends.append(backend);
160         instance()->connect(backend, SIGNAL(activated(uint)), SLOT(notificationActivated(uint)));
161     }
162 }
163
164
165 void QtUi::unregisterNotificationBackend(AbstractNotificationBackend *backend)
166 {
167     _notificationBackends.removeAll(backend);
168 }
169
170
171 void QtUi::unregisterAllNotificationBackends()
172 {
173     _notificationBackends.clear();
174 }
175
176
177 const QList<AbstractNotificationBackend *> &QtUi::notificationBackends()
178 {
179     return _notificationBackends;
180 }
181
182
183 uint QtUi::invokeNotification(BufferId bufId, AbstractNotificationBackend::NotificationType type, const QString &sender, const QString &text)
184 {
185     static int notificationId = 0;
186
187     AbstractNotificationBackend::Notification notification(++notificationId, bufId, type, sender, text);
188     _notifications.append(notification);
189     foreach(AbstractNotificationBackend *backend, _notificationBackends)
190     backend->notify(notification);
191     return notificationId;
192 }
193
194
195 void QtUi::closeNotification(uint notificationId)
196 {
197     QList<AbstractNotificationBackend::Notification>::iterator i = _notifications.begin();
198     while (i != _notifications.end()) {
199         if (i->notificationId == notificationId) {
200             foreach(AbstractNotificationBackend *backend, _notificationBackends)
201             backend->close(notificationId);
202             i = _notifications.erase(i);
203         }
204         else ++i;
205     }
206 }
207
208
209 void QtUi::closeNotifications(BufferId bufferId)
210 {
211     QList<AbstractNotificationBackend::Notification>::iterator i = _notifications.begin();
212     while (i != _notifications.end()) {
213         if (!bufferId.isValid() || i->bufferId == bufferId) {
214             foreach(AbstractNotificationBackend *backend, _notificationBackends)
215             backend->close(i->notificationId);
216             i = _notifications.erase(i);
217         }
218         else ++i;
219     }
220 }
221
222
223 const QList<AbstractNotificationBackend::Notification> &QtUi::activeNotifications()
224 {
225     return _notifications;
226 }
227
228
229 void QtUi::notificationActivated(uint notificationId)
230 {
231     if (notificationId != 0) {
232         QList<AbstractNotificationBackend::Notification>::iterator i = _notifications.begin();
233         while (i != _notifications.end()) {
234             if (i->notificationId == notificationId) {
235                 BufferId bufId = i->bufferId;
236                 if (bufId.isValid())
237                     Client::bufferModel()->switchToBuffer(bufId);
238                 break;
239             }
240             ++i;
241         }
242     }
243     closeNotification(notificationId);
244
245     activateMainWidget();
246 }
247
248
249 void QtUi::bufferMarkedAsRead(BufferId bufferId)
250 {
251     if (bufferId.isValid()) {
252         closeNotifications(bufferId);
253     }
254 }