1 /***************************************************************************
2 * Copyright (C) 2005-2016 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 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
19 ***************************************************************************/
21 #include "highlightrulemanager.h"
27 INIT_SYNCABLE_OBJECT(HighlightRuleManager)
28 HighlightRuleManager &HighlightRuleManager::operator=(const HighlightRuleManager &other)
33 SyncableObject::operator=(other);
34 _highlightRuleList = other._highlightRuleList;
35 _nicksCaseSensitive = other._nicksCaseSensitive;
36 _highlightNick = other._highlightNick;
41 int HighlightRuleManager::indexOf(const QString &name) const
43 for (int i = 0; i < _highlightRuleList.count(); i++) {
44 if (_highlightRuleList[i].name == name)
51 QVariantMap HighlightRuleManager::initHighlightRuleList() const
53 QVariantMap highlightRuleListMap;
56 QVariantList isCaseSensitive;
57 QVariantList isActive;
58 QVariantList isInverse;
62 for (int i = 0; i < _highlightRuleList.count(); i++) {
63 name << _highlightRuleList[i].name;
64 isRegEx << _highlightRuleList[i].isRegEx;
65 isCaseSensitive << _highlightRuleList[i].isCaseSensitive;
66 isActive << _highlightRuleList[i].isEnabled;
67 isInverse << _highlightRuleList[i].isInverse;
68 sender << _highlightRuleList[i].sender;
69 channel << _highlightRuleList[i].chanName;
72 highlightRuleListMap["name"] = name;
73 highlightRuleListMap["isRegEx"] = isRegEx;
74 highlightRuleListMap["isCaseSensitive"] = isCaseSensitive;
75 highlightRuleListMap["isEnabled"] = isActive;
76 highlightRuleListMap["isInverse"] = isInverse;
77 highlightRuleListMap["sender"] = sender;
78 highlightRuleListMap["channel"] = channel;
79 highlightRuleListMap["highlightNick"] = _highlightNick;
80 highlightRuleListMap["nicksCaseSensitive"] = _nicksCaseSensitive;
81 return highlightRuleListMap;
85 void HighlightRuleManager::initSetHighlightRuleList(const QVariantMap &highlightRuleList)
87 QStringList name = highlightRuleList["name"].toStringList();
88 QVariantList isRegEx = highlightRuleList["isRegEx"].toList();
89 QVariantList isCaseSensitive = highlightRuleList["isCaseSensitive"].toList();
90 QVariantList isActive = highlightRuleList["isEnabled"].toList();
91 QVariantList isInverse = highlightRuleList["isInverse"].toList();
92 QStringList sender = highlightRuleList["sender"].toStringList();
93 QStringList channel = highlightRuleList["channel"].toStringList();
95 int count = name.count();
96 if (count != isRegEx.count() || count != isCaseSensitive.count() || count != isActive.count() ||
97 count != isInverse.count() || count != sender.count() || count != channel.count()) {
98 qWarning() << "Corrupted HighlightRuleList settings! (Count mismatch)";
102 _highlightRuleList.clear();
103 for (int i = 0; i < name.count(); i++) {
104 _highlightRuleList << HighlightRule(name[i], isRegEx[i].toBool(), isCaseSensitive[i].toBool(),
105 isActive[i].toBool(), isInverse[i].toBool(), sender[i], channel[i]);
107 _highlightNick = HighlightNickType(highlightRuleList["highlightNick"].toInt());
108 _nicksCaseSensitive = highlightRuleList["nicksCaseSensitive"].toBool();
111 void HighlightRuleManager::addHighlightRule(const QString &name, bool isRegEx, bool isCaseSensitive, bool isActive,
112 bool isInverse, const QString &sender, const QString &channel)
114 if (contains(name)) {
118 HighlightRule newItem = HighlightRule(name, isRegEx, isCaseSensitive, isActive, isInverse, sender, channel);
119 _highlightRuleList << newItem;
121 SYNC(ARG(name), ARG(isRegEx), ARG(isCaseSensitive), ARG(isActive), ARG(isInverse), ARG(sender), ARG(channel))
125 bool HighlightRuleManager::match(const QString &msgContents,
126 const QString &msgSender,
127 Message::Type msgType,
128 Message::Flags msgFlags,
129 const QString &bufferName,
130 const QString ¤tNick,
131 const QStringList identityNicks)
133 if (!((msgType & (Message::Plain | Message::Notice | Message::Action)) && !(msgFlags & Message::Self))) {
137 bool matches = false;
139 for (int i = 0; i < _highlightRuleList.count(); i++) {
140 const HighlightRule &rule = _highlightRuleList.at(i);
144 if (rule.chanName.size() > 0 && rule.chanName.compare(".*") != 0) {
145 if (rule.chanName.startsWith("!")) {
146 QRegExp rx(rule.chanName.mid(1), Qt::CaseInsensitive);
147 if (rx.exactMatch(bufferName))
151 QRegExp rx(rule.chanName, Qt::CaseInsensitive);
152 if (!rx.exactMatch(bufferName))
159 rx = QRegExp(rule.name, rule.isCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive);
161 rx = QRegExp("(^|\\W)" + QRegExp::escape(rule.name) + "(\\W|$)", rule.isCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive);
163 bool nameMatch = (rx.indexIn(stripFormatCodes(msgContents)) >= 0);
166 if (rule.sender.isEmpty()) {
170 rx = QRegExp(rule.sender, rule.isCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive);
172 rx = QRegExp(rule.sender, Qt::CaseInsensitive, QRegExp::Wildcard);
174 senderMatch = rx.exactMatch(msgSender);
177 if (nameMatch && senderMatch) {
178 // If an inverse rule matches, then we know that we never want to return a highlight.
179 if (rule.isInverse) {
190 if (!currentNick.isEmpty()) {
191 QStringList nickList;
192 if (_highlightNick == CurrentNick) {
193 nickList << currentNick;
195 else if (_highlightNick == AllNicks) {
196 nickList = identityNicks;
197 if (!nickList.contains(currentNick))
198 nickList.prepend(currentNick);
201 for(const QString &nickname : nickList) {
202 QRegExp nickRegExp("(^|\\W)" + QRegExp::escape(nickname) + "(\\W|$)", _nicksCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive);
203 if (nickRegExp.indexIn(stripFormatCodes(msgContents)) >= 0) {
212 void HighlightRuleManager::removeHighlightRule(const QString &highlightRule)
214 removeAt(indexOf(highlightRule));
215 SYNC(ARG(highlightRule))
219 void HighlightRuleManager::toggleHighlightRule(const QString &highlightRule)
221 int idx = indexOf(highlightRule);
224 _highlightRuleList[idx].isEnabled = !_highlightRuleList[idx].isEnabled;
225 SYNC(ARG(highlightRule))
228 bool HighlightRuleManager::match(const Message &msg, const QString ¤tNick, const QStringList &identityNicks)
230 return match(msg.contents(), msg.sender(), msg.type(), msg.flags(), msg.bufferInfo().bufferName(), currentNick, identityNicks);