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