File indexing completed on 2024-05-12 05:35:49
0001 /* 0002 SPDX-FileCopyrightText: 2012-2016 Ivan Cukic <ivan.cukic@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "BlacklistedApplicationsModel.h" 0008 0009 #include <QDebug> 0010 #include <QList> 0011 #include <QScopeGuard> 0012 #include <QSet> 0013 #include <QSqlDatabase> 0014 #include <QSqlError> 0015 #include <QSqlQuery> 0016 #include <QVariant> 0017 0018 #include <KService> 0019 0020 #include "kactivitymanagerd_plugins_settings.h" 0021 0022 #include <utils/d_ptr_implementation.h> 0023 0024 #include "definitions.h" 0025 0026 class BlacklistedApplicationsModel::Private 0027 { 0028 public: 0029 struct ApplicationData { 0030 QString name; 0031 QString title; 0032 QString icon; 0033 bool blocked; 0034 }; 0035 0036 QList<ApplicationData> applications; 0037 0038 KActivityManagerdPluginsSettings *pluginConfig; 0039 bool enabled; 0040 }; 0041 0042 BlacklistedApplicationsModel::BlacklistedApplicationsModel(QObject *parent) 0043 : QAbstractListModel(parent) 0044 { 0045 d->enabled = false; 0046 d->pluginConfig = new KActivityManagerdPluginsSettings; 0047 } 0048 0049 BlacklistedApplicationsModel::~BlacklistedApplicationsModel() 0050 { 0051 } 0052 0053 QHash<int, QByteArray> BlacklistedApplicationsModel::roleNames() const 0054 { 0055 return {{ApplicationIdRole, "name"}, {Qt::DecorationRole, "icon"}, {Qt::DisplayRole, "title"}, {BlockedApplicationRole, "blocked"}}; 0056 } 0057 0058 void BlacklistedApplicationsModel::load() 0059 { 0060 QSqlDatabase database; 0061 0062 const QString path = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/kactivitymanagerd/resources/database"); 0063 database = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), QStringLiteral("plugins_sqlite_db_resources")); 0064 database.setDatabaseName(path); 0065 auto databaseRemove = qScopeGuard([&] { 0066 QSqlDatabase::removeDatabase(database.connectionName()); 0067 }); 0068 0069 // Loading plugin configuration 0070 d->pluginConfig->load(); 0071 const auto defaultBlockedValue = d->pluginConfig->defaultBlockedByDefaultValue(); 0072 const auto &blockedAppList = d->pluginConfig->blockedApplications(); 0073 auto blockedApplications = QSet<QString>(blockedAppList.cbegin(), blockedAppList.cend()); 0074 const auto &allowedAppList = d->pluginConfig->allowedApplications(); 0075 auto allowedApplications = QSet<QString>(allowedAppList.cbegin(), allowedAppList.cend()); 0076 0077 // Reading new applications from the database 0078 0079 if (!database.open()) { 0080 // qDebug() << "Failed to open the database" << path << d->database.lastError(); 0081 return; 0082 } 0083 0084 auto query = database.exec(QStringLiteral("SELECT DISTINCT(initiatingAgent) FROM ResourceScoreCache ORDER BY initiatingAgent")); 0085 0086 if (d->applications.length() > 0) { 0087 beginRemoveRows(QModelIndex(), 0, d->applications.length() - 1); 0088 d->applications.clear(); 0089 endRemoveRows(); 0090 } 0091 0092 while (query.next()) { 0093 const auto name = query.value(0).toString(); 0094 0095 if (defaultBlockedValue) { 0096 if (!allowedApplications.contains(name)) { 0097 blockedApplications << name; 0098 } 0099 } else { 0100 if (!blockedApplications.contains(name)) { 0101 allowedApplications << name; 0102 } 0103 } 0104 } 0105 0106 QStringList applications = (blockedApplications + allowedApplications).values(); 0107 0108 if (applications.length() > 0) { 0109 std::sort(applications.begin(), applications.end()); 0110 0111 beginInsertRows(QModelIndex(), 0, applications.length() - 1); 0112 0113 for (const auto &name : std::as_const(applications)) { 0114 const auto service = KService::serviceByDesktopName(name); 0115 const auto blocked = blockedApplications.contains(name); 0116 0117 if (service) { 0118 d->applications << Private::ApplicationData{name, service->name(), service->icon(), blocked}; 0119 } else { 0120 d->applications << Private::ApplicationData{name, name, QString(), blocked}; 0121 } 0122 } 0123 0124 endInsertRows(); 0125 } 0126 } 0127 0128 void BlacklistedApplicationsModel::save() 0129 { 0130 d->pluginConfig->save(); 0131 Q_EMIT changed(false); 0132 } 0133 0134 void BlacklistedApplicationsModel::defaults() 0135 { 0136 for (int i = 0; i < rowCount(); i++) { 0137 d->applications[i].blocked = false; 0138 } 0139 0140 Q_EMIT dataChanged(QAbstractListModel::index(0), QAbstractListModel::index(rowCount() - 1)); 0141 0142 Q_EMIT defaulted(true); 0143 } 0144 0145 void BlacklistedApplicationsModel::toggleApplicationBlocked(int index) 0146 { 0147 if (index > rowCount()) { 0148 return; 0149 } 0150 0151 d->applications[index].blocked = !d->applications[index].blocked; 0152 Q_EMIT dataChanged(QAbstractListModel::index(index), QAbstractListModel::index(index)); 0153 0154 QStringList blockedApplications; 0155 QStringList allowedApplications; 0156 0157 for (int i = 0; i < rowCount(); i++) { 0158 const auto name = d->applications[i].name; 0159 if (d->applications[i].blocked) { 0160 blockedApplications << name; 0161 } else { 0162 allowedApplications << name; 0163 } 0164 } 0165 0166 d->pluginConfig->setBlockedApplications(blockedApplications); 0167 d->pluginConfig->setAllowedApplications(allowedApplications); 0168 0169 const auto allowedApplicationsItem = d->pluginConfig->findItem("allowedApplications"); 0170 Q_ASSERT(allowedApplicationsItem); 0171 const auto blockedApplicationsItem = d->pluginConfig->findItem("allowedApplications"); 0172 Q_ASSERT(blockedApplicationsItem); 0173 0174 Q_EMIT changed(blockedApplicationsItem->isSaveNeeded() && allowedApplicationsItem->isSaveNeeded()); 0175 Q_EMIT defaulted(blockedApplicationsItem->isDefault() && allowedApplicationsItem->isDefault()); 0176 } 0177 0178 QVariant BlacklistedApplicationsModel::headerData(int section, Qt::Orientation orientation, int role) const 0179 { 0180 Q_UNUSED(section) 0181 Q_UNUSED(orientation) 0182 Q_UNUSED(role) 0183 return QVariant(); 0184 } 0185 0186 QVariant BlacklistedApplicationsModel::data(const QModelIndex &modelIndex, int role) const 0187 { 0188 const auto index = modelIndex.row(); 0189 0190 if (index > rowCount()) { 0191 return QVariant(); 0192 } 0193 0194 const auto &application = d->applications[index]; 0195 0196 switch (role) { 0197 default: 0198 return QVariant(); 0199 0200 case ApplicationIdRole: 0201 return application.name; 0202 0203 case Qt::DisplayRole: 0204 return application.title; 0205 0206 case Qt::DecorationRole: 0207 return application.icon.isEmpty() ? QStringLiteral("application-x-executable") : application.icon; 0208 0209 case BlockedApplicationRole: 0210 return application.blocked; 0211 } 0212 } 0213 0214 int BlacklistedApplicationsModel::rowCount(const QModelIndex &parent) const 0215 { 0216 Q_UNUSED(parent) 0217 return d->applications.size(); 0218 } 0219 0220 bool BlacklistedApplicationsModel::enabled() const 0221 { 0222 return d->enabled; 0223 } 0224 0225 void BlacklistedApplicationsModel::setEnabled(bool enabled) 0226 { 0227 d->enabled = enabled; 0228 Q_EMIT enabledChanged(enabled); 0229 } 0230 0231 // #include <BlacklistedApplicationsModel.moc>