1 /*
2     SPDX-License-Identifier: GPL-2.0-or-later
3 
4     SPDX-FileCopyrightText: 2002 Dario Abatianni <eisfuchs@tigress.com>
5     SPDX-FileCopyrightText: 2004-2006, 2009 Peter Simonsson <peter.simonsson@gmail.com>
6     SPDX-FileCopyrightText: 2006-2008 Eike Hein <hein@kde.org>
7 */
8 
9 #ifndef CHANNEL_H
10 #define CHANNEL_H
11 
12 #include <config-konversation.h>
13 
14 #include "server.h"
15 #include "chatwindow.h"
16 #include "channelnick.h"
17 
18 #ifdef HAVE_QCA2
19 #include "cipher.h"
20 #endif
21 
22 #include <QElapsedTimer>
23 #include <QTimer>
24 #include <QString>
25 
26 
27 class QLabel;
28 class QTimer;
29 class QTreeWidgetItem;
30 class QStringList;
31 class QSplitter;
32 class QToolButton;
33 
34 class KLineEdit;
35 class KComboBox;
36 
37 class AwayLabel;
38 class NickListView;
39 class Nick;
40 class QuickButton;
41 class ModeButton;
42 class IRCInput;
43 class TopicHistoryModel;
44 
45 namespace Konversation
46 {
47     class TopicLabel;
48     class ChannelOptionsDialog;
49 }
50 
51 class NickList : public QList<Nick*>
52 {
53     public:
54         NickList();
55 
56         QString completeNick(const QString& pattern, bool& complete, QStringList& found,
57                              bool skipNonAlfaNum, bool caseSensitive) const;
58 
59         bool containsNick(const QString& nickname) const;
60 
61 };
62 
63 class Channel : public ChatWindow
64 {
65     Q_OBJECT
66 
67     friend class Nick;
68 
69     public:
70         explicit Channel(QWidget* parent, const QString& name);
71         ~Channel() override;
72 //META
73 
74         bool canBeFrontView() const override;
75         bool searchView() const override;
76 
77         void append(const QString& nickname, const QString& message, const QHash<QString, QString> &messageTags = QHash<QString, QString>(), const QString& label = QString()) override;
78         void appendAction(const QString& nickname, const QString& message, const QHash<QString, QString> &messageTags = QHash<QString, QString>()) override;
79         void nickActive(const QString& nickname);
80         #ifdef HAVE_QCA2
81         Konversation::Cipher* getCipher() const;
82         #endif
83 
84 //General administrative stuff
85     public:
86         void setName(const QString& newName) override;
87         QString getPassword() const;
88 
89         Konversation::ChannelSettings channelSettings() const;
90 
91         void setServer(Server* newServer) override;
92 
93         void setEncryptedOutput(bool);
94 
isJoined()95         bool isJoined() const { return m_joined; }
96         bool rejoinable() const;
97 //Unsure of future placement and/or continued existence of these members
numberOfNicks()98         int numberOfNicks() const { return nicks; }
numberOfOps()99         int numberOfOps() const { return ops; }
100         void setChannelEncoding(const QString& encoding) override;
101         QString getChannelEncoding() const override;
102         QString getChannelEncodingDefaultDesc() const override;
103 
104         bool log() const override;
105 
106     private:
107         // use with caution! does not check for duplicates
108         void fastAddNickname(ChannelNickPtr channelnick, Nick *nick = nullptr);
109         void setActive(bool active);
110         void repositionNick(Nick *nick);
111         bool shouldShowEvent(ChannelNickPtr channelNick) const;
112 
113     public Q_SLOTS:
114         void setNickname(const QString& newNickname);
115         void scheduleAutoWho(int msec = -1);
116         void setAutoUserhost(bool state);
117         void rejoin();
118 
119     protected Q_SLOTS:
120         void serverOnline(bool online) override;
121 
122     private Q_SLOTS:
123         void autoUserhost();
124         void autoWho();
125         void updateAutoWho();
126         void fadeActivity();
127         void delayedSortNickList();
128 
129 //Nicklist
130     public:
131         void flushNickQueue();
132 
133         ChannelNickPtr getOwnChannelNick() const;
134         ChannelNickPtr getChannelNick(const QString &ircnick) const;
135 
136         void joinNickname(ChannelNickPtr channelNick, const QHash<QString, QString> &messageTags);
137         void removeNick(ChannelNickPtr channelNick, const QString &reason, bool quit, const QHash<QString, QString> &messageTags);
138         void kickNick(ChannelNickPtr channelNick, const QString &kicker, const QString &reason, const QHash<QString, QString> &messageTags);
139         void addNickname(ChannelNickPtr channelNick);
140         void nickRenamed(const QString &oldNick, const NickInfo& channelnick, const QHash<QString, QString> &messageTags);
141         void queueNicks(const QStringList& nicknameList);
142         void endOfNames();
143         Nick *getNickByName(const QString& lookname) const;
getNickList()144         NickList getNickList() const { return nicknameList; }
145 
146         void adjustNicks(int value);
147         void adjustOps(int value);
148         void emitUpdateInfo() override;
149 
150         void resizeNicknameListViewColumns();
151 
152     private Q_SLOTS:
153         void purgeNicks();
154         void processQueuedNicks(bool flush = false);
155 
156         void updateNickInfos();
157         void updateChannelNicks(const QString& channel);
158 
159 //Topic
160     public:
161         QString getTopic() const;
getTopicHistory()162         TopicHistoryModel* getTopicHistory() const { return m_topicHistory; }
163 
164         void setTopic(const QString& text, const QHash<QString, QString> &messageTags);
165         void setTopic(const QString& nickname, const QString& text, const QHash<QString, QString> &messageTags);
166         void setTopicAuthor(const QString& author, QDateTime timestamp);
167 
168     Q_SIGNALS:
169         void joined(Channel* channel);
170 
171 
172 //Modes
173 //TODO: the only representation of the channel limit is held in the GUI
174 
175     public:
176         /// Internal - Empty the modelist
177         void clearModeList();
178         /// Get the list of modes that this channel has - e.g. {+l,+s,-m}
179         //TODO: does this method return a list of all modes, all modes that have been changed, or all modes that are +?
getModeList()180         QStringList getModeList() const { return m_modeList; }
181 
182         /** Outputs a message on the channel, and modifies the mode for a ChannelNick.
183          *  @param sourceNick The server or the nick of the person that made the mode change.
184          *  @param mode The mode that is changing one of v,h,o,a for voice halfop op admin
185          *  @param plus True if the mode is being granted, false if it's being taken away.
186          *  @param parameter This depends on what the mode change is.  In most cases it is the nickname of the person that is being given voice/op/admin etc.  See the code.
187          */
188         void updateMode(const QString& sourceNick, char mode, bool plus, const QString &parameter, const QHash<QString, QString> &messageTags);
189 
190     Q_SIGNALS:
191         void modesChanged();
192 
193 //Bans
194     public:
195 
196         void addBan(const QString& ban);
197         void removeBan(const QString& ban);
198 
199         void clearBanList();
getBanList()200         QStringList getBanList() const { return m_BanList; }
201 
202     Q_SIGNALS:
203         void banAdded(const QString& newban);
204         void banRemoved(const QString& newban);
205         void banListCleared();
206 
207 //Generic GUI
208     public:
209         bool eventFilter(QObject* watched, QEvent* e) override;
210 
211 //Specific GUI
212     public:
213         void updateModeWidgets(char mode, bool plus, const QString &parameter);
214 
215         /// Sounds suspiciously like a destructor..
216         bool closeYourself(bool askForConfirmation=true) override;
217 
218         bool autoJoin();
219 
220         QStringList getSelectedNickList() const;
221 
222     Q_SIGNALS:
223         void sendFile();
224 
225     public Q_SLOTS:
226         void updateAppearance() override;
227         void updateQuickButtons();
228         void channelTextEntered();
229         void channelPassthroughCommand();
230         void sendText(const QString& line) override;
231         void showOptionsDialog();
232         void showQuickButtons(bool show);
233         void showModeButtons(bool show);
234 
235         void indicateAway(bool show) override;
236         void showTopic(bool show);
237         void showNicknameBox(bool show);
238         void showNicknameList(bool show);
239 
240         void setAutoJoin(bool autojoin);
241 
242         void connectionStateChanged(Server*, Konversation::ConnectionState);
243 
244     protected:
245         void showEvent(QShowEvent* event) override;
246         /// Called from ChatWindow adjustFocus
247         void childAdjustFocus() override;
248 
249     private Q_SLOTS:
250         void completeNick(); ///< I guess this is a GUI function, might be nice to have at DCOP level though --argonel
251         void endCompleteNick();
252         void quickButtonClicked(const QString& definition);
253         void modeButtonClicked(int id,bool on);
254         void channelLimitChanged();
255 
256         void doubleClickCommand(QTreeWidgetItem *item,int column);  ///< Connected to NickListView::itemDoubleClicked()
257         // Dialogs
258         void changeNickname(const QString& newNickname);
259 
260         void textPasted(const QString& text); ///< connected to IRCInput::textPasted() - used to handle large/multiline pastings
261 
262         void sendFileMenu(); ///< connected to IRCInput::sendFile()
263         void nicknameComboboxChanged();
264         /// Enable/disable the mode buttons depending on whether you are op or not.
265         void refreshModeButtons();
266 
267 //only the GUI cares about sorted nicklists
268         ///Request a delayed nicklist sorting
269         void requestNickListSort();
270         ///Sort the nicklist
271         void sortNickList(bool delayed=false);
272 
273         void nicknameListViewTextChanged(int textChangedFlags);
274 
275     private:
276         void syncSplitters();
277 
278     private:
279         // to take care of redraw problem if hidden
280         bool quickButtonsChanged;
281         bool quickButtonsState;
282         bool modeButtonsChanged;
283         bool modeButtonsState;
284         bool awayChanged;
285         bool awayState;
286         bool splittersInitialized;
287         bool topicSplitterHidden;
288         bool channelSplitterHidden;
289 
290         int completionPosition;
291 
292         QSplitter* m_horizSplitter;
293         QSplitter* m_vertSplitter;
294         QWidget* topicWidget;
295         QToolButton* m_topicButton;
296         Konversation::TopicLabel* topicLine;
297 
298         //TODO: abstract these
299         QFrame* modeBox;
300         ModeButton* modeT;
301         ModeButton* modeN;
302         ModeButton* modeS;
303         ModeButton* modeI;
304         ModeButton* modeP;
305         ModeButton* modeM;
306         ModeButton* modeK;
307         ModeButton* modeL;
308 
309         KLineEdit* limit; //TODO: this GUI element is the only storage for the mode
310 
311         NickListView* nicknameListView;
312         QFrame* commandLineBox;
313         QFrame* nickListButtons;
314         QWidget* m_buttonsGrid;
315         KComboBox* nicknameCombobox;
316         QString oldNick; ///< GUI
317         AwayLabel* awayLabel;
318         QLabel* cipherLabel;
319 
320 //Members from here to end are not GUI
321         bool m_joined;
322         NickList nicknameList;
323         QTimer userhostTimer;
324         int m_nicknameListViewTextChanged;
325         QHash<QString, Nick*> m_nicknameNickHash;
326 
327         TopicHistoryModel* m_topicHistory;
328         QStringList m_BanList;
329 
330         QTimer m_whoTimer; ///< For continuous auto /WHO
331         QElapsedTimer m_whoTimerStarted;
332 
333         QTimer m_fadeActivityTimer; ///< For the smoothing function used in activity sorting
334 
335         QStringList m_nickQueue;
336         int m_processedNicksCount;
337         int m_processedOpsCount;
338         bool m_initialNamesReceived;
339 
340         QTimer* m_delayedSortTimer;
341         int m_delayedSortTrigger;
342 
343         QStringList m_modeList;
344         ChannelNickPtr m_ownChannelNick;
345 
346         int nicks; ///< How many nicks on the channel
347         int ops; ///< How many ops on the channel
348 
349         Konversation::ChannelOptionsDialog *m_optionsDialog;
350         #ifdef HAVE_QCA2
351         mutable Konversation::Cipher *m_cipher;
352         #endif
353 
354         Q_DISABLE_COPY(Channel)
355 };
356 
357 #endif
358