X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fcommon%2Fignorelistmanager.cpp;h=63750f60e256603b8b96d084dcb1f0e590883469;hp=92052915eeca4837d20dedd66e32de400aa73000;hb=1a45f16a9734820fba42fe1db3f38dd1eee49df6;hpb=04315f46a16fc3627218377071e008b6b9744992 diff --git a/src/common/ignorelistmanager.cpp b/src/common/ignorelistmanager.cpp index 92052915..63750f60 100644 --- a/src/common/ignorelistmanager.cpp +++ b/src/common/ignorelistmanager.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-2013 by the Quassel Project * + * Copyright (C) 2005-2018 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -23,7 +23,6 @@ #include #include #include -#include INIT_SYNCABLE_OBJECT(IgnoreListManager) IgnoreListManager &IgnoreListManager::operator=(const IgnoreListManager &other) @@ -40,7 +39,7 @@ IgnoreListManager &IgnoreListManager::operator=(const IgnoreListManager &other) int IgnoreListManager::indexOf(const QString &ignore) const { for (int i = 0; i < _ignoreList.count(); i++) { - if (_ignoreList[i].ignoreRule == ignore) + if (_ignoreList[i].contents() == ignore) return i; } return -1; @@ -59,13 +58,13 @@ QVariantMap IgnoreListManager::initIgnoreList() const QVariantList isActiveList; for (int i = 0; i < _ignoreList.count(); i++) { - ignoreTypeList << _ignoreList[i].type; - ignoreRuleList << _ignoreList[i].ignoreRule; - scopeRuleList << _ignoreList[i].scopeRule; - isRegExList << _ignoreList[i].isRegEx; - scopeList << _ignoreList[i].scope; - strictnessList << _ignoreList[i].strictness; - isActiveList << _ignoreList[i].isActive; + ignoreTypeList << _ignoreList[i].type(); + ignoreRuleList << _ignoreList[i].contents(); + scopeRuleList << _ignoreList[i].scopeRule(); + isRegExList << _ignoreList[i].isRegEx(); + scopeList << _ignoreList[i].scope(); + strictnessList << _ignoreList[i].strictness(); + isActiveList << _ignoreList[i].isEnabled(); } ignoreListMap["ignoreType"] = ignoreTypeList; @@ -92,7 +91,7 @@ void IgnoreListManager::initSetIgnoreList(const QVariantMap &ignoreList) int count = ignoreRule.count(); if (count != scopeRule.count() || count != isRegEx.count() || count != scope.count() || count != strictness.count() || count != ignoreType.count() || count != isActive.count()) { - qWarning() << "Corrupted IgnoreList settings! (Count missmatch)"; + qWarning() << "Corrupted IgnoreList settings! (Count mismatch)"; return; } @@ -107,7 +106,7 @@ void IgnoreListManager::initSetIgnoreList(const QVariantMap &ignoreList) /* since overloaded methods aren't syncable (yet?) we can't use that anymore void IgnoreListManager::addIgnoreListItem(const IgnoreListItem &item) { - addIgnoreListItem(item.type, item.ignoreRule, item.isRegEx, item.strictness, item.scope, item.scopeRule, item.isActive); + addIgnoreListItem(item.type(), item.contents(), item.isRegEx(), item.strictness(), item.scope(), item.scopeRule(), item.isEnabled()); } */ void IgnoreListManager::addIgnoreListItem(int type, const QString &ignoreRule, bool isRegEx, int strictness, @@ -134,32 +133,24 @@ IgnoreListManager::StrictnessType IgnoreListManager::_match(const QString &msgCo return UnmatchedStrictness; foreach(IgnoreListItem item, _ignoreList) { - if (!item.isActive || item.type == CtcpIgnore) + if (!item.isEnabled() || item.type() == CtcpIgnore) continue; - if (item.scope == GlobalScope - || (item.scope == NetworkScope && scopeMatch(item.scopeRule, network)) - || (item.scope == ChannelScope && scopeMatch(item.scopeRule, bufferName))) { + if (item.scope() == GlobalScope + || (item.scope() == NetworkScope && item.scopeRuleMatcher().match(network)) + || (item.scope() == ChannelScope && item.scopeRuleMatcher().match(bufferName))) { QString str; - if (item.type == MessageIgnore) + if (item.type() == MessageIgnore) str = msgContents; else str = msgSender; - QRegExp ruleRx = QRegExp(item.ignoreRule); - ruleRx.setCaseSensitivity(Qt::CaseInsensitive); - if (!item.isRegEx) { - ruleRx.setPatternSyntax(QRegExp::Wildcard); - } - // qDebug() << "IgnoreListManager::match: "; // qDebug() << "string: " << str; // qDebug() << "pattern: " << ruleRx.pattern(); // qDebug() << "scopeRule: " << item.scopeRule; // qDebug() << "now testing"; - if ((!item.isRegEx && ruleRx.exactMatch(str)) || - (item.isRegEx && ruleRx.indexIn(str) != -1)) { -// qDebug() << "MATCHED!"; - return item.strictness; + if (item.contentsMatcher().match(str)) { + return item.strictness(); } } } @@ -167,20 +158,6 @@ IgnoreListManager::StrictnessType IgnoreListManager::_match(const QString &msgCo } -bool IgnoreListManager::scopeMatch(const QString &scopeRule, const QString &string) const -{ - foreach(QString rule, scopeRule.split(";")) { - QRegExp ruleRx = QRegExp(rule.trimmed()); - ruleRx.setCaseSensitivity(Qt::CaseInsensitive); - ruleRx.setPatternSyntax(QRegExp::Wildcard); - if (ruleRx.exactMatch(string)) { - return true; - } - } - return false; -} - - void IgnoreListManager::removeIgnoreListItem(const QString &ignoreRule) { removeAt(indexOf(ignoreRule)); @@ -193,7 +170,7 @@ void IgnoreListManager::toggleIgnoreRule(const QString &ignoreRule) int idx = indexOf(ignoreRule); if (idx == -1) return; - _ignoreList[idx].isActive = !_ignoreList[idx].isActive; + _ignoreList[idx].setIsEnabled(!_ignoreList[idx].isEnabled()); SYNC(ARG(ignoreRule)) } @@ -201,24 +178,73 @@ void IgnoreListManager::toggleIgnoreRule(const QString &ignoreRule) bool IgnoreListManager::ctcpMatch(const QString sender, const QString &network, const QString &type) { foreach(IgnoreListItem item, _ignoreList) { - if (!item.isActive) + if (!item.isEnabled()) continue; - if (item.scope == GlobalScope || (item.scope == NetworkScope && scopeMatch(item.scopeRule, network))) { - QString sender_; - QStringList types = item.ignoreRule.split(QRegExp("\\s+"), QString::SkipEmptyParts); - - sender_ = types.takeAt(0); - - QRegExp ruleRx = QRegExp(sender_); - ruleRx.setCaseSensitivity(Qt::CaseInsensitive); - if (!item.isRegEx) - ruleRx.setPatternSyntax(QRegExp::Wildcard); - if ((!item.isRegEx && ruleRx.exactMatch(sender)) || - (item.isRegEx && ruleRx.indexIn(sender) != -1)) { - if (types.isEmpty() || types.contains(type, Qt::CaseInsensitive)) + if (item.scope() == GlobalScope + || (item.scope() == NetworkScope && item.scopeRuleMatcher().match(network))) { + + // For CTCP ignore rules, use ctcpSender + if (item.senderCTCPMatcher().match(sender)) { + // Sender matches, check types + if (item.ctcpTypes().isEmpty() + || item.ctcpTypes().contains(type, Qt::CaseInsensitive)) { + // Either all types are blocked, or type matches return true; + } } } } return false; } + + +/************************************************************************** + * IgnoreListItem + *************************************************************************/ +bool IgnoreListManager::IgnoreListItem::operator!=(const IgnoreListItem &other) const +{ + return (_type != other._type || + _contents != other._contents || + _isRegEx != other._isRegEx || + _strictness != other._strictness || + _scope != other._scope || + _scopeRule != other._scopeRule || + _isEnabled != other._isEnabled); + // Don't compare ExpressionMatch objects as they are created as needed from the above +} + + +void IgnoreListManager::IgnoreListItem::determineExpressions() const +{ + // Don't update if not needed + if (!_cacheInvalid) { + return; + } + + // Set up matching rules + // Message is either wildcard or regex + ExpressionMatch::MatchMode contentsMode = + _isRegEx ? ExpressionMatch::MatchMode::MatchRegEx : + ExpressionMatch::MatchMode::MatchWildcard; + + // Ignore rules are always case-insensitive + // Scope matching is always wildcard + // TODO: Expand upon ignore rule handling with next protocol break + + if (_type == CtcpIgnore) { + // Set up CTCP sender + _contentsMatch = {}; + _ctcpSenderMatch = ExpressionMatch(_cacheCtcpSender, contentsMode, false); + } + else { + // Set up message contents + _contentsMatch = ExpressionMatch(_contents, contentsMode, false); + _ctcpSenderMatch = {}; + } + // Scope rules are always multiple wildcard entries + // (Adding a regex option would be awesome, but requires a backwards-compatible protocol change) + _scopeRuleMatch = ExpressionMatch(_scopeRule, + ExpressionMatch::MatchMode::MatchMultiWildcard, false); + + _cacheInvalid = false; +}