From ebe14ade2f3496aefc8926ce704a161c4451fedd Mon Sep 17 00:00:00 2001 From: Janne Koschinski Date: Tue, 5 Sep 2017 18:11:51 +0200 Subject: [PATCH] Implement sender matching for highlight rules - Implements configuration, sync, and matching behavior for sender-based matching in highlight rules - The match type (regexp or wildcard) is the same as configured for the message itself. - The sender rule has to match exactly --- src/common/highlightrulemanager.cpp | 36 +++++++++++++------ src/common/highlightrulemanager.h | 21 ++++++----- src/core/corehighlightrulemanager.h | 6 ++-- .../corehighlightsettingspage.cpp | 18 +++++++--- .../settingspages/corehighlightsettingspage.h | 8 +++-- .../corehighlightsettingspage.ui | 5 +++ 6 files changed, 65 insertions(+), 29 deletions(-) diff --git a/src/common/highlightrulemanager.cpp b/src/common/highlightrulemanager.cpp index 7b24ed51..4d74deb0 100644 --- a/src/common/highlightrulemanager.cpp +++ b/src/common/highlightrulemanager.cpp @@ -57,6 +57,7 @@ QVariantMap HighlightRuleManager::initHighlightRuleList() const QVariantList isCaseSensitive; QVariantList isActive; QVariantList isInverse; + QStringList sender; QStringList channel; for (int i = 0; i < _highlightRuleList.count(); i++) { @@ -65,6 +66,7 @@ QVariantMap HighlightRuleManager::initHighlightRuleList() const isCaseSensitive << _highlightRuleList[i].isCaseSensitive; isActive << _highlightRuleList[i].isEnabled; isInverse << _highlightRuleList[i].isInverse; + sender << _highlightRuleList[i].sender; channel << _highlightRuleList[i].chanName; } @@ -73,6 +75,7 @@ QVariantMap HighlightRuleManager::initHighlightRuleList() const highlightRuleListMap["isCaseSensitive"] = isCaseSensitive; highlightRuleListMap["isEnabled"] = isActive; highlightRuleListMap["isInverse"] = isInverse; + highlightRuleListMap["sender"] = sender; highlightRuleListMap["channel"] = channel; highlightRuleListMap["highlightNick"] = _highlightNick; highlightRuleListMap["nicksCaseSensitive"] = _nicksCaseSensitive; @@ -87,11 +90,12 @@ void HighlightRuleManager::initSetHighlightRuleList(const QVariantMap &highlight QVariantList isCaseSensitive = highlightRuleList["isCaseSensitive"].toList(); QVariantList isActive = highlightRuleList["isEnabled"].toList(); QVariantList isInverse = highlightRuleList["isInverse"].toList(); + QStringList sender = highlightRuleList["sender"].toStringList(); QStringList channel = highlightRuleList["channel"].toStringList(); int count = name.count(); - if (count != isRegEx.count() || count != isCaseSensitive.count() || - count != isActive.count() || count != channel.count()) { + if (count != isRegEx.count() || count != isCaseSensitive.count() || count != isActive.count() || + count != isInverse.count() || count != sender.count() || count != channel.count()) { qWarning() << "Corrupted HighlightRuleList settings! (Count mismatch)"; return; } @@ -99,23 +103,23 @@ void HighlightRuleManager::initSetHighlightRuleList(const QVariantMap &highlight _highlightRuleList.clear(); for (int i = 0; i < name.count(); i++) { _highlightRuleList << HighlightRule(name[i], isRegEx[i].toBool(), isCaseSensitive[i].toBool(), - isActive[i].toBool(), isInverse[i].toBool(), channel[i]); + isActive[i].toBool(), isInverse[i].toBool(), sender[i], channel[i]); } _highlightNick = HighlightNickType(highlightRuleList["highlightNick"].toInt()); _nicksCaseSensitive = highlightRuleList["nicksCaseSensitive"].toBool(); } void HighlightRuleManager::addHighlightRule(const QString &name, bool isRegEx, bool isCaseSensitive, bool isActive, - bool isInverse, const QString &channel) + bool isInverse, const QString &sender, const QString &channel) { if (contains(name)) { return; } - HighlightRule newItem = HighlightRule(name, isRegEx, isCaseSensitive, isActive, isInverse, channel); + HighlightRule newItem = HighlightRule(name, isRegEx, isCaseSensitive, isActive, isInverse, sender, channel); _highlightRuleList << newItem; - SYNC(ARG(name), ARG(isRegEx), ARG(isCaseSensitive), ARG(isActive), ARG(isInverse), ARG(channel)) + SYNC(ARG(name), ARG(isRegEx), ARG(isCaseSensitive), ARG(isActive), ARG(isInverse), ARG(sender), ARG(channel)) } @@ -148,12 +152,24 @@ bool HighlightRuleManager::_match(const QString &msgContents, const QString &msg QRegExp rx; if (rule.isRegEx) { rx = QRegExp(rule.name, rule.isCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive); - } - else { + } else { rx = QRegExp("(^|\\W)" + QRegExp::escape(rule.name) + "(\\W|$)", rule.isCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive); } - bool match = (rx.indexIn(stripFormatCodes(msgContents)) >= 0); - if (match) { + bool nameMatch = (rx.indexIn(stripFormatCodes(msgContents)) >= 0); + + bool senderMatch; + if (rule.sender.isEmpty()) { + senderMatch = true; + } else { + if (rule.isRegEx) { + rx = QRegExp(rule.sender, rule.isCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive); + } else { + rx = QRegExp(rule.sender, Qt::CaseInsensitive, QRegExp::Wildcard); + } + senderMatch = rx.exactMatch(msgSender); + } + + if (nameMatch && senderMatch) { // If an inverse rule matches, then we know that we never want to return a highlight. if (rule.isInverse) { return false; diff --git a/src/common/highlightrulemanager.h b/src/common/highlightrulemanager.h index b606a0a8..427b6581 100644 --- a/src/common/highlightrulemanager.h +++ b/src/common/highlightrulemanager.h @@ -23,6 +23,7 @@ #include #include +#include #include "message.h" #include "syncableobject.h" @@ -47,12 +48,13 @@ public: bool isCaseSensitive = false; bool isEnabled = true; bool isInverse = false; + QString sender; QString chanName; HighlightRule() {} - HighlightRule(const QString &name_, bool isRegEx_, bool isCaseSensitive_, - bool isEnabled_, bool isInverse_, const QString &chanName_) - : name(name_), isRegEx(isRegEx_), isCaseSensitive(isCaseSensitive_), isEnabled(isEnabled_), - isInverse(isInverse_), chanName(chanName_) { + HighlightRule(QString name_, bool isRegEx_, bool isCaseSensitive_, bool isEnabled_, bool isInverse_, + QString sender_, QString chanName_) + : name(std::move(name_)), isRegEx(isRegEx_), isCaseSensitive(isCaseSensitive_), isEnabled(isEnabled_), + isInverse(isInverse_), sender(std::move(sender_)), chanName(std::move(chanName_)) { } bool operator!=(const HighlightRule &other) { @@ -61,6 +63,7 @@ public: isCaseSensitive != other.isCaseSensitive || isEnabled != other.isEnabled || isInverse != other.isInverse || + sender != other.sender || chanName != other.chanName); } }; @@ -114,14 +117,14 @@ public slots: * @param chanName The channel in which the rule should apply */ virtual inline void requestAddHighlightRule(const QString &name, bool isRegEx, bool isCaseSensitive, bool isEnabled, - bool isInverse, const QString &chanName) + bool isInverse, const QString &sender, const QString &chanName) { - REQUEST(ARG(name), ARG(isRegEx), ARG(isCaseSensitive), ARG(isEnabled), ARG(isInverse), ARG(chanName)) + REQUEST(ARG(name), ARG(isRegEx), ARG(isCaseSensitive), ARG(isEnabled), ARG(isInverse), ARG(sender), ARG(chanName)) } - virtual void addHighlightRule(const QString &name, bool isRegEx, bool isCaseSensitive, - bool isEnabled, bool isInverse, const QString &chanName); + virtual void addHighlightRule(const QString &name, bool isRegEx, bool isCaseSensitive, bool isEnabled, + bool isInverse, const QString &sender, const QString &chanName); virtual inline void requestSetHighlightNick(HighlightNickType highlightNick) { @@ -141,7 +144,7 @@ protected: bool _match(const QString &msgContents, const QString &msgSender, Message::Type msgType, Message::Flags msgFlags, const QString &bufferName, const QString ¤tNick, const QStringList identityNicks); signals: - void ruleAdded(QString name, bool isRegEx, bool isCaseSensitive, bool isEnabled, bool isInverse, QString chanName); + void ruleAdded(QString name, bool isRegEx, bool isCaseSensitive, bool isEnabled, bool isInverse, QString sender, QString chanName); private: HighlightRuleList _highlightRuleList; diff --git a/src/core/corehighlightrulemanager.h b/src/core/corehighlightrulemanager.h index 9cb1b634..5f2db906 100644 --- a/src/core/corehighlightrulemanager.h +++ b/src/core/corehighlightrulemanager.h @@ -40,10 +40,10 @@ public: public slots: virtual inline void requestToggleHighlightRule(const QString &highlightRule) { toggleHighlightRule(highlightRule); } virtual inline void requestRemoveHighlightRule(const QString &highlightRule) { removeHighlightRule(highlightRule); } - virtual inline void requestAddHighlightRule(const QString &name, bool isRegEx, bool isCaseSensitive, - bool isEnabled, bool isInverse, const QString &chanName) + virtual inline void requestAddHighlightRule(const QString &name, bool isRegEx, bool isCaseSensitive, bool isEnabled, + bool isInverse, const QString &sender, const QString &chanName) { - addHighlightRule(name, isRegEx, isCaseSensitive, isEnabled, isInverse, chanName); + addHighlightRule(name, isRegEx, isCaseSensitive, isEnabled, isInverse, sender, chanName); } diff --git a/src/qtui/settingspages/corehighlightsettingspage.cpp b/src/qtui/settingspages/corehighlightsettingspage.cpp index 467991fb..8e9b852e 100644 --- a/src/qtui/settingspages/corehighlightsettingspage.cpp +++ b/src/qtui/settingspages/corehighlightsettingspage.cpp @@ -107,7 +107,8 @@ void CoreHighlightSettingsPage::defaults() } -void CoreHighlightSettingsPage::addNewRow(QString name, bool regex, bool cs, bool enable, bool inverse, QString chanName, bool self) +void CoreHighlightSettingsPage::addNewRow(const QString &name, bool regex, bool cs, bool enable, bool inverse, const QString &sender, + const QString &chanName, bool self) { ui.highlightTable->setRowCount(ui.highlightTable->rowCount()+1); @@ -143,18 +144,21 @@ void CoreHighlightSettingsPage::addNewRow(QString name, bool regex, bool cs, boo auto *chanNameItem = new QTableWidgetItem(chanName); + auto *senderItem = new QTableWidgetItem(sender); + int lastRow = ui.highlightTable->rowCount()-1; ui.highlightTable->setItem(lastRow, CoreHighlightSettingsPage::NameColumn, nameItem); ui.highlightTable->setItem(lastRow, CoreHighlightSettingsPage::RegExColumn, regexItem); ui.highlightTable->setItem(lastRow, CoreHighlightSettingsPage::CsColumn, csItem); ui.highlightTable->setItem(lastRow, CoreHighlightSettingsPage::EnableColumn, enableItem); ui.highlightTable->setItem(lastRow, CoreHighlightSettingsPage::InverseColumn, inverseItem); + ui.highlightTable->setItem(lastRow, CoreHighlightSettingsPage::SenderColumn, senderItem); ui.highlightTable->setItem(lastRow, CoreHighlightSettingsPage::ChanColumn, chanNameItem); if (!self) ui.highlightTable->setCurrentItem(nameItem); - highlightList << HighlightRuleManager::HighlightRule(name, regex, cs, enable, inverse, chanName); + highlightList << HighlightRuleManager::HighlightRule(name, regex, cs, enable, inverse, sender, chanName); } @@ -227,6 +231,11 @@ void CoreHighlightSettingsPage::tableChanged(QTableWidgetItem *item) case CoreHighlightSettingsPage::InverseColumn: highlightRule.isInverse = (item->checkState() == Qt::Checked); break; + case CoreHighlightSettingsPage::SenderColumn: + if (!item->text().isEmpty() && item->text().trimmed().isEmpty()) + item->setText(""); + highlightRule.sender = item->text(); + break; case CoreHighlightSettingsPage::ChanColumn: if (!item->text().isEmpty() && item->text().trimmed().isEmpty()) item->setText(""); @@ -244,7 +253,7 @@ void CoreHighlightSettingsPage::load() auto ruleManager = Client::highlightRuleManager(); for (HighlightRuleManager::HighlightRule rule : ruleManager->highlightRuleList()) { - addNewRow(rule.name, rule.isRegEx, rule.isCaseSensitive, rule.isEnabled, rule.isInverse, rule.chanName); + addNewRow(rule.name, rule.isRegEx, rule.isCaseSensitive, rule.isEnabled, rule.isInverse, rule.sender, rule.chanName); } switch (ruleManager->highlightNick()) @@ -282,7 +291,8 @@ void CoreHighlightSettingsPage::save() clonedManager.clear(); for (const HighlightRuleManager::HighlightRule &rule : highlightList) { - clonedManager.addHighlightRule(rule.name, rule.isRegEx, rule.isCaseSensitive, rule.isEnabled, rule.isInverse, rule.chanName); + clonedManager.addHighlightRule(rule.name, rule.isRegEx, rule.isCaseSensitive, rule.isEnabled, rule.isInverse, + rule.sender, rule.chanName); } HighlightRuleManager::HighlightNickType highlightNickType = HighlightRuleManager::NoNick; diff --git a/src/qtui/settingspages/corehighlightsettingspage.h b/src/qtui/settingspages/corehighlightsettingspage.h index 915ea785..2820850a 100644 --- a/src/qtui/settingspages/corehighlightsettingspage.h +++ b/src/qtui/settingspages/corehighlightsettingspage.h @@ -47,7 +47,8 @@ public slots: private slots: void widgetHasChanged(); - void addNewRow(QString name = tr("highlight rule"), bool regex = false, bool cs = false, bool enable = true, bool inverse = false, QString chanName = "", bool self = false); + void addNewRow(const QString &name = tr("highlight rule"), bool regex = false, bool cs = false, bool enable = true, + bool inverse = false, const QString &sender = "", const QString &chanName = "", bool self = false); void removeSelectedRows(); void selectRow(QTableWidgetItem *item); void tableChanged(QTableWidgetItem *item); @@ -61,8 +62,9 @@ private: CsColumn = 2, EnableColumn = 3, InverseColumn = 4, - ChanColumn = 5, - ColumnCount = 6 + SenderColumn = 5, + ChanColumn = 6, + ColumnCount = 7 }; void emptyTable(); diff --git a/src/qtui/settingspages/corehighlightsettingspage.ui b/src/qtui/settingspages/corehighlightsettingspage.ui index 6e18ecbc..7abdcef2 100644 --- a/src/qtui/settingspages/corehighlightsettingspage.ui +++ b/src/qtui/settingspages/corehighlightsettingspage.ui @@ -53,6 +53,11 @@ Inverse + + + Sender + + Channel -- 2.20.1