File indexing completed on 2024-06-09 04:48:44

0001 /**
0002  * SPDX-FileCopyrightText: 2021 Bart De Vries <bart@mogwai.be>
0003  *
0004  * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005  */
0006 
0007 #include "models/feedsproxymodel.h"
0008 
0009 #include <QDebug>
0010 
0011 #include <KLocalizedString>
0012 
0013 FeedsProxyModel::FeedsProxyModel(QObject *parent)
0014     : QSortFilterProxyModel(parent)
0015 {
0016     m_feedsModel = new FeedsModel(this);
0017     setSourceModel(m_feedsModel);
0018     setDynamicSortFilter(true);
0019     sort(0);
0020 }
0021 
0022 bool FeedsProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
0023 {
0024     QString leftTitle = sourceModel()->data(left, FeedsModel::TitleRole).toString();
0025     QString rightTitle = sourceModel()->data(right, FeedsModel::TitleRole).toString();
0026 
0027     if (m_currentSort == SortType::UnreadDescending || m_currentSort == SortType::UnreadAscending) {
0028         int leftUnreadCount = sourceModel()->data(left, FeedsModel::UnreadCountRole).toInt();
0029         int rightUnreadCount = sourceModel()->data(right, FeedsModel::UnreadCountRole).toInt();
0030 
0031         if (leftUnreadCount != rightUnreadCount) {
0032             if (m_currentSort == SortType::UnreadDescending) {
0033                 return leftUnreadCount > rightUnreadCount;
0034             } else {
0035                 return leftUnreadCount < rightUnreadCount;
0036             }
0037         }
0038     } else if (m_currentSort == SortType::NewDescending || m_currentSort == SortType::NewAscending) {
0039         int leftNewCount = sourceModel()->data(left, FeedsModel::NewCountRole).toInt();
0040         int rightNewCount = sourceModel()->data(right, FeedsModel::NewCountRole).toInt();
0041 
0042         if (leftNewCount != rightNewCount) {
0043             if (m_currentSort == SortType::NewDescending) {
0044                 return leftNewCount > rightNewCount;
0045             } else {
0046                 return leftNewCount < rightNewCount;
0047             }
0048         }
0049     } else if (m_currentSort == SortType::FavoriteDescending || m_currentSort == SortType::FavoriteAscending) {
0050         int leftFavoriteCount = sourceModel()->data(left, FeedsModel::FavoriteCountRole).toInt();
0051         int rightFavoriteCount = sourceModel()->data(right, FeedsModel::FavoriteCountRole).toInt();
0052 
0053         if (leftFavoriteCount != rightFavoriteCount) {
0054             if (m_currentSort == SortType::FavoriteDescending) {
0055                 return leftFavoriteCount > rightFavoriteCount;
0056             } else {
0057                 return leftFavoriteCount < rightFavoriteCount;
0058             }
0059         }
0060     } else if (m_currentSort == SortType::TitleDescending) {
0061         return QString::localeAwareCompare(leftTitle, rightTitle) > 0;
0062     }
0063 
0064     // In case there is a "tie" always use ascending alphabetical ordering
0065     return QString::localeAwareCompare(leftTitle, rightTitle) < 0;
0066 }
0067 
0068 bool FeedsProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
0069 {
0070     QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
0071 
0072     bool found = m_searchFilter.isEmpty();
0073     if (!m_searchFilter.isEmpty()) {
0074         if (sourceModel()->data(index, FeedsModel::Roles::TitleRole).value<QString>().contains(m_searchFilter, Qt::CaseInsensitive)) {
0075             found |= true;
0076         }
0077     }
0078 
0079     return found;
0080 }
0081 
0082 QString FeedsProxyModel::searchFilter() const
0083 {
0084     return m_searchFilter;
0085 }
0086 
0087 FeedsProxyModel::SortType FeedsProxyModel::sortType() const
0088 {
0089     return m_currentSort;
0090 }
0091 
0092 void FeedsProxyModel::setSearchFilter(const QString &searchString)
0093 {
0094     if (searchString != m_searchFilter) {
0095         beginResetModel();
0096         m_searchFilter = searchString;
0097         endResetModel();
0098 
0099         Q_EMIT searchFilterChanged();
0100     }
0101 }
0102 
0103 void FeedsProxyModel::setSortType(SortType type)
0104 {
0105     if (type != m_currentSort) {
0106         m_currentSort = type;
0107 
0108         // HACK: get the list re-sorted with a custom lessThan implementation
0109         sort(-1);
0110         sort(0);
0111 
0112         Q_EMIT sortTypeChanged();
0113     }
0114 }
0115 
0116 QString FeedsProxyModel::getSortName(SortType type) const
0117 {
0118     switch (type) {
0119     case SortType::UnreadDescending:
0120         return i18nc("@label:chooser Sort podcasts by decreasing number of unplayed episodes", "Unplayed count: descending");
0121     case SortType::UnreadAscending:
0122         return i18nc("@label:chooser Sort podcasts by increasing number of unplayed episodes", "Unplayed count: ascending");
0123     case SortType::NewDescending:
0124         return i18nc("@label:chooser Sort podcasts by decreasing number of new episodes", "New count: descending");
0125     case SortType::NewAscending:
0126         return i18nc("@label:chooser Sort podcasts by increasing number of new episodes", "New count: ascending");
0127     case SortType::FavoriteDescending:
0128         return i18nc("@label:chooser Sort podcasts by decreasing number of favorites", "Favorite count: descending");
0129     case SortType::FavoriteAscending:
0130         return i18nc("@label:chooser Sort podcasts by increasing number of favorites", "Favorite count: ascending");
0131     case SortType::TitleAscending:
0132         return i18nc("@label:chooser Sort podcasts titles alphabetically", "Podcast title: A → Z");
0133     case SortType::TitleDescending:
0134         return i18nc("@label:chooser Sort podcasts titles in reverse alphabetical order", "Podcast title: Z → A");
0135     default:
0136         return QString();
0137     }
0138 }
0139 
0140 QString FeedsProxyModel::getSortIconName(SortType type) const
0141 {
0142     switch (type) {
0143     case SortType::UnreadDescending:
0144     case SortType::NewDescending:
0145     case SortType::FavoriteDescending:
0146         return QStringLiteral("view-sort-descending");
0147     case SortType::UnreadAscending:
0148     case SortType::NewAscending:
0149     case SortType::FavoriteAscending:
0150         return QStringLiteral("view-sort-ascending");
0151     case SortType::TitleDescending:
0152         return QStringLiteral("view-sort-descending-name");
0153     case SortType::TitleAscending:
0154         return QStringLiteral("view-sort-ascending-name");
0155     default:
0156         return QString();
0157     }
0158 }
0159 
0160 // Hack to get a QItemSelection in QML
0161 QItemSelection FeedsProxyModel::createSelection(int rowa, int rowb)
0162 {
0163     return QItemSelection(index(rowa, 0), index(rowb, 0));
0164 }