cmake: avoid de-duplication of user's CXXFLAGS
[quassel.git] / src / common / eventmanager.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 <QMetaEnum>
26
27 #include "types.h"
28
29 class Event;
30 class Network;
31
32 class COMMON_EXPORT EventManager : public QObject
33 {
34     Q_OBJECT
35     Q_FLAGS(EventFlag EventFlags)
36     Q_ENUMS(EventType)
37
38 public:
39     enum RegistrationMode
40     {
41         Prepend,
42         Append
43     };
44
45     enum Priority
46     {
47         VeryLowPriority,
48         LowPriority,
49         NormalPriority,
50         HighPriority,
51         HighestPriority
52     };
53
54     enum EventFlag
55     {
56         Self = 0x01,      ///< Self-generated (user input) event
57         Fake = 0x08,      ///< Ignore this in CoreSessionEventProcessor
58         Netsplit = 0x10,  ///< Netsplit join/part, ignore on display
59         Backlog = 0x20,
60         Silent = 0x40,  ///< Don't generate a MessageEvent
61         Stopped = 0x80
62     };
63     Q_DECLARE_FLAGS(EventFlags, EventFlag)
64
65     /*
66
67     */
68     /* These values make sense! Don't change without knowing what you do! */
69     enum EventType
70     {
71         Invalid = 0xffffffff,
72         GenericEvent = 0x00000000,
73
74         // for event group handlers (handleIrcEvent() will handle all IrcEvent* enums)
75         // event groups are specified by bits 20-24
76         EventGroupMask = 0x00ff0000,
77
78         NetworkEvent = 0x00010000,
79         NetworkConnecting,
80         NetworkInitializing,
81         NetworkInitialized,
82         NetworkReconnecting,
83         NetworkDisconnecting,
84         NetworkDisconnected,
85         NetworkSplitJoin,
86         NetworkSplitQuit,
87         NetworkIncoming,
88
89         IrcServerEvent = 0x00020000,
90         IrcServerIncoming,
91         IrcServerParseError,
92
93         IrcEvent = 0x00030000,
94         IrcEventAuthenticate,
95         IrcEventAccount,
96         IrcEventAway,
97         IrcEventCap,
98         IrcEventChghost,
99         IrcEventInvite,
100         IrcEventJoin,
101         IrcEventKick,
102         IrcEventMode,
103         IrcEventNick,
104         IrcEventNotice,
105         IrcEventPart,
106         IrcEventPing,
107         IrcEventPong,
108         IrcEventPrivmsg,
109         IrcEventQuit,
110         IrcEventTagmsg,
111         IrcEventTopic,
112         IrcEventError,  /// ERROR message from server
113         IrcEventWallops,
114         IrcEventRawPrivmsg,  ///< Undecoded privmsg (still needs CTCP parsing)
115         IrcEventRawNotice,   ///< Undecoded notice (still needs CTCP parsing)
116         IrcEventUnknown,     ///< Unknown non-numeric cmd
117
118         IrcEventNumeric = 0x00031000,     /* needs 1000 (0x03e8) consecutive free values! */
119         IrcEventNumericMask = 0x00000fff, /* for checking if an event is numeric */
120
121         MessageEvent = 0x00040000,  ///< Stringified event suitable for converting to Message
122
123         CtcpEvent = 0x00050000,
124         CtcpEventFlush,
125
126         KeyEvent = 0x00060000
127     };
128
129     EventManager(QObject* parent = nullptr);
130
131     static EventType eventTypeByName(const QString& name);
132     static EventType eventGroupByName(const QString& name);
133     static QString enumName(EventType type);
134     static QString enumName(int type);  // for sanity tests
135
136     Event* createEvent(const QVariantMap& map);
137
138 public slots:
139     void registerObject(QObject* object,
140                         Priority priority = NormalPriority,
141                         const QString& methodPrefix = "process",
142                         const QString& filterPrefix = "filter");
143     void registerEventHandler(EventType event, QObject* object, const char* slot, Priority priority = NormalPriority, bool isFilter = false);
144     void registerEventHandler(
145         QList<EventType> events, QObject* object, const char* slot, Priority priority = NormalPriority, bool isFilter = false);
146
147     void registerEventFilter(EventType event, QObject* object, const char* slot);
148     void registerEventFilter(QList<EventType> events, QObject* object, const char* slot);
149
150     //! Send an event to the registered handlers
151     /**
152       The EventManager takes ownership of the event and will delete it once it's processed.
153       @param event The event to be dispatched
154      */
155     void postEvent(Event* event);
156
157 protected:
158     virtual Network* networkById(NetworkId id) const = 0;
159     void customEvent(QEvent* event) override;
160
161 private:
162     struct Handler
163     {
164         QObject* object;
165         int methodIndex;
166         Priority priority;
167
168         explicit Handler(QObject* obj = nullptr, int method = 0, Priority prio = NormalPriority)
169         {
170             object = obj;
171             methodIndex = method;
172             priority = prio;
173         }
174     };
175
176     using HandlerHash = QHash<uint, QList<Handler>>;
177
178     inline const HandlerHash& registeredHandlers() const { return _registeredHandlers; }
179     inline HandlerHash& registeredHandlers() { return _registeredHandlers; }
180
181     inline const HandlerHash& registeredFilters() const { return _registeredFilters; }
182     inline HandlerHash& registeredFilters() { return _registeredFilters; }
183
184     //! Add handlers to an existing sorted (by priority) handler list
185     void insertHandlers(const QList<Handler>& newHandlers, QList<Handler>& existing, bool checkDupes = false);
186     //! Add filters to an existing filter hash
187     void insertFilters(const QList<Handler>& newFilters, QHash<QObject*, Handler>& existing);
188
189     int findEventType(const QString& methodSignature, const QString& methodPrefix) const;
190
191     void processEvent(Event* event);
192     void dispatchEvent(Event* event);
193
194     //! @return the EventType enum
195     static QMetaEnum eventEnum();
196
197     HandlerHash _registeredHandlers;
198     HandlerHash _registeredFilters;
199     QList<Event*> _eventQueue;
200     static QMetaEnum _enum;
201 };
202
203 Q_DECLARE_OPERATORS_FOR_FLAGS(EventManager::EventFlags)