From 27302bba72a29977e81b9a0b2d8cde3a62ebc818 Mon Sep 17 00:00:00 2001 From: Sebastian Goth Date: Sun, 16 Aug 2009 17:07:45 +0200 Subject: [PATCH] Introduce IgnoreList backend Implements core- and clientside filtering and the synchronized ignorelist itself. --- src/client/CMakeLists.txt | 2 + src/client/client.cpp | 12 +- src/client/client.h | 3 + src/client/clientignorelistmanager.cpp | 32 +++++ src/client/clientignorelistmanager.h | 41 +++++++ src/client/messagefilter.cpp | 7 ++ src/client/messagefilter.h | 2 + src/client/messagemodel.h | 3 +- src/common/CMakeLists.txt | 2 + src/common/ignorelistmanager.cpp | 162 +++++++++++++++++++++++++ src/common/ignorelistmanager.h | 114 +++++++++++++++++ src/core/CMakeLists.txt | 2 + src/core/coreignorelistmanager.cpp | 55 +++++++++ src/core/coreignorelistmanager.h | 42 +++++++ src/core/coresession.cpp | 24 +++- src/core/coresession.h | 2 + src/qtui/chatlinemodel.h | 3 +- src/qtui/chatmonitorfilter.cpp | 8 ++ src/qtui/chatmonitorview.cpp | 9 ++ src/qtui/chatmonitorview.h | 1 + src/qtui/chatview.cpp | 5 + 21 files changed, 522 insertions(+), 9 deletions(-) create mode 100644 src/client/clientignorelistmanager.cpp create mode 100644 src/client/clientignorelistmanager.h create mode 100644 src/common/ignorelistmanager.cpp create mode 100644 src/common/ignorelistmanager.h create mode 100644 src/core/coreignorelistmanager.cpp create mode 100644 src/core/coreignorelistmanager.h diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index f60f66c5..818dd8ab 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -19,6 +19,7 @@ set(SOURCES clientbufferviewconfig.cpp clientbufferviewmanager.cpp clientidentity.cpp + clientignorelistmanager.cpp clientirclisthelper.cpp clientsettings.cpp clientsyncer.cpp @@ -43,6 +44,7 @@ set(MOC_HDRS clientbufferviewmanager.h clientcoreinfo.h clientidentity.h + clientignorelistmanager.h clientirclisthelper.h clientuserinputhandler.h clientsyncer.h diff --git a/src/client/client.cpp b/src/client/client.cpp index e6f7f05a..b1c0ced8 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -33,6 +33,7 @@ #include "clientbufferviewmanager.h" #include "clientirclisthelper.h" #include "clientidentity.h" +#include "clientignorelistmanager.h" #include "clientuserinputhandler.h" #include "ircchannel.h" #include "ircuser.h" @@ -91,6 +92,7 @@ Client::Client(QObject *parent) _ircListHelper(new ClientIrcListHelper(this)), _inputHandler(0), _networkConfig(0), + _ignoreListManager(0), _messageModel(0), _messageProcessor(0), _connectedToCore(false), @@ -336,6 +338,11 @@ void Client::setSyncedToCore() { _networkConfig = new NetworkConfig("GlobalNetworkConfig", this); signalProxy()->synchronize(networkConfig()); + // create IgnoreListManager + Q_ASSERT(!_ignoreListManager); + _ignoreListManager = new ClientIgnoreListManager(this); + signalProxy()->synchronize(ignoreListManager()); + // trigger backlog request once all active bufferviews are initialized connect(bufferViewOverlay(), SIGNAL(initDone()), this, SLOT(requestInitialBacklog())); @@ -399,6 +406,10 @@ void Client::disconnectedFromCore() { _aliasManager = 0; } + if(_ignoreListManager) { + _ignoreListManager->deleteLater(); + _ignoreListManager = 0; + } // we probably don't want to save pending input for reconnect _userInputBuffer.clear(); @@ -532,4 +543,3 @@ void Client::logMessage(QtMsgType type, const char *msg) { emit instance()->logUpdated(msgString); } } - diff --git a/src/client/client.h b/src/client/client.h index 57c49093..8563ad27 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -46,6 +46,7 @@ class BufferViewOverlay; class ClientAliasManager; class ClientBacklogManager; class ClientBufferViewManager; +class ClientIgnoreListManager; class ClientIrcListHelper; class ClientSyncer; class ClientUserInputHandler; @@ -112,6 +113,7 @@ public: static inline BufferViewOverlay *bufferViewOverlay() { return instance()->_bufferViewOverlay; } static inline ClientUserInputHandler *inputHandler() { return instance()->_inputHandler; } static inline NetworkConfig *networkConfig() { return instance()->_networkConfig; } + static inline ClientIgnoreListManager *ignoreListManager() { return instance()->_ignoreListManager; } static AccountId currentCoreAccount(); @@ -218,6 +220,7 @@ private: ClientIrcListHelper *_ircListHelper; ClientUserInputHandler *_inputHandler; NetworkConfig *_networkConfig; + ClientIgnoreListManager *_ignoreListManager; MessageModel *_messageModel; AbstractMessageProcessor *_messageProcessor; diff --git a/src/client/clientignorelistmanager.cpp b/src/client/clientignorelistmanager.cpp new file mode 100644 index 00000000..f0429690 --- /dev/null +++ b/src/client/clientignorelistmanager.cpp @@ -0,0 +1,32 @@ +/*************************************************************************** + * Copyright (C) 2005-09 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "clientignorelistmanager.h" + +ClientIgnoreListManager::ClientIgnoreListManager(QObject *parent) + : IgnoreListManager(parent) +{ + connect(this, SIGNAL(updated(const QVariantMap&)), this, SLOT(ignoreListUpdated(const QVariantMap&))); +} + +void ClientIgnoreListManager::ignoreListUpdated(const QVariantMap &newMap) { + if(newMap != initIgnoreList()) + emit ignoreListChanged(); +} diff --git a/src/client/clientignorelistmanager.h b/src/client/clientignorelistmanager.h new file mode 100644 index 00000000..841ff4f6 --- /dev/null +++ b/src/client/clientignorelistmanager.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2005-09 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef CLIENTIGNORELISTMANAGER_H +#define CLIENTIGNORELISTMANAGER_H + +#include "ignorelistmanager.h" + +class ClientIgnoreListManager : public IgnoreListManager +{ + Q_OBJECT + +public: + explicit ClientIgnoreListManager(QObject *parent = 0); + inline virtual const QMetaObject *syncMetaObject() const { return &IgnoreListManager::staticMetaObject; } + +signals: + void ignoreListChanged(); + +private slots: + void ignoreListUpdated(const QVariantMap &newMap); +}; + +#endif // CLIENTIGNORELISTMANAGER_H diff --git a/src/client/messagefilter.cpp b/src/client/messagefilter.cpp index edb7a319..53ac5e1b 100644 --- a/src/client/messagefilter.cpp +++ b/src/client/messagefilter.cpp @@ -25,6 +25,7 @@ #include "buffermodel.h" #include "messagemodel.h" #include "networkmodel.h" +#include "clientignorelistmanager.h" MessageFilter::MessageFilter(QAbstractItemModel *source, QObject *parent) : QSortFilterProxyModel(parent), @@ -142,6 +143,12 @@ bool MessageFilter::filterAcceptsRow(int sourceRow, const QModelIndex &sourcePar if(myNetworkId != msgNetworkId) return false; + // ignorelist handling + const MessageModelItem *item = const_cast(static_cast(sourceModel()))->messageItemAt(sourceRow); + // only match if message is not flagged as server msg + if(!(item->message().flags() & Message::ServerMsg) && + Client::ignoreListManager()->match(item->message(), Client::networkModel()->networkName(item->bufferId()))) + return false; if(flags & Message::Redirected) { int redirectionTarget = 0; diff --git a/src/client/messagefilter.h b/src/client/messagefilter.h index 84d089f4..f8e85a55 100644 --- a/src/client/messagefilter.h +++ b/src/client/messagefilter.h @@ -49,6 +49,8 @@ public slots: void messageTypeFilterChanged(); void messageRedirectionChanged(); void requestBacklog(); + // redefined as public slot + void invalidateFilter() { QSortFilterProxyModel::invalidateFilter(); } protected: QString bufferName() const { return Client::networkModel()->bufferName(singleBufferId()); } diff --git a/src/client/messagemodel.h b/src/client/messagemodel.h index 2e30dd21..afb8ec30 100644 --- a/src/client/messagemodel.h +++ b/src/client/messagemodel.h @@ -70,6 +70,8 @@ public: void clear(); + virtual const MessageModelItem *messageItemAt(int i) const = 0; + public slots: void requestBacklog(BufferId bufferId); void messagesReceived(BufferId bufferId, int count); @@ -81,7 +83,6 @@ protected: virtual int messageCount() const = 0; virtual bool messagesIsEmpty() const = 0; - virtual const MessageModelItem *messageItemAt(int i) const = 0; virtual MessageModelItem *messageItemAt(int i) = 0; virtual const MessageModelItem *firstMessageItem() const= 0; virtual MessageModelItem *firstMessageItem() = 0; diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 819077a3..f36d00e8 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -13,6 +13,7 @@ set(SOURCES bufferviewmanager.cpp cliparser.cpp identity.cpp + ignorelistmanager.cpp ircchannel.cpp irclisthelper.cpp ircuser.cpp @@ -41,6 +42,7 @@ set(MOC_HDRS bufferviewmanager.h coreinfo.h identity.h + ignorelistmanager.h ircchannel.h irclisthelper.h ircuser.h diff --git a/src/common/ignorelistmanager.cpp b/src/common/ignorelistmanager.cpp new file mode 100644 index 00000000..a9fb4c68 --- /dev/null +++ b/src/common/ignorelistmanager.cpp @@ -0,0 +1,162 @@ +/*************************************************************************** + * Copyright (C) 2005-09 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "ignorelistmanager.h" + +#include +#include +#include + +#include "message.h" + +IgnoreListManager &IgnoreListManager::operator=(const IgnoreListManager &other) { + if(this == &other) + return *this; + + SyncableObject::operator=(other); + _ignoreList = other._ignoreList; + return *this; +} + +int IgnoreListManager::indexOf(const QString &ignore) const { + for(int i = 0; i < _ignoreList.count(); i++) { + if(_ignoreList[i].ignoreRule == ignore) + return i; + } + return -1; +} + +QVariantMap IgnoreListManager::initIgnoreList() const { + QVariantMap ignoreListMap; + QVariantList ignoreTypeList; + QStringList ignoreRuleList; + QStringList scopeRuleList; + QVariantList isRegExList; + QVariantList scopeList; + QVariantList strictnessList; + QVariantList isActiveList; + + for(int i = 0; i < _ignoreList.count(); i++) { + ignoreTypeList << _ignoreList[i].type; + ignoreRuleList << _ignoreList[i].ignoreRule; + scopeRuleList << _ignoreList[i].scopeRule; + isRegExList << _ignoreList[i].isRegEx; + scopeList << _ignoreList[i].scope; + strictnessList << _ignoreList[i].strictness; + isActiveList << _ignoreList[i].isActive; + } + + ignoreListMap["ignoreType"] = ignoreTypeList; + ignoreListMap["ignoreRule"] = ignoreRuleList; + ignoreListMap["scopeRule"] = scopeRuleList; + ignoreListMap["isRegEx"] = isRegExList; + ignoreListMap["scope"] = scopeList; + ignoreListMap["strictness"] = strictnessList; + ignoreListMap["isActive"] = isActiveList; + return ignoreListMap; +} + +void IgnoreListManager::initSetIgnoreList(const QVariantMap &ignoreList) { + QVariantList ignoreType = ignoreList["ignoreType"].toList(); + QStringList ignoreRule = ignoreList["ignoreRule"].toStringList(); + QStringList scopeRule = ignoreList["scopeRule"].toStringList(); + QVariantList isRegEx = ignoreList["isRegEx"].toList(); + QVariantList scope = ignoreList["scope"].toList(); + QVariantList strictness = ignoreList["strictness"].toList(); + QVariantList isActive = ignoreList["isActive"].toList(); + + 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)"; + return; + } + + _ignoreList.clear(); + for(int i = 0; i < ignoreRule.count(); i++) { + _ignoreList << IgnoreListItem(static_cast(ignoreType[i].toInt()), ignoreRule[i], isRegEx[i].toBool(), + static_cast(strictness[i].toInt()), static_cast(scope[i].toInt()), + scopeRule[i], isActive[i].toBool()); + } +} + +void IgnoreListManager::addIgnoreListItem(const IgnoreListItem &item) { + addIgnoreListItem(item.type, item.ignoreRule, item.isRegEx, item.strictness, item.scope, item.scopeRule, item.isActive); +} + +void IgnoreListManager::addIgnoreListItem(IgnoreType type, const QString &ignoreRule, bool isRegEx, StrictnessType strictness, + ScopeType scope, const QString &scopeRule, bool isActive) { + if(contains(ignoreRule)) { + return; + } + + _ignoreList << IgnoreListItem(type, ignoreRule, isRegEx, strictness, scope, scopeRule, isActive); + + emit ignoreAdded(type, ignoreRule, isRegEx, strictness, scope, scopeRule, isActive); +} + +IgnoreListManager::StrictnessType IgnoreListManager::match(const Message &msg, const QString &network) { + if(!(msg.type() & (Message::Plain | Message::Notice | Message::Action))) + return UnmatchedStrictness; + + foreach(IgnoreListItem item, _ignoreList) { + if(!item.isActive) + continue; + if(item.scope == GlobalScope || (item.scope == NetworkScope && scopeMatch(item.scopeRule, network)) || + (item.scope == ChannelScope && scopeMatch(item.scopeRule, msg.bufferInfo().bufferName()))) { + + QString str; + if(item.type == MessageIgnore) + str = msg.contents(); + else + str = msg.sender(); + + 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)) { +// qDebug() << "MATCHED!"; + return item.strictness; + } + } + } + return UnmatchedStrictness; +} + +bool IgnoreListManager::scopeMatch(const QString &scopeRule, const QString &string) { + foreach(QString rule, scopeRule.split(";")) { + QRegExp ruleRx = QRegExp(rule.trimmed()); + ruleRx.setCaseSensitivity(Qt::CaseInsensitive); + ruleRx.setPatternSyntax(QRegExp::Wildcard); + if(ruleRx.exactMatch(string)) { + return true; + } + } + return false; +} diff --git a/src/common/ignorelistmanager.h b/src/common/ignorelistmanager.h new file mode 100644 index 00000000..a906b953 --- /dev/null +++ b/src/common/ignorelistmanager.h @@ -0,0 +1,114 @@ +/*************************************************************************** + * Copyright (C) 2005-09 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef IGNORELISTMANAGER_H +#define IGNORELISTMANAGER_H + +#include + +#include "syncableobject.h" + +class Message; + +class IgnoreListManager : public SyncableObject +{ + Q_OBJECT +public: + inline IgnoreListManager(QObject *parent = 0) : SyncableObject(parent) { setAllowClientUpdates(true); } + IgnoreListManager &operator=(const IgnoreListManager &other); + + enum IgnoreType { + SenderIgnore, + MessageIgnore + }; + + enum StrictnessType { + UnmatchedStrictness = 0, + SoftStrictness = 1, + HardStrictness = 2 + }; + + enum ScopeType { + GlobalScope, + NetworkScope, + ChannelScope, + }; + + struct IgnoreListItem { + IgnoreType type; + QString ignoreRule; + bool isRegEx; + StrictnessType strictness; + ScopeType scope; + QString scopeRule; + bool isActive; + IgnoreListItem() {} + IgnoreListItem(IgnoreType type_, const QString &ignoreRule_, bool isRegEx_, StrictnessType strictness_, + ScopeType scope_, const QString &scopeRule_, bool isActive_) + : type(type_), ignoreRule(ignoreRule_), isRegEx(isRegEx_), strictness(strictness_), scope(scope_), scopeRule(scopeRule_), isActive(isActive_) {} + bool operator!=(const IgnoreListItem &other) { + return (type != other.type || + ignoreRule != other.ignoreRule || + isRegEx != other.isRegEx || + strictness != other.strictness || + scope != other.scope || + scopeRule != other.scopeRule || + isActive != other.isActive); + } + }; + typedef QList IgnoreList; + + int indexOf(const QString &ignore) const; + inline bool contains(const QString &ignore) const { return indexOf(ignore) != -1; } + inline bool isEmpty() const { return _ignoreList.isEmpty(); } + inline int count() const { return _ignoreList.count(); } + inline void removeAt(int index) { _ignoreList.removeAt(index); } + inline IgnoreListItem &operator[](int i) { return _ignoreList[i]; } + inline const IgnoreListItem &operator[](int i) const { return _ignoreList.at(i); } + inline const IgnoreList &ignoreList() const { return _ignoreList; } + + //! Check if a message matches the IgnoreRule + /** This method checks if a message matches the users ignorelist. + * \param msg The Message that should be checked + * \param network The networkname the message belongs to + * \return UnmatchedStrictness, HardStrictness or SoftStrictness representing the match type + */ + StrictnessType match(const Message &msg, const QString &network = QString()); + +public slots: + virtual QVariantMap initIgnoreList() const; + virtual void initSetIgnoreList(const QVariantMap &ignoreList); + + virtual void addIgnoreListItem(IgnoreType type, const QString &ignoreRule, bool isRegEx, StrictnessType strictness, + ScopeType scope, const QString &scopeRule, bool isActive); + virtual void addIgnoreListItem(const IgnoreListItem &item); +protected: + void setIgnoreList(const QList &ignoreList) { _ignoreList = ignoreList; } + +signals: + void ignoreAdded(IgnoreType type, const QString &ignoreRule, bool isRegex, StrictnessType strictness, ScopeType scope, const QVariant &scopeRule, bool isActive); + +private: + // scopeRule is a ; separated list, string is a network/channel-name + bool scopeMatch(const QString &scopeRule, const QString &string); + IgnoreList _ignoreList; +}; + +#endif // IGNORELISTMANAGER_H diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index d5624d6c..f7b3ce11 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -18,6 +18,7 @@ set(SOURCES corebufferviewmanager.cpp corecoreinfo.cpp coreidentity.cpp + coreignorelistmanager.cpp coreircchannel.cpp coreirclisthelper.cpp corenetwork.cpp @@ -46,6 +47,7 @@ set(MOC_HDRS corebufferviewmanager.h corecoreinfo.h coreidentity.h + coreignorelistmanager.h coreircchannel.h coreirclisthelper.h corenetwork.h diff --git a/src/core/coreignorelistmanager.cpp b/src/core/coreignorelistmanager.cpp new file mode 100644 index 00000000..db9cc7d1 --- /dev/null +++ b/src/core/coreignorelistmanager.cpp @@ -0,0 +1,55 @@ +/*************************************************************************** + * Copyright (C) 2005-09 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "coreignorelistmanager.h" + +#include "core.h" +#include "coresession.h" + +CoreIgnoreListManager::CoreIgnoreListManager(CoreSession *parent) + : IgnoreListManager(parent) +{ + CoreSession *session = qobject_cast(parent); + if(!session) { + qWarning() << "CoreIgnoreListManager: unable to load IgnoreList. Parent is not a Coresession!"; + //loadDefaults(); + return; + } + + initSetIgnoreList(Core::getUserSetting(session->user(), "IgnoreList").toMap()); + //if(isEmpty()) + //loadDefaults(); +} + +CoreIgnoreListManager::~CoreIgnoreListManager() { + CoreSession *session = qobject_cast(parent()); + if(!session) { + qWarning() << "CoreIgnoreListManager: unable to save IgnoreList. Parent is not a Coresession!"; + return; + } + + Core::setUserSetting(session->user(), "IgnoreList", initIgnoreList()); +} + +//void CoreIgnoreListManager::loadDefaults() { +// foreach(IgnoreListItem item, IgnoreListManager::defaults()) { +// addIgnoreListItem(item.ignoreRule, item.isRegEx, item.strictness, item.scope, item.scopeRule); +// } +//} diff --git a/src/core/coreignorelistmanager.h b/src/core/coreignorelistmanager.h new file mode 100644 index 00000000..9576c1b0 --- /dev/null +++ b/src/core/coreignorelistmanager.h @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (C) 2005-09 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef COREIGNORELISTMANAGER_H +#define COREIGNORELISTMANAGER_H + +#include "ignorelistmanager.h" + +class CoreSession; + +class CoreIgnoreListManager : public IgnoreListManager { + Q_OBJECT + +public: + explicit CoreIgnoreListManager(CoreSession *parent); + ~CoreIgnoreListManager(); + + inline virtual const QMetaObject *syncMetaObject() const { return &IgnoreListManager::staticMetaObject; } + +//private: +// void loadDefaults(); + +}; + +#endif //COREIGNORELISTMANAGER_H diff --git a/src/core/coresession.cpp b/src/core/coresession.cpp index 33f5b09d..d81f9c00 100644 --- a/src/core/coresession.cpp +++ b/src/core/coresession.cpp @@ -39,6 +39,7 @@ #include "util.h" #include "coreusersettings.h" #include "logger.h" +#include "coreignorelistmanager.h" class ProcessMessagesEvent : public QEvent { public: @@ -57,7 +58,8 @@ CoreSession::CoreSession(UserId uid, bool restoreState, QObject *parent) _networkConfig(new CoreNetworkConfig("GlobalNetworkConfig", this)), _coreInfo(this), scriptEngine(new QScriptEngine(this)), - _processMessages(false) + _processMessages(false), + _ignoreListManager(this) { SignalProxy *p = signalProxy(); connect(p, SIGNAL(peerRemoved(QIODevice *)), this, SLOT(removeClient(QIODevice *))); @@ -91,7 +93,7 @@ CoreSession::CoreSession(UserId uid, bool restoreState, QObject *parent) p->synchronize(ircListHelper()); p->synchronize(networkConfig()); p->synchronize(&_coreInfo); - + p->synchronize(&_ignoreListManager); // Restore session state if(restoreState) restoreSessionState(); @@ -241,12 +243,18 @@ void CoreSession::customEvent(QEvent *event) { } void CoreSession::processMessages() { + QString networkName; if(_messageQueue.count() == 1) { const RawMessage &rawMsg = _messageQueue.first(); BufferInfo bufferInfo = Core::bufferInfo(user(), rawMsg.networkId, rawMsg.bufferType, rawMsg.target); Message msg(bufferInfo, rawMsg.type, rawMsg.text, rawMsg.sender, rawMsg.flags); - Core::storeMessage(msg); - emit displayMsg(msg); + + networkName = _networks.value(bufferInfo.networkId())->networkName(); + // if message is ignored with "HardStrictness" we discard it here + if(_ignoreListManager.match(msg, networkName) != IgnoreListManager::HardStrictness) { + Core::storeMessage(msg); + emit displayMsg(msg); + } } else { QHash > bufferInfoCache; MessageList messages; @@ -259,7 +267,13 @@ void CoreSession::processMessages() { bufferInfo = Core::bufferInfo(user(), rawMsg.networkId, rawMsg.bufferType, rawMsg.target); bufferInfoCache[rawMsg.networkId][rawMsg.target] = bufferInfo; } - messages << Message(bufferInfo, rawMsg.type, rawMsg.text, rawMsg.sender, rawMsg.flags); + + Message msg(bufferInfo, rawMsg.type, rawMsg.text, rawMsg.sender, rawMsg.flags); + networkName = _networks.value(bufferInfo.networkId())->networkName(); + // if message is ignored with "HardStrictness" we discard it here + if(_ignoreListManager.match(msg, networkName) == IgnoreListManager::HardStrictness) + continue; + messages << msg; } Core::storeMessages(messages); // FIXME: extend protocol to a displayMessages(MessageList) diff --git a/src/core/coresession.h b/src/core/coresession.h index e2ccf9ea..7abd0f11 100644 --- a/src/core/coresession.h +++ b/src/core/coresession.h @@ -26,6 +26,7 @@ #include "corecoreinfo.h" #include "corealiasmanager.h" +#include "coreignorelistmanager.h" #include "message.h" #include "storage.h" @@ -187,6 +188,7 @@ private: }; QList _messageQueue; bool _processMessages; + CoreIgnoreListManager _ignoreListManager; }; #endif diff --git a/src/qtui/chatlinemodel.h b/src/qtui/chatlinemodel.h index c089cb40..407821f8 100644 --- a/src/qtui/chatlinemodel.h +++ b/src/qtui/chatlinemodel.h @@ -40,13 +40,12 @@ public: typedef ChatLineModelItem::Word Word; typedef ChatLineModelItem::WrapList WrapList; - + virtual inline const MessageModelItem *messageItemAt(int i) const { return &_messageList[i]; } protected: // virtual MessageModelItem *createMessageModelItem(const Message &); virtual inline int messageCount() const { return _messageList.count(); } virtual inline bool messagesIsEmpty() const { return _messageList.isEmpty(); } - virtual inline const MessageModelItem *messageItemAt(int i) const { return &_messageList[i]; } virtual inline MessageModelItem *messageItemAt(int i) { return &_messageList[i]; } virtual inline const MessageModelItem *firstMessageItem() const { return &_messageList.first(); } virtual inline MessageModelItem *firstMessageItem() { return &_messageList.first(); } diff --git a/src/qtui/chatmonitorfilter.cpp b/src/qtui/chatmonitorfilter.cpp index 001e6c5f..055ed933 100644 --- a/src/qtui/chatmonitorfilter.cpp +++ b/src/qtui/chatmonitorfilter.cpp @@ -24,6 +24,7 @@ #include "chatlinemodel.h" #include "networkmodel.h" #include "chatviewsettings.h" +#include "clientignorelistmanager.h" ChatMonitorFilter::ChatMonitorFilter(MessageModel *model, QObject *parent) : MessageFilter(model, parent) @@ -73,6 +74,12 @@ bool ChatMonitorFilter::filterAcceptsRow(int sourceRow, const QModelIndex &sourc && !_bufferIds.contains(source_index.data(MessageModel::BufferIdRole).value())) return false; + // ignorelist handling + const MessageModelItem *item = const_cast(static_cast(sourceModel()))->messageItemAt(sourceRow); + // only match if message is not flagged as server msg + if(!(item->message().flags() & Message::ServerMsg) && + Client::ignoreListManager()->match(item->message(), Client::networkModel()->networkName(item->bufferId()))) + return false; return true; } @@ -157,4 +164,5 @@ void ChatMonitorFilter::buffersSettingChanged(const QVariant &newValue) { foreach (QVariant v, newValue.toList()) { _bufferIds << v.value(); } + invalidate(); } diff --git a/src/qtui/chatmonitorview.cpp b/src/qtui/chatmonitorview.cpp index da61ee7f..5501412e 100644 --- a/src/qtui/chatmonitorview.cpp +++ b/src/qtui/chatmonitorview.cpp @@ -36,12 +36,14 @@ #include "qtuisettings.h" #include "settingspagedlg.h" #include "settingspages/chatmonitorsettingspage.h" +#include "clientignorelistmanager.h" ChatMonitorView::ChatMonitorView(ChatMonitorFilter *filter, QWidget *parent) : ChatView(filter, parent), _filter(filter) { scene()->setSenderCutoffMode(ChatScene::CutoffLeft); + connect(Client::instance(), SIGNAL(coreConnectionStateChanged(bool)), this, SLOT(coreConnectionStateChanged(bool))); } void ChatMonitorView::addActionsToMenu(QMenu *menu, const QPointF &pos) { @@ -104,3 +106,10 @@ void ChatMonitorView::showSettingsPage() { SettingsPageDlg dlg(new ChatMonitorSettingsPage(), this); dlg.exec(); } + +// connect only after client is synced to core since ChatMonitorView is created before +// the ignoreListManager +void ChatMonitorView::coreConnectionStateChanged(bool connected) { + if(connected) + connect(Client::ignoreListManager(), SIGNAL(ignoreListChanged()), _filter, SLOT(invalidateFilter())); +} diff --git a/src/qtui/chatmonitorview.h b/src/qtui/chatmonitorview.h index f238f7b3..74a90c19 100644 --- a/src/qtui/chatmonitorview.h +++ b/src/qtui/chatmonitorview.h @@ -38,6 +38,7 @@ protected: private slots: void showFieldsChanged(bool checked); void showSettingsPage(); + virtual void coreConnectionStateChanged(bool connected); protected: inline ChatMonitorFilter *filter() const { return _filter; } diff --git a/src/qtui/chatview.cpp b/src/qtui/chatview.cpp index 85fb48ac..4c3994fc 100644 --- a/src/qtui/chatview.cpp +++ b/src/qtui/chatview.cpp @@ -30,6 +30,7 @@ #include "messagefilter.h" #include "qtui.h" #include "qtuistyle.h" +#include "clientignorelistmanager.h" ChatView::ChatView(BufferId bufferId, QWidget *parent) : QGraphicsView(parent), @@ -73,6 +74,10 @@ void ChatView::init(MessageFilter *filter) { setScene(_scene); connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(verticalScrollbarChanged(int))); + + // only connect if client is synched with a core + if(Client::isSynced()) + connect(Client::ignoreListManager(), SIGNAL(ignoreListChanged()), filter, SLOT(invalidateFilter())); } bool ChatView::event(QEvent *event) { -- 2.20.1