File indexing completed on 2024-12-01 07:40:36

0001 // SPDX-FileCopyrightText: 2020 Tobias Fella <tobias.fella@kde.org>
0002 // SPDX-License-Identifier: GPL-2.0-or-later
0003 
0004 #include "sortfilterroomlistmodel.h"
0005 
0006 #include "neochatconnection.h"
0007 #include "roomlistmodel.h"
0008 #include "spacehierarchycache.h"
0009 
0010 SortFilterRoomListModel::SortFilterRoomListModel(QObject *parent)
0011     : QSortFilterProxyModel(parent)
0012 {
0013     sort(0);
0014     invalidateFilter();
0015     connect(this, &SortFilterRoomListModel::filterTextChanged, this, [this]() {
0016         invalidateFilter();
0017     });
0018     connect(this, &SortFilterRoomListModel::sourceModelChanged, this, [this]() {
0019         connect(sourceModel(), &QAbstractListModel::rowsInserted, this, &SortFilterRoomListModel::invalidateRowsFilter);
0020         connect(sourceModel(), &QAbstractListModel::rowsRemoved, this, &SortFilterRoomListModel::invalidateRowsFilter);
0021     });
0022 }
0023 
0024 void SortFilterRoomListModel::setRoomSortOrder(SortFilterRoomListModel::RoomSortOrder sortOrder)
0025 {
0026     m_sortOrder = sortOrder;
0027     Q_EMIT roomSortOrderChanged();
0028     if (sortOrder == SortFilterRoomListModel::Alphabetical) {
0029         setSortRole(RoomListModel::DisplayNameRole);
0030     } else if (sortOrder == SortFilterRoomListModel::LastActivity) {
0031         setSortRole(RoomListModel::LastActiveTimeRole);
0032     }
0033     invalidate();
0034 }
0035 
0036 SortFilterRoomListModel::RoomSortOrder SortFilterRoomListModel::roomSortOrder() const
0037 {
0038     return m_sortOrder;
0039 }
0040 
0041 bool SortFilterRoomListModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
0042 {
0043     if (m_sortOrder == SortFilterRoomListModel::LastActivity) {
0044         // display favorite rooms always on top
0045         const auto categoryLeft = static_cast<NeoChatRoomType::Types>(sourceModel()->data(source_left, RoomListModel::CategoryRole).toInt());
0046         const auto categoryRight = static_cast<NeoChatRoomType::Types>(sourceModel()->data(source_right, RoomListModel::CategoryRole).toInt());
0047 
0048         if (categoryLeft == NeoChatRoomType::Types::Favorite && categoryRight == NeoChatRoomType::Types::Favorite) {
0049             return sourceModel()->data(source_left, RoomListModel::LastActiveTimeRole).toDateTime()
0050                 > sourceModel()->data(source_right, RoomListModel::LastActiveTimeRole).toDateTime();
0051         }
0052         if (categoryLeft == NeoChatRoomType::Types::Favorite) {
0053             return true;
0054         } else if (categoryRight == NeoChatRoomType::Types::Favorite) {
0055             return false;
0056         }
0057 
0058         return sourceModel()->data(source_left, RoomListModel::LastActiveTimeRole).toDateTime()
0059             > sourceModel()->data(source_right, RoomListModel::LastActiveTimeRole).toDateTime();
0060     }
0061     if (m_sortOrder != SortFilterRoomListModel::Categories) {
0062         return QSortFilterProxyModel::lessThan(source_left, source_right);
0063     }
0064     if (sourceModel()->data(source_left, RoomListModel::CategoryRole) != sourceModel()->data(source_right, RoomListModel::CategoryRole)) {
0065         return sourceModel()->data(source_left, RoomListModel::CategoryRole).toInt() < sourceModel()->data(source_right, RoomListModel::CategoryRole).toInt();
0066     }
0067     return sourceModel()->data(source_left, RoomListModel::LastActiveTimeRole).toDateTime()
0068         > sourceModel()->data(source_right, RoomListModel::LastActiveTimeRole).toDateTime();
0069 }
0070 
0071 void SortFilterRoomListModel::setFilterText(const QString &text)
0072 {
0073     m_filterText = text;
0074     Q_EMIT filterTextChanged();
0075 }
0076 
0077 QString SortFilterRoomListModel::filterText() const
0078 {
0079     return m_filterText;
0080 }
0081 
0082 bool SortFilterRoomListModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
0083 {
0084     Q_UNUSED(source_parent);
0085 
0086     if (sourceModel()->data(sourceModel()->index(source_row, 0), RoomListModel::JoinStateRole).toString() == QStringLiteral("upgraded")
0087         && dynamic_cast<RoomListModel *>(sourceModel())
0088                ->connection()
0089                ->room(sourceModel()->data(sourceModel()->index(source_row, 0), RoomListModel::ReplacementIdRole).toString())) {
0090         return false;
0091     }
0092 
0093     bool acceptRoom =
0094         sourceModel()->data(sourceModel()->index(source_row, 0), RoomListModel::DisplayNameRole).toString().contains(m_filterText, Qt::CaseInsensitive)
0095         && sourceModel()->data(sourceModel()->index(source_row, 0), RoomListModel::IsSpaceRole).toBool() == false;
0096 
0097     if (m_activeSpaceId.isEmpty()) {
0098         return acceptRoom;
0099     } else {
0100         const auto &rooms = SpaceHierarchyCache::instance().getRoomListForSpace(m_activeSpaceId, false);
0101         return std::find(rooms.begin(), rooms.end(), sourceModel()->data(sourceModel()->index(source_row, 0), RoomListModel::RoomIdRole).toString())
0102             != rooms.end()
0103             && acceptRoom;
0104     }
0105 }
0106 
0107 QString SortFilterRoomListModel::activeSpaceId() const
0108 {
0109     return m_activeSpaceId;
0110 }
0111 
0112 void SortFilterRoomListModel::setActiveSpaceId(const QString &spaceId)
0113 {
0114     m_activeSpaceId = spaceId;
0115     Q_EMIT activeSpaceIdChanged();
0116     invalidate();
0117 }
0118 
0119 #include "moc_sortfilterroomlistmodel.cpp"