File indexing completed on 2024-05-05 05:38:29

0001 /*
0002     SPDX-FileCopyrightText: 2019 Kai Uwe Broulik <kde@privat.broulik.de>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 
0007 #include "notificationfilterproxymodel_p.h"
0008 
0009 using namespace NotificationManager;
0010 
0011 NotificationFilterProxyModel::NotificationFilterProxyModel(QObject *parent)
0012     : QSortFilterProxyModel(parent)
0013 {
0014     setRecursiveFilteringEnabled(true);
0015 }
0016 
0017 NotificationFilterProxyModel::~NotificationFilterProxyModel() = default;
0018 
0019 Notifications::Urgencies NotificationFilterProxyModel::urgencies() const
0020 {
0021     return m_urgencies;
0022 }
0023 
0024 void NotificationFilterProxyModel::setUrgencies(Notifications::Urgencies urgencies)
0025 {
0026     if (m_urgencies != urgencies) {
0027         m_urgencies = urgencies;
0028         invalidateFilter();
0029         Q_EMIT urgenciesChanged();
0030     }
0031 }
0032 
0033 bool NotificationFilterProxyModel::showExpired() const
0034 {
0035     return m_showExpired;
0036 }
0037 
0038 void NotificationFilterProxyModel::setShowExpired(bool show)
0039 {
0040     if (m_showExpired != show) {
0041         m_showExpired = show;
0042         invalidateFilter();
0043         Q_EMIT showExpiredChanged();
0044     }
0045 }
0046 
0047 bool NotificationFilterProxyModel::showDismissed() const
0048 {
0049     return m_showDismissed;
0050 }
0051 
0052 void NotificationFilterProxyModel::setShowDismissed(bool show)
0053 {
0054     if (m_showDismissed != show) {
0055         m_showDismissed = show;
0056         invalidateFilter();
0057         Q_EMIT showDismissedChanged();
0058     }
0059 }
0060 
0061 QStringList NotificationFilterProxyModel::blacklistedDesktopEntries() const
0062 {
0063     return m_blacklistedDesktopEntries;
0064 }
0065 
0066 void NotificationFilterProxyModel::setBlackListedDesktopEntries(const QStringList &blacklist)
0067 {
0068     if (m_blacklistedDesktopEntries != blacklist) {
0069         m_blacklistedDesktopEntries = blacklist;
0070         invalidateFilter();
0071         Q_EMIT blacklistedDesktopEntriesChanged();
0072     }
0073 }
0074 
0075 QStringList NotificationFilterProxyModel::blacklistedNotifyRcNames() const
0076 {
0077     return m_blacklistedNotifyRcNames;
0078 }
0079 
0080 void NotificationFilterProxyModel::setBlacklistedNotifyRcNames(const QStringList &blacklist)
0081 {
0082     if (m_blacklistedNotifyRcNames != blacklist) {
0083         m_blacklistedNotifyRcNames = blacklist;
0084         invalidateFilter();
0085         Q_EMIT blacklistedNotifyRcNamesChanged();
0086     }
0087 }
0088 
0089 QStringList NotificationFilterProxyModel::whitelistedDesktopEntries() const
0090 {
0091     return m_whitelistedDesktopEntries;
0092 }
0093 
0094 void NotificationFilterProxyModel::setWhiteListedDesktopEntries(const QStringList &whitelist)
0095 {
0096     if (m_whitelistedDesktopEntries != whitelist) {
0097         m_whitelistedDesktopEntries = whitelist;
0098         invalidateFilter();
0099         Q_EMIT whitelistedDesktopEntriesChanged();
0100     }
0101 }
0102 
0103 QStringList NotificationFilterProxyModel::whitelistedNotifyRcNames() const
0104 {
0105     return m_whitelistedNotifyRcNames;
0106 }
0107 
0108 void NotificationFilterProxyModel::setWhitelistedNotifyRcNames(const QStringList &whitelist)
0109 {
0110     if (m_whitelistedNotifyRcNames != whitelist) {
0111         m_whitelistedNotifyRcNames = whitelist;
0112         invalidateFilter();
0113         Q_EMIT whitelistedNotifyRcNamesChanged();
0114     }
0115 }
0116 
0117 bool NotificationFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
0118 {
0119     const QModelIndex sourceIdx = sourceModel()->index(source_row, 0, source_parent);
0120 
0121     const bool expired = sourceIdx.data(Notifications::ExpiredRole).toBool();
0122     if (!m_showExpired && expired) {
0123         return false;
0124     }
0125 
0126     if (!m_showDismissed && sourceIdx.data(Notifications::DismissedRole).toBool()) {
0127         return false;
0128     }
0129 
0130     QString desktopEntry = sourceIdx.data(Notifications::DesktopEntryRole).toString();
0131     if (desktopEntry.isEmpty()) {
0132         // For non-configurable notifications use the fake "@other" category.
0133         if (!sourceIdx.data(Notifications::ConfigurableRole).toBool()
0134             // jobs are never configurable so this only applies to notifications
0135             && sourceIdx.data(Notifications::TypeRole).toInt() == Notifications::NotificationType) {
0136             desktopEntry = QStringLiteral("@other");
0137         }
0138     }
0139 
0140     // Blacklist takes precedence over whitelist, i.e. when in doubt don't show
0141     if (!m_blacklistedDesktopEntries.isEmpty()) {
0142         if (!desktopEntry.isEmpty() && m_blacklistedDesktopEntries.contains(desktopEntry)) {
0143             return false;
0144         }
0145     }
0146 
0147     if (!m_blacklistedNotifyRcNames.isEmpty()) {
0148         const QString notifyRcName = sourceIdx.data(Notifications::NotifyRcNameRole).toString();
0149         if (!notifyRcName.isEmpty() && m_blacklistedNotifyRcNames.contains(notifyRcName)) {
0150             return false;
0151         }
0152     }
0153 
0154     if (!m_whitelistedDesktopEntries.isEmpty()) {
0155         if (!desktopEntry.isEmpty() && m_whitelistedDesktopEntries.contains(desktopEntry)) {
0156             return true;
0157         }
0158     }
0159 
0160     if (!m_whitelistedNotifyRcNames.isEmpty()) {
0161         const QString notifyRcName = sourceIdx.data(Notifications::NotifyRcNameRole).toString();
0162         if (!notifyRcName.isEmpty() && m_whitelistedNotifyRcNames.contains(notifyRcName)) {
0163             return true;
0164         }
0165     }
0166 
0167     const bool userActionFeedback = sourceIdx.data(Notifications::UserActionFeedbackRole).toBool();
0168     if (userActionFeedback) {
0169         return true;
0170     }
0171 
0172     bool ok;
0173     const auto urgency = static_cast<Notifications::Urgency>(sourceIdx.data(Notifications::UrgencyRole).toInt(&ok));
0174     if (ok) {
0175         if (!m_urgencies.testFlag(urgency)) {
0176             return false;
0177         }
0178     }
0179 
0180     return true;
0181 }