240 lines
8.9 KiB
C++
240 lines
8.9 KiB
C++
// Copyright 2009-2023 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, qiPin;
|
|
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(unsigned 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(unsigned 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, unsigned 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(unsigned int channelID, float oldValue, float newValue);
|
|
void ensureSelfVisible();
|
|
void recheckLinks();
|
|
void updateOverlay() const;
|
|
void forceVisualUpdate(Channel *c = nullptr);
|
|
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(unsigned int channelID);
|
|
/// A signal that emitted whenever a channel is removed from the model.
|
|
///
|
|
/// @param channelID The ID of the channel
|
|
void channelRemoved(unsigned int channelID);
|
|
/// A signal that emitted whenever a channel is renamed.
|
|
///
|
|
/// @param channelID The ID of the channel
|
|
void channelRenamed(unsigned int channelID);
|
|
};
|
|
|
|
#endif
|