/
qtuimessageprocessor.h
241 lines (209 loc) · 8.74 KB
/
qtuimessageprocessor.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
/***************************************************************************
* Copyright (C) 2005-2018 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. *
***************************************************************************/
#ifndef QTUIMESSAGEPROCESSOR_H_
#define QTUIMESSAGEPROCESSOR_H_
#include <QTimer>
#include "abstractmessageprocessor.h"
#include "expressionmatch.h"
#include "nickhighlightmatcher.h"
class QtUiMessageProcessor : public AbstractMessageProcessor
{
Q_OBJECT
public:
enum Mode {
TimerBased,
Concurrent
};
QtUiMessageProcessor(QObject *parent);
inline bool isProcessing() const { return _processing; }
inline Mode processMode() const { return _processMode; }
void reset();
public slots:
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);
void highlightListChanged(const QVariant &variant);
void highlightNickChanged(const QVariant &variant);
private:
/**
* Individual highlight rule (legacy client-side version)
*/
class LegacyHighlightRule
{
public:
/**
* Construct an empty highlight rule
*/
LegacyHighlightRule() {}
/**
* Construct a highlight rule with the given parameters
*
* @param contents String representing a message contents expression to match
* @param isRegEx True if regular expression, otherwise false
* @param isCaseSensitive True if case sensitive, otherwise false
* @param isEnabled True if enabled, otherwise false
* @param chanName String representing a channel name expression to match
*/
LegacyHighlightRule(QString contents, bool isRegEx, bool isCaseSensitive, bool isEnabled,
QString chanName)
: _contents(contents), _isRegEx(isRegEx), _isCaseSensitive(isCaseSensitive),
_isEnabled(isEnabled), _chanName(chanName)
{
_cacheInvalid = true;
// Cache expression matches on construction
// NOTE: If profiling shows some rules often wind up unused, this can be removed in
// deference to caching on first use.
determineExpressions();
}
/**
* Gets the message contents this rule matches
*
* NOTE: Use HighlightRule::contentsMatcher() for performing matches
*
* CAUTION: For legacy reasons, "contents" doubles as the identifier for the ignore rule.
* Duplicate entries are not allowed.
*
* @return String representing a phrase or expression to match
*/
inline QString contents() const { return _contents; }
/**
* Sets the message contents this rule matches
*
* @param contents String representing a phrase or expression to match
*/
inline void setContents(const QString &contents) {
_contents = contents; _cacheInvalid = true;
}
/**
* Gets if this is a regular expression rule
*
* @return True if regular expression, otherwise false
*/
inline bool isRegEx() const { return _isRegEx; }
/**
* Sets if this rule is a regular expression rule
*
* @param isRegEx True if regular expression, otherwise false
*/
inline void setIsRegEx(bool isRegEx) { _isRegEx = isRegEx; _cacheInvalid = true; }
/**
* Gets if this rule is case sensitive
*
* @return True if case sensitive, otherwise false
*/
inline bool isCaseSensitive() const { return _isCaseSensitive; }
/**
* Sets if this rule is case sensitive
*
* @param isCaseSensitive True if case sensitive, otherwise false
*/
inline void setIsCaseSensitive(bool isCaseSensitive) {
_isCaseSensitive = isCaseSensitive; _cacheInvalid = true;
}
/**
* Gets if this rule is enabled and active
*
* @return True if enabled, otherwise false
*/
inline bool isEnabled() const { return _isEnabled; }
/**
* Sets if this rule is enabled and active
*
* @param isEnabled True if enabled, otherwise false
*/
inline void setIsEnabled(bool isEnabled) { _isEnabled = isEnabled; }
/**
* Gets the channel name this rule matches
*
* NOTE: Use HighlightRule::chanNameMatcher() for performing matches
*
* @return String representing a phrase or expression to match
*/
inline QString chanName() const { return _chanName; }
/**
* Sets the channel name this rule matches
*
* @param chanName String representing a phrase or expression to match
*/
inline void setChanName(const QString &chanName) {
_chanName = chanName; _cacheInvalid = true;
}
/**
* Gets the expression matcher for the message contents, caching if needed
*
* @return Expression matcher to compare with message contents
*/
inline ExpressionMatch contentsMatcher() const {
if (_cacheInvalid) { determineExpressions(); } return _contentsMatch;
}
/**
* Gets the expression matcher for the channel name, caching if needed
*
* @return Expression matcher to compare with channel name
*/
inline ExpressionMatch chanNameMatcher() const {
if (_cacheInvalid) { determineExpressions(); } return _chanNameMatch;
}
bool operator!=(const LegacyHighlightRule &other) const;
private:
/**
* Update internal cache of expression matching if needed
*/
void determineExpressions() const;
QString _contents = {};
bool _isRegEx = false;
bool _isCaseSensitive = false;
bool _isEnabled = true;
QString _chanName = {};
// These represent internal cache and should be safe to mutate in 'const' functions
// See https://stackoverflow.com/questions/3141087/what-is-meant-with-const-at-end-of-function-declaration
mutable bool _cacheInvalid = true; ///< If true, match cache needs redone
mutable ExpressionMatch _contentsMatch = {}; ///< Expression match cache for message content
mutable ExpressionMatch _chanNameMatch = {}; ///< Expression match cache for channel name
};
using LegacyHighlightRuleList = QList<LegacyHighlightRule>;
void checkForHighlight(Message &msg);
void startProcessing();
using HighlightNickType = NotificationSettings::HighlightNickType;
LegacyHighlightRuleList _highlightRuleList; ///< Custom highlight rule list
NickHighlightMatcher _nickMatcher = {}; ///< Nickname highlight matcher
/// Nickname highlighting mode
HighlightNickType _highlightNick = HighlightNickType::CurrentNick;
bool _nicksCaseSensitive = false; ///< If true, match nicknames with exact case
QList<QList<Message> > _processQueue;
QList<Message> _currentBatch;
QTimer _processTimer;
bool _processing;
Mode _processMode;
};
#endif