Merge branch 'bufferviewoverlay'
[quassel.git] / src / client / bufferviewoverlay.cpp
1 /***************************************************************************
2  *   Copyright (C) 2005-08 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  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20
21 #include "bufferviewoverlay.h"
22
23 #include <QEvent>
24
25 #include "bufferviewconfig.h"
26 #include "client.h"
27 #include "clientbufferviewmanager.h"
28 #include "networkmodel.h"
29
30 const int BufferViewOverlay::_updateEventId = QEvent::registerEventType();
31
32 BufferViewOverlay::BufferViewOverlay(QObject *parent)
33   : QObject(parent),
34     _aboutToUpdate(false),
35     _addBuffersAutomatically(false),
36     _hideInactiveBuffers(false),
37     _allowedBufferTypes(0),
38     _minimumActivity(0)
39 {
40 }
41
42 void BufferViewOverlay::addView(int viewId) {
43   if(_bufferViewIds.contains(viewId))
44     return;
45
46   BufferViewConfig *config = Client::bufferViewManager()->bufferViewConfig(viewId);
47   if(!config) {
48     qDebug() << "BufferViewOverlay::addView(): no such buffer view:" << viewId;
49     return;
50   }
51
52   _bufferViewIds << viewId;
53   if(config->isInitialized()) {
54     viewInitialized(config);
55   } else {
56     disconnect(config, SIGNAL(initDone()), this, SLOT(viewInitialized()));
57     connect(config, SIGNAL(initDone()), this, SLOT(viewInitialized()));
58   }
59 }
60
61 void BufferViewOverlay::removeView(int viewId) {
62   if(!_bufferViewIds.contains(viewId))
63     return;
64
65   _bufferViewIds.remove(viewId);
66   BufferViewConfig *config = qobject_cast<BufferViewConfig *>(sender());
67   if(config)
68     disconnect(config, 0, this, 0);
69   update();
70 }
71
72 void BufferViewOverlay::viewInitialized(BufferViewConfig *config) {
73   if(!config) {
74     qWarning() << "BufferViewOverlay::viewInitialized() received invalid view!";
75     return;
76   }
77   disconnect(config, SIGNAL(initDone()), this, SLOT(viewInitialized()));
78
79   connect(config, SIGNAL(networkIdSet(const NetworkId &)), this, SLOT(update()));
80   connect(config, SIGNAL(addNewBuffersAutomaticallySet(bool)), this, SLOT(update()));
81   connect(config, SIGNAL(sortAlphabeticallySet(bool)), this, SLOT(update()));
82   connect(config, SIGNAL(hideInactiveBuffersSet(bool)), this, SLOT(update()));
83   connect(config, SIGNAL(allowedBufferTypesSet(int)), this, SLOT(update()));
84   connect(config, SIGNAL(minimumActivitySet(int)), this, SLOT(update()));
85   connect(config, SIGNAL(bufferListSet()), this, SLOT(update()));
86   connect(config, SIGNAL(bufferAdded(const BufferId &, int)), this, SLOT(update()));
87   connect(config, SIGNAL(bufferRemoved(const BufferId &)), this, SLOT(update()));
88   connect(config, SIGNAL(bufferPermanentlyRemoved(const BufferId &)), this, SLOT(update()));
89
90   // check if the view was removed in the meantime...
91   if(_bufferViewIds.contains(config->bufferViewId()))
92     update();
93 }
94
95 void BufferViewOverlay::viewInitialized() {
96   BufferViewConfig *config = qobject_cast<BufferViewConfig *>(sender());
97   Q_ASSERT(config);
98
99   viewInitialized(config);
100 }
101
102 void BufferViewOverlay::update() {
103   if(_aboutToUpdate) {
104     return;
105   }
106   _aboutToUpdate = true;
107   QCoreApplication::postEvent(this, new QEvent((QEvent::Type)_updateEventId));
108 }
109
110 void BufferViewOverlay::updateHelper() {
111   bool changed = false;
112
113   bool addBuffersAutomatically = false;
114   bool hideInactiveBuffers = true;
115   int allowedBufferTypes = 0;
116   int minimumActivity = -1;
117   QSet<NetworkId> networkIds;
118   QSet<BufferId> buffers;
119   QSet<BufferId> removedBuffers;
120   QSet<BufferId> tempRemovedBuffers;
121
122   if(Client::bufferViewManager()) {
123     BufferViewConfig *config = 0;
124     QSet<int>::const_iterator viewIter;
125     for(viewIter = _bufferViewIds.constBegin(); viewIter != _bufferViewIds.constEnd(); viewIter++) {
126       config = Client::bufferViewManager()->bufferViewConfig(*viewIter);
127       if(!config)
128         continue;
129
130       networkIds << config->networkId();
131       if(config->networkId().isValid()) {
132         NetworkId networkId = config->networkId();
133         // we have to filter out all the buffers that don't belong to this net... :/
134         QSet<BufferId> bufferIds;
135         foreach(BufferId bufferId, config->bufferList()) {
136           if(Client::networkModel()->networkId(bufferId) == networkId)
137             bufferIds << bufferId;
138         }
139         buffers += bufferIds;
140
141         bufferIds.clear();
142         foreach(BufferId bufferId, config->temporarilyRemovedBuffers()) {
143           if(Client::networkModel()->networkId(bufferId) == networkId)
144             bufferIds << bufferId;
145         }
146         tempRemovedBuffers += bufferIds;
147       } else {
148         buffers += config->bufferList().toSet();
149         tempRemovedBuffers += config->temporarilyRemovedBuffers();
150       }
151
152       // in the overlay a buffer is removed it is removed from all views
153       if(removedBuffers.isEmpty())
154         removedBuffers = config->removedBuffers();
155       else
156         removedBuffers.intersect(config->removedBuffers());
157
158
159       addBuffersAutomatically |= config->addNewBuffersAutomatically();
160       hideInactiveBuffers &= config->hideInactiveBuffers();
161       allowedBufferTypes |= config->allowedBufferTypes();
162       if(minimumActivity == -1 || config->minimumActivity() < minimumActivity)
163         minimumActivity = config->minimumActivity();
164     }
165   }
166
167   changed |= (addBuffersAutomatically != _addBuffersAutomatically);
168   changed |= (hideInactiveBuffers != _hideInactiveBuffers);
169   changed |= (allowedBufferTypes != _allowedBufferTypes);
170   changed |= (minimumActivity != _minimumActivity);
171   changed |= (networkIds != _networkIds);
172   changed |= (buffers != _buffers);
173   changed |= (removedBuffers != _removedBuffers);
174   changed |= (tempRemovedBuffers != _tempRemovedBuffers);
175
176   _addBuffersAutomatically = addBuffersAutomatically;
177   _hideInactiveBuffers = hideInactiveBuffers;
178   _allowedBufferTypes = allowedBufferTypes;
179   _minimumActivity = minimumActivity;
180   _networkIds = networkIds;
181   _buffers = buffers;
182   _removedBuffers = removedBuffers;
183   _tempRemovedBuffers = tempRemovedBuffers;
184
185   if(changed)
186     emit hasChanged();
187 }
188
189 void BufferViewOverlay::customEvent(QEvent *event) {
190   if(event->type() == _updateEventId) {
191     updateHelper();
192     _aboutToUpdate = false;
193   }
194 }