1/***************************************************************************
2 * Copyright (C) 2005-2014 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 "nicklistwidget.h"
22
23#include "nickview.h"
24#include "client.h"
25#include "networkmodel.h"
26#include "buffermodel.h"
27#include "nickviewfilter.h"
28#include "qtuisettings.h"
29
30#include <QAction>
31#include <QDebug>
32#include <QEvent>
33#include <QAbstractButton>
34
35NickListWidget::NickListWidget(QWidget *parent)
36 : AbstractItemView(parent)
37{
38 ui.setupUi(this);
39}
40
41
42QDockWidget *NickListWidget::dock() const
43{
44 QDockWidget *dock = qobject_cast<QDockWidget *>(parent());
45 if (dock)
46 return dock;
47 else
48 return 0;
49}
50
51
52void NickListWidget::hideEvent(QHideEvent *event)
53{
54 emit nickSelectionChanged(QModelIndexList());
55 AbstractItemView::hideEvent(event);
56}
57
58
59void NickListWidget::showEvent(QShowEvent *event)
60{
61 NickView *view = qobject_cast<NickView *>(ui.stackedWidget->currentWidget());
62 if (view)
63 emit nickSelectionChanged(view->selectedIndexes());
64
65 AbstractItemView::showEvent(event);
66}
67
68
69void NickListWidget::showWidget(bool visible)
70{
71 if (!selectionModel())
72 return;
73
74 QModelIndex currentIndex = selectionModel()->currentIndex();
75 if (currentIndex.data(NetworkModel::BufferTypeRole) == BufferInfo::ChannelBuffer) {
76 QDockWidget *dock_ = dock();
77 if (!dock_)
78 return;
79
80 if (visible)
81 dock_->show();
82 else
83 dock_->close();
84 }
85}
86
87
88void NickListWidget::currentChanged(const QModelIndex &current, const QModelIndex &previous)
89{
90 BufferInfo::Type bufferType = (BufferInfo::Type)current.data(NetworkModel::BufferTypeRole).toInt();
91 BufferId newBufferId = current.data(NetworkModel::BufferIdRole).value<BufferId>();
92 BufferId oldBufferId = previous.data(NetworkModel::BufferIdRole).value<BufferId>();
93
94 if (bufferType != BufferInfo::ChannelBuffer) {
95 ui.stackedWidget->setCurrentWidget(ui.emptyPage);
96 emit nickSelectionChanged(QModelIndexList());
97 return;
98 }
99
100 // See NickListDock::NickListDock() below
101// if(bufferType != BufferInfo::ChannelBuffer) {
102// ui.stackedWidget->setCurrentWidget(ui.emptyPage);
103// QDockWidget *dock_ = dock();
104// if(dock_) {
105// dock_->close();
106// }
107// return;
108// } else {
109// QDockWidget *dock_ = dock();
110// if(dock_ && dock_->toggleViewAction()->isChecked()) {
111// dock_->show();
112// }
113// }
114
115 if (newBufferId == oldBufferId)
116 return;
117
118 NickView *view;
119 if (nickViews.contains(newBufferId)) {
120 view = nickViews.value(newBufferId);
121 ui.stackedWidget->setCurrentWidget(view);
122 }
123 else {
124 view = new NickView(this);
125 NickViewFilter *filter = new NickViewFilter(newBufferId, Client::networkModel());
126 view->setModel(filter);
127 QModelIndex source_current = Client::bufferModel()->mapToSource(current);
128 view->setRootIndex(filter->mapFromSource(source_current));
129 nickViews[newBufferId] = view;
130 ui.stackedWidget->addWidget(view);
131 ui.stackedWidget->setCurrentWidget(view);
132 connect(view, SIGNAL(selectionUpdated()), SLOT(nickSelectionChanged()));
133 }
134 emit nickSelectionChanged(view->selectedIndexes());
135}
136
137
138void NickListWidget::nickSelectionChanged()
139{
140 NickView *view = qobject_cast<NickView *>(sender());
141 Q_ASSERT(view);
142 if (view != ui.stackedWidget->currentWidget()) {
143 qDebug() << "Nick selection of hidden view changed!";
144 return;
145 }
146 emit nickSelectionChanged(view->selectedIndexes());
147}
148
149
150void NickListWidget::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
151{
152 Q_ASSERT(model());
153 if (!parent.isValid()) {
154 // ok this means that whole networks are about to be removed
155 // we can't determine which buffers are affect, so we hope that all nets are removed
156 // this is the most common case (for example disconnecting from the core or terminating the clint)
157 NickView *nickView;
158 QHash<BufferId, NickView *>::iterator iter = nickViews.begin();
159 while (iter != nickViews.end()) {
160 nickView = *iter;
161 iter = nickViews.erase(iter);
162 ui.stackedWidget->removeWidget(nickView);
163 QAbstractItemModel *model = nickView->model();
164 nickView->setModel(0);
165 if (QSortFilterProxyModel *filter = qobject_cast<QSortFilterProxyModel *>(model))
166 filter->setSourceModel(0);
167 model->deleteLater();
168 nickView->deleteLater();
169 }
170 }
171 else {
172 // check if there are explicitly buffers removed
173 for (int i = start; i <= end; i++) {
174 QVariant variant = parent.child(i, 0).data(NetworkModel::BufferIdRole);
175 if (!variant.isValid())
176 continue;
177
178 BufferId bufferId = variant.value<BufferId>();
179 removeBuffer(bufferId);
180 }
181 }
182}
183
184
185void NickListWidget::removeBuffer(BufferId bufferId)
186{
187 if (!nickViews.contains(bufferId))
188 return;
189
190 NickView *view = nickViews.take(bufferId);
191 ui.stackedWidget->removeWidget(view);
192 QAbstractItemModel *model = view->model();
193 view->setModel(0);
194 if (QSortFilterProxyModel *filter = qobject_cast<QSortFilterProxyModel *>(model))
195 filter->setSourceModel(0);
196 model->deleteLater();
197 view->deleteLater();
198}
199
200
201QSize NickListWidget::sizeHint() const
202{
203 QWidget *currentWidget = ui.stackedWidget->currentWidget();
204 if (!currentWidget || currentWidget == ui.emptyPage)
205 return QSize(100, height());
206 else
207 return currentWidget->sizeHint();
208}
209
210
211// ==============================
212// NickList Dock
213// ==============================
214NickListDock::NickListDock(const QString &title, QWidget *parent)
215 : QDockWidget(title, parent)
216{
217 // THIS STUFF IS NEEDED FOR NICKLIST AUTOHIDE...
218 // AS THIS BRINGS LOTS OF FUCKUPS WITH IT IT'S DEACTIVATED FOR NOW...
219
220// QAction *toggleView = toggleViewAction();
221// disconnect(toggleView, SIGNAL(triggered(bool)), this, 0);
222// toggleView->setChecked(QtUiSettings().value("ShowNickList", QVariant(true)).toBool());
223
224// // reconnecting the closebuttons clicked signal to the action
225// foreach(QAbstractButton *button, findChildren<QAbstractButton *>()) {
226// if(disconnect(button, SIGNAL(clicked()), this, SLOT(close())))
227// connect(button, SIGNAL(clicked()), toggleView, SLOT(trigger()));
228// }
229}
230
231
232// NickListDock::~NickListDock() {
233// QtUiSettings().setValue("ShowNickList", toggleViewAction()->isChecked());
234// }
235
236// bool NickListDock::event(QEvent *event) {
237// switch (event->type()) {
238// case QEvent::Hide:
239// case QEvent::Show:
240// emit visibilityChanged(event->type() == QEvent::Show);
241// return QWidget::event(event);
242// default:
243// return QDockWidget::event(event);
244// }
245// }
246