1 /*
2    Drawpile - a collaborative drawing program.
3 
4    Copyright (C) 2007-2019 Calle Laakkonen
5 
6    Drawpile is free software: you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation, either version 3 of the License, or
9    (at your option) any later version.
10 
11    Drawpile is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with Drawpile.  If not, see <http://www.gnu.org/licenses/>.
18 */
19 #ifndef DP_NET_USERLISTMODEL_H
20 #define DP_NET_USERLISTMODEL_H
21 
22 #include <QAbstractTableModel>
23 #include <QSortFilterProxyModel>
24 #include <QList>
25 #include <QPixmap>
26 
27 class QJsonArray;
28 
29 namespace protocol { class MessagePtr; }
30 
31 namespace canvas {
32 
33 /**
34  * @brief Information about a user
35  */
36 struct User {
37 	int id;
38 	QString name;
39 	QPixmap avatar;
40 	bool isLocal;
41 	bool isOperator;
42 	bool isTrusted;
43 	bool isMod;
44 	bool isBot;
45 	bool isAuth;
46 	bool isLocked;
47 	bool isMuted;
48 	bool isOnline;
49 };
50 
51 class OnlineUserListModel;
52 
53 /**
54  * A list model to represent session users.
55  */
56 class UserListModel : public QAbstractTableModel {
57 	Q_OBJECT
58 public:
59 	enum UserListRoles {
60 		IdRole = Qt::UserRole + 1,
61 		NameRole,
62 		AvatarRole,
63 		IsOpRole,
64 		IsTrustedRole,
65 		IsModRole,
66 		IsAuthRole,
67 		IsBotRole,
68 		IsLockedRole,
69 		IsMutedRole,
70 		IsOnlineRole
71 	};
72 
73 	UserListModel(QObject *parent=nullptr);
74 
75 	QVariant data(const QModelIndex& index, int role=Qt::DisplayRole) const override;
76 	int rowCount(const QModelIndex& parent=QModelIndex()) const override;
77 	int columnCount(const QModelIndex& parent=QModelIndex()) const override;
78 	QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override;
79 
80 	//! A new user logs in
81 	void userLogin(const User &user);
82 
83 	//! A user logs out (marked as offline)
84 	void userLogout(int id);
85 
86 	//! Mark all users as offline
87 	void allLogout();
88 
89 	//! Clear all users and history
90 	void reset();
91 
92 	//! Get all users (includes logged out users)
users()93 	const QVector<User> &users() const { return m_users; }
94 
95 	//! Get a shared instance of a filtered model that only lists online users
onlineUsers()96 	OnlineUserListModel *onlineUsers() const { return m_onlineUsers; }
97 
98 	/**
99 	 * @brief Get user info by ID
100 	 *
101 	 * This will return info about past users as well.
102 	 * @param id user id
103 	 * @return
104 	 */
105 	User getUserById(int id) const;
106 
107 	/**
108 	 * @brief Get the name of the user with the given context ID
109 	 *
110 	 * If no such user exists, "User #X" is returned, where X is the ID number.
111 	 * @param id
112 	 * @return user name
113 	 */
114 	QString getUsername(int id) const;
115 
116 	//! Get a list of users with operator privileges
117 	QList<uint8_t> operatorList() const;
118 
119 	//! Get a list of users who are locked
120 	QList<uint8_t> lockList() const;
121 
122 	//! Get a list of trusted users
123 	QList<uint8_t> trustedList() const;
124 
125 	/**
126 	 * @brief Get the command for (un)locking a single user
127 	 * @param localId
128 	 * @param userId
129 	 * @param lock
130 	 * @return
131 	 */
132 	protocol::MessagePtr getLockUserCommand(int localId, int userId, bool lock) const;
133 
134 	/**
135 	 * @brief Get the command for granting or revoking operator privileges
136 	 * @param localId
137 	 * @param userId
138 	 * @param op
139 	 * @return
140 	 */
141 	protocol::MessagePtr getOpUserCommand(int localId, int userId, bool op) const;
142 
143 	/**
144 	 * @brief Get the command for granting or revoking trusted status
145 	 * @param localId
146 	 * @param userId
147 	 * @param trusted
148 	 * @return
149 	 */
150 	protocol::MessagePtr getTrustUserCommand(int localId, int userId, bool op) const;
151 
152 public slots:
153 	void updateOperators(const QList<uint8_t> operatorIds);
154 	void updateTrustedUsers(const QList<uint8_t> trustedIds);
155 	void updateLocks(const QList<uint8_t> lockedUserIds);
156 	void updateMuteList(const QJsonArray &mutedUserIds);
157 
158 private:
159 	QVector<User> m_users;
160 	OnlineUserListModel *m_onlineUsers;
161 };
162 
163 /**
164  * A filtered user list model that only includes online users
165  */
166 class OnlineUserListModel : public QSortFilterProxyModel
167 {
168 	Q_OBJECT
169 public:
170 	using QSortFilterProxyModel::QSortFilterProxyModel;
171 
172 protected:
173 	bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;
174 };
175 
176 }
177 
178 Q_DECLARE_METATYPE(canvas::User)
179 
180 #endif
181 
182