1 /***************************************************************************
2 * Copyright (C) 2005-2020 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"
32 const int BufferViewOverlay::_updateEventId = QEvent::registerEventType();
34 BufferViewOverlay::BufferViewOverlay(QObject* parent)
38 void BufferViewOverlay::reset()
40 _aboutToUpdate = false;
42 _bufferViewIds.clear();
43 _uninitializedViewCount = 0;
46 _allowedBufferTypes = 0;
50 _removedBuffers.clear();
51 _tempRemovedBuffers.clear();
54 void BufferViewOverlay::save()
56 CoreAccountSettings().setBufferViewOverlay(_bufferViewIds);
59 void BufferViewOverlay::restore()
61 QSet<int> currentIds = _bufferViewIds;
63 currentIds += CoreAccountSettings().bufferViewOverlay();
65 QSet<int>::const_iterator iter;
66 for (iter = currentIds.constBegin(); iter != currentIds.constEnd(); ++iter) {
71 void BufferViewOverlay::addView(int viewId)
73 if (_bufferViewIds.contains(viewId))
76 BufferViewConfig* config = Client::bufferViewManager()->bufferViewConfig(viewId);
78 qDebug() << "BufferViewOverlay::addView(): no such buffer view:" << viewId;
82 _bufferViewIds << viewId;
83 bool wasInitialized = isInitialized();
84 _uninitializedViewCount++;
86 if (config->isInitialized()) {
87 viewInitialized(config);
91 if (config->networkId().isValid()) {
92 foreach (BufferId bufferId, config->bufferList()) {
93 if (Client::networkModel()->networkId(bufferId) == config->networkId())
96 for (BufferId bufferId : config->temporarilyRemovedBuffers()) {
97 if (Client::networkModel()->networkId(bufferId) == config->networkId())
102 buffers = (toQSet(config->bufferList()) + config->temporarilyRemovedBuffers()).values();
104 Client::backlogManager()->checkForBacklog(buffers);
108 // we use a queued connection here since manipulating the connection list of a sending object
109 // doesn't seem to be such a good idea while executing a connected slots.
110 connect(config, &BufferViewConfig::initDone, this, selectOverload<>(&BufferViewOverlay::viewInitialized), Qt::QueuedConnection);
115 void BufferViewOverlay::removeView(int viewId)
117 if (!_bufferViewIds.contains(viewId))
120 _bufferViewIds.remove(viewId);
121 BufferViewConfig* config = Client::bufferViewManager()->bufferViewConfig(viewId);
123 disconnect(config, nullptr, this, nullptr);
125 // update initialized State:
126 bool wasInitialized = isInitialized();
127 _uninitializedViewCount = 0;
128 QSet<int>::iterator viewIter = _bufferViewIds.begin();
129 while (viewIter != _bufferViewIds.end()) {
130 config = Client::bufferViewManager()->bufferViewConfig(*viewIter);
132 viewIter = _bufferViewIds.erase(viewIter);
135 if (!config->isInitialized())
136 _uninitializedViewCount++;
142 if (!wasInitialized && isInitialized())
147 void BufferViewOverlay::viewInitialized(BufferViewConfig* config)
150 qWarning() << "BufferViewOverlay::viewInitialized() received invalid view!";
153 connect(config, &BufferViewConfig::configChanged, this, &BufferViewOverlay::update);
155 // check if the view was removed in the meantime...
156 if (_bufferViewIds.contains(config->bufferViewId()))
159 _uninitializedViewCount--;
164 void BufferViewOverlay::viewInitialized()
166 auto* config = qobject_cast<BufferViewConfig*>(sender());
169 viewInitialized(config);
172 void BufferViewOverlay::update()
174 if (_aboutToUpdate) {
177 _aboutToUpdate = true;
178 QCoreApplication::postEvent(this, new QEvent((QEvent::Type)_updateEventId));
181 void BufferViewOverlay::updateHelper()
186 bool changed = false;
188 int allowedBufferTypes = 0;
189 int minimumActivity = -1;
190 QSet<NetworkId> networkIds;
191 QSet<BufferId> buffers;
192 QSet<BufferId> removedBuffers;
193 QSet<BufferId> tempRemovedBuffers;
195 if (Client::bufferViewManager()) {
196 BufferViewConfig* config = nullptr;
197 QSet<int>::const_iterator viewIter;
198 for (viewIter = _bufferViewIds.constBegin(); viewIter != _bufferViewIds.constEnd(); ++viewIter) {
199 config = Client::bufferViewManager()->bufferViewConfig(*viewIter);
203 allowedBufferTypes |= config->allowedBufferTypes();
204 if (minimumActivity == -1 || config->minimumActivity() < minimumActivity)
205 minimumActivity = config->minimumActivity();
207 networkIds << config->networkId();
209 // we have to apply several filters before we can add a buffer to a category (visible, removed, ...)
210 buffers += filterBuffersByConfig(config->bufferList(), config);
211 tempRemovedBuffers += filterBuffersByConfig(config->temporarilyRemovedBuffers().values(), config);
212 removedBuffers += config->removedBuffers();
215 // prune the sets from overlap
216 QSet<BufferId> availableBuffers = toQSet(Client::networkModel()->allBufferIds());
218 buffers.intersect(availableBuffers);
220 tempRemovedBuffers.intersect(availableBuffers);
221 tempRemovedBuffers.subtract(buffers);
223 removedBuffers.intersect(availableBuffers);
224 removedBuffers.subtract(tempRemovedBuffers);
225 removedBuffers.subtract(buffers);
228 changed |= (allowedBufferTypes != _allowedBufferTypes);
229 changed |= (minimumActivity != _minimumActivity);
230 changed |= (networkIds != _networkIds);
231 changed |= (buffers != _buffers);
232 changed |= (removedBuffers != _removedBuffers);
233 changed |= (tempRemovedBuffers != _tempRemovedBuffers);
235 _allowedBufferTypes = allowedBufferTypes;
236 _minimumActivity = minimumActivity;
237 _networkIds = networkIds;
239 _removedBuffers = removedBuffers;
240 _tempRemovedBuffers = tempRemovedBuffers;
242 _aboutToUpdate = false;
248 QSet<BufferId> BufferViewOverlay::filterBuffersByConfig(const QList<BufferId>& buffers, const BufferViewConfig* config)
252 QSet<BufferId> bufferIds;
253 BufferInfo bufferInfo;
254 foreach (BufferId bufferId, buffers) {
255 bufferInfo = Client::networkModel()->bufferInfo(bufferId);
256 if (!(bufferInfo.type() & config->allowedBufferTypes()))
258 if (config->networkId().isValid() && bufferInfo.networkId() != config->networkId())
260 bufferIds << bufferId;
266 void BufferViewOverlay::customEvent(QEvent* event)
268 if (event->type() == _updateEventId) {
273 bool BufferViewOverlay::allNetworks()
276 return _networkIds.contains(NetworkId());
279 const QSet<NetworkId>& BufferViewOverlay::networkIds()
285 const QSet<BufferId>& BufferViewOverlay::bufferIds()
291 const QSet<BufferId>& BufferViewOverlay::removedBufferIds()
294 return _removedBuffers;
297 const QSet<BufferId>& BufferViewOverlay::tempRemovedBufferIds()
300 return _tempRemovedBuffers;
303 int BufferViewOverlay::allowedBufferTypes()
306 return _allowedBufferTypes;
309 int BufferViewOverlay::minimumActivity()
312 return _minimumActivity;