1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
|
// Copyright 2009-2021 The Mumble Developers. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file at the root of the
// Mumble source tree or at <https://www.mumble.info/LICENSE>.
#ifndef MUMBLE_MUMBLE_USERMODEL_H_
#define MUMBLE_MUMBLE_USERMODEL_H_
#include <QtCore/QAbstractItemModel>
#include <QtCore/QHash>
#include <QtCore/QObject>
#include <QtCore/QSet>
#include <QtGui/QIcon>
class User;
class ClientUser;
class Channel;
struct ModelItem Q_DECL_FINAL {
friend class UserModel;
private:
Q_DISABLE_COPY(ModelItem)
public:
Channel *cChan;
ClientUser *pUser;
bool isListener;
bool bCommentSeen;
ModelItem *parent;
QList< ModelItem * > qlChildren;
QList< ModelItem * > qlHiddenChildren;
/// Number of users in this channel (recursive)
int iUsers;
static QHash< const Channel *, ModelItem * > c_qhChannels;
static QHash< const ClientUser *, ModelItem * > c_qhUsers;
static QHash< const ClientUser *, QList< ModelItem * > > s_userProxies;
static bool bUsersTop;
ModelItem(Channel *c);
ModelItem(ClientUser *p, bool isListener = false);
ModelItem(ModelItem *);
~ModelItem();
ModelItem *child(int idx) const;
bool validRow(int idx) const;
ClientUser *userAt(int idx) const;
Channel *channelAt(int idx) const;
int rowOf(Channel *c) const;
int rowOf(ClientUser *p, const bool isListener) const;
int rowOfSelf() const;
int rows() const;
int insertIndex(Channel *c) const;
int insertIndex(ClientUser *p, bool isListener = false) const;
QString hash() const;
void wipe();
};
class UserModel : public QAbstractItemModel {
friend struct ModelItem;
friend class UserView;
private:
Q_OBJECT
Q_DISABLE_COPY(UserModel)
protected:
QIcon qiTalkingOn, qiTalkingMuted, qiTalkingWhisper, qiTalkingShout, qiTalkingOff;
QIcon qiMutedPushToMute, qiMutedSelf, qiMutedServer, qiMutedLocal, qiIgnoredLocal, qiMutedSuppressed;
QIcon qiPrioritySpeaker;
QIcon qiRecording;
QIcon qiDeafenedSelf, qiDeafenedServer;
QIcon qiAuthenticated, qiChannel, qiLinkedChannel, qiActiveChannel;
QIcon qiFriend;
QIcon qiComment, qiCommentSeen, qiFilter;
QIcon qiLock_locked, qiLock_unlocked;
QIcon qiEar;
ModelItem *miRoot;
QSet< Channel * > qsLinked;
QMap< QString, ClientUser * > qmHashes;
bool bClicked;
void recursiveClone(const ModelItem *old, ModelItem *item, QModelIndexList &from, QModelIndexList &to);
ModelItem *moveItem(ModelItem *oldparent, ModelItem *newparent, ModelItem *item);
QString stringIndex(const QModelIndex &index) const;
/// @returns The QModelIndex that is currently selected. If there is no selection, the returned index
/// is invalid.
QModelIndex getSelectedIndex() const;
/// Removes the given user as a listener to the given channel
///
/// @param item A pointer to the listener's ModelItem that shall be removed
/// @param citem A pointer to the ModelItem that represents the channel the listener
/// is in. The listener has to be a direct child of this item. If this is nullptr,
/// the parent of the provided item is used directly.
void removeChannelListener(ModelItem *item, ModelItem *citem = nullptr);
public:
UserModel(QObject *parent = 0);
~UserModel() Q_DECL_OVERRIDE;
QModelIndex index(ClientUser *, int column = 0) const;
QModelIndex index(Channel *, int column = 0) const;
QModelIndex index(ModelItem *) const;
QModelIndex channelListenerIndex(const ClientUser *, const Channel *, int column = 0) const;
QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;
Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
QModelIndex parent(const QModelIndex &index) const Q_DECL_OVERRIDE;
int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
Qt::DropActions supportedDropActions() const Q_DECL_OVERRIDE;
QStringList mimeTypes() const Q_DECL_OVERRIDE;
QMimeData *mimeData(const QModelIndexList &idx) const Q_DECL_OVERRIDE;
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
const QModelIndex &parent) Q_DECL_OVERRIDE;
ClientUser *addUser(unsigned int id, const QString &name);
ClientUser *getUser(const QModelIndex &idx) const;
ClientUser *getUser(const QString &hash) const;
/// @returns A pointer to the currently selected User or nullptr if there is none
ClientUser *getSelectedUser() const;
/// Sets the selection to the User with the given session
///
/// @param session The session ID of the respective User
void setSelectedUser(unsigned int session);
Channel *addChannel(int id, Channel *p, const QString &name);
Channel *getChannel(const QModelIndex &idx) const;
/// @returns A pointer to the currently selected Channel or nullptr if there is none
Channel *getSelectedChannel() const;
/// Sets the selection to the Channel with the given ID
///
/// @param session The ID of the respective Channel
void setSelectedChannel(int id);
/// Adds the guven user as a listener to the given channel
///
/// @param p A pointer to the user
/// @param c A pointer to the channel
void addChannelListener(ClientUser *p, Channel *c);
/// Removes the guven user as a listener to the given channel
///
/// @param p A pointer to the user
/// @param c A pointer to the channel. If this is nullptr, then all listeners
/// for the given user are removed (from all channels).
void removeChannelListener(const ClientUser *p, const Channel *c = nullptr);
/// @param idx The QModelIndex to check
/// @returns Whether the ModelItem associated with the given index is a listener-proxy
bool isChannelListener(const QModelIndex &idx) const;
/// Sets the selection to the ChannelListener of the given user in the given channel
///
/// @param userSession The session ID of the respective User
/// @param channelID The ID of the respective Channel
void setSelectedChannelListener(unsigned int userSession, int channelID);
Channel *getSubChannel(Channel *p, int idx) const;
void renameUser(ClientUser *p, const QString &name);
void renameChannel(Channel *c, const QString &name);
void repositionChannel(Channel *c, const int position);
void setUserId(ClientUser *p, int id);
void setHash(ClientUser *p, const QString &hash);
void setFriendName(ClientUser *p, const QString &name);
void setComment(ClientUser *p, const QString &comment);
void setCommentHash(ClientUser *p, const QByteArray &hash);
void seenComment(const QModelIndex &idx);
void moveUser(ClientUser *p, Channel *c);
void moveChannel(Channel *c, Channel *p);
void setComment(Channel *c, const QString &comment);
void setCommentHash(Channel *c, const QByteArray &hash);
void removeUser(ClientUser *p);
bool removeChannel(Channel *c, const bool onlyIfUnoccupied = false);
void linkChannels(Channel *c, QList< Channel * > links);
void unlinkChannels(Channel *c, QList< Channel * > links);
void unlinkAll(Channel *c);
void removeAll();
void expandAll(Channel *c);
void collapseEmpty(Channel *c);
QVariant otherRoles(const QModelIndex &idx, int role) const;
unsigned int uiSessionComment;
int iChannelDescription;
/// Creates the display string for the given user/listener
///
/// @param user The user to create the string for
/// @param isChannelListener Whether the display String is in fact for a listener of the given user
/// @param parentChannel The channel in which the listener resides. May be nullptr, if isChannelListener is false
/// @return The created display string
static QString createDisplayString(const ClientUser &user, bool isChannelListener, const Channel *parentChannel);
public slots:
/// Invalidates the model data of the ClientUser triggering this slot.
void userStateChanged();
void on_channelListenerLocalVolumeAdjustmentChanged(int channelID, float oldValue, float newValue);
void ensureSelfVisible();
void recheckLinks();
void updateOverlay() const;
void toggleChannelFiltered(Channel *c);
signals:
/// A signal emitted whenever a user is added to the model.
///
/// @param userSessionID The ID of that user's session
void userAdded(unsigned int userSessionID);
/// A signal emitted whenever a user is removed from the model.
///
/// @param userSessionID The ID of that user's session
void userRemoved(unsigned int userSessionID);
/// A signal that emitted whenever a channel is added to the model.
///
/// @param channelID The ID of the channel
void channelAdded(int channelID);
/// A signal that emitted whenever a channel is removed from the model.
///
/// @param channelID The ID of the channel
void channelRemoved(int channelID);
/// A signal that emitted whenever a channel is renamed.
///
/// @param channelID The ID of the channel
void channelRenamed(int channelID);
};
#endif
|