1 /* 2 SPDX-FileCopyrightText: 2019 Kai Uwe Broulik <kde@privat.broulik.de> 3 4 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 */ 6 7 #include "notificationfilterproxymodel_p.h" 8 9 using namespace NotificationManager; 10 NotificationFilterProxyModel(QObject * parent)11NotificationFilterProxyModel::NotificationFilterProxyModel(QObject *parent) 12 : QSortFilterProxyModel(parent) 13 { 14 setRecursiveFilteringEnabled(true); 15 } 16 17 NotificationFilterProxyModel::~NotificationFilterProxyModel() = default; 18 urgencies() const19Notifications::Urgencies NotificationFilterProxyModel::urgencies() const 20 { 21 return m_urgencies; 22 } 23 setUrgencies(Notifications::Urgencies urgencies)24void NotificationFilterProxyModel::setUrgencies(Notifications::Urgencies urgencies) 25 { 26 if (m_urgencies != urgencies) { 27 m_urgencies = urgencies; 28 invalidateFilter(); 29 emit urgenciesChanged(); 30 } 31 } 32 showExpired() const33bool NotificationFilterProxyModel::showExpired() const 34 { 35 return m_showExpired; 36 } 37 setShowExpired(bool show)38void NotificationFilterProxyModel::setShowExpired(bool show) 39 { 40 if (m_showExpired != show) { 41 m_showExpired = show; 42 invalidateFilter(); 43 emit showExpiredChanged(); 44 } 45 } 46 showDismissed() const47bool NotificationFilterProxyModel::showDismissed() const 48 { 49 return m_showDismissed; 50 } 51 setShowDismissed(bool show)52void NotificationFilterProxyModel::setShowDismissed(bool show) 53 { 54 if (m_showDismissed != show) { 55 m_showDismissed = show; 56 invalidateFilter(); 57 emit showDismissedChanged(); 58 } 59 } 60 blacklistedDesktopEntries() const61QStringList NotificationFilterProxyModel::blacklistedDesktopEntries() const 62 { 63 return m_blacklistedDesktopEntries; 64 } 65 setBlackListedDesktopEntries(const QStringList & blacklist)66void NotificationFilterProxyModel::setBlackListedDesktopEntries(const QStringList &blacklist) 67 { 68 if (m_blacklistedDesktopEntries != blacklist) { 69 m_blacklistedDesktopEntries = blacklist; 70 invalidateFilter(); 71 emit blacklistedDesktopEntriesChanged(); 72 } 73 } 74 blacklistedNotifyRcNames() const75QStringList NotificationFilterProxyModel::blacklistedNotifyRcNames() const 76 { 77 return m_blacklistedNotifyRcNames; 78 } 79 setBlacklistedNotifyRcNames(const QStringList & blacklist)80void NotificationFilterProxyModel::setBlacklistedNotifyRcNames(const QStringList &blacklist) 81 { 82 if (m_blacklistedNotifyRcNames != blacklist) { 83 m_blacklistedNotifyRcNames = blacklist; 84 invalidateFilter(); 85 emit blacklistedNotifyRcNamesChanged(); 86 } 87 } 88 whitelistedDesktopEntries() const89QStringList NotificationFilterProxyModel::whitelistedDesktopEntries() const 90 { 91 return m_whitelistedDesktopEntries; 92 } 93 setWhiteListedDesktopEntries(const QStringList & whitelist)94void NotificationFilterProxyModel::setWhiteListedDesktopEntries(const QStringList &whitelist) 95 { 96 if (m_whitelistedDesktopEntries != whitelist) { 97 m_whitelistedDesktopEntries = whitelist; 98 invalidateFilter(); 99 emit whitelistedDesktopEntriesChanged(); 100 } 101 } 102 whitelistedNotifyRcNames() const103QStringList NotificationFilterProxyModel::whitelistedNotifyRcNames() const 104 { 105 return m_whitelistedNotifyRcNames; 106 } 107 setWhitelistedNotifyRcNames(const QStringList & whitelist)108void NotificationFilterProxyModel::setWhitelistedNotifyRcNames(const QStringList &whitelist) 109 { 110 if (m_whitelistedNotifyRcNames != whitelist) { 111 m_whitelistedNotifyRcNames = whitelist; 112 invalidateFilter(); 113 emit whitelistedNotifyRcNamesChanged(); 114 } 115 } 116 filterAcceptsRow(int source_row,const QModelIndex & source_parent) const117bool NotificationFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const 118 { 119 const QModelIndex sourceIdx = sourceModel()->index(source_row, 0, source_parent); 120 121 const bool expired = sourceIdx.data(Notifications::ExpiredRole).toBool(); 122 if (!m_showExpired && expired) { 123 return false; 124 } 125 126 if (!m_showDismissed && sourceIdx.data(Notifications::DismissedRole).toBool()) { 127 return false; 128 } 129 130 QString desktopEntry = sourceIdx.data(Notifications::DesktopEntryRole).toString(); 131 if (desktopEntry.isEmpty()) { 132 // For non-configurable notifications use the fake "@other" category. 133 if (!sourceIdx.data(Notifications::ConfigurableRole).toBool() 134 // jobs are never configurable so this only applies to notifications 135 && sourceIdx.data(Notifications::TypeRole).toInt() == Notifications::NotificationType) { 136 desktopEntry = QStringLiteral("@other"); 137 } 138 } 139 140 // Blacklist takes precedence over whitelist, i.e. when in doubt don't show 141 if (!m_blacklistedDesktopEntries.isEmpty()) { 142 if (!desktopEntry.isEmpty() && m_blacklistedDesktopEntries.contains(desktopEntry)) { 143 return false; 144 } 145 } 146 147 if (!m_blacklistedNotifyRcNames.isEmpty()) { 148 const QString notifyRcName = sourceIdx.data(Notifications::NotifyRcNameRole).toString(); 149 if (!notifyRcName.isEmpty() && m_blacklistedNotifyRcNames.contains(notifyRcName)) { 150 return false; 151 } 152 } 153 154 if (!m_whitelistedDesktopEntries.isEmpty()) { 155 if (!desktopEntry.isEmpty() && m_whitelistedDesktopEntries.contains(desktopEntry)) { 156 return true; 157 } 158 } 159 160 if (!m_whitelistedNotifyRcNames.isEmpty()) { 161 const QString notifyRcName = sourceIdx.data(Notifications::NotifyRcNameRole).toString(); 162 if (!notifyRcName.isEmpty() && m_whitelistedNotifyRcNames.contains(notifyRcName)) { 163 return true; 164 } 165 } 166 167 const bool userActionFeedback = sourceIdx.data(Notifications::UserActionFeedbackRole).toBool(); 168 if (userActionFeedback) { 169 return true; 170 } 171 172 bool ok; 173 const auto urgency = static_cast<Notifications::Urgency>(sourceIdx.data(Notifications::UrgencyRole).toInt(&ok)); 174 if (ok) { 175 if (!m_urgencies.testFlag(urgency)) { 176 return false; 177 } 178 } 179 180 return true; 181 } 182