1 /***************************************************************************
2 * Copyright (C) 2005-2018 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)
39 void BufferViewOverlay::reset()
41 _aboutToUpdate = false;
43 _bufferViewIds.clear();
44 _uninitializedViewCount = 0;
47 _allowedBufferTypes = 0;
51 _removedBuffers.clear();
52 _tempRemovedBuffers.clear();
56 void BufferViewOverlay::save()
58 CoreAccountSettings().setBufferViewOverlay(_bufferViewIds);
62 void BufferViewOverlay::restore()
64 QSet<int> currentIds = _bufferViewIds;
66 currentIds += CoreAccountSettings().bufferViewOverlay();
68 QSet<int>::const_iterator iter;
69 for (iter = currentIds.constBegin(); iter != currentIds.constEnd(); ++iter) {
75 void BufferViewOverlay::addView(int viewId)
77 if (_bufferViewIds.contains(viewId))
80 BufferViewConfig *config = Client::bufferViewManager()->bufferViewConfig(viewId);
82 qDebug() << "BufferViewOverlay::addView(): no such buffer view:" << viewId;
86 _bufferViewIds << viewId;
87 bool wasInitialized = isInitialized();
88 _uninitializedViewCount++;
90 if (config->isInitialized()) {
91 viewInitialized(config);
95 if (config->networkId().isValid()) {
96 foreach(BufferId bufferId, config->bufferList()) {
97 if (Client::networkModel()->networkId(bufferId) == config->networkId())
100 foreach(BufferId bufferId, config->temporarilyRemovedBuffers().toList()) {
101 if (Client::networkModel()->networkId(bufferId) == config->networkId())
106 buffers = BufferIdList::fromSet(config->bufferList().toSet() + config->temporarilyRemovedBuffers());
108 Client::backlogManager()->checkForBacklog(buffers);
112 disconnect(config, SIGNAL(initDone()), this, SLOT(viewInitialized()));
113 // we use a queued connection here since manipulating the connection list of a sending object
114 // doesn't seem to be such a good idea while executing a connected slots.
115 connect(config, SIGNAL(initDone()), this, SLOT(viewInitialized()), Qt::QueuedConnection);
121 void BufferViewOverlay::removeView(int viewId)
123 if (!_bufferViewIds.contains(viewId))
126 _bufferViewIds.remove(viewId);
127 BufferViewConfig *config = Client::bufferViewManager()->bufferViewConfig(viewId);
129 disconnect(config, nullptr, this, nullptr);
131 // update initialized State:
132 bool wasInitialized = isInitialized();
133 _uninitializedViewCount = 0;
134 QSet<int>::iterator viewIter = _bufferViewIds.begin();
135 while (viewIter != _bufferViewIds.end()) {
136 config = Client::bufferViewManager()->bufferViewConfig(*viewIter);
138 viewIter = _bufferViewIds.erase(viewIter);
141 if (!config->isInitialized())
142 _uninitializedViewCount++;
148 if (!wasInitialized && isInitialized())
154 void BufferViewOverlay::viewInitialized(BufferViewConfig *config)
157 qWarning() << "BufferViewOverlay::viewInitialized() received invalid view!";
160 disconnect(config, SIGNAL(initDone()), this, SLOT(viewInitialized()));
162 connect(config, SIGNAL(configChanged()), this, SLOT(update()));
164 // check if the view was removed in the meantime...
165 if (_bufferViewIds.contains(config->bufferViewId()))
168 _uninitializedViewCount--;
174 void BufferViewOverlay::viewInitialized()
176 BufferViewConfig *config = qobject_cast<BufferViewConfig *>(sender());
179 viewInitialized(config);
183 void BufferViewOverlay::update()
185 if (_aboutToUpdate) {
188 _aboutToUpdate = true;
189 QCoreApplication::postEvent(this, new QEvent((QEvent::Type)_updateEventId));
193 void BufferViewOverlay::updateHelper()
198 bool changed = false;
200 int allowedBufferTypes = 0;
201 int minimumActivity = -1;
202 QSet<NetworkId> networkIds;
203 QSet<BufferId> buffers;
204 QSet<BufferId> removedBuffers;
205 QSet<BufferId> tempRemovedBuffers;
207 if (Client::bufferViewManager()) {
208 BufferViewConfig *config = nullptr;
209 QSet<int>::const_iterator viewIter;
210 for (viewIter = _bufferViewIds.constBegin(); viewIter != _bufferViewIds.constEnd(); ++viewIter) {
211 config = Client::bufferViewManager()->bufferViewConfig(*viewIter);
215 allowedBufferTypes |= config->allowedBufferTypes();
216 if (minimumActivity == -1 || config->minimumActivity() < minimumActivity)
217 minimumActivity = config->minimumActivity();
219 networkIds << config->networkId();
221 // we have to apply several filters before we can add a buffer to a category (visible, removed, ...)
222 buffers += filterBuffersByConfig(config->bufferList(), config);
223 tempRemovedBuffers += filterBuffersByConfig(config->temporarilyRemovedBuffers().toList(), config);
224 removedBuffers += config->removedBuffers();
227 // prune the sets from overlap
228 QSet<BufferId> availableBuffers = Client::networkModel()->allBufferIds().toSet();
230 buffers.intersect(availableBuffers);
232 tempRemovedBuffers.intersect(availableBuffers);
233 tempRemovedBuffers.subtract(buffers);
235 removedBuffers.intersect(availableBuffers);
236 removedBuffers.subtract(tempRemovedBuffers);
237 removedBuffers.subtract(buffers);
240 changed |= (allowedBufferTypes != _allowedBufferTypes);
241 changed |= (minimumActivity != _minimumActivity);
242 changed |= (networkIds != _networkIds);
243 changed |= (buffers != _buffers);
244 changed |= (removedBuffers != _removedBuffers);
245 changed |= (tempRemovedBuffers != _tempRemovedBuffers);
247 _allowedBufferTypes = allowedBufferTypes;
248 _minimumActivity = minimumActivity;
249 _networkIds = networkIds;
251 _removedBuffers = removedBuffers;
252 _tempRemovedBuffers = tempRemovedBuffers;
254 _aboutToUpdate = false;
261 QSet<BufferId> BufferViewOverlay::filterBuffersByConfig(const QList<BufferId> &buffers, const BufferViewConfig *config)
265 QSet<BufferId> bufferIds;
266 BufferInfo bufferInfo;
267 foreach(BufferId bufferId, buffers) {
268 bufferInfo = Client::networkModel()->bufferInfo(bufferId);
269 if (!(bufferInfo.type() & config->allowedBufferTypes()))
271 if (config->networkId().isValid() && bufferInfo.networkId() != config->networkId())
273 bufferIds << bufferId;
280 void BufferViewOverlay::customEvent(QEvent *event)
282 if (event->type() == _updateEventId) {
288 bool BufferViewOverlay::allNetworks()
291 return _networkIds.contains(NetworkId());
295 const QSet<NetworkId> &BufferViewOverlay::networkIds()
302 const QSet<BufferId> &BufferViewOverlay::bufferIds()
309 const QSet<BufferId> &BufferViewOverlay::removedBufferIds()
312 return _removedBuffers;
316 const QSet<BufferId> &BufferViewOverlay::tempRemovedBufferIds()
319 return _tempRemovedBuffers;
323 int BufferViewOverlay::allowedBufferTypes()
326 return _allowedBufferTypes;
330 int BufferViewOverlay::minimumActivity()
333 return _minimumActivity;