Add rudimentary keyboard navigation for previous/next buffer
[quassel.git] / src / uisupport / toolbaractionprovider.cpp
1 /***************************************************************************
2  *   Copyright (C) 2005-09 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 <QMenu>
22 #include <QToolBar>
23
24 #include "toolbaractionprovider.h"
25
26 #include "iconloader.h"
27
28 ToolBarActionProvider::ToolBarActionProvider(QObject *parent)
29 : NetworkModelController(parent)
30 {
31   registerAction(NetworkConnectAll, DesktopIcon("network-connect"), tr("Connect"))->setToolTip(tr("Connect to IRC"));
32   registerAction(NetworkDisconnectAll, DesktopIcon("network-disconnect"), tr("Disconnect"))->setToolTip(tr("Disconnect from IRC"));
33
34   registerAction(BufferPart, DesktopIcon("irc-close-channel"), tr("Part"))->setToolTip(tr("Leave currently selected channel"));
35   registerAction(JoinChannel, DesktopIcon("irc-join-channel"), tr("Join"))->setToolTip(tr("Join a channel"));
36
37   registerAction(NickQuery, DesktopIcon("mail-message-new"), tr("Query"))->setToolTip(tr("Start a private conversation")); // fix icon
38   registerAction(NickWhois, DesktopIcon("im-user"), tr("Whois"))->setToolTip(tr("Request user information")); // fix icon
39
40   registerAction(NickOp, DesktopIcon("irc-operator"), tr("Op"))->setToolTip(tr("Give operator privileges to user"));
41   registerAction(NickDeop, DesktopIcon("irc-remove-operator"), tr("Deop"))->setToolTip(tr("Take operator privileges from user"));
42   registerAction(NickVoice, DesktopIcon("irc-voice"), tr("Voice"))->setToolTip(tr("Give voice to user"));
43   registerAction(NickDevoice, DesktopIcon("irc-unvoice"), tr("Devoice"))->setToolTip(tr("Take voice from user"));
44   registerAction(NickKick, DesktopIcon("im-kick-user"), tr("Kick"))->setToolTip(tr("Remove user from channel"));
45   registerAction(NickBan, DesktopIcon("im-ban-user"), tr("Ban"))->setToolTip(tr("Ban user from channel"));
46   registerAction(NickKickBan, DesktopIcon("im-ban-kick-user"), tr("Kick/Ban"))->setToolTip(tr("Remove and ban user from channel"));
47
48   _networksConnectMenu = new QMenu();
49   _networksConnectMenu->setSeparatorsCollapsible(false);
50   _networksConnectMenu->addSeparator();
51   _networksConnectMenu->addAction(tr("Connect to all"));
52   action(NetworkConnectAll)->setMenu(_networksConnectMenu);
53   action(NetworkConnectAll)->setEnabled(false);
54
55   _networksDisconnectMenu = new QMenu();
56   _networksDisconnectMenu->setSeparatorsCollapsible(false);
57   _networksDisconnectMenu->addSeparator();
58   _networksDisconnectMenu->addAction(tr("Disconnect from all"));
59   action(NetworkDisconnectAll)->setMenu(_networksDisconnectMenu);
60   action(NetworkDisconnectAll)->setEnabled(false);
61
62   connect(Client::instance(), SIGNAL(networkCreated(NetworkId)), SLOT(networkCreated(NetworkId)));
63   connect(Client::instance(), SIGNAL(networkRemoved(NetworkId)), SLOT(networkRemoved(NetworkId)));
64
65   updateStates();
66 }
67
68 ToolBarActionProvider::~ToolBarActionProvider() {
69
70 }
71
72 void ToolBarActionProvider::disconnectedFromCore() {
73   _currentBuffer = QModelIndex();
74   updateStates();
75   NetworkModelController::disconnectedFromCore();
76 }
77
78 void ToolBarActionProvider::updateStates() {
79   action(BufferPart)->setEnabled(_currentBuffer.isValid()
80                               && _currentBuffer.data(NetworkModel::BufferTypeRole) == BufferInfo::ChannelBuffer
81                               && _currentBuffer.data(NetworkModel::ItemActiveRole).toBool());
82
83 }
84
85 void ToolBarActionProvider::addActions(QToolBar *bar, ToolBarType type) {
86   switch(type) {
87     case MainToolBar:
88       bar->addAction(action(NetworkConnectAll));
89       bar->addAction(action(NetworkDisconnectAll));
90       bar->addAction(action(JoinChannel));
91       bar->addAction(action(BufferPart));
92       break;
93     case NickToolBar:
94       bar->addAction(action(NickQuery));
95       bar->addAction(action(NickWhois));
96       bar->addSeparator();
97       bar->addAction(action(NickOp));
98       bar->addAction(action(NickDeop));
99       bar->addAction(action(NickVoice));
100       bar->addAction(action(NickDevoice));
101       bar->addAction(action(NickKick));
102       bar->addAction(action(NickBan));
103       bar->addAction(action(NickKickBan));
104       break;
105     default:
106       return;
107   }
108 }
109
110 void ToolBarActionProvider::currentBufferChanged(const QModelIndex &index) {
111   _currentBuffer = index;
112   updateStates();
113 }
114
115 void ToolBarActionProvider::nickSelectionChanged(const QModelIndexList &indexList) {
116   _selectedNicks = indexList;
117   updateStates();
118 }
119
120 // override those to set indexes right
121 void ToolBarActionProvider::handleNetworkAction(ActionType type, QAction *action) {
122   setIndexList(_currentBuffer);
123   NetworkModelController::handleNetworkAction(type, action);
124 }
125
126 void ToolBarActionProvider::handleBufferAction(ActionType type, QAction *action) {
127   setIndexList(_currentBuffer);
128   NetworkModelController::handleBufferAction(type, action);
129 }
130
131 void ToolBarActionProvider::handleNickAction(ActionType type, QAction *action) {
132   setIndexList(_selectedNicks);
133   NetworkModelController::handleNickAction(type, action);
134 }
135
136 void ToolBarActionProvider::handleGeneralAction(ActionType type, QAction *action) {
137   setIndexList(_currentBuffer);
138   NetworkModelController::handleGeneralAction(type, action);
139 }
140
141 void ToolBarActionProvider::networkCreated(NetworkId id) {
142   const Network *net = Client::network(id);
143   Action *act = new Action(net->networkName(), this);
144   _networkActions[id] = act;
145   act->setObjectName(QString("NetworkAction-%1").arg(id.toInt()));
146   act->setData(QVariant::fromValue<NetworkId>(id));
147   connect(net, SIGNAL(updatedRemotely()), SLOT(networkUpdated()));
148   connect(act, SIGNAL(triggered()), SLOT(connectOrDisconnectNet()));
149   networkUpdated(net);
150 }
151
152 void ToolBarActionProvider::networkRemoved(NetworkId id) {
153   Action *act = _networkActions.take(id);
154   if(act)
155     act->deleteLater();
156 }
157
158 void ToolBarActionProvider::networkUpdated(const Network *net) {
159   if(!net)
160     net = qobject_cast<const Network *>(sender());
161   if(!net)
162     return;
163   Action *act = _networkActions.value(net->networkId());
164   if(!act)
165     return;
166
167   _networksConnectMenu->removeAction(act);
168   _networksDisconnectMenu->removeAction(act);
169
170   QMenu *newMenu = net->connectionState() != Network::Disconnected ? _networksDisconnectMenu : _networksConnectMenu;
171   act->setText(net->networkName());
172
173   const int lastidx = newMenu->actions().count() - 2;
174   QAction *beforeAction = newMenu->actions().at(lastidx);
175   for(int i = 0; i < newMenu->actions().count() - 2; i++) {
176     QAction *action = newMenu->actions().at(i);
177     if(net->networkName().localeAwareCompare(action->text()) < 0) {
178       beforeAction = action;
179       break;
180     }
181   }
182   newMenu->insertAction(beforeAction, act);
183
184   action(NetworkConnectAll)->setEnabled(_networksConnectMenu->actions().count() > 2);
185   action(NetworkDisconnectAll)->setEnabled(_networksDisconnectMenu->actions().count() > 2);
186   action(JoinChannel)->setEnabled(_networksDisconnectMenu->actions().count() > 2);
187 }
188
189 void ToolBarActionProvider::connectOrDisconnectNet() {
190   QAction *act = qobject_cast<QAction *>(sender());
191   if(!act)
192     return;
193   const Network *net = Client::network(act->data().value<NetworkId>());
194   if(!net)
195     return;
196
197   if(net->connectionState() == Network::Disconnected) net->requestConnect();
198   else net->requestDisconnect();
199 }
200
201 //void ToolBarActionProvider::