X-Git-Url: https://git.quassel-irc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fcommon%2Fignorelistmanager.cpp;h=1599cde70ccd46fa335ab92437fc8095f07a694c;hb=cd4f987d0d8ace10272bf1d87c788b741a9e85e8;hp=92052915eeca4837d20dedd66e32de400aa73000;hpb=9fc57dc2c000e80fb8bd746a090e2e8210e1278e;p=quassel.git diff --git a/src/common/ignorelistmanager.cpp b/src/common/ignorelistmanager.cpp index 92052915..1599cde7 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) @@ -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; } @@ -145,19 +144,13 @@ IgnoreListManager::StrictnessType IgnoreListManager::_match(const QString &msgCo 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)) { + if ((!item.isRegEx && item.regEx.exactMatch(str)) || + (item.isRegEx && item.regEx.indexIn(str) != -1)) { // qDebug() << "MATCHED!"; return item.strictness; } @@ -169,15 +162,57 @@ 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; + // A match happens when the string does NOT match ANY inverted rules and matches AT LEAST one + // normal rule, unless no normal rules exist (implicit wildcard match). This gives inverted + // rules higher priority regardless of ordering. + // + // TODO: After switching to Qt 5, use of this should be split into two parts, one part that + // would generate compiled QRegularExpressions for match/inverted match, regenerating it on any + // rule changes, and another part that would check each message against these compiled rules. + + // Keep track if any matches are found + bool matches = false; + // Keep track if normal rules and inverted rules are found, allowing for implicit wildcard + bool normalRuleFound = false, invertedRuleFound = false; + + // Split each scope rule by separator, ignoring empty parts + foreach(QString rule, scopeRule.split(";", QString::SkipEmptyParts)) { + // Trim whitespace from the start/end of the rule + rule = rule.trimmed(); + // Ignore empty rules + if (rule.isEmpty()) + continue; + + // Check if this is an inverted rule (starts with '!') + if (rule.startsWith("!")) { + // Inverted rule found + invertedRuleFound = true; + + // Take the reminder of the string + QRegExp ruleRx(rule.mid(1), Qt::CaseInsensitive); + ruleRx.setPatternSyntax(QRegExp::Wildcard); + if (ruleRx.exactMatch(string)) { + // Matches an inverted rule, full rule cannot match + return false; + } + } else { + // Normal rule found + normalRuleFound = true; + + QRegExp ruleRx(rule, Qt::CaseInsensitive); + ruleRx.setPatternSyntax(QRegExp::Wildcard); + if (ruleRx.exactMatch(string)) { + // Matches a normal rule, full rule might match + matches = true; + // Continue checking in case other inverted rules negate this + } } } - return false; + // No inverted rules matched, okay to match normally + // Return true if... + // ...we found a normal match + // ...implicit wildcard: we had inverted rules (that didn't match) and no normal rules + return matches || (invertedRuleFound && !normalRuleFound); }