1 /***************************************************************************
2 * Copyright (C) 2005-2015 by the Quassel Project *
3 * devel@quassel-irc.org *
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. *
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. *
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 ***************************************************************************/
21 #include "bufferviewoverlay.h"
25 #include "bufferviewconfig.h"
27 #include "clientbacklogmanager.h"
28 #include "clientbufferviewmanager.h"
29 #include "networkmodel.h"
31 const int BufferViewOverlay::_updateEventId = QEvent::registerEventType();
33 BufferViewOverlay::BufferViewOverlay(QObject *parent)
35 _aboutToUpdate(false),
36 _uninitializedViewCount(0),
37 _allowedBufferTypes(0),
43 void BufferViewOverlay::reset()
45 _aboutToUpdate = false;
47 _bufferViewIds.clear();
48 _uninitializedViewCount = 0;
51 _allowedBufferTypes = 0;
55 _removedBuffers.clear();
56 _tempRemovedBuffers.clear();
60 void BufferViewOverlay::save()
62 CoreAccountSettings().setBufferViewOverlay(_bufferViewIds);
66 void BufferViewOverlay::restore()
68 QSet<int> currentIds = _bufferViewIds;
70 currentIds += CoreAccountSettings().bufferViewOverlay();
72 QSet<int>::const_iterator iter;
73 for (iter = currentIds.constBegin(); iter != currentIds.constEnd(); ++iter) {
79 void BufferViewOverlay::addView(int viewId)
81 if (_bufferViewIds.contains(viewId))
84 BufferViewConfig *config = Client::bufferViewManager()->bufferViewConfig(viewId);
86 qDebug() << "BufferViewOverlay::addView(): no such buffer view:" << viewId;
90 _bufferViewIds << viewId;
91 bool wasInitialized = isInitialized();
92 _uninitializedViewCount++;
94 if (config->isInitialized()) {
95 viewInitialized(config);
99 if (config->networkId().isValid()) {
100 foreach(BufferId bufferId, config->bufferList()) {
101 if (Client::networkModel()->networkId(bufferId) == config->networkId())
104 foreach(BufferId bufferId, config->temporarilyRemovedBuffers().toList()) {
105 if (Client::networkModel()->networkId(bufferId) == config->networkId())
110 buffers = BufferIdList::fromSet(config->bufferList().toSet() + config->temporarilyRemovedBuffers());
112 Client::backlogManager()->checkForBacklog(buffers);
116 disconnect(config, SIGNAL(initDone()), this, SLOT(viewInitialized()));
117 // we use a queued connection here since manipulating the connection list of a sending object
118 // doesn't seem to be such a good idea while executing a connected slots.
119 connect(config, SIGNAL(initDone()), this, SLOT(viewInitialized()), Qt::QueuedConnection);
125 void BufferViewOverlay::removeView(int viewId)
127 if (!_bufferViewIds.contains(viewId))
130 _bufferViewIds.remove(viewId);
131 BufferViewConfig *config = Client::bufferViewManager()->bufferViewConfig(viewId);
133 disconnect(config, 0, this, 0);
135 // update initialized State:
136 bool wasInitialized = isInitialized();
137 _uninitializedViewCount = 0;
138 QSet<int>::iterator viewIter = _bufferViewIds.begin();
139 while (viewIter != _bufferViewIds.end()) {
140 config = Client::bufferViewManager()->bufferViewConfig(*viewIter);
142 viewIter = _bufferViewIds.erase(viewIter);
145 if (!config->isInitialized())
146 _uninitializedViewCount++;
152 if (!wasInitialized && isInitialized())
158 void BufferViewOverlay::viewInitialized(BufferViewConfig *config)
161 qWarning() << "BufferViewOverlay::viewInitialized() received invalid view!";
164 disconnect(config, SIGNAL(initDone()), this, SLOT(viewInitialized()));
166 connect(config, SIGNAL(configChanged()), this, SLOT(update()));
168 // check if the view was removed in the meantime...
169 if (_bufferViewIds.contains(config->bufferViewId()))
172 _uninitializedViewCount--;
178 void BufferViewOverlay::viewInitialized()
180 BufferViewConfig *config = qobject_cast<BufferViewConfig *>(sender());
183 viewInitialized(config);
187 void BufferViewOverlay::update()
189 if (_aboutToUpdate) {
192 _aboutToUpdate = true;
193 QCoreApplication::postEvent(this, new QEvent((QEvent::Type)_updateEventId));
197 void BufferViewOverlay::updateHelper()
202 bool changed = false;
204 int allowedBufferTypes = 0;
205 int minimumActivity = -1;
206 QSet<NetworkId> networkIds;
207 QSet<BufferId> buffers;
208 QSet<BufferId> removedBuffers;
209 QSet<BufferId> tempRemovedBuffers;
211 if (Client::bufferViewManager()) {
212 BufferViewConfig *config = 0;
213 QSet<int>::const_iterator viewIter;
214 for (viewIter = _bufferViewIds.constBegin(); viewIter != _bufferViewIds.constEnd(); ++viewIter) {
215 config = Client::bufferViewManager()->bufferViewConfig(*viewIter);
219 allowedBufferTypes |= config->allowedBufferTypes();
220 if (minimumActivity == -1 || config->minimumActivity() < minimumActivity)
221 minimumActivity = config->minimumActivity();
223 networkIds << config->networkId();
225 // we have to apply several filters before we can add a buffer to a category (visible, removed, ...)
226 buffers += filterBuffersByConfig(config->bufferList(), config);
227 tempRemovedBuffers += filterBuffersByConfig(config->temporarilyRemovedBuffers().toList(), config);
228 removedBuffers += config->removedBuffers();
231 // prune the sets from overlap
232 QSet<BufferId> availableBuffers = Client::networkModel()->allBufferIds().toSet();
234 buffers.intersect(availableBuffers);
236 tempRemovedBuffers.intersect(availableBuffers);
237 tempRemovedBuffers.subtract(buffers);
239 removedBuffers.intersect(availableBuffers);
240 removedBuffers.subtract(tempRemovedBuffers);
241 removedBuffers.subtract(buffers);
244 changed |= (allowedBufferTypes != _allowedBufferTypes);
245 changed |= (minimumActivity != _minimumActivity);
246 changed |= (networkIds != _networkIds);
247 changed |= (buffers != _buffers);
248 changed |= (removedBuffers != _removedBuffers);
249 changed |= (tempRemovedBuffers != _tempRemovedBuffers);
251 _allowedBufferTypes = allowedBufferTypes;
252 _minimumActivity = minimumActivity;
253 _networkIds = networkIds;
255 _removedBuffers = removedBuffers;
256 _tempRemovedBuffers = tempRemovedBuffers;
258 _aboutToUpdate = false;
265 QSet<BufferId> BufferViewOverlay::filterBuffersByConfig(const QList<BufferId> &buffers, const BufferViewConfig *config)
269 QSet<BufferId> bufferIds;
270 BufferInfo bufferInfo;
271 foreach(BufferId bufferId, buffers) {
272 bufferInfo = Client::networkModel()->bufferInfo(bufferId);
273 if (!(bufferInfo.type() & config->allowedBufferTypes()))
275 if (config->networkId().isValid() && bufferInfo.networkId() != config->networkId())
277 bufferIds << bufferId;
284 void BufferViewOverlay::customEvent(QEvent *event)
286 if (event->type() == _updateEventId) {
292 bool BufferViewOverlay::allNetworks()
295 return _networkIds.contains(NetworkId());
299 const QSet<NetworkId> &BufferViewOverlay::networkIds()
306 const QSet<BufferId> &BufferViewOverlay::bufferIds()
313 const QSet<BufferId> &BufferViewOverlay::removedBufferIds()
316 return _removedBuffers;
320 const QSet<BufferId> &BufferViewOverlay::tempRemovedBufferIds()
323 return _tempRemovedBuffers;
327 int BufferViewOverlay::allowedBufferTypes()
330 return _allowedBufferTypes;
334 int BufferViewOverlay::minimumActivity()
337 return _minimumActivity;