#include <QInputDialog>
#include <QMenu>
#include <QMessageBox>
+#include <QMap>
#include "contextmenuactionprovider.h"
#include "clientidentity.h"
#include "network.h"
#include "util.h"
+#include "client.h"
+#include "clientignorelistmanager.h"
ContextMenuActionProvider::ContextMenuActionProvider(QObject *parent) : NetworkModelController(parent) {
registerAction(NetworkConnect, SmallIcon("network-connect"), tr("Connect"));
registerAction(NickCtcpVersion, tr("Version"));
registerAction(NickCtcpTime, tr("Time"));
registerAction(NickCtcpPing, tr("Ping"));
- registerAction(NickCtcpFinger, tr("Finger"));
+ registerAction(NickCtcpClientinfo, tr("Client info"));
+ registerAction(NickIgnoreCustom, tr("Custom..."));
+
+ // these texts are only dummies! don't think about tr() here!
+ registerAction(NickIgnoreUser, "*!ident@host.domain.tld");
+ registerAction(NickIgnoreHost, "*!*@host.domain.tld");
+ registerAction(NickIgnoreDomain, "*!ident@*.domain.tld");
+ registerAction(NickIgnoreToggleEnabled0, "Enable", true);
+ registerAction(NickIgnoreToggleEnabled1, "Enable", true);
+ registerAction(NickIgnoreToggleEnabled2, "Enable", true);
+ registerAction(NickIgnoreToggleEnabled3, "Enable", true);
+ registerAction(NickIgnoreToggleEnabled4, "Enable", true);
registerAction(NickOp, SmallIcon("irc-operator"), tr("Give Operator Status"));
registerAction(NickDeop, SmallIcon("irc-remove-operator"), tr("Take Operator Status"));
nickCtcpMenu->addAction(action(NickCtcpPing));
nickCtcpMenu->addAction(action(NickCtcpVersion));
nickCtcpMenu->addAction(action(NickCtcpTime));
- nickCtcpMenu->addAction(action(NickCtcpFinger));
+ nickCtcpMenu->addAction(action(NickCtcpClientinfo));
_nickCtcpMenuAction = new Action(tr("CTCP"), 0);
_nickCtcpMenuAction->setMenu(nickCtcpMenu);
nickModeMenu->addAction(action(NickKickBan));
_nickModeMenuAction = new Action(tr("Actions"), 0);
_nickModeMenuAction->setMenu(nickModeMenu);
+
+ QMenu *ignoreMenu = new QMenu();
+ _nickIgnoreMenuAction = new Action(tr("Ignore"), 0);
+ _nickIgnoreMenuAction->setMenu(ignoreMenu);
+
+ // These are disabled actions used as descriptions
+ // They don't need any of the Action fancyness so we use plain QActions
+ _ignoreDescriptions << new QAction(tr("Add Ignore Rule"), this);
+ _ignoreDescriptions << new QAction(tr("Existing Rules"), this);
+ foreach(QAction *act, _ignoreDescriptions)
+ act->setEnabled(false);
}
ContextMenuActionProvider::~ContextMenuActionProvider() {
_nickCtcpMenuAction->deleteLater();
_nickModeMenuAction->menu()->deleteLater();
_nickModeMenuAction->deleteLater();
+ _nickIgnoreMenuAction->menu()->deleteLater();
+ _nickIgnoreMenuAction->deleteLater();
+ qDeleteAll(_ignoreDescriptions);
+ _ignoreDescriptions.clear();
}
void ContextMenuActionProvider::addActions(QMenu *menu, BufferId bufId, QObject *receiver, const char *method) {
NetworkModel::ItemType itemType = static_cast<NetworkModel::ItemType>(index.data(NetworkModel::ItemTypeRole).toInt());
addAction(_nickModeMenuAction, menu, itemType == NetworkModel::IrcUserItemType);
addAction(_nickCtcpMenuAction, menu);
+
+ IrcUser *ircUser = qobject_cast<IrcUser *>(index.data(NetworkModel::IrcUserRole).value<QObject *>());
+ if(ircUser) {
+ // ignoreliststuff
+ QString bufferName;
+ BufferInfo bufferInfo = index.data(NetworkModel::BufferInfoRole).value<BufferInfo>();
+ if(bufferInfo.type() == BufferInfo::ChannelBuffer)
+ bufferName = bufferInfo.bufferName();
+ QMap<QString, bool> ignoreMap = Client::ignoreListManager()->matchingRulesForHostmask(ircUser->hostmask(), ircUser->network()->networkName(), bufferName);
+ addIgnoreMenu(menu, ircUser->hostmask(), ignoreMap);
+ // end of ignoreliststuff
+ }
menu->addSeparator();
addAction(NickQuery, menu, itemType == NetworkModel::IrcUserItemType && !haveQuery && indexList().count() == 1);
addAction(NickSwitchTo, menu, itemType == NetworkModel::IrcUserItemType && haveQuery);
menu->addAction(_hideEventsMenuAction);
}
+
+void ContextMenuActionProvider::addIgnoreMenu(QMenu *menu, const QString &hostmask, const QMap<QString, bool> &ignoreMap) {
+ QMenu *ignoreMenu = _nickIgnoreMenuAction->menu();
+ ignoreMenu->clear();
+ QString nick = nickFromMask(hostmask);
+ QString ident = userFromMask(hostmask);
+ QString host = hostFromMask(hostmask);
+ QString domain = host;
+ QRegExp domainRx = QRegExp("(\\.[^.]+\\.\\w+\\D)$");
+ if(domainRx.indexIn(host) != -1)
+ domain = domainRx.cap(1);
+ // we can't rely on who-data
+ // if we don't have the data, we skip actions where we would need it
+ bool haveWhoData = !ident.isEmpty() && !host.isEmpty();
+
+ // add "Add Ignore Rule" description
+ ignoreMenu->addAction(_ignoreDescriptions.at(0));
+
+ if(haveWhoData) {
+ QString text;
+ text = QString("*!%1@%2").arg(ident, host);
+ action(NickIgnoreUser)->setText(text);
+ action(NickIgnoreUser)->setProperty("ignoreRule", text);
+
+ text = QString("*!*@%1").arg(host);
+ action(NickIgnoreHost)->setText(text);
+ action(NickIgnoreHost)->setProperty("ignoreRule", text);
+
+ text = domain.at(0) == '.' ? QString("*!%1@*%2").arg(ident, domain)
+ : QString("*!%1@%2").arg(ident, domain);
+
+ action(NickIgnoreDomain)->setText(text);
+ action(NickIgnoreDomain)->setProperty("ignoreRule", text);
+
+ if(!ignoreMap.contains(action(NickIgnoreUser)->property("ignoreRule").toString()))
+ ignoreMenu->addAction(action(NickIgnoreUser));
+ if(!ignoreMap.contains(action(NickIgnoreHost)->property("ignoreRule").toString()))
+ ignoreMenu->addAction(action(NickIgnoreHost));
+ // we only add that NickIgnoreDomain if it isn't the same as NickIgnoreUser
+ // as happens with @foobar.com hostmasks and ips
+ if(!ignoreMap.contains(action(NickIgnoreDomain)->property("ignoreRule").toString())
+ && action(NickIgnoreUser)->property("ignoreRule").toString() != action(NickIgnoreDomain)->property("ignoreRule").toString())
+ ignoreMenu->addAction(action(NickIgnoreDomain));
+ }
+
+ action(NickIgnoreCustom)->setProperty("ignoreRule", hostmask);
+ ignoreMenu->addAction(action(NickIgnoreCustom));
+
+ ignoreMenu->addSeparator();
+
+ if(haveWhoData) {
+ QMap<QString, bool>::const_iterator ruleIter = ignoreMap.begin();
+ int counter = 0;
+ if(!ignoreMap.isEmpty())
+ // add "Existing Rules" description
+ ignoreMenu->addAction(_ignoreDescriptions.at(1));
+ while(ruleIter != ignoreMap.constEnd()) {
+ if(counter < 5) {
+ ActionType type = static_cast<ActionType>(NickIgnoreToggleEnabled0 + counter*0x100000);
+ Action *act = action(type);
+ act->setText(ruleIter.key());
+ act->setProperty("ignoreRule", ruleIter.key());
+ act->setChecked(ruleIter.value());
+ ignoreMenu->addAction(act);
+ }
+ counter++;
+ ruleIter++;
+ }
+ if(counter)
+ ignoreMenu->addSeparator();
+ }
+ ignoreMenu->addAction(action(ShowIgnoreList));
+ addAction(_nickIgnoreMenuAction, menu);
+}