-added tray icon notification
[quassel.git] / src / qtui / nicklistwidget.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 "nicklistwidget.h"
22
23 #include "buffer.h"
24 #include "nickview.h"
25 #include "client.h"
26 #include "networkmodel.h"
27 #include "buffermodel.h"
28 #include "nickviewfilter.h"
29 #include "qtuisettings.h"
30
31 NickListWidget::NickListWidget(QWidget *parent)
32   : AbstractItemView(parent),
33     _showNickListAction(new QAction(tr("Nicks"), this)),
34     _showDockAction(0)
35 {
36   _showNickListAction->setCheckable(true);
37   QtUiSettings s;
38   _showNickListAction->setChecked(s.value("ShowNickListAction", QVariant(true)).toBool());
39   ui.setupUi(this);
40   connect(_showNickListAction, SIGNAL(toggled(bool)), this, SLOT(showWidget(bool)));
41 }
42
43 NickListWidget::~NickListWidget() {
44   QtUiSettings s;
45   s.setValue("ShowNickListAction", showNickListAction()->isChecked());
46 }
47
48 void NickListWidget::setShowDockAction(QAction *action) {
49   _showDockAction = action;
50 }
51
52 QAction *NickListWidget::showDockAction() const {
53   return _showDockAction;
54 }
55
56 QAction *NickListWidget::showNickListAction() const {
57   return _showNickListAction;
58 }
59
60 void NickListWidget::showWidget(bool visible) {
61   if(!selectionModel())
62     return;
63
64   QModelIndex currentIndex = selectionModel()->currentIndex();
65   if(currentIndex.data(NetworkModel::BufferTypeRole) == BufferInfo::ChannelBuffer && showDockAction()) {
66     if(visible  != showDockAction()->isChecked()) {
67       // show or hide
68       showDockAction()->trigger();
69     }
70   }
71 }
72
73 void NickListWidget::changedVisibility(bool visible) {
74   if(!selectionModel())
75     return;
76
77   QModelIndex currentIndex = selectionModel()->currentIndex();
78   if(currentIndex.data(NetworkModel::BufferTypeRole) == BufferInfo::ChannelBuffer && !visible) {
79     showNickListAction()->setChecked(false);
80   }
81 }
82
83 void NickListWidget::currentChanged(const QModelIndex &current, const QModelIndex &previous) {
84   BufferInfo::Type bufferType = (BufferInfo::Type)current.data(NetworkModel::BufferTypeRole).toInt();
85   BufferId newBufferId = current.data(NetworkModel::BufferIdRole).value<BufferId>();
86   BufferId oldBufferId = previous.data(NetworkModel::BufferIdRole).value<BufferId>();
87
88   if(bufferType != BufferInfo::ChannelBuffer) {
89     ui.stackedWidget->setCurrentWidget(ui.emptyPage);
90     if(showDockAction() && showDockAction()->isChecked()) {
91       // hide
92       showDockAction()->trigger();
93     }
94     return;
95   } else {
96     if(showNickListAction()->isChecked())
97       if(showDockAction()&& !showDockAction()->isChecked()) {
98         // show
99         showDockAction()->trigger();
100       }
101   }
102
103   if(newBufferId == oldBufferId)
104     return;
105
106   if(nickViews.contains(newBufferId)) {
107     ui.stackedWidget->setCurrentWidget(nickViews.value(newBufferId));
108   } else {
109     NickView *view = new NickView(this);
110     NickViewFilter *filter = new NickViewFilter(newBufferId, Client::networkModel());
111     view->setModel(filter);
112     QModelIndex source_current = Client::bufferModel()->mapToSource(current);
113     view->setRootIndex(filter->mapFromSource(source_current));
114     view->expandAll();
115     nickViews[newBufferId] = view;
116     ui.stackedWidget->addWidget(view);
117     ui.stackedWidget->setCurrentWidget(view);
118   }
119 }
120
121 void NickListWidget::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) {
122   Q_ASSERT(model());
123   if(!parent.isValid()) {
124     // ok this means that whole networks are about to be removed
125     // we can't determine which buffers are affect, so we hope that all nets are removed
126     // this is the most common case (for example disconnecting from the core or terminating the clint)
127     NickView *nickView;
128     QHash<BufferId, NickView *>::iterator iter = nickViews.begin();
129     while(iter != nickViews.end()) {
130       nickView = *iter;
131       iter = nickViews.erase(iter);
132       ui.stackedWidget->removeWidget(nickView);
133       QAbstractItemModel *model = nickView->model();
134       nickView->setModel(0);
135       if(QSortFilterProxyModel *filter = qobject_cast<QSortFilterProxyModel *>(model))
136         filter->setSourceModel(0);
137       model->deleteLater();
138       nickView->deleteLater();
139     }
140   } else {
141     // check if there are explicitly buffers removed
142     for(int i = start; i <= end; i++) {
143       QVariant variant = parent.child(i,0).data(NetworkModel::BufferIdRole);
144       if(!variant.isValid())
145         continue;
146
147       BufferId bufferId = qVariantValue<BufferId>(variant);
148       removeBuffer(bufferId);
149     }
150   }
151 }
152
153 void NickListWidget::removeBuffer(BufferId bufferId) {
154   if(!nickViews.contains(bufferId))
155     return;
156
157   NickView *view = nickViews.take(bufferId);
158   ui.stackedWidget->removeWidget(view);
159   QAbstractItemModel *model = view->model();
160   view->setModel(0);
161   if(QSortFilterProxyModel *filter = qobject_cast<QSortFilterProxyModel *>(model))
162     filter->setSourceModel(0);
163   model->deleteLater();
164   view->deleteLater();
165 }
166
167 QSize NickListWidget::sizeHint() const {
168   QWidget *currentWidget = ui.stackedWidget->currentWidget();
169   if(!currentWidget || currentWidget == ui.emptyPage)
170     return QSize(100, height());
171   else
172     return currentWidget->sizeHint();
173 }