1 // Copyright 2005-2019 The Mumble Developers. All rights reserved.
2 // Use of this source code is governed by a BSD-style license
3 // that can be found in the LICENSE file at the root of the
4 // Mumble source tree or at <https://www.mumble.info/LICENSE>.
5 
6 #ifndef MUMBLE_MUMBLE_USERMODEL_H_
7 #define MUMBLE_MUMBLE_USERMODEL_H_
8 
9 #include <QtCore/QAbstractItemModel>
10 #include <QtCore/QHash>
11 #include <QtCore/QObject>
12 #include <QtCore/QSet>
13 #include <QtGui/QIcon>
14 
15 class User;
16 class ClientUser;
17 class Channel;
18 
19 struct ModelItem Q_DECL_FINAL {
20 	friend class UserModel;
21 
22 private:
23 	Q_DISABLE_COPY(ModelItem)
24 public:
25 	Channel *cChan;
26 	ClientUser *pUser;
27 
28 	bool bCommentSeen;
29 
30 	ModelItem *parent;
31 	QList<ModelItem *> qlChildren;
32 	QList<ModelItem *> qlHiddenChildren;
33 	/// Number of users in this channel (recursive)
34 	int iUsers;
35 
36 	static QHash <Channel *, ModelItem *> c_qhChannels;
37 	static QHash <ClientUser *, ModelItem *> c_qhUsers;
38 	static bool bUsersTop;
39 
40 	ModelItem(Channel *c);
41 	ModelItem(ClientUser *p);
42 	ModelItem(ModelItem *);
43 	~ModelItem();
44 
45 	ModelItem *child(int idx) const;
46 
47 	bool validRow(int idx) const;
48 	ClientUser *userAt(int idx) const;
49 	Channel *channelAt(int idx) const;
50 	int rowOf(Channel *c) const;
51 	int rowOf(ClientUser *p) const;
52 	int rowOfSelf() const;
53 	int rows() const;
54 	int insertIndex(Channel *c) const;
55 	int insertIndex(ClientUser *p) const;
56 	QString hash() const;
57 	void wipe();
58 };
59 
60 class UserModel : public QAbstractItemModel {
61 		friend struct ModelItem;
62 		friend class UserView;
63 	private:
64 		Q_OBJECT
65 		Q_DISABLE_COPY(UserModel)
66 	protected:
67 		QIcon qiTalkingOn, qiTalkingWhisper, qiTalkingShout, qiTalkingOff;
68 		QIcon qiMutedPushToMute, qiMutedSelf, qiMutedServer, qiMutedLocal, qiIgnoredLocal, qiMutedSuppressed;
69 		QIcon qiPrioritySpeaker;
70 		QIcon qiRecording;
71 		QIcon qiDeafenedSelf, qiDeafenedServer;
72 		QIcon qiAuthenticated, qiChannel, qiLinkedChannel, qiActiveChannel;
73 		QIcon qiFriend;
74 		QIcon qiComment, qiCommentSeen, qiFilter;
75 		ModelItem *miRoot;
76 		QSet<Channel *> qsLinked;
77 		QMap<QString, ClientUser *> qmHashes;
78 
79 		bool bClicked;
80 
81 		void recursiveClone(const ModelItem *old, ModelItem *item, QModelIndexList &from, QModelIndexList &to);
82 		ModelItem *moveItem(ModelItem *oldparent, ModelItem *newparent, ModelItem *item);
83 
84 		QString stringIndex(const QModelIndex &index) const;
85 	public:
86 		UserModel(QObject *parent = 0);
87 		~UserModel() Q_DECL_OVERRIDE;
88 
89 		QModelIndex index(ClientUser *, int column = 0) const;
90 		QModelIndex index(Channel *, int column = 0) const;
91 		QModelIndex index(ModelItem *) const;
92 
93 		QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;
94 		Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE;
95 		QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
96 		QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
97 		QModelIndex parent(const QModelIndex &index) const Q_DECL_OVERRIDE;
98 		int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
99 		int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
100 		Qt::DropActions supportedDropActions() const Q_DECL_OVERRIDE;
101 		QStringList mimeTypes() const Q_DECL_OVERRIDE;
102 		QMimeData *mimeData(const QModelIndexList &idx) const Q_DECL_OVERRIDE;
103 		bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex & parent) Q_DECL_OVERRIDE;
104 
105 		ClientUser *addUser(unsigned int id, const QString &name);
106 		ClientUser *getUser(const QModelIndex &idx) const;
107 		ClientUser *getUser(const QString &hash) const;
108 
109 		Channel *addChannel(int id, Channel *p, const QString &name);
110 		Channel *getChannel(const QModelIndex &idx) const;
111 
112 		Channel *getSubChannel(Channel *p, int idx) const;
113 
114 		void renameUser(ClientUser *p, const QString &name);
115 		void renameChannel(Channel *c, const QString &name);
116 		void repositionChannel(Channel *c, const int position);
117 		void setUserId(ClientUser *p, int id);
118 		void setHash(ClientUser *p, const QString &hash);
119 		void setFriendName(ClientUser *p, const QString &name);
120 		void setComment(ClientUser *p, const QString &comment);
121 		void setCommentHash(ClientUser *p, const QByteArray &hash);
122 		void seenComment(const QModelIndex &idx);
123 
124 		void moveUser(ClientUser *p, Channel *c);
125 		void moveChannel(Channel *c, Channel *p);
126 		void setComment(Channel *c, const QString &comment);
127 		void setCommentHash(Channel *c, const QByteArray &hash);
128 
129 		void removeUser(ClientUser *p);
130 		bool removeChannel(Channel *c, const bool onlyIfUnoccupied = false);
131 
132 		void linkChannels(Channel *c, QList<Channel *> links);
133 		void unlinkChannels(Channel *c, QList<Channel *> links);
134 		void unlinkAll(Channel *c);
135 
136 		void removeAll();
137 
138 		void expandAll(Channel *c);
139 		void collapseEmpty(Channel *c);
140 
141 		QVariant otherRoles(const QModelIndex &idx, int role) const;
142 
143 		unsigned int uiSessionComment;
144 		int iChannelDescription;
145 	public slots:
146 		/// Invalidates the model data of the ClientUser triggering this slot.
147 		void userStateChanged();
148 		void ensureSelfVisible();
149 		void recheckLinks();
150 		void updateOverlay() const;
151 		void toggleChannelFiltered(Channel *c);
152 };
153 
154 #endif
155