1 /***************************************************************************
2 * Copyright (C) 2005-2016 by the Quassel Project *
3 * devel@quassel-irc.org *
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. *
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. *
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 ***************************************************************************/
21 #ifndef NETWORKMODEL_H
22 #define NETWORKMODEL_H
24 #include "bufferinfo.h"
25 #include "clientsettings.h"
28 #include "treemodel.h"
31 class StatusBufferItem;
33 /*****************************************
35 *****************************************/
36 class NetworkItem : public PropertyMapItem
39 Q_PROPERTY(QString networkName READ networkName)
40 Q_PROPERTY(QString currentServer READ currentServer)
41 Q_PROPERTY(int nickCount READ nickCount)
44 NetworkItem(const NetworkId &netid, AbstractTreeItem *parent = 0);
46 virtual QVariant data(int column, int row) const;
49 * Escapes a string as HTML, ready for Qt markup.
51 * Implementation depends on Qt version - Qt4 uses Qt::escape, while Qt5 uses .toHtmlEscaped().
53 * @param[in] string QString to escape
54 * @param[in] useNonbreakingSpaces
56 * If true, replace spaces with non-breaking spaces (i.e. ' '), otherwise only HTML escape.
59 static QString escapeHTML(const QString &string, bool useNonbreakingSpaces = false);
61 inline bool isActive() const { return (bool)_network ? _network->isConnected() : false; }
63 inline const NetworkId &networkId() const { return _networkId; }
64 inline QString networkName() const { return (bool)_network ? _network->networkName() : QString(); }
65 inline QString currentServer() const { return (bool)_network ? _network->currentServer() : QString(); }
66 inline int nickCount() const { return (bool)_network ? _network->ircUsers().count() : 0; }
68 virtual QString toolTip(int column) const;
70 BufferItem *findBufferItem(BufferId bufferId);
71 inline BufferItem *findBufferItem(const BufferInfo &bufferInfo) { return findBufferItem(bufferInfo.bufferId()); }
72 BufferItem *bufferItem(const BufferInfo &bufferInfo);
73 inline StatusBufferItem *statusBufferItem() const { return _statusBufferItem; }
76 void setNetworkName(const QString &networkName);
77 void setCurrentServer(const QString &serverName);
79 void attachNetwork(Network *network);
80 void attachIrcChannel(IrcChannel *channel);
81 void attachIrcUser(IrcUser *ircUser);
84 void networkDataChanged(int column = -1);
87 void onBeginRemoveChilds(int start, int end);
88 void onNetworkDestroyed();
92 StatusBufferItem *_statusBufferItem;
94 QPointer<Network> _network;
98 /*****************************************
100 *****************************************/
101 class BufferItem : public PropertyMapItem
104 Q_PROPERTY(QString bufferName READ bufferName WRITE setBufferName)
105 Q_PROPERTY(QString topic READ topic)
106 Q_PROPERTY(int nickCount READ nickCount)
109 BufferItem(const BufferInfo &bufferInfo, AbstractTreeItem *parent = 0);
111 inline const BufferInfo &bufferInfo() const { return _bufferInfo; }
112 virtual QVariant data(int column, int role) const;
113 virtual bool setData(int column, const QVariant &value, int role);
115 inline BufferId bufferId() const { return _bufferInfo.bufferId(); }
116 inline BufferInfo::Type bufferType() const { return _bufferInfo.type(); }
118 virtual void setBufferName(const QString &name);
119 virtual inline QString bufferName() const { return _bufferInfo.bufferName(); }
120 virtual inline QString topic() const { return QString(); }
121 virtual inline int nickCount() const { return 0; }
123 virtual inline bool isActive() const { return qobject_cast<NetworkItem *>(parent())->isActive(); }
125 inline MsgId lastSeenMsgId() const { return _lastSeenMsgId; }
126 inline MsgId markerLineMsgId() const { return _markerLineMsgId; }
127 void setLastSeenMsgId(MsgId msgId);
128 void setMarkerLineMsgId(MsgId msgId);
130 inline BufferInfo::ActivityLevel activityLevel() const { return _activity; }
131 void setActivityLevel(BufferInfo::ActivityLevel level);
132 void clearActivityLevel();
133 void updateActivityLevel(const Message &msg);
134 void setActivity(Message::Types msg, bool highlight);
135 bool addActivity(Message::Types msg, bool highlight);
137 inline const MsgId &firstUnreadMsgId() const { return _firstUnreadMsgId; }
139 bool isCurrentBuffer() const;
140 virtual QString toolTip(int column) const;
143 virtual inline void setTopic(const QString &) { emit dataChanged(1); }
144 virtual inline void setEncrypted(bool) { emit dataChanged(); }
147 BufferInfo _bufferInfo;
148 BufferInfo::ActivityLevel _activity;
149 MsgId _lastSeenMsgId;
150 MsgId _markerLineMsgId;
151 MsgId _firstUnreadMsgId;
155 /*****************************************
157 *****************************************/
158 class StatusBufferItem : public BufferItem
163 StatusBufferItem(const BufferInfo &bufferInfo, NetworkItem *parent);
165 virtual QString toolTip(int column) const;
166 virtual inline QString bufferName() const { return tr("Status Buffer"); }
170 /*****************************************
172 *****************************************/
173 class QueryBufferItem : public BufferItem
178 QueryBufferItem(const BufferInfo &bufferInfo, NetworkItem *parent);
180 virtual QVariant data(int column, int role) const;
181 virtual bool setData(int column, const QVariant &value, int role);
183 virtual inline bool isActive() const { return (bool)_ircUser; }
184 virtual QString toolTip(int column) const;
186 virtual void setBufferName(const QString &name);
189 void setIrcUser(IrcUser *ircUser);
190 void removeIrcUser();
197 /*****************************************
199 *****************************************/
200 class UserCategoryItem;
202 class ChannelBufferItem : public BufferItem
207 ChannelBufferItem(const BufferInfo &bufferInfo, AbstractTreeItem *parent);
209 virtual QVariant data(int column, int role) const;
210 virtual inline bool isActive() const { return (bool)_ircChannel; }
211 virtual QString toolTip(int column) const;
213 virtual inline QString topic() const { return (bool)_ircChannel ? _ircChannel->topic() : QString(); }
214 virtual inline int nickCount() const { return (bool)_ircChannel ? _ircChannel->ircUsers().count() : 0; }
216 void attachIrcChannel(IrcChannel *ircChannel);
219 * Gets the list of channel modes for a given nick.
221 * @param[in] nick IrcUser nickname to check
222 * @returns Channel modes as a string if any, otherwise empty string
224 QString nickChannelModes(const QString &nick) const;
227 void join(const QList<IrcUser *> &ircUsers);
228 void part(IrcUser *ircUser);
230 UserCategoryItem *findCategoryItem(int categoryId);
231 void addUserToCategory(IrcUser *ircUser);
232 void addUsersToCategory(const QList<IrcUser *> &ircUser);
233 void removeUserFromCategory(IrcUser *ircUser);
234 void userModeChanged(IrcUser *ircUser);
237 void ircChannelParted();
238 void ircChannelDestroyed();
241 IrcChannel *_ircChannel;
245 /*****************************************
246 * User Category Items (like @vh etc.)
247 *****************************************/
249 class UserCategoryItem : public PropertyMapItem
252 Q_PROPERTY(QString categoryName READ categoryName)
255 UserCategoryItem(int category, AbstractTreeItem *parent);
257 QString categoryName() const;
258 inline int categoryId() const { return _category; }
259 virtual QVariant data(int column, int role) const;
261 IrcUserItem *findIrcUser(IrcUser *ircUser);
262 void addUsers(const QList<IrcUser *> &ircUser);
263 bool removeUser(IrcUser *ircUser);
265 static int categoryFromModes(const QString &modes);
270 static const QList<QChar> categories;
274 /*****************************************
276 *****************************************/
277 class IrcUserItem : public PropertyMapItem
280 Q_PROPERTY(QString nickName READ nickName)
283 IrcUserItem(IrcUser *ircUser, AbstractTreeItem *parent);
285 inline QString nickName() const { return _ircUser ? _ircUser->nick() : QString(); }
286 inline bool isActive() const { return _ircUser ? !_ircUser->isAway() : false; }
288 inline IrcUser *ircUser() { return _ircUser; }
289 virtual QVariant data(int column, int role) const;
290 virtual QString toolTip(int column) const;
293 * Gets the list of channel modes for this nick if parented to channel.
295 * @returns Channel modes as a string if any, otherwise empty string
297 QString channelModes() const;
300 inline void ircUserQuited() { parent()->removeChild(this); }
303 QPointer<IrcUser> _ircUser;
307 /*****************************************
309 *****************************************/
310 class NetworkModel : public TreeModel
316 BufferTypeRole = TreeModel::UserRole,
326 BufferFirstUnreadMsgIdRole,
331 NetworkItemType = 0x01,
332 BufferItemType = 0x02,
333 UserCategoryItemType = 0x04,
334 IrcUserItemType = 0x08
336 Q_DECLARE_FLAGS(ItemTypes, ItemType)
338 NetworkModel(QObject *parent = 0);
339 static QList<QVariant> defaultHeader();
341 static bool mimeContainsBufferList(const QMimeData *mimeData);
342 static QList<QPair<NetworkId, BufferId> > mimeDataToBufferList(const QMimeData *mimeData);
344 virtual QStringList mimeTypes() const;
345 virtual QMimeData *mimeData(const QModelIndexList &) const;
347 void attachNetwork(Network *network);
349 bool isBufferIndex(const QModelIndex &) const;
350 //Buffer *getBufferByIndex(const QModelIndex &) const;
351 QModelIndex networkIndex(NetworkId networkId);
352 QModelIndex bufferIndex(BufferId bufferId);
354 const Network *networkByIndex(const QModelIndex &index) const;
356 BufferInfo::ActivityLevel bufferActivity(const BufferInfo &buffer) const;
358 //! Finds a buffer with a given name in a given network
359 /** This performs a linear search through all BufferItems, hence it is expensive.
360 * @param networkId The network which we search in
361 * @param bufferName The bufferName we look for
362 * @return The id of the buffer if found, an invalid one else
364 BufferId bufferId(NetworkId networkId, const QString &bufferName, Qt::CaseSensitivity cs = Qt::CaseInsensitive) const;
366 QString bufferName(BufferId bufferId) const;
367 BufferInfo::Type bufferType(BufferId bufferId) const;
368 BufferInfo bufferInfo(BufferId bufferId) const;
369 MsgId lastSeenMsgId(BufferId bufferId) const;
370 MsgId markerLineMsgId(BufferId bufferId) const;
371 NetworkId networkId(BufferId bufferId) const;
372 QString networkName(BufferId bufferId) const;
374 inline QList<BufferId> allBufferIds() const { return _bufferItemCache.keys(); }
375 QList<BufferId> allBufferIdsSorted() const;
376 void sortBufferIds(QList<BufferId> &bufferIds) const;
379 void bufferUpdated(BufferInfo bufferInfo);
380 void removeBuffer(BufferId bufferId);
381 MsgId lastSeenMsgId(const BufferId &bufferId);
382 void setLastSeenMsgId(const BufferId &bufferId, const MsgId &msgId);
383 void setMarkerLineMsgId(const BufferId &bufferId, const MsgId &msgId);
384 void setBufferActivity(const BufferId &bufferId, BufferInfo::ActivityLevel activity);
385 void clearBufferActivity(const BufferId &bufferId);
386 void updateBufferActivity(Message &msg);
387 void networkRemoved(const NetworkId &networkId);
388 void bufferActivityChanged(BufferId, Message::Types);
391 void requestSetLastSeenMsg(BufferId buffer, MsgId msg);
392 void lastSeenMsgSet(BufferId buffer, MsgId msg);
393 void markerLineSet(BufferId buffer, MsgId msg);
396 void checkForRemovedBuffers(const QModelIndex &parent, int start, int end);
397 void checkForNewBuffers(const QModelIndex &parent, int start, int end);
398 void messageRedirectionSettingsChanged();
401 int networkRow(NetworkId networkId) const;
402 NetworkItem *findNetworkItem(NetworkId networkId) const;
403 NetworkItem *networkItem(NetworkId networkId);
404 inline BufferItem *findBufferItem(const BufferInfo &bufferInfo) const { return findBufferItem(bufferInfo.bufferId()); }
405 BufferItem *findBufferItem(BufferId bufferId) const;
406 BufferItem *bufferItem(const BufferInfo &bufferInfo);
408 void updateBufferActivity(BufferItem *bufferItem, const Message &msg);
410 static bool bufferItemLessThan(const BufferItem *left, const BufferItem *right);
412 QHash<BufferId, BufferItem *> _bufferItemCache;
414 int _userNoticesTarget;
415 int _serverNoticesTarget;
416 int _errorMsgsTarget;
420 Q_DECLARE_OPERATORS_FOR_FLAGS(NetworkModel::ItemTypes)
422 #endif // NETWORKMODEL_H