X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fclient%2Fmessagefilter.cpp;h=6ff6378b123cd568ebfc041b78188b14757fdf57;hp=1001ea321a265452df84b0ba3c33825e3a737d3f;hb=52209badc8e769e50aa3019b63689dda0e79e9d0;hpb=52f0d47d0cb1932c9e86ebb75cdd4dd0d625dd6f diff --git a/src/client/messagefilter.cpp b/src/client/messagefilter.cpp index 1001ea32..6ff6378b 100644 --- a/src/client/messagefilter.cpp +++ b/src/client/messagefilter.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-2015 by the Quassel Project * + * Copyright (C) 2005-2019 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -20,32 +20,33 @@ #include "messagefilter.h" +#include + +#include "buffermodel.h" #include "buffersettings.h" #include "client.h" -#include "buffermodel.h" +#include "clientignorelistmanager.h" #include "messagemodel.h" #include "networkmodel.h" -#include "clientignorelistmanager.h" +#include "util.h" -MessageFilter::MessageFilter(QAbstractItemModel *source, QObject *parent) - : QSortFilterProxyModel(parent), - _messageTypeFilter(0) +MessageFilter::MessageFilter(QAbstractItemModel* source, QObject* parent) + : QSortFilterProxyModel(parent) + , _messageTypeFilter(0) { init(); setSourceModel(source); } - -MessageFilter::MessageFilter(MessageModel *source, const QList &buffers, QObject *parent) - : QSortFilterProxyModel(parent), - _validBuffers(buffers.toSet()), - _messageTypeFilter(0) +MessageFilter::MessageFilter(MessageModel* source, const QList& buffers, QObject* parent) + : QSortFilterProxyModel(parent) + , _validBuffers(toQSet(buffers)) + , _messageTypeFilter(0) { init(); setSourceModel(source); } - void MessageFilter::init() { setDynamicSortFilter(true); @@ -53,22 +54,21 @@ void MessageFilter::init() _userNoticesTarget = _serverNoticesTarget = _errorMsgsTarget = -1; BufferSettings defaultSettings; - defaultSettings.notify("UserNoticesTarget", this, SLOT(messageRedirectionChanged())); - defaultSettings.notify("ServerNoticesTarget", this, SLOT(messageRedirectionChanged())); - defaultSettings.notify("ErrorMsgsTarget", this, SLOT(messageRedirectionChanged())); + defaultSettings.notify("UserNoticesTarget", this, &MessageFilter::messageRedirectionChanged); + defaultSettings.notify("ServerNoticesTarget", this, &MessageFilter::messageRedirectionChanged); + defaultSettings.notify("ErrorMsgsTarget", this, &MessageFilter::messageRedirectionChanged); messageRedirectionChanged(); _messageTypeFilter = defaultSettings.messageFilter(); - defaultSettings.notify("MessageTypeFilter", this, SLOT(messageTypeFilterChanged())); + defaultSettings.notify("MessageTypeFilter", this, &MessageFilter::messageTypeFilterChanged); - BufferSettings mySettings(idString()); + BufferSettings mySettings(MessageFilter::idString()); if (mySettings.hasFilter()) _messageTypeFilter = mySettings.messageFilter(); - mySettings.notify("MessageTypeFilter", this, SLOT(messageTypeFilterChanged())); - mySettings.notify("hasMessageTypeFilter", this, SLOT(messageTypeFilterChanged())); + mySettings.notify("MessageTypeFilter", this, &MessageFilter::messageTypeFilterChanged); + mySettings.notify("hasMessageTypeFilter", this, &MessageFilter::messageTypeFilterChanged); } - void MessageFilter::messageTypeFilterChanged() { int newFilter; @@ -81,12 +81,11 @@ void MessageFilter::messageTypeFilterChanged() if (_messageTypeFilter != newFilter) { _messageTypeFilter = newFilter; - _filteredQuitMsgs.clear(); + _filteredQuitMsgTime.clear(); invalidateFilter(); } } - void MessageFilter::messageRedirectionChanged() { BufferSettings bufferSettings; @@ -111,24 +110,22 @@ void MessageFilter::messageRedirectionChanged() invalidateFilter(); } - QString MessageFilter::idString() const { if (_validBuffers.isEmpty()) return "*"; - QList bufferIds = _validBuffers.toList(); - qSort(bufferIds); + QList bufferIds = _validBuffers.values(); + std::sort(bufferIds.begin(), bufferIds.end()); QStringList bufferIdStrings; - foreach(BufferId id, bufferIds) - bufferIdStrings << QString::number(id.toInt()); + foreach (BufferId id, bufferIds) + bufferIdStrings << QString::number(id.toInt()); return bufferIdStrings.join("|"); } - -bool MessageFilter::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const +bool MessageFilter::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const { Q_UNUSED(sourceParent); QModelIndex sourceIdx = sourceModel()->index(sourceRow, 2); @@ -157,7 +154,8 @@ bool MessageFilter::filterAcceptsRow(int sourceRow, const QModelIndex &sourcePar // ignorelist handling // only match if message is not flagged as server msg if (!(flags & Message::ServerMsg) && Client::ignoreListManager() - && Client::ignoreListManager()->match(sourceIdx.data(MessageModel::MessageRole).value(), Client::networkModel()->networkName(bufferId))) + && Client::ignoreListManager()->match(sourceIdx.data(MessageModel::MessageRole).value(), + Client::networkModel()->networkName(bufferId))) return false; if (flags & Message::Redirected) { @@ -189,7 +187,7 @@ bool MessageFilter::filterAcceptsRow(int sourceRow, const QModelIndex &sourcePar if (!redirectedTo.isValid()) { BufferId redirectedTo = Client::bufferModel()->currentIndex().data(NetworkModel::BufferIdRole).value(); if (redirectedTo.isValid()) - sourceModel()->setData(sourceIdx, QVariant::fromValue(redirectedTo), MessageModel::RedirectedToRole); + sourceModel()->setData(sourceIdx, QVariant::fromValue(redirectedTo), MessageModel::RedirectedToRole); } if (_validBuffers.contains(redirectedTo)) @@ -221,21 +219,32 @@ bool MessageFilter::filterAcceptsRow(int sourceRow, const QModelIndex &sourcePar if (myNetworkId != msgNetworkId) return false; - uint messageTimestamp = sourceModel()->data(sourceIdx, MessageModel::TimestampRole).value().toTime_t(); - QString quiter = sourceModel()->data(sourceIdx, Qt::DisplayRole).toString().section(' ', 0, 0, QString::SectionSkipEmpty).toLower(); + // Extract timestamp and nickname from the new quit message + qint64 messageTimestamp = sourceModel()->data(sourceIdx, MessageModel::TimestampRole).value().toMSecsSinceEpoch(); + QString quiter = nickFromMask(sourceModel()->data(sourceIdx, MessageModel::MessageRole).value().sender()).toLower(); + + // Check that nickname matches query name if (quiter != bufferName().toLower()) return false; - if (_filteredQuitMsgs.contains(quiter, messageTimestamp)) + // Check if a quit message was already forwarded within +/- 1000 ms + static constexpr qint64 MAX_QUIT_DELTA_MS = 1 * 1000; + // No need to check if it's the appropriate buffer, each query has a unique message filter + if (std::binary_search(_filteredQuitMsgTime.begin(), _filteredQuitMsgTime.end(), messageTimestamp, [](qint64 a, qint64 b) { + return ((a + MAX_QUIT_DELTA_MS) < b); + })) { + // New element is less than if at least 1000 ms older/newer + // Match found, no need to forward another quit message return false; + } - MessageFilter *that = const_cast(this); - that->_filteredQuitMsgs.insert(quiter, messageTimestamp); + // Mark query as having a quit message inserted + auto* that = const_cast(this); + that->_filteredQuitMsgTime.insert(messageTimestamp); return true; } } - void MessageFilter::requestBacklog() { QSet::const_iterator bufferIdIter = _validBuffers.constBegin();