Quassel IRC  Pre-Release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
bufferviewoverlay.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005-2015 by the Quassel Project *
3  * devel@quassel-irc.org *
4  * *
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. *
9  * *
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. *
14  * *
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  ***************************************************************************/
20 
21 #include "bufferviewoverlay.h"
22 
23 #include <QEvent>
24 
25 #include "bufferviewconfig.h"
26 #include "client.h"
27 #include "clientbacklogmanager.h"
29 #include "networkmodel.h"
30 
31 const int BufferViewOverlay::_updateEventId = QEvent::registerEventType();
32 
34  : QObject(parent),
35  _aboutToUpdate(false),
36  _uninitializedViewCount(0),
37  _allowedBufferTypes(0),
38  _minimumActivity(0)
39 {
40 }
41 
42 
44 {
45  _aboutToUpdate = false;
46 
47  _bufferViewIds.clear();
49 
50  _networkIds.clear();
52  _minimumActivity = 0;
53 
54  _buffers.clear();
55  _removedBuffers.clear();
56  _tempRemovedBuffers.clear();
57 }
58 
59 
61 {
63 }
64 
65 
67 {
68  QSet<int> currentIds = _bufferViewIds;
69  reset();
70  currentIds += CoreAccountSettings().bufferViewOverlay();
71 
72  QSet<int>::const_iterator iter;
73  for (iter = currentIds.constBegin(); iter != currentIds.constEnd(); iter++) {
74  addView(*iter);
75  }
76 }
77 
78 
80 {
81  if (_bufferViewIds.contains(viewId))
82  return;
83 
85  if (!config) {
86  qDebug() << "BufferViewOverlay::addView(): no such buffer view:" << viewId;
87  return;
88  }
89 
90  _bufferViewIds << viewId;
91  bool wasInitialized = isInitialized();
93 
94  if (config->isInitialized()) {
95  viewInitialized(config);
96 
97  if (wasInitialized) {
98  BufferIdList buffers;
99  if (config->networkId().isValid()) {
100  foreach(BufferId bufferId, config->bufferList()) {
101  if (Client::networkModel()->networkId(bufferId) == config->networkId())
102  buffers << bufferId;
103  }
104  foreach(BufferId bufferId, config->temporarilyRemovedBuffers().toList()) {
105  if (Client::networkModel()->networkId(bufferId) == config->networkId())
106  buffers << bufferId;
107  }
108  }
109  else {
110  buffers = BufferIdList::fromSet(config->bufferList().toSet() + config->temporarilyRemovedBuffers());
111  }
113  }
114  }
115  else {
116  disconnect(config, SIGNAL(initDone()), this, SLOT(viewInitialized()));
117  // we use a queued connection here since manipulating the connection list of a sending object
118  // doesn't seem to be such a good idea while executing a connected slots.
119  connect(config, SIGNAL(initDone()), this, SLOT(viewInitialized()), Qt::QueuedConnection);
120  }
121  save();
122 }
123 
124 
126 {
127  if (!_bufferViewIds.contains(viewId))
128  return;
129 
130  _bufferViewIds.remove(viewId);
132  if (config)
133  disconnect(config, 0, this, 0);
134 
135  // update initialized State:
136  bool wasInitialized = isInitialized();
138  QSet<int>::iterator viewIter = _bufferViewIds.begin();
139  while (viewIter != _bufferViewIds.end()) {
140  config = Client::bufferViewManager()->bufferViewConfig(*viewIter);
141  if (!config) {
142  viewIter = _bufferViewIds.erase(viewIter);
143  }
144  else {
145  if (!config->isInitialized())
147  viewIter++;
148  }
149  }
150 
151  update();
152  if (!wasInitialized && isInitialized())
153  emit initDone();
154  save();
155 }
156 
157 
159 {
160  if (!config) {
161  qWarning() << "BufferViewOverlay::viewInitialized() received invalid view!";
162  return;
163  }
164  disconnect(config, SIGNAL(initDone()), this, SLOT(viewInitialized()));
165 
166  connect(config, SIGNAL(configChanged()), this, SLOT(update()));
167 
168  // check if the view was removed in the meantime...
169  if (_bufferViewIds.contains(config->bufferViewId()))
170  update();
171 
173  if (isInitialized())
174  emit initDone();
175 }
176 
177 
179 {
180  BufferViewConfig *config = qobject_cast<BufferViewConfig *>(sender());
181  Q_ASSERT(config);
182 
183  viewInitialized(config);
184 }
185 
186 
188 {
189  if (_aboutToUpdate) {
190  return;
191  }
192  _aboutToUpdate = true;
193  QCoreApplication::postEvent(this, new QEvent((QEvent::Type)_updateEventId));
194 }
195 
196 
198 {
199  if (!_aboutToUpdate)
200  return;
201 
202  bool changed = false;
203 
204  int allowedBufferTypes = 0;
205  int minimumActivity = -1;
206  QSet<NetworkId> networkIds;
207  QSet<BufferId> buffers;
208  QSet<BufferId> removedBuffers;
209  QSet<BufferId> tempRemovedBuffers;
210 
212  BufferViewConfig *config = 0;
213  QSet<int>::const_iterator viewIter;
214  for (viewIter = _bufferViewIds.constBegin(); viewIter != _bufferViewIds.constEnd(); viewIter++) {
215  config = Client::bufferViewManager()->bufferViewConfig(*viewIter);
216  if (!config)
217  continue;
218 
219  allowedBufferTypes |= config->allowedBufferTypes();
220  if (minimumActivity == -1 || config->minimumActivity() < minimumActivity)
221  minimumActivity = config->minimumActivity();
222 
223  networkIds << config->networkId();
224 
225  // we have to apply several filters before we can add a buffer to a category (visible, removed, ...)
226  buffers += filterBuffersByConfig(config->bufferList(), config);
227  tempRemovedBuffers += filterBuffersByConfig(config->temporarilyRemovedBuffers().toList(), config);
228  removedBuffers += config->removedBuffers();
229  }
230 
231  // prune the sets from overlap
232  QSet<BufferId> availableBuffers = Client::networkModel()->allBufferIds().toSet();
233 
234  buffers.intersect(availableBuffers);
235 
236  tempRemovedBuffers.intersect(availableBuffers);
237  tempRemovedBuffers.subtract(buffers);
238 
239  removedBuffers.intersect(availableBuffers);
240  removedBuffers.subtract(tempRemovedBuffers);
241  removedBuffers.subtract(buffers);
242  }
243 
244  changed |= (allowedBufferTypes != _allowedBufferTypes);
245  changed |= (minimumActivity != _minimumActivity);
246  changed |= (networkIds != _networkIds);
247  changed |= (buffers != _buffers);
248  changed |= (removedBuffers != _removedBuffers);
249  changed |= (tempRemovedBuffers != _tempRemovedBuffers);
250 
254  _buffers = buffers;
255  _removedBuffers = removedBuffers;
256  _tempRemovedBuffers = tempRemovedBuffers;
257 
258  _aboutToUpdate = false;
259 
260  if (changed)
261  emit hasChanged();
262 }
263 
264 
265 QSet<BufferId> BufferViewOverlay::filterBuffersByConfig(const QList<BufferId> &buffers, const BufferViewConfig *config)
266 {
267  Q_ASSERT(config);
268 
269  QSet<BufferId> bufferIds;
270  BufferInfo bufferInfo;
271  foreach(BufferId bufferId, buffers) {
272  bufferInfo = Client::networkModel()->bufferInfo(bufferId);
273  if (!(bufferInfo.type() & config->allowedBufferTypes()))
274  continue;
275  if (config->networkId().isValid() && bufferInfo.networkId() != config->networkId())
276  continue;
277  bufferIds << bufferId;
278  }
279 
280  return bufferIds;
281 }
282 
283 
285 {
286  if (event->type() == _updateEventId) {
287  updateHelper();
288  }
289 }
290 
291 
293 {
294  updateHelper();
295  return _networkIds.contains(NetworkId());
296 }
297 
298 
299 const QSet<NetworkId> &BufferViewOverlay::networkIds()
300 {
301  updateHelper();
302  return _networkIds;
303 }
304 
305 
306 const QSet<BufferId> &BufferViewOverlay::bufferIds()
307 {
308  updateHelper();
309  return _buffers;
310 }
311 
312 
313 const QSet<BufferId> &BufferViewOverlay::removedBufferIds()
314 {
315  updateHelper();
316  return _removedBuffers;
317 }
318 
319 
321 {
322  updateHelper();
323  return _tempRemovedBuffers;
324 }
325 
326 
328 {
329  updateHelper();
330  return _allowedBufferTypes;
331 }
332 
333 
335 {
336  updateHelper();
337  return _minimumActivity;
338 }