1 /***************************************************************************
2 * Copyright (C) 2005-2019 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)
37 void BufferViewOverlay::reset()
39 _aboutToUpdate = false;
41 _bufferViewIds.clear();
42 _uninitializedViewCount = 0;
45 _allowedBufferTypes = 0;
49 _removedBuffers.clear();
50 _tempRemovedBuffers.clear();
53 void BufferViewOverlay::save()
55 CoreAccountSettings().setBufferViewOverlay(_bufferViewIds);
58 void BufferViewOverlay::restore()
60 QSet<int> currentIds = _bufferViewIds;
62 currentIds += CoreAccountSettings().bufferViewOverlay();
64 QSet<int>::const_iterator iter;
65 for (iter = currentIds.constBegin(); iter != currentIds.constEnd(); ++iter) {
70 void BufferViewOverlay::addView(int viewId)
72 if (_bufferViewIds.contains(viewId))
75 BufferViewConfig* config = Client::bufferViewManager()->bufferViewConfig(viewId);
77 qDebug() << "BufferViewOverlay::addView(): no such buffer view:" << viewId;
81 _bufferViewIds << viewId;
82 bool wasInitialized = isInitialized();
83 _uninitializedViewCount++;
85 if (config->isInitialized()) {
86 viewInitialized(config);
90 if (config->networkId().isValid()) {
91 foreach (BufferId bufferId, config->bufferList()) {
92 if (Client::networkModel()->networkId(bufferId) == config->networkId())
95 foreach (BufferId bufferId, config->temporarilyRemovedBuffers().toList()) {
96 if (Client::networkModel()->networkId(bufferId) == config->networkId())
101 buffers = BufferIdList::fromSet(config->bufferList().toSet() + config->temporarilyRemovedBuffers());
103 Client::backlogManager()->checkForBacklog(buffers);
107 // we use a queued connection here since manipulating the connection list of a sending object
108 // doesn't seem to be such a good idea while executing a connected slots.
109 connect(config, &BufferViewConfig::initDone, this, selectOverload<>(&BufferViewOverlay::viewInitialized), Qt::QueuedConnection);
114 void BufferViewOverlay::removeView(int viewId)
116 if (!_bufferViewIds.contains(viewId))
119 _bufferViewIds.remove(viewId);
120 BufferViewConfig* config = Client::bufferViewManager()->bufferViewConfig(viewId);
122 disconnect(config, nullptr, this, nullptr);
124 // update initialized State:
125 bool wasInitialized = isInitialized();
126 _uninitializedViewCount = 0;
127 QSet<int>::iterator viewIter = _bufferViewIds.begin();
128 while (viewIter != _bufferViewIds.end()) {
129 config = Client::bufferViewManager()->bufferViewConfig(*viewIter);
131 viewIter = _bufferViewIds.erase(viewIter);
134 if (!config->isInitialized())
135 _uninitializedViewCount++;
141 if (!wasInitialized && isInitialized())
146 void BufferViewOverlay::viewInitialized(BufferViewConfig* config)
149 qWarning() << "BufferViewOverlay::viewInitialized() received invalid view!";
152 connect(config, &BufferViewConfig::configChanged, this, &BufferViewOverlay::update);
154 // check if the view was removed in the meantime...
155 if (_bufferViewIds.contains(config->bufferViewId()))
158 _uninitializedViewCount--;
163 void BufferViewOverlay::viewInitialized()
165 auto* config = qobject_cast<BufferViewConfig*>(sender());
168 viewInitialized(config);
171 void BufferViewOverlay::update()
173 if (_aboutToUpdate) {
176 _aboutToUpdate = true;
177 QCoreApplication::postEvent(this, new QEvent((QEvent::Type)_updateEventId));
180 void BufferViewOverlay::updateHelper()
185 bool changed = false;
187 int allowedBufferTypes = 0;
188 int minimumActivity = -1;
189 QSet<NetworkId> networkIds;
190 QSet<BufferId> buffers;
191 QSet<BufferId> removedBuffers;
192 QSet<BufferId> tempRemovedBuffers;
194 if (Client::bufferViewManager()) {
195 BufferViewConfig* config = nullptr;
196 QSet<int>::const_iterator viewIter;
197 for (viewIter = _bufferViewIds.constBegin(); viewIter != _bufferViewIds.constEnd(); ++viewIter) {
198 config = Client::bufferViewManager()->bufferViewConfig(*viewIter);
202 allowedBufferTypes |= config->allowedBufferTypes();
203 if (minimumActivity == -1 || config->minimumActivity() < minimumActivity)
204 minimumActivity = config->minimumActivity();
206 networkIds << config->networkId();
208 // we have to apply several filters before we can add a buffer to a category (visible, removed, ...)
209 buffers += filterBuffersByConfig(config->bufferList(), config);
210 tempRemovedBuffers += filterBuffersByConfig(config->temporarilyRemovedBuffers().toList(), config);
211 removedBuffers += config->removedBuffers();
214 // prune the sets from overlap
215 QSet<BufferId> availableBuffers = Client::networkModel()->allBufferIds().toSet();
217 buffers.intersect(availableBuffers);
219 tempRemovedBuffers.intersect(availableBuffers);
220 tempRemovedBuffers.subtract(buffers);
222 removedBuffers.intersect(availableBuffers);
223 removedBuffers.subtract(tempRemovedBuffers);
224 removedBuffers.subtract(buffers);
227 changed |= (allowedBufferTypes != _allowedBufferTypes);
228 changed |= (minimumActivity != _minimumActivity);
229 changed |= (networkIds != _networkIds);
230 changed |= (buffers != _buffers);
231 changed |= (removedBuffers != _removedBuffers);
232 changed |= (tempRemovedBuffers != _tempRemovedBuffers);
234 _allowedBufferTypes = allowedBufferTypes;
235 _minimumActivity = minimumActivity;
236 _networkIds = networkIds;
238 _removedBuffers = removedBuffers;
239 _tempRemovedBuffers = tempRemovedBuffers;
241 _aboutToUpdate = false;
247 QSet<BufferId> BufferViewOverlay::filterBuffersByConfig(const QList<BufferId>& buffers, const BufferViewConfig* config)
251 QSet<BufferId> bufferIds;
252 BufferInfo bufferInfo;
253 foreach (BufferId bufferId, buffers) {
254 bufferInfo = Client::networkModel()->bufferInfo(bufferId);
255 if (!(bufferInfo.type() & config->allowedBufferTypes()))
257 if (config->networkId().isValid() && bufferInfo.networkId() != config->networkId())
259 bufferIds << bufferId;
265 void BufferViewOverlay::customEvent(QEvent* event)
267 if (event->type() == _updateEventId) {
272 bool BufferViewOverlay::allNetworks()
275 return _networkIds.contains(NetworkId());
278 const QSet<NetworkId>& BufferViewOverlay::networkIds()
284 const QSet<BufferId>& BufferViewOverlay::bufferIds()
290 const QSet<BufferId>& BufferViewOverlay::removedBufferIds()
293 return _removedBuffers;
296 const QSet<BufferId>& BufferViewOverlay::tempRemovedBufferIds()
299 return _tempRemovedBuffers;
302 int BufferViewOverlay::allowedBufferTypes()
305 return _allowedBufferTypes;
308 int BufferViewOverlay::minimumActivity()
311 return _minimumActivity;