cmake: avoid de-duplication of user's CXXFLAGS
[quassel.git] / src / uisupport / networkmodelcontroller.h
1 /***************************************************************************
2  *   Copyright (C) 2005-2019 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 "uisupport-export.h"
24
25 #include <functional>
26 #include <type_traits>
27
28 #include <QDialog>
29
30 #include "action.h"
31 #include "actioncollection.h"
32 #include "messagefilter.h"
33
34 class QComboBox;
35 class QDialogButtonBox;
36 class QLineEdit;
37
38 class UISUPPORT_EXPORT NetworkModelController : public QObject
39 {
40     Q_OBJECT
41
42 public:
43     NetworkModelController(QObject* parent = nullptr);
44
45     // don't change enums without doublechecking masks etc. in code
46     enum ActionType
47     {
48         // Network actions
49         NetworkMask = 0x0f,
50         NetworkConnect = 0x01,
51         NetworkDisconnect = 0x02,
52         NetworkConnectAllWithDropdown = 0x03,
53         NetworkDisconnectAllWithDropdown = 0x04,
54         NetworkConnectAll = 0x05,
55         NetworkDisconnectAll = 0x06,
56
57         // Buffer actions
58         BufferMask = 0xf0,
59         BufferJoin = 0x10,
60         BufferPart = 0x20,
61         BufferSwitchTo = 0x30,
62         BufferRemove = 0x40,
63
64         // Hide actions
65         HideMask = 0x0f00,
66         HideJoin = 0x0100,
67         HidePart = 0x0200,
68         HideQuit = 0x0300,
69         HideNick = 0x0400,
70         HideMode = 0x0500,
71         HideDayChange = 0x0600,
72         HideTopic = 0x0700,
73         HideJoinPartQuit = 0xd00,
74         HideUseDefaults = 0xe00,
75         HideApplyToAll = 0xf00,
76
77         // General actions
78         GeneralMask = 0xf000,
79         JoinChannel = 0x1000,
80         ShowChannelList = 0x2000,
81         ShowIgnoreList = 0x3000,
82         ShowNetworkConfig = 0x4000,
83
84         // Nick actions
85         NickMask = 0xff0000,
86         NickWhois = 0x010000,
87         NickQuery = 0x020000,
88         NickSwitchTo = 0x030000,
89         NickCtcpVersion = 0x040000,
90         NickCtcpPing = 0x050000,
91         NickCtcpTime = 0x060000,
92         NickCtcpClientinfo = 0x070000,
93         NickOp = 0x080000,
94         NickDeop = 0x090000,
95         NickVoice = 0x0a0000,
96         NickDevoice = 0x0b0000,
97         NickHalfop = 0x0c0000,
98         NickDehalfop = 0x0d0000,
99         NickKick = 0x0e0000,
100         NickBan = 0x0f0000,
101         NickKickBan = 0x100000,
102         NickIgnoreUser = 0x200000,
103         NickIgnoreHost = 0x300000,
104         NickIgnoreDomain = 0x400000,
105         NickIgnoreCustom = 0x500000,
106         // The next 5 types have to stay together
107         // Don't change without reading ContextMenuActionProvider::addIgnoreMenu!
108         NickIgnoreToggleEnabled0 = 0x600000,
109         NickIgnoreToggleEnabled1 = 0x700000,
110         NickIgnoreToggleEnabled2 = 0x800000,
111         NickIgnoreToggleEnabled3 = 0x900000,
112         NickIgnoreToggleEnabled4 = 0xa00000,
113
114         // Actions that are handled externally
115         // These emit a signal to the action requester, rather than being handled here
116         ExternalMask = 0xff000000,
117         HideBufferTemporarily = 0x01000000,
118         HideBufferPermanently = 0x02000000
119     };
120
121     inline Action* action(ActionType type) const;
122
123 public:
124     enum ItemActiveState
125     {
126         InactiveState = 0x01,
127         ActiveState = 0x02
128     };
129     Q_DECLARE_FLAGS(ItemActiveStates, ItemActiveState)
130
131 public slots:
132     virtual void connectedToCore() {}
133     virtual void disconnectedFromCore() {}
134
135 protected:
136     inline ActionCollection* actionCollection() const;
137     inline QList<QModelIndex> indexList() const;
138     inline MessageFilter* messageFilter() const;
139     inline QString contextItem() const;  ///< Channel name or nick to provide context menu for
140
141     void setIndexList(const QModelIndex&);
142     void setIndexList(const QList<QModelIndex>&);
143     void setMessageFilter(MessageFilter*);
144     void setContextItem(const QString&);
145
146     using ActionSlot = std::function<void(QAction*)>;
147
148     template<typename Receiver, typename Slot>
149     ActionSlot buildActionSlot(Receiver* receiver, Slot slot)
150     {
151         static_assert(!std::is_same<Slot, const char*>::value, "Old-style slots not supported");
152         return [receiver, slot = std::move(slot)](QAction* action) { (receiver->*slot)(action); };
153     }
154
155     void setSlot(ActionSlot slot);
156
157     Action* registerAction(ActionType type, const QString& text, bool checkable = false);
158     Action* registerAction(NetworkModelController::ActionType type, const QIcon& icon, const QString& text, bool checkable = false);
159     bool checkRequirements(const QModelIndex& index,
160                            ItemActiveStates requiredActiveState = QFlags<ItemActiveState>(ActiveState | InactiveState));
161
162     QString nickName(const QModelIndex& index) const;
163     BufferId findQueryBuffer(const QModelIndex& index, const QString& predefinedNick = QString()) const;
164     BufferId findQueryBuffer(NetworkId, const QString& nickName) const;
165     void removeBuffers(const QModelIndexList& indexList);
166
167 protected slots:
168     virtual void actionTriggered(QAction*);
169
170 signals:
171     /**
172      * Request to show the channel list dialog for the network, optionally searching by channel name
173      *
174      * @see MainWin::showChannelList()
175      *
176      * @param networkId        Network ID for associated network
177      * @param channelFilters   Partial channel name to search for, or empty to show all
178      * @param listImmediately  If true, immediately list channels, otherwise just show dialog
179      */
180     void showChannelList(NetworkId, const QString&, bool);
181     void showNetworkConfig(NetworkId);
182     void showIgnoreList(QString);
183
184 protected:
185     virtual void handleNetworkAction(ActionType, QAction*);
186     virtual void handleBufferAction(ActionType, QAction*);
187     virtual void handleHideAction(ActionType, QAction*);
188     virtual void handleNickAction(ActionType, QAction* action);
189     virtual void handleGeneralAction(ActionType, QAction*);
190     virtual void handleExternalAction(ActionType, QAction*);
191
192     class JoinDlg;
193
194 private:
195     NetworkModel* _model;
196
197     ActionCollection* _actionCollection;
198     QHash<ActionType, Action*> _actionByType;
199
200     QList<QModelIndex> _indexList;
201     MessageFilter* _messageFilter{nullptr};
202     QString _contextItem;  ///< Channel name or nick to provide context menu for
203     ActionSlot _actionSlot;
204 };
205
206 //! Input dialog for joining a channel
207 class NetworkModelController::JoinDlg : public QDialog
208 {
209     Q_OBJECT
210
211 public:
212     JoinDlg(const QModelIndex& index, QWidget* parent = nullptr);
213
214     QString channelName() const;
215     QString channelPassword() const;
216     NetworkId networkId() const;
217
218 private slots:
219     void on_channel_textChanged(const QString&);
220
221 private:
222     QComboBox* networks;
223     QLineEdit* channel;
224     QLineEdit* password;
225     QDialogButtonBox* buttonBox;
226 };
227
228 // inlines
229 ActionCollection* NetworkModelController::actionCollection() const
230 {
231     return _actionCollection;
232 }
233 Action* NetworkModelController::action(ActionType type) const
234 {
235     return _actionByType.value(type, 0);
236 }
237 QList<QModelIndex> NetworkModelController::indexList() const
238 {
239     return _indexList;
240 }
241 MessageFilter* NetworkModelController::messageFilter() const
242 {
243     return _messageFilter;
244 }
245 QString NetworkModelController::contextItem() const
246 {
247     return _contextItem;
248 }