Commit 5b940a87 authored by Méven Car's avatar Méven Car
Browse files

Remove PrivacyTab from the Activities Kcm

parent ee931882
Pipeline #208204 passed with stage
in 3 minutes and 7 seconds
/*
SPDX-FileCopyrightText: 2012-2016 Ivan Cukic <ivan.cukic@kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#include "BlacklistedApplicationsModel.h"
#include <QDebug>
#include <QList>
#include <QScopeGuard>
#include <QSet>
#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
#include <QVariant>
#include <KService>
#include "kactivitymanagerd_plugins_settings.h"
#include <utils/d_ptr_implementation.h>
#include "definitions.h"
class BlacklistedApplicationsModel::Private
{
public:
struct ApplicationData {
QString name;
QString title;
QString icon;
bool blocked;
};
QList<ApplicationData> applications;
KActivityManagerdPluginsSettings *pluginConfig;
bool enabled;
};
BlacklistedApplicationsModel::BlacklistedApplicationsModel(QObject *parent)
: QAbstractListModel(parent)
{
d->enabled = false;
d->pluginConfig = new KActivityManagerdPluginsSettings;
}
BlacklistedApplicationsModel::~BlacklistedApplicationsModel()
{
}
QHash<int, QByteArray> BlacklistedApplicationsModel::roleNames() const
{
return {{ApplicationIdRole, "name"}, {Qt::DecorationRole, "icon"}, {Qt::DisplayRole, "title"}, {BlockedApplicationRole, "blocked"}};
}
void BlacklistedApplicationsModel::load()
{
QSqlDatabase database;
const QString path = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/kactivitymanagerd/resources/database");
database = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), QStringLiteral("plugins_sqlite_db_resources"));
database.setDatabaseName(path);
auto databaseRemove = qScopeGuard([&] {
QSqlDatabase::removeDatabase(database.connectionName());
});
// Loading plugin configuration
d->pluginConfig->load();
const auto defaultBlockedValue = d->pluginConfig->defaultBlockedByDefaultValue();
const auto &blockedAppList = d->pluginConfig->blockedApplications();
auto blockedApplications = QSet<QString>(blockedAppList.cbegin(), blockedAppList.cend());
const auto &allowedAppList = d->pluginConfig->allowedApplications();
auto allowedApplications = QSet<QString>(allowedAppList.cbegin(), allowedAppList.cend());
// Reading new applications from the database
if (!database.open()) {
// qDebug() << "Failed to open the database" << path << d->database.lastError();
return;
}
auto query = database.exec(QStringLiteral("SELECT DISTINCT(initiatingAgent) FROM ResourceScoreCache ORDER BY initiatingAgent"));
if (d->applications.length() > 0) {
beginRemoveRows(QModelIndex(), 0, d->applications.length() - 1);
d->applications.clear();
endRemoveRows();
}
while (query.next()) {
const auto name = query.value(0).toString();
if (defaultBlockedValue) {
if (!allowedApplications.contains(name)) {
blockedApplications << name;
}
} else {
if (!blockedApplications.contains(name)) {
allowedApplications << name;
}
}
}
QStringList applications = (blockedApplications + allowedApplications).values();
if (applications.length() > 0) {
std::sort(applications.begin(), applications.end());
beginInsertRows(QModelIndex(), 0, applications.length() - 1);
for (const auto &name : std::as_const(applications)) {
const auto service = KService::serviceByDesktopName(name);
const auto blocked = blockedApplications.contains(name);
if (service) {
d->applications << Private::ApplicationData{name, service->name(), service->icon(), blocked};
} else {
d->applications << Private::ApplicationData{name, name, QString(), blocked};
}
}
endInsertRows();
}
}
void BlacklistedApplicationsModel::save()
{
d->pluginConfig->save();
Q_EMIT changed(false);
}
void BlacklistedApplicationsModel::defaults()
{
for (int i = 0; i < rowCount(); i++) {
d->applications[i].blocked = false;
}
Q_EMIT dataChanged(QAbstractListModel::index(0), QAbstractListModel::index(rowCount() - 1));
Q_EMIT defaulted(true);
}
void BlacklistedApplicationsModel::toggleApplicationBlocked(int index)
{
if (index > rowCount()) {
return;
}
d->applications[index].blocked = !d->applications[index].blocked;
Q_EMIT dataChanged(QAbstractListModel::index(index), QAbstractListModel::index(index));
QStringList blockedApplications;
QStringList allowedApplications;
for (int i = 0; i < rowCount(); i++) {
const auto name = d->applications[i].name;
if (d->applications[i].blocked) {
blockedApplications << name;
} else {
allowedApplications << name;
}
}
d->pluginConfig->setBlockedApplications(blockedApplications);
d->pluginConfig->setAllowedApplications(allowedApplications);
const auto allowedApplicationsItem = d->pluginConfig->findItem("allowedApplications");
Q_ASSERT(allowedApplicationsItem);
const auto blockedApplicationsItem = d->pluginConfig->findItem("allowedApplications");
Q_ASSERT(blockedApplicationsItem);
Q_EMIT changed(blockedApplicationsItem->isSaveNeeded() && allowedApplicationsItem->isSaveNeeded());
Q_EMIT defaulted(blockedApplicationsItem->isDefault() && allowedApplicationsItem->isDefault());
}
QVariant BlacklistedApplicationsModel::headerData(int section, Qt::Orientation orientation, int role) const
{
Q_UNUSED(section)
Q_UNUSED(orientation)
Q_UNUSED(role)
return QVariant();
}
QVariant BlacklistedApplicationsModel::data(const QModelIndex &modelIndex, int role) const
{
const auto index = modelIndex.row();
if (index > rowCount()) {
return QVariant();
}
const auto &application = d->applications[index];
switch (role) {
default:
return QVariant();
case ApplicationIdRole:
return application.name;
case Qt::DisplayRole:
return application.title;
case Qt::DecorationRole:
return application.icon.isEmpty() ? QStringLiteral("application-x-executable") : application.icon;
case BlockedApplicationRole:
return application.blocked;
}
}
int BlacklistedApplicationsModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return d->applications.size();
}
bool BlacklistedApplicationsModel::enabled() const
{
return d->enabled;
}
void BlacklistedApplicationsModel::setEnabled(bool enabled)
{
d->enabled = enabled;
Q_EMIT enabledChanged(enabled);
}
// #include <BlacklistedApplicationsModel.moc>
......@@ -29,16 +29,13 @@ set (KAMD_KCM_SRCS
MainConfigurationWidget.cpp
ActivitiesTab.cpp
SwitchingTab.cpp
PrivacyTab.cpp
BlacklistedApplicationsModel.cpp
ExtraActivitiesInterface.cpp
)
ki18n_wrap_ui (
KAMD_KCM_SRCS
ui/MainConfigurationWidgetBase.ui
ui/PrivacyTabBase.ui
ui/SwitchingTabBase.ui
)
......@@ -100,7 +97,6 @@ install (
DIRECTORY
qml/activitiesTab
qml/privacyTab
DESTINATION ${KAMD_KCM_DATADIR}/qml
)
......
......@@ -11,7 +11,6 @@
#include "ui_MainConfigurationWidgetBase.h"
#include "ActivitiesTab.h"
#include "PrivacyTab.h"
#include "SwitchingTab.h"
#include "kactivitiesdata.h"
......@@ -22,7 +21,6 @@ class MainConfigurationWidget::Private : public Ui::MainConfigurationWidgetBase
public:
ActivitiesTab *tabActivities;
SwitchingTab *tabSwitching;
PrivacyTab *tabPrivacy;
};
MainConfigurationWidget::MainConfigurationWidget(QWidget *parent, QVariantList args)
......@@ -33,13 +31,8 @@ MainConfigurationWidget::MainConfigurationWidget(QWidget *parent, QVariantList a
d->tabs->insertTab(0, d->tabActivities = new ActivitiesTab(d->tabs), i18n("Activities"));
d->tabs->insertTab(1, d->tabSwitching = new SwitchingTab(d->tabs), i18n("Switching"));
d->tabs->insertTab(2, d->tabPrivacy = new PrivacyTab(d->tabs), i18n("Privacy"));
addConfig(d->tabPrivacy->pluginConfig(), d->tabPrivacy);
addConfig(d->tabSwitching->mainConfig(), d->tabSwitching);
connect(d->tabPrivacy, &PrivacyTab::blackListModelChanged, this, &MainConfigurationWidget::unmanagedWidgetChangeState);
connect(d->tabPrivacy, &PrivacyTab::blackListModelDefaulted, this, &MainConfigurationWidget::unmanagedWidgetDefaultState);
}
MainConfigurationWidget::~MainConfigurationWidget()
......@@ -49,22 +42,16 @@ MainConfigurationWidget::~MainConfigurationWidget()
void MainConfigurationWidget::defaults()
{
KCModule::defaults();
d->tabPrivacy->defaults();
}
void MainConfigurationWidget::load()
{
KCModule::load();
d->tabPrivacy->load();
}
void MainConfigurationWidget::save()
{
KCModule::save();
d->tabPrivacy->save();
}
#include "MainConfigurationWidget.moc"
/*
SPDX-FileCopyrightText: 2012-2016 Ivan Cukic <ivan.cukic@kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#include "PrivacyTab.h"
#include "kactivitymanagerd_plugins_settings.h"
#include "kactivitymanagerd_settings.h"
#include "resourcescoring_interface.h"
#include <QDBusConnection>
#include <QDBusPendingCall>
#include <QMenu>
#include <QQmlComponent>
#include <QQmlContext>
#include <QQmlEngine>
#include <QQuickWidget>
#include <KConfigGroup>
#include <KMessageWidget>
#include <KSharedConfig>
#include "BlacklistedApplicationsModel.h"
#include "ui_PrivacyTabBase.h"
#include <utils/d_ptr_implementation.h>
#include "kactivities-kcm-features.h"
#include "common/dbus/common.h"
class PrivacyTab::Private : public Ui::PrivacyTabBase
{
public:
KActivityManagerdSettings *mainConfig;
KActivityManagerdPluginsSettings *pluginConfig;
BlacklistedApplicationsModel *blacklistedApplicationsModel;
Private(QObject *parent)
: mainConfig(new KActivityManagerdSettings(parent))
, pluginConfig(new KActivityManagerdPluginsSettings(parent))
{
}
};
KCoreConfigSkeleton *PrivacyTab::pluginConfig()
{
return d->pluginConfig;
}
PrivacyTab::PrivacyTab(QWidget *parent)
: QWidget(parent)
, d(this)
{
d->setupUi(this);
// Keep history initialization
d->kcfg_keepHistoryFor->setRange(0, INT_MAX);
d->kcfg_keepHistoryFor->setSpecialValueText(i18nc("unlimited number of months", "Forever"));
connect(d->kcfg_keepHistoryFor, SIGNAL(valueChanged(int)), this, SLOT(spinKeepHistoryValueChanged(int)));
spinKeepHistoryValueChanged(0);
// Clear recent history button
auto menu = new QMenu(this);
connect(menu->addAction(i18n("Forget the last hour")), &QAction::triggered, this, &PrivacyTab::forgetLastHour);
connect(menu->addAction(i18n("Forget the last two hours")), &QAction::triggered, this, &PrivacyTab::forgetTwoHours);
connect(menu->addAction(i18n("Forget a day")), &QAction::triggered, this, &PrivacyTab::forgetDay);
connect(menu->addAction(i18n("Forget everything")), &QAction::triggered, this, &PrivacyTab::forgetAll);
d->buttonClearRecentHistory->setMenu(menu);
// Blacklist applications
d->blacklistedApplicationsModel = new BlacklistedApplicationsModel(this);
connect(d->blacklistedApplicationsModel, &BlacklistedApplicationsModel::changed, this, &PrivacyTab::blackListModelChanged);
connect(d->blacklistedApplicationsModel, &BlacklistedApplicationsModel::defaulted, this, &PrivacyTab::blackListModelDefaulted);
d->viewBlacklistedApplications->setClearColor(QGuiApplication::palette().window().color());
d->viewBlacklistedApplications->rootContext()->setContextProperty(QStringLiteral("applicationModel"), d->blacklistedApplicationsModel);
d->viewBlacklistedApplications->setSource(QUrl::fromLocalFile(KAMD_KCM_DATADIR + QStringLiteral("/qml/privacyTab/BlacklistApplicationView.qml")));
// React to changes
connect(d->radioRememberSpecificApplications, &QAbstractButton::toggled, d->blacklistedApplicationsModel, &BlacklistedApplicationsModel::setEnabled);
d->blacklistedApplicationsModel->setEnabled(false);
d->messageWidget->setVisible(false);
}
PrivacyTab::~PrivacyTab()
{
}
void PrivacyTab::defaults()
{
d->blacklistedApplicationsModel->defaults();
}
void PrivacyTab::load()
{
d->blacklistedApplicationsModel->load();
}
void PrivacyTab::save()
{
d->blacklistedApplicationsModel->save();
// clang-format off
const auto whatToRemember =
d->radioRememberSpecificApplications->isChecked() ? SpecificApplications :
d->radioDontRememberApplications->isChecked() ? NoApplications :
/* otherwise */ AllApplications;
// clang-format on
d->mainConfig->setResourceScoringEnabled(whatToRemember != NoApplications);
d->mainConfig->save();
}
void PrivacyTab::forget(int count, const QString &what)
{
org::kde::ActivityManager::ResourcesScoring rankingsservice(QStringLiteral(KAMD_DBUS_SERVICE),
QStringLiteral(KAMD_DBUS_RESOURCES_SCORING_PATH),
QDBusConnection::sessionBus());
rankingsservice.DeleteRecentStats(QString(), count, what);
d->messageWidget->animatedShow();
}
void PrivacyTab::forgetLastHour()
{
forget(1, QStringLiteral("h"));
}
void PrivacyTab::forgetTwoHours()
{
forget(2, QStringLiteral("h"));
}
void PrivacyTab::forgetDay()
{
forget(1, QStringLiteral("d"));
}
void PrivacyTab::forgetAll()
{
forget(0, QStringLiteral("everything"));
}
void PrivacyTab::spinKeepHistoryValueChanged(int value)
{
static auto months = ki18ncp("unit of time. months to keep the history", " month", " months");
if (value) {
d->kcfg_keepHistoryFor->setPrefix(i18nc("for in 'keep history for 5 months'", "For "));
d->kcfg_keepHistoryFor->setSuffix(months.subs(value).toString());
}
}
/*
SPDX-FileCopyrightText: 2012-2016 Ivan Cukic <ivan.cukic@kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#ifndef PRIVACY_TAB_H
#define PRIVACY_TAB_H
#include <QWidget>
#include <utils/d_ptr.h>
class KCoreConfigSkeleton;
/**
* PrivacyTab
*/
class PrivacyTab : public QWidget
{
Q_OBJECT
public:
explicit PrivacyTab(QWidget *parent);
~PrivacyTab() override;
KCoreConfigSkeleton *pluginConfig();
public Q_SLOTS:
void defaults();
void load();
void save();
private Q_SLOTS:
void forget(int count, const QString &what);
void forgetLastHour();
void forgetTwoHours();
void forgetDay();
void forgetAll();
void spinKeepHistoryValueChanged(int value);
Q_SIGNALS:
void blackListModelChanged(bool changed);
void blackListModelDefaulted(bool isDefault);
private:
enum WhatToRemember {
AllApplications = 0,
SpecificApplications = 1,
NoApplications = 2,
};
D_PTR;
};
#endif // PRIVACY_TAB_H
/* vim:set foldenable foldmethod=marker:
SPDX-FileCopyrightText: 2012 Ivan Cukic <ivan.cukic@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
import QtQuick 2.5
import QtQuick.Controls 2.5 as QQC2
import org.kde.kirigami 2.5 as Kirigami
QQC2.ScrollView {
enabled: applicationModel.enabled
Component.onCompleted: background.visible = true;
GridView {
id: gridView
clip: true
cellHeight: Kirigami.Units.gridUnit * 5
cellWidth: Kirigami.Units.gridUnit * 9
model: applicationModel
delegate: Item {
height: gridView.cellHeight
width: gridView.cellWidth
Rectangle {
anchors.fill: parent
visible: mouseArea.containsMouse
color: Kirigami.Theme.hoverColor
}
Kirigami.Icon {
id: icon
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.verticalCenter
height: Kirigami.Units.iconSizes.medium
width: height
source: model.icon
opacity: model.blocked ? 0.6 : 1.0
Behavior on opacity { NumberAnimation { duration: Kirigami.Units.shortDuration } }
}
Kirigami.Icon {
anchors.bottom: icon.bottom
anchors.right: icon.right
height: Kirigami.Units.iconSizes.small
width: height
source: "emblem-unavailable"
opacity: model.blocked ? 1.0 : 0.0
Behavior on opacity { NumberAnimation { duration: Kirigami.Units.shortDuration } }
}
QQC2.Label {
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.verticalCenter
width: parent.width - 20
text: model.title
horizontalAlignment: Text.AlignHCenter
elide: Text.ElideRight
maximumLineCount: 2
wrapMode: Text.Wrap
opacity: model.blocked ? 0.6 : 1.0
Behavior on opacity { NumberAnimation { duration: Kirigami.Units.shortDuration } }
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: applicationModel.toggleApplicationBlocked(model.index)
}
}