connect(this, SIGNAL(connected()), mainUi(), SLOT(connectedToCore()));
connect(this, SIGNAL(disconnected()), mainUi(), SLOT(disconnectedFromCore()));
+ // Listen to network removed events
+ connect(this, SIGNAL(networkRemoved(NetworkId)),
+ _messageProcessor, SLOT(networkRemoved(NetworkId)));
+
// attach backlog manager
p->synchronize(backlogManager());
connect(backlogManager(), SIGNAL(messagesReceived(BufferId, int)), _messageModel, SLOT(messagesReceived(BufferId, int)));
{
NotificationSettings notificationSettings;
_nicksCaseSensitive = notificationSettings.nicksCaseSensitive();
+ _nickMatcher.setCaseSensitive(_nicksCaseSensitive);
_highlightNick = notificationSettings.highlightNick();
+ _nickMatcher.setHighlightMode(
+ static_cast<NickHighlightMatcher::HighlightNickType>(_highlightNick));
highlightListChanged(notificationSettings.highlightList());
notificationSettings.notify("Highlights/NicksCaseSensitive", this, SLOT(nicksCaseSensitiveChanged(const QVariant &)));
notificationSettings.notify("Highlights/CustomList", this, SLOT(highlightListChanged(const QVariant &)));
if (!((msg.type() & (Message::Plain | Message::Notice | Message::Action)) && !(msg.flags() & Message::Self)))
return;
- // TODO: Cache this (per network)
- const Network *net = Client::network(msg.bufferInfo().networkId());
+ // Cached per network
+ const NetworkId &netId = msg.bufferInfo().networkId();
+ const Network *net = Client::network(netId);
+
if (net && !net->myNick().isEmpty()) {
// Get current nick
QString currentNick = net->myNick();
// Check nicknames
if (_highlightNick != HighlightNickType::NoNick && !currentNick.isEmpty()) {
- // Update cache if needed
- determineNickExpressions(currentNick, identityNicks);
-
- // Check for a match
- if (_cachedNickMatcher.isValid()
- && _cachedNickMatcher.match(stripFormatCodes(msgContents))) {
- // Nick matcher is valid and match found
+ // Nickname matching allowed and current nickname is known
+ // Run the nickname matcher on the unformatted string
+ if (_nickMatcher.match(stripFormatCodes(msgContents), netId, currentNick,
+ identityNicks)) {
msg.setFlags(msg.flags() | Message::Highlight);
return;
}
void QtUiMessageProcessor::nicksCaseSensitiveChanged(const QVariant &variant)
{
_nicksCaseSensitive = variant.toBool();
- _cacheNickConfigInvalid = true;
+ // Update nickname matcher, too
+ _nickMatcher.setCaseSensitive(_nicksCaseSensitive);
}
void QtUiMessageProcessor::highlightNickChanged(const QVariant &variant)
{
- _highlightNick = (NotificationSettings::HighlightNickType)variant.toInt();
- _cacheNickConfigInvalid = true;
-}
-
-
-void QtUiMessageProcessor::determineNickExpressions(const QString ¤tNick,
- const QStringList identityNicks) const
-{
- // Don't do anything for no nicknames
- if (_highlightNick == HighlightNickType::NoNick) {
- return;
- }
-
- // Only update if needed (check nickname config, current nick, identity nicks for change)
- if (!_cacheNickConfigInvalid
- && _cachedNickCurrent == currentNick
- && _cachedIdentityNicks == identityNicks) {
- return;
- }
-
- // Add all nicknames
- QStringList nickList;
- if (_highlightNick == HighlightNickType::CurrentNick) {
- nickList << currentNick;
- }
- else if (_highlightNick == HighlightNickType::AllNicks) {
- nickList = identityNicks;
- if (!nickList.contains(currentNick))
- nickList.prepend(currentNick);
- }
-
- // Set up phrase matcher, joining with newlines
- _cachedNickMatcher = ExpressionMatch(nickList.join("\n"),
- ExpressionMatch::MatchMode::MatchMultiPhrase,
- _nicksCaseSensitive);
-
- _cacheNickConfigInvalid = false;
- _cachedNickCurrent = currentNick;
- _cachedIdentityNicks = identityNicks;
+ _highlightNick = (HighlightNickType)variant.toInt();
+ // Convert from QtUiMessageProcessor::HighlightNickType (which is from NotificationSettings) to
+ // NickHighlightMatcher::HighlightNickType
+ _nickMatcher.setHighlightMode(
+ static_cast<NickHighlightMatcher::HighlightNickType>(_highlightNick));
}
#include "abstractmessageprocessor.h"
#include "expressionmatch.h"
+#include "nickhighlightmatcher.h"
class QtUiMessageProcessor : public AbstractMessageProcessor
{
void process(Message &msg);
void process(QList<Message> &msgs);
+ /**
+ * Network removed from system
+ *
+ * Handles cleaning up cache from stale networks.
+ *
+ * @param id Network ID of removed network
+ */
+ inline void networkRemoved(NetworkId id) {
+ // Clean up nickname matching cache
+ _nickMatcher.removeNetwork(id);
+ }
+
private slots:
void processNextMessage();
void nicksCaseSensitiveChanged(const QVariant &variant);
using HighlightNickType = NotificationSettings::HighlightNickType;
- /**
- * Update internal cache of expression matching if needed
- */
- void determineNickExpressions(const QString ¤tNick,
- const QStringList identityNicks) const;
+ LegacyHighlightRuleList _highlightRuleList; ///< Custom highlight rule list
+ NickHighlightMatcher _nickMatcher = {}; ///< Nickname highlight matcher
- /**
- * Check if nickname matching cache is invalid
- * @param currentNick
- * @param identityNicks
- * @return
- */
- bool cacheNickInvalid(const QString ¤tNick, const QStringList identityNicks) const {
- if (_cacheNickConfigInvalid) return true;
- if (_cachedNickCurrent != currentNick) return true;
- if (_cachedIdentityNicks != identityNicks) return true;
- }
-
- LegacyHighlightRuleList _highlightRuleList;
+ /// Nickname highlighting mode
HighlightNickType _highlightNick = HighlightNickType::CurrentNick;
- bool _nicksCaseSensitive = false;
-
- // These represent internal cache and should be safe to mutate in 'const' functions
- mutable bool _cacheNickConfigInvalid = true; ///< If true, nick match cache needs redone
- mutable QString _cachedNickCurrent = {}; ///< Last cached current nick
- mutable QStringList _cachedIdentityNicks = {}; ///< Last cached identity nicks
- mutable ExpressionMatch _cachedNickMatcher = {}; ///< Expression match cache for nicks
+ bool _nicksCaseSensitive = false; ///< If true, match nicknames with exact case
QList<QList<Message> > _processQueue;
QList<Message> _currentBatch;