51c551c3328a97dde609021d002f4dd3cc4e30b6
[quassel.git] / src / qtui / bufferwidget.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 "bufferwidget.h"
22 #include "buffer.h"
23 #include "chatline.h"
24 #include "chatline-old.h"
25 #include "chatwidget.h"
26 #include "settings.h"
27 #include "client.h"
28 #include "identity.h"
29 #include "network.h"
30 #include "networkmodel.h"
31
32 #include "global.h"
33
34 BufferWidget::BufferWidget(QWidget *parent)
35   : QWidget(parent),
36     _bufferModel(0),
37     _selectionModel(0),
38     _currentBuffer(0)
39 {
40   ui.setupUi(this);
41 }
42
43 BufferWidget::~BufferWidget() {
44 }
45
46 void BufferWidget::init() {
47 }
48
49 void BufferWidget::setModel(BufferModel *bufferModel) {
50   if(_bufferModel) {
51     disconnect(_bufferModel, 0, this, 0);
52   }
53   _bufferModel = bufferModel;
54
55   if(bufferModel) {
56     connect(bufferModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)),
57             this, SLOT(rowsAboutToBeRemoved(QModelIndex, int, int)));
58   }
59 }
60
61 void BufferWidget::setSelectionModel(QItemSelectionModel *selectionModel) {
62   if(_selectionModel) {
63     disconnect(_selectionModel, 0, this, 0);
64   }
65   _selectionModel = selectionModel;
66
67   if(selectionModel) {
68     connect(selectionModel, SIGNAL(currentChanged(QModelIndex, QModelIndex)),
69             this, SLOT(currentChanged(QModelIndex, QModelIndex)));
70   }
71 }
72
73 void BufferWidget::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) {
74   Q_ASSERT(model());
75   if(!parent.isValid()) {
76     // ok this means that whole networks are about to be removed
77     // we can't determine which buffers are affect, so we hope that all nets are removed
78     // this is the most common case (for example disconnecting from the core or terminating the clint)
79     if(model()->rowCount(parent) != end - start + 1)
80       return;
81
82     ChatWidget *chatWidget;
83     QHash<BufferId, ChatWidget *>::iterator iter = _chatWidgets.begin();
84     while(iter != _chatWidgets.end()) {
85       chatWidget = *iter;
86       iter = _chatWidgets.erase(iter);
87       ui.stackedWidget->removeWidget(chatWidget);
88       chatWidget->deleteLater();
89     }
90     
91   } else {
92     // check if there are explicitly buffers removed
93     for(int i = start; i <= end; i++) {
94       QVariant variant = parent.child(i,0).data(NetworkModel::BufferIdRole);
95       if(!variant.isValid())
96         continue;
97       
98       BufferId bufferId = qVariantValue<BufferId>(variant);
99       removeBuffer(bufferId);
100     }
101   }
102 }
103
104 void BufferWidget::removeBuffer(BufferId bufferId) {
105   if(!_chatWidgets.contains(bufferId))
106     return;
107
108   if(Client::buffer(bufferId)) Client::buffer(bufferId)->setVisible(false);
109   ChatWidget *chatWidget = _chatWidgets.take(bufferId);
110   ui.stackedWidget->removeWidget(chatWidget);
111   chatWidget->deleteLater();
112 }
113
114 void BufferWidget::currentChanged(const QModelIndex &current, const QModelIndex &previous) {
115   BufferId newBufferId = current.data(NetworkModel::BufferIdRole).value<BufferId>();
116   BufferId oldBufferId = previous.data(NetworkModel::BufferIdRole).value<BufferId>();
117   if(newBufferId != oldBufferId)
118     setCurrentBuffer(newBufferId);
119 }
120
121 void BufferWidget::setCurrentBuffer(BufferId bufferId) {
122   if(!bufferId.isValid()) {
123     ui.stackedWidget->setCurrentWidget(ui.page);
124     return;
125   }
126   
127   ChatWidget *chatWidget = 0;
128   ChatView *chatView = 0;
129   Buffer *buf = Client::buffer(bufferId);
130   if(!buf) {
131     qWarning() << "BufferWidget::setBuffer(BufferId): Can't show unknown Buffer:" << bufferId;
132     return;
133   }
134   Buffer *prevBuffer = Client::buffer(currentBuffer());
135   if(prevBuffer) prevBuffer->setVisible(false);
136   if(Global::SPUTDEV) {
137     if(_chatViews.contains(bufferId)) {
138       chatView = _chatViews[bufferId];
139     } else {
140       chatView = new ChatView(buf, this);
141       //chatView->init(bufferId);
142       QList<ChatLine *> lines;
143       QList<AbstractUiMsg *> msgs = buf->contents();
144       foreach(AbstractUiMsg *msg, msgs) {
145         lines.append(dynamic_cast<ChatLine *>(msg));
146       }
147       chatView->setContents(lines);
148       connect(buf, SIGNAL(msgAppended(AbstractUiMsg *)), chatView, SLOT(appendMsg(AbstractUiMsg *)));
149       connect(buf, SIGNAL(msgPrepended(AbstractUiMsg *)), chatView, SLOT(prependMsg(AbstractUiMsg *)));
150       _chatViews[bufferId] = chatView;
151       ui.stackedWidget->addWidget(chatView);
152       chatView->setFocusProxy(this);
153     }
154     _currentBuffer = bufferId;
155     ui.stackedWidget->setCurrentWidget(chatView);
156   } else {
157     if(_chatWidgets.contains(bufferId)) {
158       chatWidget = _chatWidgets[bufferId];
159     } else {
160       chatWidget = new ChatWidget(this);
161       chatWidget->init(bufferId);
162       QList<ChatLineOld *> lines;
163       QList<AbstractUiMsg *> msgs = buf->contents();
164       foreach(AbstractUiMsg *msg, msgs) {
165         lines.append(dynamic_cast<ChatLineOld*>(msg));
166       }
167       chatWidget->setContents(lines);
168       connect(buf, SIGNAL(msgAppended(AbstractUiMsg *)), chatWidget, SLOT(appendMsg(AbstractUiMsg *)));
169       connect(buf, SIGNAL(msgPrepended(AbstractUiMsg *)), chatWidget, SLOT(prependMsg(AbstractUiMsg *)));
170       _chatWidgets[bufferId] = chatWidget;
171       ui.stackedWidget->addWidget(chatWidget);
172       chatWidget->setFocusProxy(this);
173     }
174     _currentBuffer = bufferId;
175     ui.stackedWidget->setCurrentWidget(chatWidget);
176   }
177   buf->setVisible(true);
178   setFocus();
179 }
180