Introducing an abstract layer above BufferWidget and Chat{Widget|View}. This allows
[quassel.git] / src / uisupport / abstractbuffercontainer.cpp
1 /***************************************************************************
2  *   Copyright (C) 2005-08 by the Quassel IRC Team                         *
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 "abstractbuffercontainer.h"
22 #include "buffer.h"
23 #include "client.h"
24 #include "networkmodel.h"
25
26 AbstractBufferContainer::AbstractBufferContainer(QWidget *parent) : AbstractItemView(parent), _currentBuffer(0)
27 {
28
29 }
30
31 AbstractBufferContainer::~AbstractBufferContainer() {
32
33 }
34
35
36 void AbstractBufferContainer::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) {
37   Q_ASSERT(model());
38   if(!parent.isValid()) {
39     // ok this means that whole networks are about to be removed
40     // we can't determine which buffers are affect, so we hope that all nets are removed
41     // this is the most common case (for example disconnecting from the core or terminating the client)
42     if(model()->rowCount(parent) != end - start + 1)
43       return;
44
45     AbstractChatView *chatView;
46     QHash<BufferId, AbstractChatView *>::iterator iter = _chatViews.begin();
47     while(iter != _chatViews.end()) {
48       chatView = *iter;
49       iter = _chatViews.erase(iter);
50       removeChatView(chatView);
51     }
52   } else {
53     // check if there are explicitly buffers removed
54     for(int i = start; i <= end; i++) {
55       QVariant variant = parent.child(i,0).data(NetworkModel::BufferIdRole);
56       if(!variant.isValid())
57         continue;
58
59       BufferId bufferId = variant.value<BufferId>();
60       removeBuffer(bufferId);
61     }
62   }
63 }
64
65 void AbstractBufferContainer::removeBuffer(BufferId bufferId) {
66   if(!_chatViews.contains(bufferId))
67     return;
68
69   if(Client::buffer(bufferId)) Client::buffer(bufferId)->setVisible(false);
70   AbstractChatView *chatView = _chatViews.take(bufferId);
71   removeChatView(chatView);
72 }
73
74 void AbstractBufferContainer::currentChanged(const QModelIndex &current, const QModelIndex &previous) {
75   BufferId newBufferId = current.data(NetworkModel::BufferIdRole).value<BufferId>();
76   BufferId oldBufferId = previous.data(NetworkModel::BufferIdRole).value<BufferId>();
77   if(newBufferId != oldBufferId)
78     setCurrentBuffer(newBufferId);
79 }
80
81 void AbstractBufferContainer::setCurrentBuffer(BufferId bufferId) {
82   if(!bufferId.isValid()) {
83     showChatView(0);
84     return;
85   }
86
87   AbstractChatView *chatView = 0;
88   Buffer *buf = Client::buffer(bufferId);
89   if(!buf) {
90     qWarning() << "AbstractBufferContainer::setBuffer(BufferId): Can't show unknown Buffer:" << bufferId;
91     return;
92   }
93   Buffer *prevBuffer = Client::buffer(currentBuffer());
94   if(prevBuffer) prevBuffer->setVisible(false);
95   if(_chatViews.contains(bufferId)) {
96     chatView = _chatViews[bufferId];
97   } else {
98     chatView = createChatView(bufferId);
99     chatView->setContents(buf->contents());
100     connect(buf, SIGNAL(msgAppended(AbstractUiMsg *)), this, SLOT(appendMsg(AbstractUiMsg *)));
101     connect(buf, SIGNAL(msgPrepended(AbstractUiMsg *)), this, SLOT(prependMsg(AbstractUiMsg *)));
102     _chatViews[bufferId] = chatView;
103   }
104   _currentBuffer = bufferId;
105   showChatView(chatView);
106   buf->setVisible(true);
107   setFocus();
108 }
109
110 void AbstractBufferContainer::appendMsg(AbstractUiMsg *msg) {
111   Buffer *buf = qobject_cast<Buffer *>(sender());
112   if(!buf) {
113     qWarning() << "AbstractBufferContainer::appendMsg(): Invalid slot caller!";
114     return;
115   }
116   BufferId id = buf->bufferInfo().bufferId();
117   if(!_chatViews.contains(id)) {
118     qWarning() << "AbstractBufferContainer::appendMsg(): Received message for unknown buffer!";
119     return;
120   }
121   _chatViews[id]->appendMsg(msg);
122 }
123
124 void AbstractBufferContainer::prependMsg(AbstractUiMsg *msg) {
125   Buffer *buf = qobject_cast<Buffer *>(sender());
126   if(!buf) {
127     qWarning() << "AbstractBufferContainer:prependMsg(): Invalid slot caller!";
128     return;
129   }
130   BufferId id = buf->bufferInfo().bufferId();
131   if(!_chatViews.contains(id)) {
132     qWarning() << "AbstractBufferContainer::prependMsg(): Received message for unknown buffer!";
133     return;
134   }
135   _chatViews[id]->prependMsg(msg);
136 }