Implement core-side highlights
[quassel.git] / src / common / highlightrulemanager.cpp
diff --git a/src/common/highlightrulemanager.cpp b/src/common/highlightrulemanager.cpp
new file mode 100644 (file)
index 0000000..9f780f5
--- /dev/null
@@ -0,0 +1,184 @@
+/***************************************************************************
+ *   Copyright (C) 2005-2016 by the Quassel Project                        *
+ *   devel@quassel-irc.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) version 3.                                           *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
+ ***************************************************************************/
+
+#include "highlightrulemanager.h"
+#include "util.h"
+
+#include <QtCore>
+#include <QDebug>
+#include <QStringList>
+
+INIT_SYNCABLE_OBJECT(HighlightRuleManager)
+HighlightRuleManager &HighlightRuleManager::operator=(const HighlightRuleManager &other)
+{
+    if (this == &other)
+        return *this;
+
+    SyncableObject::operator=(other);
+    _highlightRuleList = other._highlightRuleList;
+    return *this;
+}
+
+
+int HighlightRuleManager::indexOf(const QString &name) const
+{
+    for (int i = 0; i < _highlightRuleList.count(); i++) {
+        if (_highlightRuleList[i].name == name)
+            return i;
+    }
+    return -1;
+}
+
+
+QVariantMap HighlightRuleManager::initHighlightRuleList() const
+{
+    QVariantMap highlightRuleListMap;
+    QStringList name;
+    QVariantList isRegEx;
+    QVariantList isCaseSensitive;
+    QVariantList isActive;
+    QStringList channel;
+
+    for (int i = 0; i < _highlightRuleList.count(); i++) {
+        name << _highlightRuleList[i].name;
+        isRegEx << _highlightRuleList[i].isRegEx;
+        isCaseSensitive << _highlightRuleList[i].isCaseSensitive;
+        isActive << _highlightRuleList[i].isEnabled;
+        channel << _highlightRuleList[i].chanName;
+    }
+
+    highlightRuleListMap["name"] = name;
+    highlightRuleListMap["isRegEx"] = isRegEx;
+    highlightRuleListMap["isCaseSensitive"] = isCaseSensitive;
+    highlightRuleListMap["isEnabled"] = isActive;
+    highlightRuleListMap["channel"] = channel;
+    return highlightRuleListMap;
+}
+
+
+void HighlightRuleManager::initSetHighlightRuleList(const QVariantMap &highlightRuleList)
+{
+    QStringList name = highlightRuleList["name"].toStringList();
+    QVariantList isRegEx = highlightRuleList["isRegEx"].toList();
+    QVariantList isCaseSensitive = highlightRuleList["isCaseSensitive"].toList();
+    QVariantList isActive = highlightRuleList["isEnabled"].toList();
+    QStringList channel = highlightRuleList["channel"].toStringList();
+
+    int count = name.count();
+    if (count != isRegEx.count() || count != isCaseSensitive.count() ||
+        count != isActive.count() || count != channel.count()) {
+        qWarning() << "Corrupted HighlightRuleList settings! (Count mismatch)";
+        return;
+    }
+
+    _highlightRuleList.clear();
+    for (int i = 0; i < name.count(); i++) {
+        _highlightRuleList << HighlightRule(name[i], isRegEx[i].toBool(), isCaseSensitive[i].toBool(),
+                                            isActive[i].toBool(), channel[i]);
+    }
+}
+
+void HighlightRuleManager::addHighlightRule(const QString &name, bool isRegEx, bool isCaseSensitive, bool isActive,
+                                            const QString &channel)
+{
+    if (contains(name)) {
+        return;
+    }
+
+    HighlightRule newItem = HighlightRule(name, isRegEx, isCaseSensitive, isActive, channel);
+    _highlightRuleList << newItem;
+
+    SYNC(ARG(name), ARG(isRegEx), ARG(isCaseSensitive), ARG(isActive), ARG(channel))
+}
+
+
+bool HighlightRuleManager::_match(const QString &msgContents, const QString &msgSender, Message::Type msgType, Message::Flags msgFlags, const QString &bufferName, const QString &currentNick, const QStringList identityNicks)
+{
+    if (!((msgType & (Message::Plain | Message::Notice | Message::Action)) && !(msgFlags & Message::Self))) {
+       return false;
+    }
+
+    if (!currentNick.isEmpty()) {
+        QStringList nickList;
+        if (_highlightNick == CurrentNick) {
+            nickList << currentNick;
+        }
+        else if (_highlightNick == AllNicks) {
+            nickList = identityNicks;
+            if (!nickList.contains(currentNick))
+                nickList.prepend(currentNick);
+        }
+            foreach(QString nickname, nickList) {
+                QRegExp nickRegExp("(^|\\W)" + QRegExp::escape(nickname) + "(\\W|$)", _nicksCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive);
+                if (nickRegExp.indexIn(stripFormatCodes(msgContents)) >= 0) {
+                    return true;
+                }
+            }
+
+        for (int i = 0; i < _highlightRuleList.count(); i++) {
+            const HighlightRule &rule = _highlightRuleList.at(i);
+            if (!rule.isEnabled)
+                continue;
+
+            if (rule.chanName.size() > 0 && rule.chanName.compare(".*") != 0) {
+                if (rule.chanName.startsWith("!")) {
+                    QRegExp rx(rule.chanName.mid(1), Qt::CaseInsensitive);
+                    if (rx.exactMatch(bufferName))
+                        continue;
+                }
+                else {
+                    QRegExp rx(rule.chanName, Qt::CaseInsensitive);
+                    if (!rx.exactMatch(bufferName))
+                        continue;
+                }
+            }
+
+            QRegExp rx;
+            if (rule.isRegEx) {
+                rx = QRegExp(rule.name, rule.isCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive);
+            }
+            else {
+                rx = QRegExp("(^|\\W)" + QRegExp::escape(rule.name) + "(\\W|$)", rule.isCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive);
+            }
+            bool match = (rx.indexIn(stripFormatCodes(msgContents)) >= 0);
+            if (match) {
+                return true;
+            }
+        }
+    }
+
+    return false;
+}
+
+void HighlightRuleManager::removeHighlightRule(const QString &highlightRule)
+{
+    removeAt(indexOf(highlightRule));
+    SYNC(ARG(highlightRule))
+}
+
+
+void HighlightRuleManager::toggleHighlightRule(const QString &highlightRule)
+{
+    int idx = indexOf(highlightRule);
+    if (idx == -1)
+        return;
+    _highlightRuleList[idx].isEnabled = !_highlightRuleList[idx].isEnabled;
+    SYNC(ARG(highlightRule))
+}