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 <QInputDialog> |
22 | #include <QMenu> |
23 | #include <QMessageBox> |
24 | #include <QMap> |
25 | |
26 | #include "contextmenuactionprovider.h" |
27 | |
28 | #include "buffermodel.h" |
29 | #include "buffersettings.h" |
30 | #include "iconloader.h" |
31 | #include "clientidentity.h" |
32 | #include "network.h" |
33 | #include "util.h" |
34 | #include "client.h" |
35 | #include "clientignorelistmanager.h" |
36 | |
37 | ContextMenuActionProvider::(QObject *parent) : NetworkModelController(parent) |
38 | { |
39 | registerAction(NetworkConnect, SmallIcon("network-connect" ), tr("Connect" )); |
40 | registerAction(NetworkDisconnect, SmallIcon("network-disconnect" ), tr("Disconnect" )); |
41 | |
42 | registerAction(BufferJoin, SmallIcon("irc-join-channel" ), tr("Join" )); |
43 | registerAction(BufferPart, SmallIcon("irc-close-channel" ), tr("Part" )); |
44 | registerAction(BufferRemove, tr("Delete Chat(s)..." )); |
45 | registerAction(BufferSwitchTo, tr("Go to Chat" )); |
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(HideTopic, tr("Topic Changes" ), true); |
54 | registerAction(HideApplyToAll, tr("Set as Default..." )); |
55 | registerAction(HideUseDefaults, tr("Use Defaults..." )); |
56 | |
57 | registerAction(JoinChannel, SmallIcon("irc-join-channel" ), tr("Join Channel..." )); |
58 | |
59 | registerAction(NickQuery, tr("Start Query" )); |
60 | registerAction(NickSwitchTo, tr("Show Query" )); |
61 | registerAction(NickWhois, tr("Whois" )); |
62 | |
63 | registerAction(NickCtcpVersion, tr("Version" )); |
64 | registerAction(NickCtcpTime, tr("Time" )); |
65 | registerAction(NickCtcpPing, tr("Ping" )); |
66 | registerAction(NickCtcpClientinfo, tr("Client info" )); |
67 | registerAction(NickIgnoreCustom, tr("Custom..." )); |
68 | |
69 | // these texts are only dummies! don't think about tr() here! |
70 | registerAction(NickIgnoreUser, "*!ident@host.domain.tld" ); |
71 | registerAction(NickIgnoreHost, "*!*@host.domain.tld" ); |
72 | registerAction(NickIgnoreDomain, "*!ident@*.domain.tld" ); |
73 | registerAction(NickIgnoreToggleEnabled0, "Enable" , true); |
74 | registerAction(NickIgnoreToggleEnabled1, "Enable" , true); |
75 | registerAction(NickIgnoreToggleEnabled2, "Enable" , true); |
76 | registerAction(NickIgnoreToggleEnabled3, "Enable" , true); |
77 | registerAction(NickIgnoreToggleEnabled4, "Enable" , true); |
78 | |
79 | registerAction(NickOp, SmallIcon("irc-operator" ), tr("Give Operator Status" )); |
80 | registerAction(NickDeop, SmallIcon("irc-remove-operator" ), tr("Take Operator Status" )); |
81 | registerAction(NickHalfop, SmallIcon("irc-voice" ), tr("Give Half-Operator Status" )); |
82 | registerAction(NickDehalfop, SmallIcon("irc-unvoice" ), tr("Take Half-Operator Status" )); |
83 | registerAction(NickVoice, SmallIcon("irc-voice" ), tr("Give Voice" )); |
84 | registerAction(NickDevoice, SmallIcon("irc-unvoice" ), tr("Take Voice" )); |
85 | registerAction(NickKick, SmallIcon("im-kick-user" ), tr("Kick From Channel" )); |
86 | registerAction(NickBan, SmallIcon("im-ban-user" ), tr("Ban From Channel" )); |
87 | registerAction(NickKickBan, SmallIcon("im-ban-kick-user" ), tr("Kick && Ban" )); |
88 | |
89 | registerAction(HideBufferTemporarily, tr("Hide Chat(s) Temporarily" )); |
90 | registerAction(HideBufferPermanently, tr("Hide Chat(s) Permanently" )); |
91 | registerAction(ShowChannelList, tr("Show Channel List" )); |
92 | registerAction(ShowIgnoreList, tr("Show Ignore List" )); |
93 | |
94 | QMenu * = new QMenu(); |
95 | hideEventsMenu->addAction(action(HideJoin)); |
96 | hideEventsMenu->addAction(action(HidePart)); |
97 | hideEventsMenu->addAction(action(HideQuit)); |
98 | hideEventsMenu->addAction(action(HideNick)); |
99 | hideEventsMenu->addAction(action(HideMode)); |
100 | hideEventsMenu->addAction(action(HideTopic)); |
101 | hideEventsMenu->addAction(action(HideDayChange)); |
102 | hideEventsMenu->addSeparator(); |
103 | hideEventsMenu->addAction(action(HideApplyToAll)); |
104 | hideEventsMenu->addAction(action(HideUseDefaults)); |
105 | _hideEventsMenuAction = new Action(tr("Hide Events" ), 0); |
106 | _hideEventsMenuAction->setMenu(hideEventsMenu); |
107 | |
108 | QMenu * = new QMenu(); |
109 | nickCtcpMenu->addAction(action(NickCtcpPing)); |
110 | nickCtcpMenu->addAction(action(NickCtcpVersion)); |
111 | nickCtcpMenu->addAction(action(NickCtcpTime)); |
112 | nickCtcpMenu->addAction(action(NickCtcpClientinfo)); |
113 | _nickCtcpMenuAction = new Action(tr("CTCP" ), 0); |
114 | _nickCtcpMenuAction->setMenu(nickCtcpMenu); |
115 | |
116 | QMenu * = new QMenu(); |
117 | nickModeMenu->addAction(action(NickOp)); |
118 | nickModeMenu->addAction(action(NickDeop)); |
119 | // this is where the halfops will be placed if available |
120 | nickModeMenu->addAction(action(NickHalfop)); |
121 | nickModeMenu->addAction(action(NickDehalfop)); |
122 | nickModeMenu->addAction(action(NickVoice)); |
123 | nickModeMenu->addAction(action(NickDevoice)); |
124 | nickModeMenu->addSeparator(); |
125 | nickModeMenu->addAction(action(NickKick)); |
126 | nickModeMenu->addAction(action(NickBan)); |
127 | nickModeMenu->addAction(action(NickKickBan)); |
128 | _nickModeMenuAction = new Action(tr("Actions" ), 0); |
129 | _nickModeMenuAction->setMenu(nickModeMenu); |
130 | |
131 | QMenu * = new QMenu(); |
132 | _nickIgnoreMenuAction = new Action(tr("Ignore" ), 0); |
133 | _nickIgnoreMenuAction->setMenu(ignoreMenu); |
134 | |
135 | // These are disabled actions used as descriptions |
136 | // They don't need any of the Action fancyness so we use plain QActions |
137 | _ignoreDescriptions << new QAction(tr("Add Ignore Rule" ), this); |
138 | _ignoreDescriptions << new QAction(tr("Existing Rules" ), this); |
139 | foreach(QAction *act, _ignoreDescriptions) |
140 | act->setEnabled(false); |
141 | } |
142 | |
143 | |
144 | ContextMenuActionProvider::() |
145 | { |
146 | _hideEventsMenuAction->menu()->deleteLater(); |
147 | _hideEventsMenuAction->deleteLater(); |
148 | _nickCtcpMenuAction->menu()->deleteLater(); |
149 | _nickCtcpMenuAction->deleteLater(); |
150 | _nickModeMenuAction->menu()->deleteLater(); |
151 | _nickModeMenuAction->deleteLater(); |
152 | _nickIgnoreMenuAction->menu()->deleteLater(); |
153 | _nickIgnoreMenuAction->deleteLater(); |
154 | qDeleteAll(_ignoreDescriptions); |
155 | _ignoreDescriptions.clear(); |
156 | } |
157 | |
158 | |
159 | void ContextMenuActionProvider::(QMenu *, BufferId bufId, QObject *receiver, const char *method) |
160 | { |
161 | if (!bufId.isValid()) |
162 | return; |
163 | addActions(menu, Client::networkModel()->bufferIndex(bufId), receiver, method); |
164 | } |
165 | |
166 | |
167 | void ContextMenuActionProvider::(QMenu *, const QModelIndex &index, QObject *receiver, const char *method, bool isCustomBufferView) |
168 | { |
169 | if (!index.isValid()) |
170 | return; |
171 | addActions(menu, QList<QModelIndex>() << index, 0, QString(), receiver, method, isCustomBufferView); |
172 | } |
173 | |
174 | |
175 | void ContextMenuActionProvider::(QMenu *, MessageFilter *filter, BufferId msgBuffer, QObject *receiver, const char *slot) |
176 | { |
177 | addActions(menu, filter, msgBuffer, QString(), receiver, slot); |
178 | } |
179 | |
180 | |
181 | void ContextMenuActionProvider::(QMenu *, MessageFilter *filter, BufferId msgBuffer, const QString &chanOrNick, QObject *receiver, const char *method) |
182 | { |
183 | if (!filter) |
184 | return; |
185 | addActions(menu, QList<QModelIndex>() << Client::networkModel()->bufferIndex(msgBuffer), filter, chanOrNick, receiver, method, false); |
186 | } |
187 | |
188 | |
189 | void ContextMenuActionProvider::(QMenu *, const QList<QModelIndex> &indexList, QObject *receiver, const char *method, bool isCustomBufferView) |
190 | { |
191 | addActions(menu, indexList, 0, QString(), receiver, method, isCustomBufferView); |
192 | } |
193 | |
194 | |
195 | // add a list of actions sensible for the current item(s) |
196 | void ContextMenuActionProvider::(QMenu *, |
197 | const QList<QModelIndex> &indexList_, |
198 | MessageFilter *filter_, |
199 | const QString &contextItem_, |
200 | QObject *receiver_, |
201 | const char *method_, |
202 | bool isCustomBufferView) |
203 | { |
204 | if (!indexList_.count()) |
205 | return; |
206 | |
207 | setIndexList(indexList_); |
208 | setMessageFilter(filter_); |
209 | setContextItem(contextItem_); |
210 | setSlot(receiver_, method_); |
211 | |
212 | if (!messageFilter()) { |
213 | // this means we are in a BufferView (or NickView) rather than a ChatView |
214 | |
215 | // first index in list determines the menu type (just in case we have both buffers and networks selected, for example) |
216 | QModelIndex index = indexList().at(0); |
217 | NetworkModel::ItemType itemType = static_cast<NetworkModel::ItemType>(index.data(NetworkModel::ItemTypeRole).toInt()); |
218 | |
219 | switch (itemType) { |
220 | case NetworkModel::NetworkItemType: |
221 | addNetworkItemActions(menu, index); |
222 | break; |
223 | case NetworkModel::BufferItemType: |
224 | addBufferItemActions(menu, index, isCustomBufferView); |
225 | break; |
226 | case NetworkModel::IrcUserItemType: |
227 | addIrcUserActions(menu, index); |
228 | break; |
229 | default: |
230 | return; |
231 | } |
232 | } |
233 | else { |
234 | // ChatView actions |
235 | if (contextItem().isEmpty()) { |
236 | // a) query buffer: handle like ircuser |
237 | // b) general chatview: handle like channel iff it displays a single buffer |
238 | // NOTE stuff breaks probably with merged buffers, need to rework a lot around here then |
239 | if (messageFilter()->containedBuffers().count() == 1) { |
240 | // we can handle this like a single bufferItem |
241 | QModelIndex index = Client::networkModel()->bufferIndex(messageFilter()->containedBuffers().values().at(0)); |
242 | setIndexList(index); |
243 | addBufferItemActions(menu, index); |
244 | return; |
245 | } |
246 | else { |
247 | // TODO: actions for merged buffers... _indexList contains the index of the message we clicked on |
248 | } |
249 | } |
250 | else { |
251 | // context item = chan or nick, _indexList = buf where the msg clicked on originated |
252 | if (isChannelName(contextItem())) { |
253 | QModelIndex msgIdx = indexList().at(0); |
254 | if (!msgIdx.isValid()) |
255 | return; |
256 | NetworkId networkId = msgIdx.data(NetworkModel::NetworkIdRole).value<NetworkId>(); |
257 | BufferId bufId = Client::networkModel()->bufferId(networkId, contextItem()); |
258 | if (bufId.isValid()) { |
259 | QModelIndex targetIdx = Client::networkModel()->bufferIndex(bufId); |
260 | setIndexList(targetIdx); |
261 | addAction(BufferJoin, menu, targetIdx, InactiveState); |
262 | addAction(BufferSwitchTo, menu, targetIdx, ActiveState); |
263 | } |
264 | else |
265 | addAction(JoinChannel, menu); |
266 | } |
267 | else { |
268 | // TODO: actions for a nick |
269 | } |
270 | } |
271 | } |
272 | } |
273 | |
274 | |
275 | void ContextMenuActionProvider::(QMenu *, const QModelIndex &index) |
276 | { |
277 | NetworkId networkId = index.data(NetworkModel::NetworkIdRole).value<NetworkId>(); |
278 | if (!networkId.isValid()) |
279 | return; |
280 | const Network *network = Client::network(networkId); |
281 | Q_CHECK_PTR(network); |
282 | if (!network) |
283 | return; |
284 | |
285 | addAction(NetworkConnect, menu, network->connectionState() == Network::Disconnected); |
286 | addAction(NetworkDisconnect, menu, network->connectionState() != Network::Disconnected); |
287 | menu->addSeparator(); |
288 | addAction(ShowChannelList, menu, index, ActiveState); |
289 | addAction(JoinChannel, menu, index, ActiveState); |
290 | } |
291 | |
292 | |
293 | void ContextMenuActionProvider::(QMenu *, const QModelIndex &index, bool isCustomBufferView) |
294 | { |
295 | BufferInfo bufferInfo = index.data(NetworkModel::BufferInfoRole).value<BufferInfo>(); |
296 | |
297 | menu->addSeparator(); |
298 | switch (bufferInfo.type()) { |
299 | case BufferInfo::ChannelBuffer: |
300 | addAction(BufferJoin, menu, index, InactiveState); |
301 | addAction(BufferPart, menu, index, ActiveState); |
302 | menu->addSeparator(); |
303 | addHideEventsMenu(menu, bufferInfo.bufferId()); |
304 | menu->addSeparator(); |
305 | addAction(HideBufferTemporarily, menu, isCustomBufferView); |
306 | addAction(HideBufferPermanently, menu, isCustomBufferView); |
307 | addAction(BufferRemove, menu, index, InactiveState); |
308 | break; |
309 | |
310 | case BufferInfo::QueryBuffer: |
311 | { |
312 | //IrcUser *ircUser = qobject_cast<IrcUser *>(index.data(NetworkModel::IrcUserRole).value<QObject *>()); |
313 | //if(ircUser) { |
314 | addIrcUserActions(menu, index); |
315 | menu->addSeparator(); |
316 | //} |
317 | addHideEventsMenu(menu, bufferInfo.bufferId()); |
318 | menu->addSeparator(); |
319 | addAction(HideBufferTemporarily, menu, isCustomBufferView); |
320 | addAction(HideBufferPermanently, menu, isCustomBufferView); |
321 | addAction(BufferRemove, menu, index); |
322 | break; |
323 | } |
324 | |
325 | default: |
326 | addAction(HideBufferTemporarily, menu, isCustomBufferView); |
327 | addAction(HideBufferPermanently, menu, isCustomBufferView); |
328 | } |
329 | } |
330 | |
331 | |
332 | void ContextMenuActionProvider::(QMenu *, const QModelIndex &index) |
333 | { |
334 | // this can be called: a) as a nicklist context menu (index has IrcUserItemType) |
335 | // b) as a query buffer context menu (index has BufferItemType and is a QueryBufferItem) |
336 | // c) right-click in a query chatview (same as b), index will be the corresponding QueryBufferItem) |
337 | // d) right-click on some nickname (_contextItem will be non-null, _filter -> chatview, index -> message buffer) |
338 | |
339 | if (contextItem().isNull()) { |
340 | // cases a, b, c |
341 | bool haveQuery = indexList().count() == 1 && findQueryBuffer(index).isValid(); |
342 | NetworkModel::ItemType itemType = static_cast<NetworkModel::ItemType>(index.data(NetworkModel::ItemTypeRole).toInt()); |
343 | addAction(_nickModeMenuAction, menu, itemType == NetworkModel::IrcUserItemType); |
344 | addAction(_nickCtcpMenuAction, menu); |
345 | |
346 | IrcUser *ircUser = qobject_cast<IrcUser *>(index.data(NetworkModel::IrcUserRole).value<QObject *>()); |
347 | if (ircUser) { |
348 | Network *network = ircUser->network(); |
349 | // only show entries for usermode +h if server supports it |
350 | if (network && network->prefixModes().contains('h')) { |
351 | action(NickHalfop)->setVisible(true); |
352 | action(NickDehalfop)->setVisible(true); |
353 | } |
354 | else { |
355 | action(NickHalfop)->setVisible(false); |
356 | action(NickDehalfop)->setVisible(false); |
357 | } |
358 | // ignoreliststuff |
359 | QString bufferName; |
360 | BufferInfo bufferInfo = index.data(NetworkModel::BufferInfoRole).value<BufferInfo>(); |
361 | if (bufferInfo.type() == BufferInfo::ChannelBuffer) |
362 | bufferName = bufferInfo.bufferName(); |
363 | QMap<QString, bool> ignoreMap = Client::ignoreListManager()->matchingRulesForHostmask(ircUser->hostmask(), ircUser->network()->networkName(), bufferName); |
364 | addIgnoreMenu(menu, ircUser->hostmask(), ignoreMap); |
365 | // end of ignoreliststuff |
366 | } |
367 | menu->addSeparator(); |
368 | addAction(NickQuery, menu, itemType == NetworkModel::IrcUserItemType && !haveQuery && indexList().count() == 1); |
369 | addAction(NickSwitchTo, menu, itemType == NetworkModel::IrcUserItemType && haveQuery); |
370 | menu->addSeparator(); |
371 | addAction(NickWhois, menu, true); |
372 | } |
373 | else if (!contextItem().isEmpty() && messageFilter()) { |
374 | // case d |
375 | // TODO |
376 | } |
377 | } |
378 | |
379 | |
380 | Action *ContextMenuActionProvider::(ActionType type, QMenu *, const QModelIndex &index, ItemActiveStates requiredActiveState) |
381 | { |
382 | return addAction(action(type), menu, checkRequirements(index, requiredActiveState)); |
383 | } |
384 | |
385 | |
386 | Action *ContextMenuActionProvider::(Action *action, QMenu *, const QModelIndex &index, ItemActiveStates requiredActiveState) |
387 | { |
388 | return addAction(action, menu, checkRequirements(index, requiredActiveState)); |
389 | } |
390 | |
391 | |
392 | Action *ContextMenuActionProvider::(ActionType type, QMenu *, bool condition) |
393 | { |
394 | return addAction(action(type), menu, condition); |
395 | } |
396 | |
397 | |
398 | Action *ContextMenuActionProvider::(Action *action, QMenu *, bool condition) |
399 | { |
400 | if (condition) { |
401 | menu->addAction(action); |
402 | action->setVisible(true); |
403 | } |
404 | else { |
405 | action->setVisible(false); |
406 | } |
407 | return action; |
408 | } |
409 | |
410 | |
411 | void ContextMenuActionProvider::(QMenu *, BufferId bufferId) |
412 | { |
413 | if (BufferSettings(bufferId).hasFilter()) |
414 | addHideEventsMenu(menu, BufferSettings(bufferId).messageFilter()); |
415 | else |
416 | addHideEventsMenu(menu); |
417 | } |
418 | |
419 | |
420 | void ContextMenuActionProvider::(QMenu *, MessageFilter *msgFilter) |
421 | { |
422 | if (BufferSettings(msgFilter->idString()).hasFilter()) |
423 | addHideEventsMenu(menu, BufferSettings(msgFilter->idString()).messageFilter()); |
424 | else |
425 | addHideEventsMenu(menu); |
426 | } |
427 | |
428 | |
429 | void ContextMenuActionProvider::(QMenu *, int filter) |
430 | { |
431 | action(HideApplyToAll)->setEnabled(filter != -1); |
432 | action(HideUseDefaults)->setEnabled(filter != -1); |
433 | if (filter == -1) |
434 | filter = BufferSettings().messageFilter(); |
435 | |
436 | action(HideJoin)->setChecked(filter & Message::Join); |
437 | action(HidePart)->setChecked(filter & Message::Part); |
438 | action(HideQuit)->setChecked(filter & Message::Quit); |
439 | action(HideNick)->setChecked(filter & Message::Nick); |
440 | action(HideMode)->setChecked(filter & Message::Mode); |
441 | action(HideDayChange)->setChecked(filter & Message::DayChange); |
442 | action(HideTopic)->setChecked(filter & Message::Topic); |
443 | |
444 | menu->addAction(_hideEventsMenuAction); |
445 | } |
446 | |
447 | |
448 | void ContextMenuActionProvider::(QMenu *, const QString &hostmask, const QMap<QString, bool> &ignoreMap) |
449 | { |
450 | QMenu * = _nickIgnoreMenuAction->menu(); |
451 | ignoreMenu->clear(); |
452 | QString nick = nickFromMask(hostmask); |
453 | QString ident = userFromMask(hostmask); |
454 | QString host = hostFromMask(hostmask); |
455 | QString domain = host; |
456 | QRegExp domainRx = QRegExp("(\\.[^.]+\\.\\w+\\D)$" ); |
457 | if (domainRx.indexIn(host) != -1) |
458 | domain = domainRx.cap(1); |
459 | // we can't rely on who-data |
460 | // if we don't have the data, we skip actions where we would need it |
461 | bool haveWhoData = !ident.isEmpty() && !host.isEmpty(); |
462 | |
463 | // add "Add Ignore Rule" description |
464 | ignoreMenu->addAction(_ignoreDescriptions.at(0)); |
465 | |
466 | if (haveWhoData) { |
467 | QString text; |
468 | text = QString("*!%1@%2" ).arg(ident, host); |
469 | action(NickIgnoreUser)->setText(text); |
470 | action(NickIgnoreUser)->setProperty("ignoreRule" , text); |
471 | |
472 | text = QString("*!*@%1" ).arg(host); |
473 | action(NickIgnoreHost)->setText(text); |
474 | action(NickIgnoreHost)->setProperty("ignoreRule" , text); |
475 | |
476 | text = domain.at(0) == '.' ? QString("*!%1@*%2" ).arg(ident, domain) |
477 | : QString("*!%1@%2" ).arg(ident, domain); |
478 | |
479 | action(NickIgnoreDomain)->setText(text); |
480 | action(NickIgnoreDomain)->setProperty("ignoreRule" , text); |
481 | |
482 | if (!ignoreMap.contains(action(NickIgnoreUser)->property("ignoreRule" ).toString())) |
483 | ignoreMenu->addAction(action(NickIgnoreUser)); |
484 | if (!ignoreMap.contains(action(NickIgnoreHost)->property("ignoreRule" ).toString())) |
485 | ignoreMenu->addAction(action(NickIgnoreHost)); |
486 | // we only add that NickIgnoreDomain if it isn't the same as NickIgnoreUser |
487 | // as happens with @foobar.com hostmasks and ips |
488 | if (!ignoreMap.contains(action(NickIgnoreDomain)->property("ignoreRule" ).toString()) |
489 | && action(NickIgnoreUser)->property("ignoreRule" ).toString() != action(NickIgnoreDomain)->property("ignoreRule" ).toString()) |
490 | ignoreMenu->addAction(action(NickIgnoreDomain)); |
491 | } |
492 | |
493 | action(NickIgnoreCustom)->setProperty("ignoreRule" , hostmask); |
494 | ignoreMenu->addAction(action(NickIgnoreCustom)); |
495 | |
496 | ignoreMenu->addSeparator(); |
497 | |
498 | if (haveWhoData) { |
499 | QMap<QString, bool>::const_iterator ruleIter = ignoreMap.begin(); |
500 | int counter = 0; |
501 | if (!ignoreMap.isEmpty()) |
502 | // add "Existing Rules" description |
503 | ignoreMenu->addAction(_ignoreDescriptions.at(1)); |
504 | while (ruleIter != ignoreMap.constEnd()) { |
505 | if (counter < 5) { |
506 | ActionType type = static_cast<ActionType>(NickIgnoreToggleEnabled0 + counter*0x100000); |
507 | Action *act = action(type); |
508 | act->setText(ruleIter.key()); |
509 | act->setProperty("ignoreRule" , ruleIter.key()); |
510 | act->setChecked(ruleIter.value()); |
511 | ignoreMenu->addAction(act); |
512 | } |
513 | counter++; |
514 | ruleIter++; |
515 | } |
516 | if (counter) |
517 | ignoreMenu->addSeparator(); |
518 | } |
519 | ignoreMenu->addAction(action(ShowIgnoreList)); |
520 | addAction(_nickIgnoreMenuAction, menu); |
521 | } |
522 | |