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
|
/**************************************************************************
* *
* SPDX-FileCopyrightText: 2016 Felix Rohrbach <kde@fxrh.de> *
* *
* SPDX-License-Identifier: GPL-3.0-or-later
* *
**************************************************************************/
#pragma once
#include "abstractroomordering.h"
#include "../quaternionroom.h"
#include <Quotient/connection.h>
#include <Quotient/util.h>
#include <Quotient/qt_connection_util.h>
#include <QtCore/QAbstractItemModel>
#include <QtCore/QMultiHash>
class QAbstractItemView;
class RoomListModel: public QAbstractItemModel
{
Q_OBJECT
template <typename T>
using ConnectionsGuard = Quotient::ConnectionsGuard<T>;
public:
enum Roles {
HasUnreadRole = Qt::UserRole + 1,
HighlightCountRole, JoinStateRole, ObjectRole
};
using Room = Quotient::Room;
explicit RoomListModel(QAbstractItemView* parent);
~RoomListModel() override = default;
QVariant roomGroupAt(QModelIndex idx) const;
QuaternionRoom* roomAt(QModelIndex idx) const;
QModelIndex indexOf(const QVariant& group) const;
QModelIndex indexOf(const QVariant& group, Room* room) const;
QModelIndex index(int row, int column,
const QModelIndex& parent = {}) const override;
QModelIndex parent(const QModelIndex& index) const override;
using QObject::parent;
QVariant data(const QModelIndex& index, int role) const override;
int columnCount(const QModelIndex&) const override;
int rowCount(const QModelIndex& parent) const override;
int totalRooms() const;
bool isValidGroupIndex(const QModelIndex& i) const;
bool isValidRoomIndex(const QModelIndex& i) const;
template <typename OrderT>
void setOrder() { doSetOrder(std::make_unique<OrderT>(this)); }
signals:
void groupAdded(int row);
void saveCurrentSelection();
void restoreCurrentSelection();
public slots:
void addConnection(Quotient::Connection* connection);
void deleteConnection(Quotient::Connection* connection);
// FIXME, quotient-im/libQuotient#63:
// This should go to the library's ConnectionManager/RoomManager
void deleteTag(QModelIndex index);
private slots:
void addRoom(Room* room);
void refresh(Room* room, const QVector<int>& roles = {});
void deleteRoom(Room* room);
void updateGroups(Room* room);
private:
friend class AbstractRoomOrdering;
std::vector<ConnectionsGuard<Quotient::Connection>> m_connections;
RoomGroups m_roomGroups;
AbstractRoomOrdering* m_roomOrder = nullptr;
QMultiHash<const Room*, QPersistentModelIndex> m_roomIndices;
RoomGroups::iterator tryInsertGroup(const QVariant& key);
void addRoomToGroups(Room* room, QVariantList groups = {});
void connectRoomSignals(Room* room);
void doRemoveRoom(const QModelIndex& idx);
void visitRoom(const Room& room,
const std::function<void(QModelIndex)>& visitor);
void doSetOrder(std::unique_ptr<AbstractRoomOrdering>&& newOrder);
std::pair<QModelIndexList, QModelIndexList>
preparePersistentIndexChange(int fromPos, int shiftValue) const;
// Beware, the returned iterators are as short-lived as QModelIndex'es
auto lowerBoundGroup(const QVariant& group)
{
return std::ranges::lower_bound(m_roomGroups, group,
m_roomOrder->groupLessThanFactory(), &RoomGroup::key);
}
auto lowerBoundGroup(const QVariant& group) const
{
return std::ranges::lower_bound(m_roomGroups, group,
m_roomOrder->groupLessThanFactory(), &RoomGroup::key);
}
auto lowerBoundRoom(RoomGroup& group, Room* room) const
{
return std::ranges::lower_bound(group.rooms, room,
m_roomOrder->roomLessThanFactory(group.key));
}
auto lowerBoundRoom(const RoomGroup& group, Room* room) const
{
return std::ranges::lower_bound(group.rooms, room,
m_roomOrder->roomLessThanFactory(group.key));
}
};
|