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 // we use a queued connection here since manipulating the connection list of a sending object
113 // doesn't seem to be such a good idea while executing a connected slots.
114 connect(config, &BufferViewConfig::initDone, this, selectOverload<>(&BufferViewOverlay::viewInitialized), Qt::QueuedConnection);
120 void BufferViewOverlay::removeView(int viewId)
122 if (!_bufferViewIds.contains(viewId))
125 _bufferViewIds.remove(viewId);
126 BufferViewConfig *config = Client::bufferViewManager()->bufferViewConfig(viewId);
128 disconnect(config, nullptr, this, nullptr);
130 // update initialized State:
131 bool wasInitialized = isInitialized();
132 _uninitializedViewCount = 0;
133 QSet<int>::iterator viewIter = _bufferViewIds.begin();
134 while (viewIter != _bufferViewIds.end()) {
135 config = Client::bufferViewManager()->bufferViewConfig(*viewIter);
137 viewIter = _bufferViewIds.erase(viewIter);
140 if (!config->isInitialized())
141 _uninitializedViewCount++;
147 if (!wasInitialized && isInitialized())
153 void BufferViewOverlay::viewInitialized(BufferViewConfig *config)
156 qWarning() << "BufferViewOverlay::viewInitialized() received invalid view!";
159 connect(config, &BufferViewConfig::configChanged, this, &BufferViewOverlay::update);
161 // check if the view was removed in the meantime...
162 if (_bufferViewIds.contains(config->bufferViewId()))
165 _uninitializedViewCount--;
171 void BufferViewOverlay::viewInitialized()
173 auto *config = qobject_cast<BufferViewConfig *>(sender());
176 viewInitialized(config);
180 void BufferViewOverlay::update()
182 if (_aboutToUpdate) {
185 _aboutToUpdate = true;
186 QCoreApplication::postEvent(this, new QEvent((QEvent::Type)_updateEventId));
190 void BufferViewOverlay::updateHelper()
195 bool changed = false;
197 int allowedBufferTypes = 0;
198 int minimumActivity = -1;
199 QSet<NetworkId> networkIds;
200 QSet<BufferId> buffers;
201 QSet<BufferId> removedBuffers;
202 QSet<BufferId> tempRemovedBuffers;
204 if (Client::bufferViewManager()) {
205 BufferViewConfig *config = nullptr;
206 QSet<int>::const_iterator viewIter;
207 for (viewIter = _bufferViewIds.constBegin(); viewIter != _bufferViewIds.constEnd(); ++viewIter) {
208 config = Client::bufferViewManager()->bufferViewConfig(*viewIter);
212 allowedBufferTypes |= config->allowedBufferTypes();
213 if (minimumActivity == -1 || config->minimumActivity() < minimumActivity)
214 minimumActivity = config->minimumActivity();
216 networkIds << config->networkId();
218 // we have to apply several filters before we can add a buffer to a category (visible, removed, ...)
219 buffers += filterBuffersByConfig(config->bufferList(), config);
220 tempRemovedBuffers += filterBuffersByConfig(config->temporarilyRemovedBuffers().toList(), config);
221 removedBuffers += config->removedBuffers();
224 // prune the sets from overlap
225 QSet<BufferId> availableBuffers = Client::networkModel()->allBufferIds().toSet();
227 buffers.intersect(availableBuffers);
229 tempRemovedBuffers.intersect(availableBuffers);
230 tempRemovedBuffers.subtract(buffers);
232 removedBuffers.intersect(availableBuffers);
233 removedBuffers.subtract(tempRemovedBuffers);
234 removedBuffers.subtract(buffers);
237 changed |= (allowedBufferTypes != _allowedBufferTypes);
238 changed |= (minimumActivity != _minimumActivity);
239 changed |= (networkIds != _networkIds);
240 changed |= (buffers != _buffers);
241 changed |= (removedBuffers != _removedBuffers);
242 changed |= (tempRemovedBuffers != _tempRemovedBuffers);
244 _allowedBufferTypes = allowedBufferTypes;
245 _minimumActivity = minimumActivity;
246 _networkIds = networkIds;
248 _removedBuffers = removedBuffers;
249 _tempRemovedBuffers = tempRemovedBuffers;
251 _aboutToUpdate = false;
258 QSet<BufferId> BufferViewOverlay::filterBuffersByConfig(const QList<BufferId> &buffers, const BufferViewConfig *config)
262 QSet<BufferId> bufferIds;
263 BufferInfo bufferInfo;
264 foreach(BufferId bufferId, buffers) {
265 bufferInfo = Client::networkModel()->bufferInfo(bufferId);
266 if (!(bufferInfo.type() & config->allowedBufferTypes()))
268 if (config->networkId().isValid() && bufferInfo.networkId() != config->networkId())
270 bufferIds << bufferId;
277 void BufferViewOverlay::customEvent(QEvent *event)
279 if (event->type() == _updateEventId) {
285 bool BufferViewOverlay::allNetworks()
288 return _networkIds.contains(NetworkId());
292 const QSet<NetworkId> &BufferViewOverlay::networkIds()
299 const QSet<BufferId> &BufferViewOverlay::bufferIds()
306 const QSet<BufferId> &BufferViewOverlay::removedBufferIds()
309 return _removedBuffers;
313 const QSet<BufferId> &BufferViewOverlay::tempRemovedBufferIds()
316 return _tempRemovedBuffers;
320 int BufferViewOverlay::allowedBufferTypes()
323 return _allowedBufferTypes;
327 int BufferViewOverlay::minimumActivity()
330 return _minimumActivity;