1 /***************************************************************************
2 * Copyright (C) 2005-2018 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)
29 HighlightRuleManager &HighlightRuleManager::operator=(const HighlightRuleManager &other)
34 SyncableObject::operator=(other);
35 _highlightRuleList = other._highlightRuleList;
36 _nicksCaseSensitive = other._nicksCaseSensitive;
37 _highlightNick = other._highlightNick;
42 int HighlightRuleManager::indexOf(int id) const
44 for (int i = 0; i < _highlightRuleList.count(); i++) {
45 if (_highlightRuleList[i].id == id)
52 int HighlightRuleManager::nextId()
55 for (int i = 0; i < _highlightRuleList.count(); i++) {
56 int id = _highlightRuleList[i].id;
65 QVariantMap HighlightRuleManager::initHighlightRuleList() const
68 QVariantMap highlightRuleListMap;
71 QVariantList isCaseSensitive;
72 QVariantList isActive;
73 QVariantList isInverse;
77 for (int i = 0; i < _highlightRuleList.count(); i++) {
78 id << _highlightRuleList[i].id;
79 name << _highlightRuleList[i].name;
80 isRegEx << _highlightRuleList[i].isRegEx;
81 isCaseSensitive << _highlightRuleList[i].isCaseSensitive;
82 isActive << _highlightRuleList[i].isEnabled;
83 isInverse << _highlightRuleList[i].isInverse;
84 sender << _highlightRuleList[i].sender;
85 channel << _highlightRuleList[i].chanName;
88 highlightRuleListMap["id"] = id;
89 highlightRuleListMap["name"] = name;
90 highlightRuleListMap["isRegEx"] = isRegEx;
91 highlightRuleListMap["isCaseSensitive"] = isCaseSensitive;
92 highlightRuleListMap["isEnabled"] = isActive;
93 highlightRuleListMap["isInverse"] = isInverse;
94 highlightRuleListMap["sender"] = sender;
95 highlightRuleListMap["channel"] = channel;
96 return highlightRuleListMap;
100 void HighlightRuleManager::initSetHighlightRuleList(const QVariantMap &highlightRuleList)
102 QVariantList id = highlightRuleList["id"].toList();
103 QStringList name = highlightRuleList["name"].toStringList();
104 QVariantList isRegEx = highlightRuleList["isRegEx"].toList();
105 QVariantList isCaseSensitive = highlightRuleList["isCaseSensitive"].toList();
106 QVariantList isActive = highlightRuleList["isEnabled"].toList();
107 QVariantList isInverse = highlightRuleList["isInverse"].toList();
108 QStringList sender = highlightRuleList["sender"].toStringList();
109 QStringList channel = highlightRuleList["channel"].toStringList();
111 int count = id.count();
112 if (count != name.count() || count != isRegEx.count() || count != isCaseSensitive.count() ||
113 count != isActive.count() || count != isInverse.count() || count != sender.count() ||
114 count != channel.count()) {
115 qWarning() << "Corrupted HighlightRuleList settings! (Count mismatch)";
119 _highlightRuleList.clear();
120 for (int i = 0; i < name.count(); i++) {
121 _highlightRuleList << HighlightRule(id[i].toInt(), name[i], isRegEx[i].toBool(), isCaseSensitive[i].toBool(),
122 isActive[i].toBool(), isInverse[i].toBool(), sender[i], channel[i]);
127 void HighlightRuleManager::addHighlightRule(int id, const QString &name, bool isRegEx, bool isCaseSensitive,
128 bool isActive, bool isInverse, const QString &sender,
129 const QString &channel)
135 HighlightRule newItem = HighlightRule(id, name, isRegEx, isCaseSensitive, isActive, isInverse, sender, channel);
136 _highlightRuleList << newItem;
138 SYNC(ARG(id), ARG(name), ARG(isRegEx), ARG(isCaseSensitive), ARG(isActive), ARG(isInverse), ARG(sender),
143 bool HighlightRuleManager::match(const QString &msgContents,
144 const QString &msgSender,
145 Message::Type msgType,
146 Message::Flags msgFlags,
147 const QString &bufferName,
148 const QString ¤tNick,
149 const QStringList identityNicks)
151 if (!((msgType & (Message::Plain | Message::Notice | Message::Action)) && !(msgFlags & Message::Self))) {
155 bool matches = false;
157 for (int i = 0; i < _highlightRuleList.count(); i++) {
158 const HighlightRule &rule = _highlightRuleList.at(i);
162 if (!rule.chanName.isEmpty()
163 && !scopeMatch(bufferName, rule.chanName, rule.isRegEx, rule.isCaseSensitive)) {
164 // A channel name rule is specified and does NOT match the current buffer name, skip
169 bool nameMatch = false;
170 if (rule.name.isEmpty()) {
171 // Empty rule, matches any message
174 // Check according to specified rule
177 rx = QRegExp(rule.name,
178 rule.isCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive);
180 rx = QRegExp("(^|\\W)" + QRegExp::escape(rule.name) + "(\\W|$)",
181 rule.isCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive);
183 nameMatch = (rx.indexIn(stripFormatCodes(msgContents)) >= 0);
187 if (rule.sender.isEmpty()) {
190 // A sender name rule is specified, match according to scope rules.
191 senderMatch = scopeMatch(msgSender, rule.sender, rule.isRegEx, rule.isCaseSensitive);
194 if (nameMatch && senderMatch) {
195 // If an inverse rule matches, then we know that we never want to return a highlight.
196 if (rule.isInverse) {
207 if (!currentNick.isEmpty()) {
208 QStringList nickList;
209 if (_highlightNick == CurrentNick) {
210 nickList << currentNick;
212 else if (_highlightNick == AllNicks) {
213 nickList = identityNicks;
214 if (!nickList.contains(currentNick))
215 nickList.prepend(currentNick);
218 for(const QString &nickname : nickList) {
219 QRegExp nickRegExp("(^|\\W)" + QRegExp::escape(nickname) + "(\\W|$)", _nicksCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive);
220 if (nickRegExp.indexIn(stripFormatCodes(msgContents)) >= 0) {
230 void HighlightRuleManager::removeHighlightRule(int highlightRule)
232 removeAt(indexOf(highlightRule));
233 SYNC(ARG(highlightRule))
237 void HighlightRuleManager::toggleHighlightRule(int highlightRule)
239 int idx = indexOf(highlightRule);
242 _highlightRuleList[idx].isEnabled = !_highlightRuleList[idx].isEnabled;
243 SYNC(ARG(highlightRule))
247 bool HighlightRuleManager::match(const Message &msg, const QString ¤tNick, const QStringList &identityNicks)
249 return match(msg.contents(), msg.sender(), msg.type(), msg.flags(), msg.bufferInfo().bufferName(), currentNick, identityNicks);