1 | /*************************************************************************** |
2 | * Copyright (C) 2005-2014 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 | #ifndef NETWORKMODEL_H |
22 | #define NETWORKMODEL_H |
23 | |
24 | #include "bufferinfo.h" |
25 | #include "clientsettings.h" |
26 | #include "message.h" |
27 | #include "network.h" |
28 | #include "treemodel.h" |
29 | |
30 | class BufferItem; |
31 | class StatusBufferItem; |
32 | |
33 | /***************************************** |
34 | * Network Items |
35 | *****************************************/ |
36 | class NetworkItem : public PropertyMapItem |
37 | { |
38 | Q_OBJECT |
39 | Q_PROPERTY(QString networkName READ networkName) |
40 | Q_PROPERTY(QString currentServer READ currentServer) |
41 | Q_PROPERTY(int nickCount READ nickCount) |
42 | |
43 | public : |
44 | NetworkItem(const NetworkId &netid, AbstractTreeItem *parent = 0); |
45 | |
46 | virtual QVariant data(int column, int row) const; |
47 | |
48 | inline bool isActive() const { return (bool)_network ? _network->isConnected() : false; } |
49 | |
50 | inline const NetworkId &networkId() const { return _networkId; } |
51 | inline QString networkName() const { return (bool)_network ? _network->networkName() : QString(); } |
52 | inline QString currentServer() const { return (bool)_network ? _network->currentServer() : QString(); } |
53 | inline int nickCount() const { return (bool)_network ? _network->ircUsers().count() : 0; } |
54 | |
55 | virtual QString toolTip(int column) const; |
56 | |
57 | BufferItem *findBufferItem(BufferId bufferId); |
58 | inline BufferItem *findBufferItem(const BufferInfo &bufferInfo) { return findBufferItem(bufferInfo.bufferId()); } |
59 | BufferItem *bufferItem(const BufferInfo &bufferInfo); |
60 | inline StatusBufferItem *statusBufferItem() const { return _statusBufferItem; } |
61 | |
62 | public slots: |
63 | void setNetworkName(const QString &networkName); |
64 | void setCurrentServer(const QString &serverName); |
65 | |
66 | void attachNetwork(Network *network); |
67 | void attachIrcChannel(IrcChannel *channel); |
68 | void attachIrcUser(IrcUser *ircUser); |
69 | |
70 | signals: |
71 | void networkDataChanged(int column = -1); |
72 | |
73 | private slots: |
74 | void onBeginRemoveChilds(int start, int end); |
75 | void onNetworkDestroyed(); |
76 | |
77 | private: |
78 | NetworkId _networkId; |
79 | StatusBufferItem *_statusBufferItem; |
80 | |
81 | QPointer<Network> _network; |
82 | }; |
83 | |
84 | |
85 | /***************************************** |
86 | * Fancy Buffer Items |
87 | *****************************************/ |
88 | class BufferItem : public PropertyMapItem |
89 | { |
90 | Q_OBJECT |
91 | Q_PROPERTY(QString bufferName READ bufferName WRITE setBufferName) |
92 | Q_PROPERTY(QString topic READ topic) |
93 | Q_PROPERTY(int nickCount READ nickCount) |
94 | |
95 | public : |
96 | BufferItem(const BufferInfo &bufferInfo, AbstractTreeItem *parent = 0); |
97 | |
98 | inline const BufferInfo &bufferInfo() const { return _bufferInfo; } |
99 | virtual QVariant data(int column, int role) const; |
100 | virtual bool setData(int column, const QVariant &value, int role); |
101 | |
102 | inline BufferId bufferId() const { return _bufferInfo.bufferId(); } |
103 | inline BufferInfo::Type bufferType() const { return _bufferInfo.type(); } |
104 | |
105 | virtual void setBufferName(const QString &name); |
106 | virtual inline QString bufferName() const { return _bufferInfo.bufferName(); } |
107 | virtual inline QString topic() const { return QString(); } |
108 | virtual inline int nickCount() const { return 0; } |
109 | |
110 | virtual inline bool isActive() const { return qobject_cast<NetworkItem *>(parent())->isActive(); } |
111 | |
112 | inline MsgId lastSeenMsgId() const { return _lastSeenMsgId; } |
113 | inline MsgId markerLineMsgId() const { return _markerLineMsgId; } |
114 | void setLastSeenMsgId(MsgId msgId); |
115 | void setMarkerLineMsgId(MsgId msgId); |
116 | |
117 | inline BufferInfo::ActivityLevel activityLevel() const { return _activity; } |
118 | void setActivityLevel(BufferInfo::ActivityLevel level); |
119 | void clearActivityLevel(); |
120 | void updateActivityLevel(const Message &msg); |
121 | |
122 | inline const MsgId &firstUnreadMsgId() const { return _firstUnreadMsgId; } |
123 | |
124 | bool isCurrentBuffer() const; |
125 | virtual QString toolTip(int column) const; |
126 | |
127 | public slots: |
128 | virtual inline void setTopic(const QString &) { emit dataChanged(1); } |
129 | virtual inline void setEncrypted(bool) { emit dataChanged(); } |
130 | |
131 | private: |
132 | BufferInfo _bufferInfo; |
133 | BufferInfo::ActivityLevel _activity; |
134 | MsgId _lastSeenMsgId; |
135 | MsgId _markerLineMsgId; |
136 | MsgId _firstUnreadMsgId; |
137 | }; |
138 | |
139 | |
140 | /***************************************** |
141 | * StatusBufferItem |
142 | *****************************************/ |
143 | class StatusBufferItem : public BufferItem |
144 | { |
145 | Q_OBJECT |
146 | |
147 | public: |
148 | StatusBufferItem(const BufferInfo &bufferInfo, NetworkItem *parent); |
149 | |
150 | virtual QString toolTip(int column) const; |
151 | virtual inline QString bufferName() const { return tr("Status Buffer" ); } |
152 | }; |
153 | |
154 | |
155 | /***************************************** |
156 | * QueryBufferItem |
157 | *****************************************/ |
158 | class QueryBufferItem : public BufferItem |
159 | { |
160 | Q_OBJECT |
161 | |
162 | public: |
163 | QueryBufferItem(const BufferInfo &bufferInfo, NetworkItem *parent); |
164 | |
165 | virtual QVariant data(int column, int role) const; |
166 | virtual bool setData(int column, const QVariant &value, int role); |
167 | |
168 | virtual inline bool isActive() const { return (bool)_ircUser; } |
169 | virtual QString toolTip(int column) const; |
170 | |
171 | virtual void setBufferName(const QString &name); |
172 | |
173 | public slots: |
174 | void setIrcUser(IrcUser *ircUser); |
175 | void removeIrcUser(); |
176 | |
177 | private: |
178 | IrcUser *_ircUser; |
179 | }; |
180 | |
181 | |
182 | /***************************************** |
183 | * ChannelBufferItem |
184 | *****************************************/ |
185 | class UserCategoryItem; |
186 | |
187 | class ChannelBufferItem : public BufferItem |
188 | { |
189 | Q_OBJECT |
190 | |
191 | public: |
192 | ChannelBufferItem(const BufferInfo &bufferInfo, AbstractTreeItem *parent); |
193 | |
194 | virtual QVariant data(int column, int role) const; |
195 | virtual inline bool isActive() const { return (bool)_ircChannel; } |
196 | virtual QString toolTip(int column) const; |
197 | |
198 | virtual inline QString topic() const { return (bool)_ircChannel ? _ircChannel->topic() : QString(); } |
199 | virtual inline int nickCount() const { return (bool)_ircChannel ? _ircChannel->ircUsers().count() : 0; } |
200 | |
201 | void attachIrcChannel(IrcChannel *ircChannel); |
202 | |
203 | public slots: |
204 | void join(const QList<IrcUser *> &ircUsers); |
205 | void part(IrcUser *ircUser); |
206 | |
207 | UserCategoryItem *findCategoryItem(int categoryId); |
208 | void addUserToCategory(IrcUser *ircUser); |
209 | void addUsersToCategory(const QList<IrcUser *> &ircUser); |
210 | void removeUserFromCategory(IrcUser *ircUser); |
211 | void userModeChanged(IrcUser *ircUser); |
212 | |
213 | private slots: |
214 | void ircChannelParted(); |
215 | void ircChannelDestroyed(); |
216 | |
217 | private: |
218 | IrcChannel *_ircChannel; |
219 | }; |
220 | |
221 | |
222 | /***************************************** |
223 | * User Category Items (like @vh etc.) |
224 | *****************************************/ |
225 | class IrcUserItem; |
226 | class UserCategoryItem : public PropertyMapItem |
227 | { |
228 | Q_OBJECT |
229 | Q_PROPERTY(QString categoryName READ categoryName) |
230 | |
231 | public : |
232 | UserCategoryItem(int category, AbstractTreeItem *parent); |
233 | |
234 | QString categoryName() const; |
235 | inline int categoryId() const { return _category; } |
236 | virtual QVariant data(int column, int role) const; |
237 | |
238 | IrcUserItem *findIrcUser(IrcUser *ircUser); |
239 | void addUsers(const QList<IrcUser *> &ircUser); |
240 | bool removeUser(IrcUser *ircUser); |
241 | |
242 | static int categoryFromModes(const QString &modes); |
243 | |
244 | private: |
245 | int _category; |
246 | |
247 | static const QList<QChar> categories; |
248 | }; |
249 | |
250 | |
251 | /***************************************** |
252 | * Irc User Items |
253 | *****************************************/ |
254 | class IrcUserItem : public PropertyMapItem |
255 | { |
256 | Q_OBJECT |
257 | Q_PROPERTY(QString nickName READ nickName) |
258 | |
259 | public : |
260 | IrcUserItem(IrcUser *ircUser, AbstractTreeItem *parent); |
261 | |
262 | inline QString nickName() const { return _ircUser ? _ircUser->nick() : QString(); } |
263 | inline bool isActive() const { return _ircUser ? !_ircUser->isAway() : false; } |
264 | |
265 | inline IrcUser *ircUser() { return _ircUser; } |
266 | virtual QVariant data(int column, int role) const; |
267 | virtual QString toolTip(int column) const; |
268 | |
269 | private slots: |
270 | inline void ircUserQuited() { parent()->removeChild(this); } |
271 | |
272 | private: |
273 | QPointer<IrcUser> _ircUser; |
274 | }; |
275 | |
276 | |
277 | /***************************************** |
278 | * NetworkModel |
279 | *****************************************/ |
280 | class NetworkModel : public TreeModel |
281 | { |
282 | Q_OBJECT |
283 | |
284 | public: |
285 | enum Role { |
286 | BufferTypeRole = TreeModel::UserRole, |
287 | ItemActiveRole, |
288 | BufferActivityRole, |
289 | BufferIdRole, |
290 | NetworkIdRole, |
291 | BufferInfoRole, |
292 | ItemTypeRole, |
293 | UserAwayRole, |
294 | IrcUserRole, |
295 | IrcChannelRole, |
296 | BufferFirstUnreadMsgIdRole, |
297 | MarkerLineMsgIdRole, |
298 | }; |
299 | |
300 | enum ItemType { |
301 | NetworkItemType = 0x01, |
302 | BufferItemType = 0x02, |
303 | UserCategoryItemType = 0x04, |
304 | IrcUserItemType = 0x08 |
305 | }; |
306 | Q_DECLARE_FLAGS(ItemTypes, ItemType) |
307 | |
308 | NetworkModel(QObject *parent = 0); |
309 | static QList<QVariant> (); |
310 | |
311 | static bool mimeContainsBufferList(const QMimeData *mimeData); |
312 | static QList<QPair<NetworkId, BufferId> > mimeDataToBufferList(const QMimeData *mimeData); |
313 | |
314 | virtual QStringList mimeTypes() const; |
315 | virtual QMimeData *mimeData(const QModelIndexList &) const; |
316 | |
317 | void attachNetwork(Network *network); |
318 | |
319 | bool isBufferIndex(const QModelIndex &) const; |
320 | //Buffer *getBufferByIndex(const QModelIndex &) const; |
321 | QModelIndex networkIndex(NetworkId networkId); |
322 | QModelIndex bufferIndex(BufferId bufferId); |
323 | |
324 | const Network *networkByIndex(const QModelIndex &index) const; |
325 | |
326 | BufferInfo::ActivityLevel bufferActivity(const BufferInfo &buffer) const; |
327 | |
328 | //! Finds a buffer with a given name in a given network |
329 | /** This performs a linear search through all BufferItems, hence it is expensive. |
330 | * @param networkId The network which we search in |
331 | * @param bufferName The bufferName we look for |
332 | * @return The id of the buffer if found, an invalid one else |
333 | */ |
334 | BufferId bufferId(NetworkId networkId, const QString &bufferName, Qt::CaseSensitivity cs = Qt::CaseInsensitive) const; |
335 | |
336 | QString bufferName(BufferId bufferId) const; |
337 | BufferInfo::Type bufferType(BufferId bufferId) const; |
338 | BufferInfo bufferInfo(BufferId bufferId) const; |
339 | MsgId lastSeenMsgId(BufferId bufferId) const; |
340 | MsgId markerLineMsgId(BufferId bufferId) const; |
341 | NetworkId networkId(BufferId bufferId) const; |
342 | QString networkName(BufferId bufferId) const; |
343 | |
344 | inline QList<BufferId> allBufferIds() const { return _bufferItemCache.keys(); } |
345 | QList<BufferId> allBufferIdsSorted() const; |
346 | void sortBufferIds(QList<BufferId> &bufferIds) const; |
347 | |
348 | public slots: |
349 | void bufferUpdated(BufferInfo bufferInfo); |
350 | void removeBuffer(BufferId bufferId); |
351 | MsgId lastSeenMsgId(const BufferId &bufferId); |
352 | void setLastSeenMsgId(const BufferId &bufferId, const MsgId &msgId); |
353 | void setMarkerLineMsgId(const BufferId &bufferId, const MsgId &msgId); |
354 | void setBufferActivity(const BufferId &bufferId, BufferInfo::ActivityLevel activity); |
355 | void clearBufferActivity(const BufferId &bufferId); |
356 | void updateBufferActivity(Message &msg); |
357 | void networkRemoved(const NetworkId &networkId); |
358 | |
359 | signals: |
360 | void requestSetLastSeenMsg(BufferId buffer, MsgId msg); |
361 | void lastSeenMsgSet(BufferId buffer, MsgId msg); |
362 | void markerLineSet(BufferId buffer, MsgId msg); |
363 | |
364 | private slots: |
365 | void checkForRemovedBuffers(const QModelIndex &parent, int start, int end); |
366 | void checkForNewBuffers(const QModelIndex &parent, int start, int end); |
367 | void messageRedirectionSettingsChanged(); |
368 | |
369 | private: |
370 | int networkRow(NetworkId networkId) const; |
371 | NetworkItem *findNetworkItem(NetworkId networkId) const; |
372 | NetworkItem *networkItem(NetworkId networkId); |
373 | inline BufferItem *findBufferItem(const BufferInfo &bufferInfo) const { return findBufferItem(bufferInfo.bufferId()); } |
374 | BufferItem *findBufferItem(BufferId bufferId) const; |
375 | BufferItem *bufferItem(const BufferInfo &bufferInfo); |
376 | |
377 | void updateBufferActivity(BufferItem *bufferItem, const Message &msg); |
378 | |
379 | static bool bufferItemLessThan(const BufferItem *left, const BufferItem *right); |
380 | |
381 | QHash<BufferId, BufferItem *> _bufferItemCache; |
382 | |
383 | int _userNoticesTarget; |
384 | int _serverNoticesTarget; |
385 | int _errorMsgsTarget; |
386 | }; |
387 | |
388 | |
389 | Q_DECLARE_OPERATORS_FOR_FLAGS(NetworkModel::ItemTypes) |
390 | |
391 | #endif // NETWORKMODEL_H |
392 | |