File indexing completed on 2024-04-14 04:51:49
0001 /** 0002 * SPDX-FileCopyrightText: 2015 Holger Kaelberer <holger.k@elberer.de> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "notifyingapplicationmodel.h" 0008 0009 #include <algorithm> 0010 0011 #include <QDebug> 0012 #include <QIcon> 0013 #include <QString> 0014 0015 #include <KLocalizedString> 0016 0017 // #include "modeltest.h" 0018 0019 NotifyingApplicationModel::NotifyingApplicationModel(QObject *parent) 0020 : QAbstractTableModel(parent) 0021 { 0022 } 0023 0024 QVector<NotifyingApplication> NotifyingApplicationModel::apps() 0025 { 0026 return m_apps; 0027 } 0028 0029 void NotifyingApplicationModel::appendApp(const NotifyingApplication &app) 0030 { 0031 if (app.name.isEmpty() || apps().contains(app)) 0032 return; 0033 beginInsertRows(QModelIndex(), m_apps.size(), m_apps.size()); 0034 m_apps.append(app); 0035 endInsertRows(); 0036 } 0037 0038 bool NotifyingApplicationModel::containsApp(const QString &name) const 0039 { 0040 for (const auto &a : m_apps) 0041 if (a.name == name) 0042 return true; 0043 return false; 0044 } 0045 0046 Qt::ItemFlags NotifyingApplicationModel::flags(const QModelIndex &index) const 0047 { 0048 Qt::ItemFlags flags = Qt::ItemIsEnabled; 0049 if (index.isValid() && index.row() >= 0 && index.row() < m_apps.size() && index.column() < 3) { 0050 if (index.column() == 0) 0051 flags |= Qt::ItemIsEditable | Qt::ItemIsUserCheckable; 0052 else if (index.column() == 2) { 0053 if (m_apps[index.row()].active) 0054 flags |= Qt::ItemIsEditable; 0055 else 0056 flags ^= Qt::ItemIsEnabled; 0057 } else if (index.column() == 1) { 0058 if (!m_apps[index.row()].active) 0059 flags ^= Qt::ItemIsEnabled; 0060 } 0061 } 0062 return flags; 0063 } 0064 0065 void NotifyingApplicationModel::clearApplications() 0066 { 0067 if (!m_apps.isEmpty()) { 0068 beginRemoveRows(QModelIndex(), 0, m_apps.size() - 1); 0069 m_apps.clear(); 0070 endRemoveRows(); 0071 } 0072 } 0073 0074 QVariant NotifyingApplicationModel::data(const QModelIndex &index, int role) const 0075 { 0076 if (!index.isValid() || index.row() < 0 || index.row() >= m_apps.size() || index.column() > 3) { 0077 return QVariant(); 0078 } 0079 0080 switch (role) { 0081 case Qt::TextAlignmentRole: { 0082 if (index.column() == 0) 0083 return int(Qt::AlignCenter | Qt::AlignVCenter); 0084 else 0085 return int(Qt::AlignLeft | Qt::AlignVCenter); 0086 break; 0087 } 0088 case Qt::DisplayRole: { 0089 if (index.column() == 1) 0090 return m_apps[index.row()].name; 0091 else if (index.column() == 0) 0092 return QVariant(); // m_apps[index.row()].active; 0093 else if (index.column() == 2) 0094 return m_apps[index.row()].blacklistExpression.pattern(); 0095 else 0096 return QVariant(); 0097 break; 0098 } 0099 case Qt::DecorationRole: { 0100 if (index.column() == 1) 0101 return QIcon::fromTheme(m_apps[index.row()].icon, QIcon::fromTheme(QStringLiteral("application-x-executable"))); 0102 else 0103 return QVariant(); 0104 break; 0105 } 0106 case Qt::EditRole: { 0107 if (index.column() == 0) 0108 return m_apps[index.row()].active ? Qt::Checked : Qt::Unchecked; 0109 else if (index.column() == 2) 0110 return m_apps[index.row()].blacklistExpression.pattern(); 0111 else 0112 return QVariant(); 0113 break; 0114 } 0115 case Qt::CheckStateRole: { 0116 if (index.column() == 0) 0117 return m_apps[index.row()].active ? Qt::Checked : Qt::Unchecked; 0118 else 0119 return QVariant(); 0120 break; 0121 } 0122 } 0123 return QVariant(); 0124 } 0125 0126 bool NotifyingApplicationModel::setData(const QModelIndex &index, const QVariant &value, int role) 0127 { 0128 if (!index.isValid() || (index.column() != 0 && index.column() != 2) || index.row() < 0 || index.row() >= m_apps.size()) 0129 return false; 0130 0131 bool res = false; 0132 QModelIndex bottomRight = createIndex(index.row(), index.column()); 0133 switch (role) { 0134 case Qt::CheckStateRole: { 0135 if (index.column() == 0) { 0136 m_apps[index.row()].active = ((Qt::CheckState)value.toInt() == Qt::Checked); 0137 bottomRight = createIndex(index.row(), index.column() + 1); 0138 res = true; 0139 } 0140 break; 0141 } 0142 case Qt::EditRole: { 0143 if (index.column() == 2) { 0144 m_apps[index.row()].blacklistExpression.setPattern(value.toString()); 0145 res = true; 0146 } 0147 } 0148 } 0149 if (res) { 0150 Q_EMIT dataChanged(index, bottomRight); 0151 Q_EMIT applicationsChanged(); // -> notify config that we need to save 0152 } 0153 return res; 0154 } 0155 0156 void NotifyingApplicationModel::sort(int column, Qt::SortOrder order) 0157 { 0158 if (column != 1) 0159 return; 0160 0161 if (order == Qt::AscendingOrder) 0162 std::sort(m_apps.begin(), m_apps.end(), [](const NotifyingApplication &a, const NotifyingApplication &b) { 0163 return (a.name.compare(b.name, Qt::CaseInsensitive) < 1); 0164 }); 0165 else 0166 std::sort(m_apps.begin(), m_apps.end(), [](const NotifyingApplication &a, const NotifyingApplication &b) { 0167 return (b.name.compare(a.name, Qt::CaseInsensitive) < 1); 0168 }); 0169 Q_EMIT dataChanged(createIndex(0, 0), createIndex(m_apps.size(), 2)); 0170 } 0171 0172 QVariant NotifyingApplicationModel::headerData(int section, Qt::Orientation /*orientation*/, int role) const 0173 { 0174 switch (role) { 0175 case Qt::DisplayRole: { 0176 if (section == 1) 0177 return i18n("Name"); 0178 else if (section == 0) 0179 return QVariant(); // i18n("Sync"); 0180 else 0181 return i18n("Blacklisted"); 0182 } 0183 case Qt::ToolTipRole: { 0184 if (section == 1) 0185 return i18n("Name of a notifying application."); 0186 else if (section == 0) 0187 return i18n("Synchronize notifications of an application?"); 0188 else 0189 return i18n( 0190 "Regular expression defining which notifications should not be sent.\nThis pattern is applied to the summary and, if selected above, the body " 0191 "of notifications."); 0192 } 0193 } 0194 return QVariant(); 0195 } 0196 0197 int NotifyingApplicationModel::columnCount(const QModelIndex &) const 0198 { 0199 return 3; 0200 } 0201 0202 int NotifyingApplicationModel::rowCount(const QModelIndex &parent) const 0203 { 0204 if (parent.isValid()) { 0205 // Return size 0 if we are a child because this is not a tree 0206 return 0; 0207 } 0208 return m_apps.size(); 0209 } 0210 0211 #include "moc_notifyingapplicationmodel.cpp"