Add newer roomlistmodel.
This commit is contained in:
parent
d3b5d1d0dc
commit
dcf7bed39a
|
@ -1,79 +1,44 @@
|
||||||
#include <QtGui/QBrush>
|
|
||||||
#include <QtGui/QColor>
|
|
||||||
|
|
||||||
#include "roomlistmodel.h"
|
#include "roomlistmodel.h"
|
||||||
#include "controller.h"
|
#include "matriqueroom.h"
|
||||||
|
#include "connection.h"
|
||||||
#include "user.h"
|
#include "user.h"
|
||||||
|
|
||||||
RoomListModel::RoomListModel() {
|
#include <QtGui/QIcon>
|
||||||
|
|
||||||
}
|
RoomListModel::RoomListModel(QObject* parent)
|
||||||
|
: QAbstractListModel(parent)
|
||||||
|
{ }
|
||||||
|
|
||||||
RoomListModel::~RoomListModel() {
|
void RoomListModel::setConnection(QMatrixClient::Connection* connection)
|
||||||
|
{
|
||||||
|
Q_ASSERT(connection);
|
||||||
|
|
||||||
}
|
using QMatrixClient::Room;
|
||||||
|
|
||||||
void RoomListModel::setConnection(QMatrixClient::Connection *conn) {
|
|
||||||
m_connection = conn;
|
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
m_rooms.clear();
|
m_connection = connection;
|
||||||
connect(m_connection, &QMatrixClient::Connection::newRoom, this, &RoomListModel::addRoom);
|
connect( connection, &QMatrixClient::Connection::loggedOut,
|
||||||
for(QMatrixClient::Room* r: m_connection->roomMap().values()) {
|
this, [=]{ deleteConnection(connection); } );
|
||||||
if (auto* room = static_cast<MatriqueRoom*>(r))
|
connect( connection, &QMatrixClient::Connection::invitedRoom,
|
||||||
{
|
this, &RoomListModel::updateRoom);
|
||||||
connect(room, &MatriqueRoom::namesChanged, this, &RoomListModel::namesChanged);
|
connect( connection, &QMatrixClient::Connection::joinedRoom,
|
||||||
m_rooms.append(room);
|
this, &RoomListModel::updateRoom);
|
||||||
} else
|
connect( connection, &QMatrixClient::Connection::leftRoom,
|
||||||
{
|
this, &RoomListModel::updateRoom);
|
||||||
qCritical() << "Attempt to add nullptr to the room list";
|
connect( connection, &QMatrixClient::Connection::aboutToDeleteRoom,
|
||||||
Q_ASSERT(false);
|
this, &RoomListModel::deleteRoom);
|
||||||
}
|
|
||||||
}
|
for( auto r: connection->roomMap() )
|
||||||
|
doAddRoom(r);
|
||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
MatriqueRoom* RoomListModel::roomAt(int row) {
|
void RoomListModel::deleteConnection(QMatrixClient::Connection* connection) {
|
||||||
return m_rooms.at(row);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RoomListModel::addRoom(MatriqueRoom* room) {
|
MatriqueRoom* RoomListModel::roomAt(QModelIndex index) const
|
||||||
qDebug() << "Adding room.";
|
{
|
||||||
beginInsertRows(QModelIndex(), m_rooms.count(), m_rooms.count());
|
return m_rooms.at(index.row());
|
||||||
connect(room, &MatriqueRoom::namesChanged, this, &RoomListModel::namesChanged );
|
|
||||||
m_rooms.append(room);
|
|
||||||
endInsertRows();
|
|
||||||
}
|
|
||||||
|
|
||||||
int RoomListModel::rowCount(const QModelIndex& parent) const {
|
|
||||||
if( parent.isValid() )
|
|
||||||
return 0;
|
|
||||||
return m_rooms.count();
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant RoomListModel::data(const QModelIndex& index, int role) const {
|
|
||||||
if(!index.isValid())
|
|
||||||
return QVariant();
|
|
||||||
|
|
||||||
if(index.row() >= m_rooms.count()) {
|
|
||||||
qDebug() << "UserListModel: something wrong here...";
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
MatriqueRoom* room = m_rooms.at(index.row());
|
|
||||||
if(role == NameRole) {
|
|
||||||
return room->displayName();
|
|
||||||
}
|
|
||||||
if(role == ValueRole) {
|
|
||||||
return room->topic();
|
|
||||||
}
|
|
||||||
if(role == AvatarRole) {
|
|
||||||
if(room->avatarUrl().toString() != "") {
|
|
||||||
return room->avatarUrl();
|
|
||||||
} else if(room->users().length() == 2) {
|
|
||||||
QMatrixClient::User* user = room->users().at(0);
|
|
||||||
return user->avatarUrl();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return QVariant();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex RoomListModel::indexOf(MatriqueRoom* room) const
|
QModelIndex RoomListModel::indexOf(MatriqueRoom* room) const
|
||||||
|
@ -81,19 +46,191 @@ QModelIndex RoomListModel::indexOf(MatriqueRoom* room) const
|
||||||
return index(m_rooms.indexOf(room), 0);
|
return index(m_rooms.indexOf(room), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RoomListModel::updateRoom(QMatrixClient::Room* room,
|
||||||
|
QMatrixClient::Room* prev)
|
||||||
|
{
|
||||||
|
// There are two cases when this method is called:
|
||||||
|
// 1. (prev == nullptr) adding a new room to the room list
|
||||||
|
// 2. (prev != nullptr) accepting/rejecting an invitation or inviting to
|
||||||
|
// the previously left room (in both cases prev has the previous state).
|
||||||
|
if (prev == room)
|
||||||
|
{
|
||||||
|
qCritical() << "RoomListModel::updateRoom: room tried to replace itself";
|
||||||
|
refresh(static_cast<MatriqueRoom*>(room));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (prev && room->id() != prev->id())
|
||||||
|
{
|
||||||
|
qCritical() << "RoomListModel::updateRoom: attempt to update room"
|
||||||
|
<< room->id() << "to" << prev->id();
|
||||||
|
// That doesn't look right but technically we still can do it.
|
||||||
|
}
|
||||||
|
// Ok, we're through with pre-checks, now for the real thing.
|
||||||
|
auto* newRoom = static_cast<MatriqueRoom*>(room);
|
||||||
|
const auto it = std::find_if(m_rooms.begin(), m_rooms.end(),
|
||||||
|
[=](const MatriqueRoom* r) { return r == prev || r == newRoom; });
|
||||||
|
if (it != m_rooms.end())
|
||||||
|
{
|
||||||
|
const int row = it - m_rooms.begin();
|
||||||
|
// There's no guarantee that prev != newRoom
|
||||||
|
if (*it == prev && *it != newRoom)
|
||||||
|
{
|
||||||
|
prev->disconnect(this);
|
||||||
|
m_rooms.replace(row, newRoom);
|
||||||
|
connectRoomSignals(newRoom);
|
||||||
|
}
|
||||||
|
emit dataChanged(index(row), index(row));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
beginInsertRows(QModelIndex(), m_rooms.count(), m_rooms.count());
|
||||||
|
doAddRoom(newRoom);
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RoomListModel::deleteRoom(QMatrixClient::Room* room)
|
||||||
|
{
|
||||||
|
auto i = m_rooms.indexOf(static_cast<MatriqueRoom*>(room));
|
||||||
|
if (i == -1)
|
||||||
|
return; // Already deleted, nothing to do
|
||||||
|
|
||||||
|
beginRemoveRows(QModelIndex(), i, i);
|
||||||
|
m_rooms.removeAt(i);
|
||||||
|
endRemoveRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RoomListModel::doAddRoom(QMatrixClient::Room* r)
|
||||||
|
{
|
||||||
|
if (auto* room = static_cast<MatriqueRoom*>(r))
|
||||||
|
{
|
||||||
|
m_rooms.append(room);
|
||||||
|
connectRoomSignals(room);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
qCritical() << "Attempt to add nullptr to the room list";
|
||||||
|
Q_ASSERT(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RoomListModel::connectRoomSignals(MatriqueRoom* room)
|
||||||
|
{
|
||||||
|
connect(room, &MatriqueRoom::displaynameChanged,
|
||||||
|
this, [=]{ displaynameChanged(room); } );
|
||||||
|
connect( room, &MatriqueRoom::unreadMessagesChanged,
|
||||||
|
this, [=]{ unreadMessagesChanged(room); } );
|
||||||
|
connect( room, &MatriqueRoom::notificationCountChanged,
|
||||||
|
this, [=]{ unreadMessagesChanged(room); } );
|
||||||
|
connect( room, &MatriqueRoom::joinStateChanged,
|
||||||
|
this, [=]{ refresh(room); });
|
||||||
|
connect( room, &MatriqueRoom::avatarChanged,
|
||||||
|
this, [=]{ refresh(room, { Qt::DecorationRole }); });
|
||||||
|
}
|
||||||
|
|
||||||
|
int RoomListModel::rowCount(const QModelIndex& parent) const
|
||||||
|
{
|
||||||
|
if( parent.isValid() )
|
||||||
|
return 0;
|
||||||
|
return m_rooms.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant RoomListModel::data(const QModelIndex& index, int role) const
|
||||||
|
{
|
||||||
|
if( !index.isValid() )
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
if( index.row() >= m_rooms.count() )
|
||||||
|
{
|
||||||
|
qDebug() << "UserListModel: something wrong here...";
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
auto room = m_rooms.at(index.row());
|
||||||
|
using QMatrixClient::JoinState;
|
||||||
|
switch (role)
|
||||||
|
{
|
||||||
|
case Qt::DisplayRole:
|
||||||
|
return room->displayName();
|
||||||
|
case Qt::DecorationRole:
|
||||||
|
{
|
||||||
|
// auto avatar = room->avatar(16, 16);
|
||||||
|
// if (!avatar.isNull())
|
||||||
|
// return avatar;
|
||||||
|
// switch( room->joinState() )
|
||||||
|
// {
|
||||||
|
// case JoinState::Join:
|
||||||
|
// return QIcon(":/irc-channel-joined.svg");
|
||||||
|
// case JoinState::Invite:
|
||||||
|
// return QIcon(":/irc-channel-invited.svg");
|
||||||
|
// case JoinState::Leave:
|
||||||
|
// return QIcon(":/irc-channel-parted.svg");
|
||||||
|
// }
|
||||||
|
if(room->avatarUrl().toString() != "") {
|
||||||
|
return room->avatarUrl();
|
||||||
|
} else if(room->users().length() == 2) {
|
||||||
|
QMatrixClient::User* user = room->users().at(0);
|
||||||
|
return user->avatarUrl();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case Qt::StatusTipRole:
|
||||||
|
{
|
||||||
|
return room->topic();
|
||||||
|
}
|
||||||
|
case Qt::ToolTipRole:
|
||||||
|
{
|
||||||
|
int hlCount = room->highlightCount();
|
||||||
|
auto result = QStringLiteral("<b>%1</b><br>").arg(room->displayName());
|
||||||
|
result += tr("Main alias: %1<br>").arg(room->canonicalAlias());
|
||||||
|
result += tr("Members: %1<br>").arg(room->memberCount());
|
||||||
|
if (hlCount > 0)
|
||||||
|
result += tr("Unread mentions: %1<br>").arg(hlCount);
|
||||||
|
result += tr("ID: %1<br>").arg(room->id());
|
||||||
|
switch (room->joinState())
|
||||||
|
{
|
||||||
|
case JoinState::Join:
|
||||||
|
result += tr("You joined this room");
|
||||||
|
break;
|
||||||
|
case JoinState::Leave:
|
||||||
|
result += tr("You left this room");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result += tr("You were invited into this room");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
case HasUnreadRole:
|
||||||
|
return room->hasUnreadMessages();
|
||||||
|
case HighlightCountRole:
|
||||||
|
return room->highlightCount();
|
||||||
|
case JoinStateRole:
|
||||||
|
return toCString(room->joinState()); // FIXME: better make the enum QVariant-convertible
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QHash<int, QByteArray> RoomListModel::roleNames() const {
|
QHash<int, QByteArray> RoomListModel::roleNames() const {
|
||||||
QHash<int, QByteArray> roles;
|
QHash<int, QByteArray> roles;
|
||||||
roles[NameRole] = "name";
|
roles[Qt::DisplayRole] = "name";
|
||||||
roles[ValueRole] = "value";
|
roles[Qt::DecorationRole] = "avatar";
|
||||||
roles[AvatarRole] = "avatar";
|
roles[Qt::StatusTipRole] = "value";
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RoomListModel::namesChanged(MatriqueRoom* room) {
|
void RoomListModel::displaynameChanged(MatriqueRoom* room)
|
||||||
|
{
|
||||||
|
refresh(room);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RoomListModel::unreadMessagesChanged(MatriqueRoom* room)
|
||||||
|
{
|
||||||
|
refresh(room);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RoomListModel::refresh(MatriqueRoom* room, const QVector<int>& roles)
|
||||||
|
{
|
||||||
int row = m_rooms.indexOf(room);
|
int row = m_rooms.indexOf(room);
|
||||||
emit dataChanged(index(row), index(row));
|
if (row == -1)
|
||||||
}
|
qCritical() << "Room" << room->id() << "not found in the room list";
|
||||||
|
else
|
||||||
void RoomListModel::unreadMessagesChanged(MatriqueRoom* room) {
|
emit dataChanged(index(row), index(row), roles);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
#ifndef ROOMLISTMODEL_H
|
#ifndef ROOMLISTMODEL_H
|
||||||
#define ROOMLISTMODEL_H
|
#define ROOMLISTMODEL_H
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QtCore/QAbstractListModel>
|
#include <QtCore/QAbstractListModel>
|
||||||
|
|
||||||
#include "libqmatrixclient/connection.h"
|
|
||||||
#include "libqmatrixclient/room.h"
|
|
||||||
|
|
||||||
#include "matriqueroom.h"
|
#include "matriqueroom.h"
|
||||||
|
|
||||||
namespace QMatrixClient {
|
namespace QMatrixClient
|
||||||
|
{
|
||||||
class Connection;
|
class Connection;
|
||||||
class Room;
|
class Room;
|
||||||
}
|
}
|
||||||
|
@ -18,40 +15,42 @@ class RoomListModel : public QAbstractListModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
Q_PROPERTY(QMatrixClient::Connection *connection READ getConnection WRITE setConnection NOTIFY connectionChanged)
|
Q_PROPERTY(QMatrixClient::Connection *connection READ getConnection WRITE setConnection)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit RoomListModel();
|
enum Roles {
|
||||||
~RoomListModel();
|
HasUnreadRole = Qt::UserRole + 1,
|
||||||
|
HighlightCountRole, JoinStateRole
|
||||||
enum RoomModelRoles {
|
|
||||||
NameRole, ValueRole, AvatarRole
|
|
||||||
};
|
};
|
||||||
|
|
||||||
QMatrixClient::Connection* m_connection;
|
explicit RoomListModel(QObject* parent = nullptr);
|
||||||
|
|
||||||
QMatrixClient::Connection* getConnection() { return m_connection; }
|
QMatrixClient::Connection* getConnection() { return m_connection; }
|
||||||
void setConnection(QMatrixClient::Connection* conn);
|
void setConnection(QMatrixClient::Connection* connection);
|
||||||
|
void deleteConnection(QMatrixClient::Connection* connection);
|
||||||
|
|
||||||
QHash<int, QByteArray> roleNames() const;
|
MatriqueRoom* roomAt(QModelIndex index) const;
|
||||||
|
QModelIndex indexOf(MatriqueRoom* room) const;
|
||||||
Q_INVOKABLE MatriqueRoom* roomAt(int row);
|
|
||||||
|
|
||||||
QVariant data(const QModelIndex& index, int role) const override;
|
QVariant data(const QModelIndex& index, int role) const override;
|
||||||
QModelIndex indexOf(MatriqueRoom* room) const;
|
QHash<int, QByteArray> roleNames() const;
|
||||||
Q_INVOKABLE int rowCount(const QModelIndex& parent=QModelIndex()) const override;
|
int rowCount(const QModelIndex& parent) const override;
|
||||||
|
|
||||||
signals:
|
|
||||||
void connectionChanged();
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void namesChanged(MatriqueRoom* room);
|
void displaynameChanged(MatriqueRoom* room);
|
||||||
void unreadMessagesChanged(MatriqueRoom* room);
|
void unreadMessagesChanged(MatriqueRoom* room);
|
||||||
void addRoom(MatriqueRoom* room);
|
void refresh(MatriqueRoom* room, const QVector<int>& roles = {});
|
||||||
|
|
||||||
|
void updateRoom(QMatrixClient::Room* room,
|
||||||
|
QMatrixClient::Room* prev);
|
||||||
|
void deleteRoom(QMatrixClient::Room* room);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
QMatrixClient::Connection* m_connection;
|
||||||
QList<MatriqueRoom*> m_rooms;
|
QList<MatriqueRoom*> m_rooms;
|
||||||
|
|
||||||
|
void doAddRoom(QMatrixClient::Room* r);
|
||||||
|
void connectRoomSignals(MatriqueRoom* room);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ROOMLISTMODEL_H
|
#endif // ROOMLISTMODEL_H
|
||||||
|
|
|
@ -116,7 +116,7 @@ Item {
|
||||||
ImageStatus {
|
ImageStatus {
|
||||||
width: parent.height
|
width: parent.height
|
||||||
height: parent.height
|
height: parent.height
|
||||||
source: avatar == null ? "qrc:/asset/img/avatar.png" : "image://mxc/" + avatar
|
source: avatar == "" ? "qrc:/asset/img/avatar.png" : "image://mxc/" + avatar
|
||||||
opaqueBackground: true
|
opaqueBackground: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue