ssl: Use QSslSocket directly to avoid redundant qobject_casts
[quassel.git] / src / common / nickhighlightmatcher.h
1 /***************************************************************************
2  *   Copyright (C) 2005-2020 by the Quassel Project                        *
3  *   devel@quassel-irc.org                                                 *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) version 3.                                           *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
19  ***************************************************************************/
20
21 #pragma once
22
23 #include "common-export.h"
24
25 #include <QHash>
26 #include <QString>
27 #include <QStringList>
28
29 #include "expressionmatch.h"
30 #include "types.h"
31
32 /**
33  * Nickname matcher with automatic caching for performance
34  */
35 class COMMON_EXPORT NickHighlightMatcher
36 {
37 public:
38     /// Nickname highlighting mode
39     enum class HighlightNickType
40     {
41         NoNick = 0x00,       ///< Don't match any nickname
42         CurrentNick = 0x01,  ///< Match the current nickname
43         AllNicks = 0x02      ///< Match all configured nicknames in the chosen identity
44     };
45     // NOTE: Keep this in sync with HighlightRuleManager::HighlightNickType and
46     // NotificationSettings::HighlightNickType!
47
48     /**
49      * Construct an empty NicknameMatcher
50      */
51     NickHighlightMatcher() = default;
52
53     /**
54      * Construct a configured NicknameMatcher
55      *
56      * @param highlightMode    Nickname highlighting mode
57      * @param isCaseSensitive  If true, nick matching is case-sensitive, otherwise case-insensitive
58      */
59     NickHighlightMatcher(HighlightNickType highlightMode, bool isCaseSensitive)
60         : _highlightMode(highlightMode)
61         , _isCaseSensitive(isCaseSensitive)
62     {}
63
64     /**
65      * Gets the nickname highlighting policy
66      *
67      * @return HighlightNickType for the given network
68      */
69     inline HighlightNickType highlightMode() const { return _highlightMode; }
70
71     /**
72      * Sets the nickname highlighting policy
73      *
74      * @param highlightMode Nickname highlighting mode
75      */
76     void setHighlightMode(HighlightNickType highlightMode)
77     {
78         if (_highlightMode != highlightMode) {
79             _highlightMode = highlightMode;
80             invalidateNickCache();
81         }
82     }
83
84     /**
85      * Gets the nickname case-sensitivity policy
86      *
87      * @return True if nickname highlights are case-sensitive, otherwise false
88      */
89     inline bool isCaseSensitive() const { return _isCaseSensitive; }
90
91     /**
92      * Sets the nickname case-sensitivity policy
93      *
94      * @param isCaseSensitive If true, nick matching is case-sensitive, otherwise case-insensitive
95      */
96     void setCaseSensitive(bool isCaseSensitive)
97     {
98         if (_isCaseSensitive != isCaseSensitive) {
99             _isCaseSensitive = isCaseSensitive;
100             invalidateNickCache();
101         }
102     }
103
104     /**
105      * Checks if the given string matches the specified network's nickname matcher
106      *
107      * Updates cache when called if needed.
108      *
109      * @param string         String to match against
110      * @param netId          Network ID of source network
111      * @param currentNick    Current nickname
112      * @param identityNicks  All nicknames configured for the current identity
113      * @return True if match found, otherwise false
114      */
115     bool match(const QString& string, const NetworkId& netId, const QString& currentNick, const QStringList& identityNicks) const;
116
117 public slots:
118     /**
119      * Removes the specified network ID from the cache
120      *
121      * @param netId Network ID of source network
122      */
123     void removeNetwork(const NetworkId& netId)
124     {
125         // Remove the network from the cache list
126         if (_nickMatchCache.remove(netId) > 0) {
127             qDebug() << "Cleared nickname matching cache for removed network ID" << netId;
128         }
129     }
130
131 private:
132     struct NickMatchCache
133     {
134         // These represent internal cache and should be safe to mutate in 'const' functions
135         QString nickCurrent = {};        ///< Last cached current nick
136         QStringList identityNicks = {};  ///< Last cached identity nicks
137         ExpressionMatch matcher = {};    ///< Expression match cache for nicks
138     };
139
140     /**
141      * Update internal cache of nickname matching if needed
142      *
143      * @param netId          Network ID of source network
144      * @param currentNick    Current nickname
145      * @param identityNicks  All nicknames configured for the current identity
146      */
147     void determineExpressions(const NetworkId& netId, const QString& currentNick, const QStringList& identityNicks) const;
148
149     /**
150      * Invalidate all nickname match caches
151      *
152      * Use this after changing global configuration.
153      */
154     inline void invalidateNickCache()
155     {
156         // Mark all as invalid
157         if (_nickMatchCache.size() > 0) {
158             _nickMatchCache.clear();
159             qDebug() << "Cleared all nickname matching cache (settings changed)";
160         }
161     }
162
163     // Global nickname configuration
164     /// Nickname highlighting mode
165     HighlightNickType _highlightMode = HighlightNickType::CurrentNick;
166     bool _isCaseSensitive = false;  ///< If true, match nicknames with exact case
167
168     // These represent internal cache and should be safe to mutate in 'const' functions
169     mutable QHash<NetworkId, NickMatchCache> _nickMatchCache;  ///< Per-network nick matching cache
170 };