1 /***************************************************************************
2 * Copyright (C) 2005-08 by the Quassel Project *
3 * devel@quassel-irc.org *
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. *
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. *
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 ***************************************************************************/
21 #include <QInputDialog>
23 #include <QMessageBox>
25 #include "networkmodelactionprovider.h"
27 #include "buffersettings.h"
28 #include "iconloader.h"
32 NetworkModelActionProvider::NetworkModelActionProvider(QObject *parent)
33 : AbstractActionProvider(parent),
34 _actionCollection(new ActionCollection(this)),
38 registerAction(NetworkConnect, SmallIcon("network-connect"), tr("Connect"));
39 registerAction(NetworkDisconnect, SmallIcon("network-disconnect"), tr("Disconnect"));
41 registerAction(BufferJoin, tr("Join"));
42 registerAction(BufferPart, tr("Part"));
43 registerAction(BufferRemove, tr("Delete Buffer..."));
45 registerAction(HideJoin, tr("Joins"), true);
46 registerAction(HidePart, tr("Parts"), true);
47 registerAction(HideQuit, tr("Quits"), true);
48 registerAction(HideNick, tr("Nick Changes"), true);
49 registerAction(HideMode, tr("Mode Changes"), true);
50 registerAction(HideDayChange, tr("Day Changes"), true);
51 registerAction(HideApplyToAll, tr("Apply to All Chat Views..."));
53 registerAction(JoinChannel, tr("Join Channel..."));
55 registerAction(NickCtcpWhois, tr("Whois"));
56 registerAction(NickCtcpVersion, tr("Version"));
57 registerAction(NickCtcpTime, tr("Time"));
58 registerAction(NickCtcpPing, tr("Ping"));
59 registerAction(NickCtcpFinger, tr("Finger"));
61 registerAction(NickOp, tr("Give Operator Status"));
62 registerAction(NickDeop, tr("Take Operator Status"));
63 registerAction(NickVoice, tr("Give Voice"));
64 registerAction(NickDevoice, tr("Take Voice"));
65 registerAction(NickKick, tr("Kick"));
66 registerAction(NickBan, tr("Ban"));
67 registerAction(NickKickBan, tr("Kickban"));
68 registerAction(NickQuery, tr("Query"));
70 registerAction(HideBufferTemporarily, tr("Hide Buffer(s) Temporarily"));
71 registerAction(HideBufferPermanently, tr("Hide Buffer(s) Permanently"));
72 registerAction(ShowChannelList, SmallIcon("format-list-unordered"), tr("Show Channel List"));
73 registerAction(ShowIgnoreList, tr("Show Ignore List"));
75 connect(_actionCollection, SIGNAL(actionTriggered(QAction *)), SLOT(actionTriggered(QAction *)));
77 action(HideApplyToAll)->setDisabled(true);
79 QMenu *hideEventsMenu = new QMenu();
80 hideEventsMenu->addAction(action(HideJoin));
81 hideEventsMenu->addAction(action(HidePart));
82 hideEventsMenu->addAction(action(HideQuit));
83 hideEventsMenu->addAction(action(HideNick));
84 hideEventsMenu->addAction(action(HideMode));
85 hideEventsMenu->addAction(action(HideDayChange));
86 hideEventsMenu->addSeparator();
87 hideEventsMenu->addAction(action(HideApplyToAll));
88 _hideEventsMenuAction = new Action(tr("Hide Events"), 0);
89 _hideEventsMenuAction->setMenu(hideEventsMenu);
92 NetworkModelActionProvider::~NetworkModelActionProvider() {
93 _hideEventsMenuAction->menu()->deleteLater();
94 _hideEventsMenuAction->deleteLater();
97 void NetworkModelActionProvider::registerAction(ActionType type, const QString &text, bool checkable) {
98 registerAction(type, QPixmap(), text, checkable);
101 void NetworkModelActionProvider::registerAction(ActionType type, const QPixmap &icon, const QString &text, bool checkable) {
104 act = new Action(text, this);
106 act = new Action(icon, text, this);
108 act->setCheckable(checkable);
111 _actionCollection->addAction(QString::number(type, 16), act);
112 _actionByType[type] = act;
115 void NetworkModelActionProvider::addActions(QMenu *menu, BufferId bufId, QObject *receiver, const char *method) {
119 addActions(menu, Client::networkModel()->bufferIndex(bufId), receiver, method);
122 void NetworkModelActionProvider::addActions(QMenu *menu, MessageFilter *filter, QObject *receiver, const char *method) {
125 _messageFilter = filter;
126 QList<QModelIndex> indexes;
127 foreach(BufferId bufId, filter->containedBuffers())
128 indexes << Client::networkModel()->bufferIndex(bufId);
129 addActions(menu, indexes, receiver, method);
132 void NetworkModelActionProvider::addActions(QMenu *menu, const QModelIndex &index, QObject *receiver, const char *method, bool isCustomBufferView) {
136 addActions(menu, QList<QModelIndex>() << index, receiver, method, isCustomBufferView);
139 // add a list of actions sensible for the current item(s)
140 void NetworkModelActionProvider::addActions(QMenu *menu,
141 const QList<QModelIndex> &indexList,
144 bool isCustomBufferView)
146 if(!indexList.count())
149 _indexList = indexList;
150 _receiver = receiver;
153 if(!_messageFilter) {
154 // this means we are in a BufferView (or NickView) rather than a ChatView
156 // first index in list determines the menu type (just in case we have both buffers and networks selected, for example)
157 QModelIndex index = _indexList.at(0);
158 NetworkModel::ItemType itemType = static_cast<NetworkModel::ItemType>(index.data(NetworkModel::ItemTypeRole).toInt());
161 case NetworkModel::NetworkItemType:
162 addNetworkItemActions(menu, index);
164 case NetworkModel::BufferItemType:
165 addBufferItemActions(menu, index, isCustomBufferView);
179 void NetworkModelActionProvider::addNetworkItemActions(QMenu *menu, const QModelIndex &index) {
180 NetworkId networkId = index.data(NetworkModel::NetworkIdRole).value<NetworkId>();
181 if(!networkId.isValid())
183 const Network *network = Client::network(networkId);
184 Q_CHECK_PTR(network);
188 addAction(NetworkConnect, menu, network->connectionState() == Network::Disconnected);
189 addAction(NetworkDisconnect, menu, network->connectionState() != Network::Disconnected);
190 menu->addSeparator();
191 addAction(ShowChannelList, menu, index, ActiveState);
192 addAction(JoinChannel, menu, index, ActiveState);
196 void NetworkModelActionProvider::addBufferItemActions(QMenu *menu, const QModelIndex &index, bool isCustomBufferView) {
197 BufferInfo bufferInfo = index.data(NetworkModel::BufferInfoRole).value<BufferInfo>();
199 switch(bufferInfo.type()) {
200 case BufferInfo::ChannelBuffer:
201 addAction(BufferJoin, menu, index, InactiveState);
202 addAction(BufferPart, menu, index, ActiveState);
203 menu->addSeparator();
204 addHideEventsMenu(menu, bufferInfo.bufferId());
205 menu->addSeparator();
206 addAction(HideBufferTemporarily, menu, isCustomBufferView);
207 addAction(HideBufferPermanently, menu, isCustomBufferView);
208 addAction(BufferRemove, menu, index);
211 case BufferInfo::QueryBuffer:
213 IrcUser *ircUser = qobject_cast<IrcUser *>(index.data(NetworkModel::IrcUserRole).value<QObject *>());
215 addIrcUserActions(menu, ircUser, false);
216 menu->addSeparator();
218 addHideEventsMenu(menu, bufferInfo.bufferId());
219 menu->addSeparator();
220 addAction(HideBufferTemporarily, menu, isCustomBufferView);
221 addAction(HideBufferPermanently, menu, isCustomBufferView);
222 addAction(BufferRemove, menu, index);
227 addAction(HideBufferTemporarily, menu, isCustomBufferView);
228 addAction(HideBufferPermanently, menu, isCustomBufferView);
232 void NetworkModelActionProvider::addIrcUserActions(QMenu *menu, IrcUser *ircUser, bool isNickView) {
237 /******** Helper Functions ***********************************************************************/
239 bool NetworkModelActionProvider::checkRequirements(const QModelIndex &index, ItemActiveStates requiredActiveState) {
243 ItemActiveStates isActive = index.data(NetworkModel::ItemActiveRole).toBool()
247 if(!(isActive & requiredActiveState))
253 Action * NetworkModelActionProvider::addAction(ActionType type , QMenu *menu, const QModelIndex &index, ItemActiveStates requiredActiveState) {
254 return addAction(action(type), menu, checkRequirements(index, requiredActiveState));
257 Action * NetworkModelActionProvider::addAction(Action *action , QMenu *menu, const QModelIndex &index, ItemActiveStates requiredActiveState) {
258 return addAction(action, menu, checkRequirements(index, requiredActiveState));
261 Action * NetworkModelActionProvider::addAction(ActionType type , QMenu *menu, bool condition) {
262 return addAction(action(type), menu, condition);
265 Action * NetworkModelActionProvider::addAction(Action *action , QMenu *menu, bool condition) {
267 menu->addAction(action);
268 action->setVisible(true);
270 action->setVisible(false);
275 void NetworkModelActionProvider::addHideEventsMenu(QMenu *menu, BufferId bufferId) {
276 addHideEventsMenu(menu, BufferSettings(bufferId).messageFilter());
279 void NetworkModelActionProvider::addHideEventsMenu(QMenu *menu, MessageFilter *msgFilter) {
280 addHideEventsMenu(menu, BufferSettings(msgFilter->idString()).messageFilter());
283 void NetworkModelActionProvider::addHideEventsMenu(QMenu *menu, int filter) {
284 action(HideJoin)->setChecked(filter & Message::Join);
285 action(HidePart)->setChecked(filter & Message::Part);
286 action(HideQuit)->setChecked(filter & Message::Quit);
287 action(HideNick)->setChecked(filter & Message::Nick);
288 action(HideMode)->setChecked(filter & Message::Mode);
289 action(HideDayChange)->setChecked(filter & Message::DayChange);
291 menu->addAction(_hideEventsMenuAction);
294 /******** Handle Actions *************************************************************************/
296 void NetworkModelActionProvider::actionTriggered(QAction *action) {
297 ActionType type = (ActionType)action->data().toInt();
299 if(type & NetworkMask)
300 handleNetworkAction(type, action);
301 else if(type & BufferMask)
302 handleBufferAction(type, action);
303 else if(type & HideMask)
304 handleHideAction(type, action);
305 else if(type & GeneralMask)
306 handleGeneralAction(type, action);
307 else if(type & NickMask)
308 handleNickAction(type, action);
309 else if(type & ExternalMask)
310 handleExternalAction(type, action);
312 qWarning() << "NetworkModelActionProvider::actionTriggered(): Unhandled action!";
319 void NetworkModelActionProvider::handleNetworkAction(ActionType type, QAction *) {
320 if(!_indexList.count())
322 const Network *network = Client::network(_indexList.at(0).data(NetworkModel::NetworkIdRole).value<NetworkId>());
323 Q_CHECK_PTR(network);
329 network->requestConnect();
331 case NetworkDisconnect:
332 network->requestDisconnect();
339 void NetworkModelActionProvider::handleBufferAction(ActionType type, QAction *) {
340 foreach(QModelIndex index, _indexList) {
341 BufferInfo bufferInfo = index.data(NetworkModel::BufferInfoRole).value<BufferInfo>();
342 if(!bufferInfo.isValid())
347 Client::instance()->userInput(bufferInfo, QString("/JOIN %1").arg(bufferInfo.bufferName()));
351 QString reason = Client::identity(Client::network(bufferInfo.networkId())->identity())->partReason();
352 Client::instance()->userInput(bufferInfo, QString("/PART %1").arg(reason));
357 int res = QMessageBox::question(0, tr("Remove buffer permanently?"),
358 tr("Do you want to delete the buffer \"%1\" permanently? This will delete all related data, including all backlog "
359 "data, from the core's database!").arg(bufferInfo.bufferName()),
360 QMessageBox::Yes|QMessageBox::No, QMessageBox::No);
361 if(res == QMessageBox::Yes) {
362 Client::removeBuffer(bufferInfo.bufferId());
372 void NetworkModelActionProvider::handleHideAction(ActionType type, QAction *action) {
373 Message::Type msgType;
376 msgType = Message::Join; break;
378 msgType = Message::Part; break;
380 msgType = Message::Quit; break;
382 msgType = Message::Nick; break;
384 msgType = Message::Mode; break;
386 msgType = Message::DayChange; break;
388 // TODO implement "apply to all" for hiding messages
395 BufferSettings(_messageFilter->idString()).filterMessage(msgType, action->isChecked());
397 foreach(QModelIndex index, _indexList) {
398 BufferId bufferId = index.data(NetworkModel::BufferIdRole).value<BufferId>();
399 if(!bufferId.isValid())
401 BufferSettings(bufferId).filterMessage(msgType, action->isChecked());
406 void NetworkModelActionProvider::handleGeneralAction(ActionType type, QAction *action) {
407 if(!_indexList.count())
409 NetworkId networkId = _indexList.at(0).data(NetworkModel::NetworkIdRole).value<NetworkId>();
410 if(!networkId.isValid())
416 // FIXME no QInputDialog in Qtopia
419 QString channelName = QInputDialog::getText(0, tr("Join Channel"), tr("Input channel name:"), QLineEdit::Normal, QString(), &ok);
420 if(ok && !channelName.isEmpty()) {
421 Client::instance()->userInput(BufferInfo::fakeStatusBuffer(networkId),
422 QString("/JOIN %1").arg(channelName));
427 case ShowChannelList:
428 emit showChannelList(networkId);
431 emit showIgnoreList(networkId);
438 void NetworkModelActionProvider::handleNickAction(ActionType type, QAction *) {
443 void NetworkModelActionProvider::handleExternalAction(ActionType type, QAction *action) {
445 if(_receiver && _method) {
446 if(!QMetaObject::invokeMethod(_receiver, _method, Q_ARG(QAction *, action)))
447 qWarning() << "NetworkModelActionProvider::handleExternalAction(): Could not invoke slot" << _receiver << _method;