File indexing completed on 2024-05-12 16:25:51

0001 /*
0002    SPDX-FileCopyrightText: 2017-2024 Laurent Montel <montel@kde.org>
0003 
0004    SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "roomfilterproxymodel.h"
0008 #include "roommodel.h"
0009 
0010 RoomFilterProxyModel::RoomFilterProxyModel(QObject *parent)
0011     : QSortFilterProxyModel(parent)
0012 {
0013     sort(0);
0014     setRecursiveFilteringEnabled(true);
0015 }
0016 
0017 RoomFilterProxyModel::~RoomFilterProxyModel() = default;
0018 
0019 bool RoomFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
0020 {
0021     if (!sourceModel()) {
0022         return false;
0023     }
0024     // assumes that we have a section → channels hierarchy
0025     if (left.parent().isValid() && right.parent().isValid()) {
0026         qint64 leftDate = 0;
0027         qint64 rightDate = 0;
0028         if (mSortOrder == OwnUserPreferences::RoomListSortOrder::ByLastMessage) {
0029             leftDate = sourceModel()->data(left, RoomModel::RoomLastMessageAt).toLongLong();
0030             rightDate = sourceModel()->data(right, RoomModel::RoomLastMessageAt).toLongLong();
0031         }
0032         if (leftDate == rightDate) {
0033             const QString leftString = sourceModel()->data(left, RoomModel::RoomFName).toString();
0034             const QString rightString = sourceModel()->data(right, RoomModel::RoomFName).toString();
0035             const bool leftFavorite = sourceModel()->data(left, RoomModel::RoomFavorite).toBool();
0036             const bool rightFavorite = sourceModel()->data(right, RoomModel::RoomFavorite).toBool();
0037             if (leftFavorite && (leftFavorite == rightFavorite)) {
0038                 auto leftRoomType = sourceModel()->data(left, RoomModel::RoomType).value<Room::RoomType>();
0039                 if (leftRoomType == Room::RoomType::Private) {
0040                     leftRoomType = Room::RoomType::Channel;
0041                 }
0042                 auto rightRoomType = sourceModel()->data(right, RoomModel::RoomType).value<Room::RoomType>();
0043                 if (rightRoomType == Room::RoomType::Private) {
0044                     rightRoomType = Room::RoomType::Channel;
0045                 }
0046                 if (leftRoomType == rightRoomType) {
0047                     return QString::localeAwareCompare(leftString, rightString) < 0;
0048                 } else {
0049                     return rightRoomType < leftRoomType;
0050                 }
0051             } else {
0052                 return QString::localeAwareCompare(leftString, rightString) < 0;
0053             }
0054         } else {
0055             return leftDate > rightDate;
0056         }
0057     }
0058     return left.row() < right.row();
0059 }
0060 
0061 void RoomFilterProxyModel::setFilterString(const QString &string)
0062 {
0063     mFilterString = string;
0064     invalidate();
0065 }
0066 
0067 void RoomFilterProxyModel::setSortOrder(OwnUserPreferences::RoomListSortOrder sortOrder)
0068 {
0069     mSortOrder = sortOrder;
0070     invalidate();
0071 }
0072 
0073 bool RoomFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
0074 {
0075     const QModelIndex modelIndex = sourceModel()->index(source_row, 0, source_parent);
0076 
0077     // By default don't display any sections
0078     // Thanks to recursive filtering, the sections with channels will be displayed
0079     if (!source_parent.isValid()) {
0080         return false;
0081     }
0082 
0083     auto match = [&](int role) {
0084         return mFilterString.isEmpty() || modelIndex.data(role).toString().contains(mFilterString, Qt::CaseInsensitive);
0085     };
0086     if (!match(RoomModel::RoomName) && !match(RoomModel::RoomFName)) {
0087         return false;
0088     }
0089 
0090     return sourceModel()->data(modelIndex, RoomModel::RoomOpen).toBool();
0091 }
0092 
0093 #include "moc_roomfilterproxymodel.cpp"