31117f4eff54e8d4c86110c45ad4b54d206b9ffc
[quassel.git] / src / uisupport / networkmodelactionprovider.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 <QInputDialog>
22 #include <QMenu>
23 #include <QMessageBox>
24
25 #include "networkmodelactionprovider.h"
26
27 #include "buffermodel.h"
28 #include "buffersettings.h"
29 #include "iconloader.h"
30 #include "identity.h"
31 #include "network.h"
32
33 NetworkModelActionProvider::NetworkModelActionProvider(QObject *parent)
34 : AbstractActionProvider(parent),
35   _actionCollection(new ActionCollection(this)),
36   _messageFilter(0),
37   _receiver(0)
38 {
39   registerAction(NetworkConnect, SmallIcon("network-connect"), tr("Connect"));
40   registerAction(NetworkDisconnect, SmallIcon("network-disconnect"), tr("Disconnect"));
41
42   registerAction(BufferJoin, tr("Join"));
43   registerAction(BufferPart, tr("Part"));
44   registerAction(BufferRemove, tr("Delete Buffer..."));
45   registerAction(BufferSwitchTo, tr("Show Buffer"));
46
47   registerAction(HideJoin, tr("Joins"), true);
48   registerAction(HidePart, tr("Parts"), true);
49   registerAction(HideQuit, tr("Quits"), true);
50   registerAction(HideNick, tr("Nick Changes"), true);
51   registerAction(HideMode, tr("Mode Changes"), true);
52   registerAction(HideDayChange, tr("Day Changes"), true);
53   registerAction(HideApplyToAll, tr("Apply to All Chat Views..."));
54
55   registerAction(JoinChannel, tr("Join Channel..."));
56
57   registerAction(NickQuery, tr("Start Query"));
58   registerAction(NickSwitchTo, tr("Show Query"));
59   registerAction(NickWhois, tr("Whois"));
60
61   registerAction(NickCtcpVersion, tr("Version"));
62   registerAction(NickCtcpTime, tr("Time"));
63   registerAction(NickCtcpPing, tr("Ping"));
64   registerAction(NickCtcpFinger, tr("Finger"));
65
66   registerAction(NickOp, tr("Give Operator Status"));
67   registerAction(NickDeop, tr("Take Operator Status"));
68   registerAction(NickVoice, tr("Give Voice"));
69   registerAction(NickDevoice, tr("Take Voice"));
70   registerAction(NickKick, tr("Kick From Channel"));
71   registerAction(NickBan, tr("Ban From Channel"));
72   registerAction(NickKickBan, tr("Kick && Ban"));
73
74   registerAction(HideBufferTemporarily, tr("Hide Buffer(s) Temporarily"));
75   registerAction(HideBufferPermanently, tr("Hide Buffer(s) Permanently"));
76   registerAction(ShowChannelList, SmallIcon("format-list-unordered"), tr("Show Channel List"));
77   registerAction(ShowIgnoreList, tr("Show Ignore List"));
78
79   connect(_actionCollection, SIGNAL(actionTriggered(QAction *)), SLOT(actionTriggered(QAction *)));
80
81   action(HideApplyToAll)->setDisabled(true);
82
83   QMenu *hideEventsMenu = new QMenu();
84   hideEventsMenu->addAction(action(HideJoin));
85   hideEventsMenu->addAction(action(HidePart));
86   hideEventsMenu->addAction(action(HideQuit));
87   hideEventsMenu->addAction(action(HideNick));
88   hideEventsMenu->addAction(action(HideMode));
89   hideEventsMenu->addAction(action(HideDayChange));
90   hideEventsMenu->addSeparator();
91   hideEventsMenu->addAction(action(HideApplyToAll));
92   _hideEventsMenuAction = new Action(tr("Hide Events"), 0);
93   _hideEventsMenuAction->setMenu(hideEventsMenu);
94
95   QMenu *nickCtcpMenu = new QMenu();
96   nickCtcpMenu->addAction(action(NickCtcpPing));
97   nickCtcpMenu->addAction(action(NickCtcpVersion));
98   nickCtcpMenu->addAction(action(NickCtcpTime));
99   nickCtcpMenu->addAction(action(NickCtcpFinger));
100   _nickCtcpMenuAction = new Action(tr("CTCP"), 0);
101   _nickCtcpMenuAction->setMenu(nickCtcpMenu);
102
103   QMenu *nickModeMenu = new QMenu();
104   nickModeMenu->addAction(action(NickOp));
105   nickModeMenu->addAction(action(NickDeop));
106   nickModeMenu->addAction(action(NickVoice));
107   nickModeMenu->addAction(action(NickDevoice));
108   nickModeMenu->addSeparator();
109   nickModeMenu->addAction(action(NickKick));
110   nickModeMenu->addAction(action(NickBan));
111   nickModeMenu->addAction(action(NickKickBan));
112   _nickModeMenuAction = new Action(tr("Actions"), 0);
113   _nickModeMenuAction->setMenu(nickModeMenu);
114 }
115
116 NetworkModelActionProvider::~NetworkModelActionProvider() {
117   _hideEventsMenuAction->menu()->deleteLater();
118   _hideEventsMenuAction->deleteLater();
119   _nickCtcpMenuAction->menu()->deleteLater();
120   _nickCtcpMenuAction->deleteLater();
121   _nickModeMenuAction->menu()->deleteLater();
122   _nickModeMenuAction->deleteLater();
123 }
124
125 void NetworkModelActionProvider::registerAction(ActionType type, const QString &text, bool checkable) {
126   registerAction(type, QPixmap(), text, checkable);
127 }
128
129 void NetworkModelActionProvider::registerAction(ActionType type, const QPixmap &icon, const QString &text, bool checkable) {
130   Action *act;
131   if(icon.isNull())
132     act = new Action(text, this);
133   else
134     act = new Action(icon, text, this);
135
136   act->setCheckable(checkable);
137   act->setData(type);
138
139   _actionCollection->addAction(QString::number(type, 16), act);
140   _actionByType[type] = act;
141 }
142
143 void NetworkModelActionProvider::addActions(QMenu *menu, BufferId bufId, QObject *receiver, const char *method) {
144   if(!bufId.isValid())
145     return;
146   _messageFilter = 0;
147   _contextItem = QString();
148   addActions(menu, Client::networkModel()->bufferIndex(bufId), receiver, method);
149 }
150
151 void NetworkModelActionProvider::addActions(QMenu *menu, const QModelIndex &index, QObject *receiver, const char *method, bool isCustomBufferView) {
152   if(!index.isValid())
153     return;
154   _messageFilter = 0;
155   _contextItem = QString();
156   addActions(menu, QList<QModelIndex>() << index, receiver, method, isCustomBufferView);
157 }
158
159 void NetworkModelActionProvider::addActions(QMenu *menu, MessageFilter *filter, BufferId msgBuffer, QObject *receiver, const char *slot) {
160   addActions(menu, filter, msgBuffer, QString(), receiver, slot);
161 }
162
163 void NetworkModelActionProvider::addActions(QMenu *menu, MessageFilter *filter, BufferId msgBuffer, const QString &chanOrNick, QObject *receiver, const char *method) {
164   if(!filter)
165     return;
166   _messageFilter = filter;
167   _contextItem = chanOrNick;
168   addActions(menu, QList<QModelIndex>() << Client::networkModel()->bufferIndex(msgBuffer), receiver, method);
169 }
170
171 // add a list of actions sensible for the current item(s)
172 void NetworkModelActionProvider::addActions(QMenu *menu,
173                                             const QList<QModelIndex> &indexList,
174                                             QObject *receiver,
175                                             const char *method,
176                                             bool isCustomBufferView)
177 {
178   if(!indexList.count())
179     return;
180
181   _indexList = indexList;
182   _receiver = receiver;
183   _method = method;
184
185   if(!_messageFilter) {
186     // this means we are in a BufferView (or NickView) rather than a ChatView
187
188     // first index in list determines the menu type (just in case we have both buffers and networks selected, for example)
189     QModelIndex index = _indexList.at(0);
190     NetworkModel::ItemType itemType = static_cast<NetworkModel::ItemType>(index.data(NetworkModel::ItemTypeRole).toInt());
191
192     switch(itemType) {
193       case NetworkModel::NetworkItemType:
194         addNetworkItemActions(menu, index);
195         break;
196       case NetworkModel::BufferItemType:
197         addBufferItemActions(menu, index, isCustomBufferView);
198         break;
199       case NetworkModel::IrcUserItemType:
200         addIrcUserActions(menu, index);
201         break;
202       default:
203         return;
204
205     }
206   } else {
207     // ChatView actions
208     if(_contextItem.isEmpty()) {
209       // a) query buffer: handle like ircuser
210       // b) general chatview: handle like channel iff it displays a single buffer
211       // NOTE stuff breaks probably with merged buffers, need to rework a lot around here then
212       if(_messageFilter->containedBuffers().count() == 1) {
213         // we can handle this like a single bufferItem
214         QModelIndex index = Client::networkModel()->bufferIndex(_messageFilter->containedBuffers().values().at(0));
215         _indexList = QList<QModelIndex>() << index;
216         addBufferItemActions(menu, index);
217         return;
218       } else {
219         // TODO: actions for merged buffers... _indexList contains the index of the message we clicked on
220
221       }
222     }
223   }
224 }
225
226 void NetworkModelActionProvider::addNetworkItemActions(QMenu *menu, const QModelIndex &index) {
227   NetworkId networkId = index.data(NetworkModel::NetworkIdRole).value<NetworkId>();
228   if(!networkId.isValid())
229     return;
230   const Network *network = Client::network(networkId);
231   Q_CHECK_PTR(network);
232   if(!network)
233     return;
234
235   addAction(NetworkConnect, menu, network->connectionState() == Network::Disconnected);
236   addAction(NetworkDisconnect, menu, network->connectionState() != Network::Disconnected);
237   menu->addSeparator();
238   addAction(ShowChannelList, menu, index, ActiveState);
239   addAction(JoinChannel, menu, index, ActiveState);
240
241 }
242
243 void NetworkModelActionProvider::addBufferItemActions(QMenu *menu, const QModelIndex &index, bool isCustomBufferView) {
244   BufferInfo bufferInfo = index.data(NetworkModel::BufferInfoRole).value<BufferInfo>();
245
246   switch(bufferInfo.type()) {
247     case BufferInfo::ChannelBuffer:
248       addAction(BufferJoin, menu, index, InactiveState);
249       addAction(BufferPart, menu, index, ActiveState);
250       menu->addSeparator();
251       addHideEventsMenu(menu, bufferInfo.bufferId());
252       menu->addSeparator();
253       addAction(HideBufferTemporarily, menu, isCustomBufferView);
254       addAction(HideBufferPermanently, menu, isCustomBufferView);
255       addAction(BufferRemove, menu, index);
256       break;
257
258     case BufferInfo::QueryBuffer:
259     {
260       //IrcUser *ircUser = qobject_cast<IrcUser *>(index.data(NetworkModel::IrcUserRole).value<QObject *>());
261       //if(ircUser) {
262         addIrcUserActions(menu, index);
263         menu->addSeparator();
264       //}
265       addHideEventsMenu(menu, bufferInfo.bufferId());
266       menu->addSeparator();
267       addAction(HideBufferTemporarily, menu, isCustomBufferView);
268       addAction(HideBufferPermanently, menu, isCustomBufferView);
269       addAction(BufferRemove, menu, index);
270       break;
271     }
272
273     default:
274       addAction(HideBufferTemporarily, menu, isCustomBufferView);
275       addAction(HideBufferPermanently, menu, isCustomBufferView);
276   }
277 }
278
279 void NetworkModelActionProvider::addIrcUserActions(QMenu *menu, const QModelIndex &index) {
280   // this can be called: a) as a nicklist context menu (index has IrcUserItemType)
281   //                     b) as a query buffer context menu (index has BufferItemType and is a QueryBufferItem)
282   //                     c) right-click in a query chatview (same as b), index will be the corresponding QueryBufferItem)
283   //                     d) right-click on some nickname (_contextItem will be non-null, _filter -> chatview, index -> message buffer)
284
285   if(_contextItem.isNull()) {
286     // cases a, b, c
287     bool haveQuery = findQueryBuffer(index).isValid();
288     NetworkModel::ItemType itemType = static_cast<NetworkModel::ItemType>(index.data(NetworkModel::ItemTypeRole).toInt());
289     addAction(_nickModeMenuAction, menu, itemType == NetworkModel::IrcUserItemType);
290     addAction(_nickCtcpMenuAction, menu);
291     menu->addSeparator();
292     addAction(NickQuery, menu, itemType == NetworkModel::IrcUserItemType && !haveQuery);
293     addAction(NickSwitchTo, menu, itemType == NetworkModel::IrcUserItemType && haveQuery);
294     menu->addSeparator();
295     addAction(NickWhois, menu, true);
296
297   } else if(!_contextItem.isEmpty() && _messageFilter) {
298     // case d
299     // TODO
300
301   }
302 }
303
304 /******** Helper Functions ***********************************************************************/
305
306 bool NetworkModelActionProvider::checkRequirements(const QModelIndex &index, ItemActiveStates requiredActiveState) {
307   if(!index.isValid())
308     return false;
309
310   ItemActiveStates isActive = index.data(NetworkModel::ItemActiveRole).toBool()
311   ? ActiveState
312   : InactiveState;
313
314   if(!(isActive & requiredActiveState))
315     return false;
316
317   return true;
318 }
319
320 Action * NetworkModelActionProvider::addAction(ActionType type , QMenu *menu, const QModelIndex &index, ItemActiveStates requiredActiveState) {
321   return addAction(action(type), menu, checkRequirements(index, requiredActiveState));
322 }
323
324 Action * NetworkModelActionProvider::addAction(Action *action , QMenu *menu, const QModelIndex &index, ItemActiveStates requiredActiveState) {
325   return addAction(action, menu, checkRequirements(index, requiredActiveState));
326 }
327
328 Action * NetworkModelActionProvider::addAction(ActionType type , QMenu *menu, bool condition) {
329   return addAction(action(type), menu, condition);
330 }
331
332 Action * NetworkModelActionProvider::addAction(Action *action , QMenu *menu, bool condition) {
333   if(condition) {
334     menu->addAction(action);
335     action->setVisible(true);
336   } else {
337     action->setVisible(false);
338   }
339   return action;
340 }
341
342 void NetworkModelActionProvider::addHideEventsMenu(QMenu *menu, BufferId bufferId) {
343   addHideEventsMenu(menu, BufferSettings(bufferId).messageFilter());
344 }
345
346 void NetworkModelActionProvider::addHideEventsMenu(QMenu *menu, MessageFilter *msgFilter) {
347   addHideEventsMenu(menu, BufferSettings(msgFilter->idString()).messageFilter());
348 }
349
350 void NetworkModelActionProvider::addHideEventsMenu(QMenu *menu, int filter) {
351   action(HideJoin)->setChecked(filter & Message::Join);
352   action(HidePart)->setChecked(filter & Message::Part);
353   action(HideQuit)->setChecked(filter & Message::Quit);
354   action(HideNick)->setChecked(filter & Message::Nick);
355   action(HideMode)->setChecked(filter & Message::Mode);
356   action(HideDayChange)->setChecked(filter & Message::DayChange);
357
358   menu->addAction(_hideEventsMenuAction);
359 }
360
361 QString NetworkModelActionProvider::nickName(const QModelIndex &index) const {
362   IrcUser *ircUser = qobject_cast<IrcUser *>(index.data(NetworkModel::IrcUserRole).value<QObject *>());
363   if(ircUser)
364     return ircUser->nick();
365
366   BufferInfo bufferInfo = index.data(NetworkModel::BufferInfoRole).value<BufferInfo>();
367   if(!bufferInfo.isValid())
368     return QString();
369
370   return bufferInfo.bufferName(); // FIXME this might break with merged queries maybe
371 }
372
373 BufferId NetworkModelActionProvider::findQueryBuffer(const QModelIndex &index, const QString &predefinedNick) const {
374   NetworkId networkId = _indexList.at(0).data(NetworkModel::NetworkIdRole).value<NetworkId>();
375   if(!networkId.isValid())
376     return BufferId();
377
378   QString nick = predefinedNick.isEmpty() ? nickName(index) : predefinedNick;
379   if(nick.isEmpty())
380     return BufferId();
381
382   return findQueryBuffer(networkId, nick);
383 }
384
385 BufferId NetworkModelActionProvider::findQueryBuffer(NetworkId networkId, const QString &nick) const {
386   return Client::networkModel()->bufferId(networkId, nick);
387 }
388
389 void NetworkModelActionProvider::handleExternalAction(ActionType type, QAction *action) {
390   Q_UNUSED(type);
391   if(_receiver && _method) {
392     if(!QMetaObject::invokeMethod(_receiver, _method, Q_ARG(QAction *, action)))
393       qWarning() << "NetworkModelActionProvider::handleExternalAction(): Could not invoke slot" << _receiver << _method;
394   }
395 }
396
397 /******** Handle Actions *************************************************************************/
398
399 void NetworkModelActionProvider::actionTriggered(QAction *action) {
400   ActionType type = (ActionType)action->data().toInt();
401   if(type > 0) {
402     if(type & NetworkMask)
403       handleNetworkAction(type, action);
404     else if(type & BufferMask)
405       handleBufferAction(type, action);
406     else if(type & HideMask)
407       handleHideAction(type, action);
408     else if(type & GeneralMask)
409       handleGeneralAction(type, action);
410     else if(type & NickMask)
411       handleNickAction(type, action);
412     else if(type & ExternalMask)
413       handleExternalAction(type, action);
414     else
415       qWarning() << "NetworkModelActionProvider::actionTriggered(): Unhandled action!";
416   }
417   _indexList.clear();
418   _messageFilter = 0;
419   _receiver = 0;
420 }
421
422 void NetworkModelActionProvider::handleNetworkAction(ActionType type, QAction *) {
423   if(!_indexList.count())
424     return;
425   const Network *network = Client::network(_indexList.at(0).data(NetworkModel::NetworkIdRole).value<NetworkId>());
426   Q_CHECK_PTR(network);
427   if(!network)
428     return;
429
430   switch(type) {
431     case NetworkConnect:
432       network->requestConnect();
433       break;
434     case NetworkDisconnect:
435       network->requestDisconnect();
436       break;
437     default:
438       break;
439   }
440 }
441
442 void NetworkModelActionProvider::handleBufferAction(ActionType type, QAction *) {
443   foreach(QModelIndex index, _indexList) {
444     BufferInfo bufferInfo = index.data(NetworkModel::BufferInfoRole).value<BufferInfo>();
445     if(!bufferInfo.isValid())
446       continue;
447
448     switch(type) {
449       case BufferJoin:
450         Client::userInput(bufferInfo, QString("/JOIN %1").arg(bufferInfo.bufferName()));
451         break;
452       case BufferPart:
453       {
454         QString reason = Client::identity(Client::network(bufferInfo.networkId())->identity())->partReason();
455         Client::userInput(bufferInfo, QString("/PART %1").arg(reason));
456         break;
457       }
458       case BufferSwitchTo:
459         Client::bufferModel()->switchToBuffer(bufferInfo.bufferId());
460         break;
461       case BufferRemove:
462       {
463         int res = QMessageBox::question(0, tr("Remove buffer permanently?"),
464         tr("Do you want to delete the buffer \"%1\" permanently? This will delete all related data, including all backlog "
465         "data, from the core's database!").arg(bufferInfo.bufferName()),
466         QMessageBox::Yes|QMessageBox::No, QMessageBox::No);
467         if(res == QMessageBox::Yes) {
468           Client::removeBuffer(bufferInfo.bufferId());
469         }
470         break;
471       }
472       default:
473         break;
474     }
475   }
476 }
477
478 void NetworkModelActionProvider::handleHideAction(ActionType type, QAction *action) {
479   Message::Type msgType;
480   switch(type) {
481     case HideJoin:
482       msgType = Message::Join; break;
483     case HidePart:
484       msgType = Message::Part; break;
485     case HideQuit:
486       msgType = Message::Quit; break;
487     case HideNick:
488       msgType = Message::Nick; break;
489     case HideMode:
490       msgType = Message::Mode; break;
491     case HideDayChange:
492       msgType = Message::DayChange; break;
493     case HideApplyToAll:
494       // TODO implement "apply to all" for hiding messages
495       return;
496       break;
497     default:
498       return;
499   }
500
501   if(_messageFilter)
502     BufferSettings(_messageFilter->idString()).filterMessage(msgType, action->isChecked());
503   else {
504     foreach(QModelIndex index, _indexList) {
505       BufferId bufferId = index.data(NetworkModel::BufferIdRole).value<BufferId>();
506       if(!bufferId.isValid())
507         continue;
508       BufferSettings(bufferId).filterMessage(msgType, action->isChecked());
509     }
510   }
511 }
512
513 void NetworkModelActionProvider::handleGeneralAction(ActionType type, QAction *action) {
514   Q_UNUSED(action)
515
516   if(!_indexList.count())
517     return;
518   NetworkId networkId = _indexList.at(0).data(NetworkModel::NetworkIdRole).value<NetworkId>();
519   if(!networkId.isValid())
520     return;
521
522   switch(type) {
523     case JoinChannel:
524     {
525     //  FIXME no QInputDialog in Qtopia
526 #   ifndef Q_WS_QWS
527       bool ok;
528       QString channelName = QInputDialog::getText(0, tr("Join Channel"), tr("Input channel name:"), QLineEdit::Normal, QString(), &ok);
529       if(ok && !channelName.isEmpty()) {
530         Client::instance()->userInput(BufferInfo::fakeStatusBuffer(networkId),
531                                       QString("/JOIN %1").arg(channelName));
532       }
533 #   endif
534       break;
535     }
536     case ShowChannelList:
537       emit showChannelList(networkId);
538       break;
539     case ShowIgnoreList:
540       emit showIgnoreList(networkId);
541       break;
542     default:
543       break;
544   }
545 }
546
547 void NetworkModelActionProvider::handleNickAction(ActionType type, QAction *) {
548   if(!_indexList.count())
549     return;
550   NetworkId networkId = _indexList.at(0).data(NetworkModel::NetworkIdRole).value<NetworkId>();
551   if(!networkId.isValid())
552     return;
553   QString nick = nickName(_indexList.at(0));
554   if(nick.isEmpty())
555     return;
556   BufferInfo bufferInfo = _indexList.at(0).data(NetworkModel::BufferInfoRole).value<BufferInfo>();
557   if(!bufferInfo.isValid())
558     return;
559
560   switch(type) {
561     case NickWhois:
562       Client::userInput(bufferInfo, QString("/WHOIS %1 %1").arg(nick));
563       break;
564     case NickCtcpVersion:
565       Client::userInput(bufferInfo, QString("/CTCP %1 VERSION").arg(nick));
566       break;
567     case NickCtcpPing:
568       Client::userInput(bufferInfo, QString("/CTCP %1 PING").arg(nick));
569       break;
570     case NickCtcpTime:
571       Client::userInput(bufferInfo, QString("/CTCP %1 TIME").arg(nick));
572       break;
573     case NickCtcpFinger:
574       Client::userInput(bufferInfo, QString("/CTCP %1 FINGER").arg(nick));
575       break;
576     case NickOp:
577       Client::userInput(bufferInfo, QString("/OP %1").arg(nick));
578       break;
579     case NickDeop:
580       Client::userInput(bufferInfo, QString("/DEOP %1").arg(nick));
581       break;
582     case NickVoice:
583       Client::userInput(bufferInfo, QString("/VOICE %1").arg(nick));
584       break;
585     case NickDevoice:
586       Client::userInput(bufferInfo, QString("/DEVOICE %1").arg(nick));
587       break;
588     case NickKick:
589       Client::userInput(bufferInfo, QString("/KICK %1").arg(nick));
590       break;
591     case NickBan:
592       Client::userInput(bufferInfo, QString("/BAN %1").arg(nick));
593       break;
594     case NickKickBan:
595       Client::userInput(bufferInfo, QString("/BAN %1").arg(nick));
596       Client::userInput(bufferInfo, QString("/KICK %1").arg(nick));
597       break;
598     case NickSwitchTo:
599       Client::bufferModel()->switchToBuffer(findQueryBuffer(networkId, nick));
600       break;
601     case NickQuery:
602       Client::userInput(bufferInfo, QString("/QUERY %1").arg(nick));
603       break;
604     default:
605       qWarning() << "Unhandled nick action";
606   }
607 }