1 /***************************************************************************
2 * Copyright (C) 2005-08 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 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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),
42 void BufferViewOverlay::reset() {
43 _aboutToUpdate = false;
45 _bufferViewIds.clear();
46 _uninitializedViewCount = 0;
49 _allowedBufferTypes = 0;
53 _removedBuffers.clear();
54 _tempRemovedBuffers.clear();
57 void BufferViewOverlay::save() {
58 CoreAccountSettings().setBufferViewOverlay(_bufferViewIds);
61 void BufferViewOverlay::restore() {
62 QSet<int> currentIds = _bufferViewIds;
64 currentIds += CoreAccountSettings().bufferViewOverlay();
66 QSet<int>::const_iterator iter;
67 for(iter = currentIds.constBegin(); iter != currentIds.constEnd(); iter++) {
72 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 foreach(BufferId bufferId, config->temporarilyRemovedBuffers().toList()) {
97 if(Client::networkModel()->networkId(bufferId) == config->networkId())
101 buffers = BufferIdList::fromSet(config->bufferList().toSet() + config->temporarilyRemovedBuffers());
103 Client::backlogManager()->checkForBacklog(buffers);
107 disconnect(config, SIGNAL(initDone()), this, SLOT(viewInitialized()));
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, SIGNAL(initDone()), this, SLOT(viewInitialized()), Qt::QueuedConnection);
115 void BufferViewOverlay::removeView(int viewId) {
116 if(!_bufferViewIds.contains(viewId))
119 _bufferViewIds.remove(viewId);
120 BufferViewConfig *config = Client::bufferViewManager()->bufferViewConfig(viewId);
122 disconnect(config, 0, this, 0);
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);
133 if(!config->isInitialized())
134 _uninitializedViewCount++;
140 if(!wasInitialized && isInitialized())
145 void BufferViewOverlay::viewInitialized(BufferViewConfig *config) {
147 qWarning() << "BufferViewOverlay::viewInitialized() received invalid view!";
150 disconnect(config, SIGNAL(initDone()), this, SLOT(viewInitialized()));
152 connect(config, SIGNAL(configChanged()), this, SLOT(update()));
154 // check if the view was removed in the meantime...
155 if(_bufferViewIds.contains(config->bufferViewId()))
158 _uninitializedViewCount--;
163 void BufferViewOverlay::viewInitialized() {
164 BufferViewConfig *config = qobject_cast<BufferViewConfig *>(sender());
167 viewInitialized(config);
170 void BufferViewOverlay::update() {
174 _aboutToUpdate = true;
175 QCoreApplication::postEvent(this, new QEvent((QEvent::Type)_updateEventId));
178 void BufferViewOverlay::updateHelper() {
182 bool changed = false;
184 int allowedBufferTypes = 0;
185 int minimumActivity = -1;
186 QSet<NetworkId> networkIds;
187 QSet<BufferId> buffers;
188 QSet<BufferId> removedBuffers;
189 QSet<BufferId> tempRemovedBuffers;
191 if(Client::bufferViewManager()) {
192 BufferViewConfig *config = 0;
193 QSet<int>::const_iterator viewIter;
194 for(viewIter = _bufferViewIds.constBegin(); viewIter != _bufferViewIds.constEnd(); viewIter++) {
195 config = Client::bufferViewManager()->bufferViewConfig(*viewIter);
199 allowedBufferTypes |= config->allowedBufferTypes();
200 if(minimumActivity == -1 || config->minimumActivity() < minimumActivity)
201 minimumActivity = config->minimumActivity();
203 networkIds << config->networkId();
206 // we have to apply several filters before we can add a buffer to a category (visible, removed, ...)
207 buffers += filterBuffersByConfig(config->bufferList(), config);
208 tempRemovedBuffers += filterBuffersByConfig(config->temporarilyRemovedBuffers().toList(), config);
209 removedBuffers += config->removedBuffers();
212 // prune the sets from overlap
213 QSet<BufferId> availableBuffers = Client::networkModel()->allBufferIds().toSet();
215 buffers.intersect(availableBuffers);
217 tempRemovedBuffers.intersect(availableBuffers);
218 tempRemovedBuffers.subtract(buffers);
220 removedBuffers.intersect(availableBuffers);
221 removedBuffers.subtract(tempRemovedBuffers);
222 removedBuffers.subtract(buffers);
225 changed |= (allowedBufferTypes != _allowedBufferTypes);
226 changed |= (minimumActivity != _minimumActivity);
227 changed |= (networkIds != _networkIds);
228 changed |= (buffers != _buffers);
229 changed |= (removedBuffers != _removedBuffers);
230 changed |= (tempRemovedBuffers != _tempRemovedBuffers);
232 _allowedBufferTypes = allowedBufferTypes;
233 _minimumActivity = minimumActivity;
234 _networkIds = networkIds;
236 _removedBuffers = removedBuffers;
237 _tempRemovedBuffers = tempRemovedBuffers;
239 _aboutToUpdate = false;
245 QSet<BufferId> BufferViewOverlay::filterBuffersByConfig(const QList<BufferId> &buffers, const BufferViewConfig *config) {
248 QSet<BufferId> bufferIds;
249 BufferInfo bufferInfo;
250 foreach(BufferId bufferId, buffers) {
251 bufferInfo = Client::networkModel()->bufferInfo(bufferId);
252 if(!(bufferInfo.type() & config->allowedBufferTypes()))
254 if(config->networkId().isValid() && bufferInfo.networkId() != config->networkId())
256 bufferIds << bufferId;
263 void BufferViewOverlay::customEvent(QEvent *event) {
264 if(event->type() == _updateEventId) {
269 bool BufferViewOverlay::allNetworks() {
271 return _networkIds.contains(NetworkId());
274 const QSet<NetworkId> &BufferViewOverlay::networkIds() {
279 const QSet<BufferId> &BufferViewOverlay::bufferIds() {
284 const QSet<BufferId> &BufferViewOverlay::removedBufferIds() {
286 return _removedBuffers;
289 const QSet<BufferId> &BufferViewOverlay::tempRemovedBufferIds() {
291 return _tempRemovedBuffers;
294 int BufferViewOverlay::allowedBufferTypes() {
296 return _allowedBufferTypes;
299 int BufferViewOverlay::minimumActivity() {
301 return _minimumActivity;