diff --git a/kcms/recentFiles/CMakeLists.txt b/kcms/recentFiles/CMakeLists.txt index 8c245e6819..fe361e414b 100644 --- a/kcms/recentFiles/CMakeLists.txt +++ b/kcms/recentFiles/CMakeLists.txt @@ -1,88 +1,35 @@ -# vim:set softtabstop=3 shiftwidth=3 tabstop=3 expandtab: +# SPDX-FileCopyrightText: 2026 James Graham +# SPDX-License-Identifier: BSD-2-Clause + add_definitions(-DTRANSLATION_DOMAIN=\"kcm_recentFiles\") -find_package (Qt6 REQUIRED NO_MODULE COMPONENTS Core Quick Sql Qml DBus) -find_package (KF6KCMUtils ${KF6_MIN_VERSION} CONFIG REQUIRED) -find_package (KF6XmlGui ${KF6_MIN_VERSION} CONFIG REQUIRED) -find_package (KF6GlobalAccel ${KF6_MIN_VERSION} CONFIG REQUIRED) -find_package (PlasmaActivities ${PROJECT_DEP_VERSION} CONFIG REQUIRED) - -set (KAMD_KCM_DATADIR - ${KDE_INSTALL_DATADIR}/kcm_recentFiles/workspace/settings/ - ) - -if (NOT IS_ABSOLUTE "${KDE_INSTALL_DATADIR}") - set (KAMD_KCM_DATADIR "${CMAKE_INSTALL_PREFIX}/${KAMD_KCM_DATADIR}") -endif () - -configure_file (recentFiles-kcm-features.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/recentFiles-kcm-features.h) - -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) - -set (KAMD_KCM_SRCS - kcm_recentFiles.cpp - - ExcludedApplicationsModel.cpp - ) - -ki18n_wrap_ui ( - KAMD_KCM_SRCS - ui/RecentFiles.ui - ) - -qt_add_dbus_interface ( - KAMD_KCM_SRCS - - common/dbus/org.kde.ActivityManager.ResourceScoring.xml - resourcescoring_interface - ) - - -kcmutils_generate_module_data( - KAMD_KCM_SRCS - MODULE_DATA_HEADER kactivitiesdata.h - MODULE_DATA_CLASS_NAME KActivitiesData - SETTINGS_HEADERS kactivitymanagerd_plugins_settings.h - SETTINGS_CLASSES KActivityManagerdPluginsSettings +kcmutils_add_qml_kcm(kcm_recentfiles + SOURCES + kcm_recentfiles.cpp + kcm_recentfiles.h + excludedapplicationsmodel.cpp + excludedapplicationsmodel.h ) -kconfig_add_kcfg_files(KAMD_KCM_SRCS kactivitymanagerd_plugins_settings.kcfgc GENERATE_MOC) +kconfig_add_kcfg_files(kcm_recentfiles kactivitymanagerd_plugins_settings.kcfgc GENERATE_MOC) -add_library (kcm_recentFiles MODULE ${KAMD_KCM_SRCS}) +ecm_qt_declare_logging_category(kcm_recentfiles + HEADER kcms_recentfiles_logging.h + IDENTIFIER KCM_RECENTFILES + CATEGORY_NAME kcm_recentFiles + DESCRIPTION "KCM for recent file usage tracking" + EXPORT KCM_RECENTFILES +) -kcmutils_generate_desktop_file(kcm_recentFiles) -target_link_libraries (kcm_recentFiles +qt_add_dbus_interface(kcm_recentfiles_DBUS_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/org.kde.ActivityManager.ResourceScoring.xml resourcescoring_interface) +target_sources(kcm_recentfiles PRIVATE ${kcm_recentfiles_DBUS_SRCS}) + +target_link_libraries (kcm_recentfiles Qt::Quick - Qt::QuickWidgets - Qt::Core - Qt::Sql - Qt::Qml Qt::DBus + Qt::Sql KF6::KCMUtils KF6::I18n KF6::Service - KF6::XmlGui Plasma::Activities - ) - -install ( - TARGETS kcm_recentFiles - DESTINATION ${KDE_INSTALL_PLUGINDIR}/plasma/kcms/systemsettings_qwidgets - ) - -install ( - DIRECTORY - - qml/recentFiles - - DESTINATION ${KAMD_KCM_DATADIR}/qml - ) - -install(FILES kactivitymanagerd_plugins_settings.kcfg DESTINATION ${KDE_INSTALL_KCFGDIR}) - -include(ECMQtDeclareLoggingCategory) -ecm_qt_declare_logging_category(kcm_recentFiles - HEADER kcms-recentfiles-debug.h - IDENTIFIER "LOG_KCMS_RECENTFILES" - CATEGORY_NAME "org.kde.kcms.recentFiles" ) diff --git a/kcms/recentFiles/common/dbus/common.h b/kcms/recentFiles/common/dbus/common.h deleted file mode 100644 index dc13843028..0000000000 --- a/kcms/recentFiles/common/dbus/common.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - SPDX-FileCopyrightText: 2010-2016 Ivan Cukic - - SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL -*/ - -// clang-format off - -#pragma once - -#define KAMD_DBUS_SERVICE "org.kde.ActivityManager" - -#define KAMD_DBUS_ACTIVITYMANAGER_PATH "/ActivityManager" - -#define KAMD_DBUS_FEATURES_PATH KAMD_DBUS_ACTIVITYMANAGER_PATH"/Features" - -#define KAMD_DBUS_RESOURCES_PATH KAMD_DBUS_ACTIVITYMANAGER_PATH"/Resources" -#define KAMD_DBUS_RESOURCES_SCORING_PATH KAMD_DBUS_RESOURCES_PATH"/Scoring" - diff --git a/kcms/recentFiles/ExcludedApplicationsModel.cpp b/kcms/recentFiles/excludedapplicationsmodel.cpp similarity index 58% rename from kcms/recentFiles/ExcludedApplicationsModel.cpp rename to kcms/recentFiles/excludedapplicationsmodel.cpp index 74b2241402..b8ae7b3949 100644 --- a/kcms/recentFiles/ExcludedApplicationsModel.cpp +++ b/kcms/recentFiles/excludedapplicationsmodel.cpp @@ -4,46 +4,21 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL */ -#include "ExcludedApplicationsModel.h" +#include "excludedapplicationsmodel.h" -#include -#include #include -#include #include #include #include -#include #include -#include "kactivitymanagerd_plugins_settings.h" - -#include - -#include "definitions.h" - -class ExcludedApplicationsModel::Private -{ -public: - struct ApplicationData { - QString name; - QString title; - QString icon; - bool blocked; - }; - - QList applications; - - KActivityManagerdPluginsSettings *pluginConfig; - bool enabled; -}; +using namespace Qt::StringLiterals; ExcludedApplicationsModel::ExcludedApplicationsModel(QObject *parent) : QAbstractListModel(parent) + , m_settings(new KActivityManagerdPluginsSettings(this)) { - d->enabled = false; - d->pluginConfig = new KActivityManagerdPluginsSettings; } ExcludedApplicationsModel::~ExcludedApplicationsModel() @@ -52,44 +27,40 @@ ExcludedApplicationsModel::~ExcludedApplicationsModel() QHash ExcludedApplicationsModel::roleNames() const { - return {{ApplicationIdRole, QByteArrayLiteral("name")}, - {Qt::DecorationRole, QByteArrayLiteral("icon")}, - {Qt::DisplayRole, QByteArrayLiteral("title")}, - {BlockedApplicationRole, QByteArrayLiteral("blocked")}}; + return {{ApplicationIdRole, "name"_ba}, {Qt::DecorationRole, "iconSource"_ba}, {Qt::DisplayRole, "title"_ba}, {BlockedApplicationRole, "blocked"_ba}}; } void ExcludedApplicationsModel::load() { QSqlDatabase database; - const QString path = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/kactivitymanagerd/resources/database"); - database = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), QStringLiteral("plugins_sqlite_db_resources")); + const QString path = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/kactivitymanagerd/resources/database"_L1; + database = QSqlDatabase::addDatabase("QSQLITE"_L1, "plugins_sqlite_db_resources"_L1); 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(); + m_settings->load(); + const auto defaultBlockedValue = m_settings->defaultBlockedByDefaultValue(); + const auto &blockedAppList = m_settings->blockedApplications(); auto blockedApplications = QSet(blockedAppList.cbegin(), blockedAppList.cend()); - const auto &allowedAppList = d->pluginConfig->allowedApplications(); + const auto &allowedAppList = m_settings->allowedApplications(); auto allowedApplications = QSet(allowedAppList.cbegin(), allowedAppList.cend()); // Reading new applications from the database - if (!database.open()) { // qDebug() << "Failed to open the database" << path << d->database.lastError(); return; } QSqlQuery query(database); - query.exec(QStringLiteral("SELECT DISTINCT(initiatingAgent) FROM ResourceScoreCache ORDER BY initiatingAgent")); + query.exec("SELECT DISTINCT(initiatingAgent) FROM ResourceScoreCache ORDER BY initiatingAgent"_L1); - if (d->applications.length() > 0) { - beginRemoveRows(QModelIndex(), 0, d->applications.length() - 1); - d->applications.clear(); + if (m_applications.length() > 0) { + beginRemoveRows(QModelIndex(), 0, m_applications.length() - 1); + m_applications.clear(); endRemoveRows(); } @@ -119,9 +90,9 @@ void ExcludedApplicationsModel::load() const auto blocked = blockedApplications.contains(name); if (service) { - d->applications << Private::ApplicationData{name, service->name(), service->icon(), blocked}; + m_applications << ApplicationData{name, service->name(), service->icon(), blocked}; } else { - d->applications << Private::ApplicationData{name, name, QString(), blocked}; + m_applications << ApplicationData{name, name, QString(), blocked}; } } @@ -131,14 +102,14 @@ void ExcludedApplicationsModel::load() void ExcludedApplicationsModel::save() { - d->pluginConfig->save(); + m_settings->save(); Q_EMIT changed(false); } void ExcludedApplicationsModel::defaults() { for (int i = 0; i < rowCount(); i++) { - d->applications[i].blocked = false; + m_applications[i].blocked = false; } Q_EMIT dataChanged(QAbstractListModel::index(0), QAbstractListModel::index(rowCount() - 1)); @@ -152,27 +123,27 @@ void ExcludedApplicationsModel::toggleApplicationBlocked(int index) return; } - d->applications[index].blocked = !d->applications[index].blocked; + m_applications[index].blocked = !m_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) { + const auto name = m_applications[i].name; + if (m_applications[i].blocked) { blockedApplications << name; } else { allowedApplications << name; } } - d->pluginConfig->setBlockedApplications(blockedApplications); - d->pluginConfig->setAllowedApplications(allowedApplications); + m_settings->setBlockedApplications(blockedApplications); + m_settings->setAllowedApplications(allowedApplications); - const auto allowedApplicationsItem = d->pluginConfig->findItem("allowedApplications"); + const auto allowedApplicationsItem = m_settings->findItem("allowedApplications"); Q_ASSERT(allowedApplicationsItem); - const auto blockedApplicationsItem = d->pluginConfig->findItem("allowedApplications"); + const auto blockedApplicationsItem = m_settings->findItem("allowedApplications"); Q_ASSERT(blockedApplicationsItem); Q_EMIT changed(blockedApplicationsItem->isSaveNeeded() && allowedApplicationsItem->isSaveNeeded()); @@ -195,7 +166,7 @@ QVariant ExcludedApplicationsModel::data(const QModelIndex &modelIndex, int role return QVariant(); } - const auto &application = d->applications[index]; + const auto &application = m_applications[index]; switch (role) { default: @@ -208,7 +179,7 @@ QVariant ExcludedApplicationsModel::data(const QModelIndex &modelIndex, int role return application.title; case Qt::DecorationRole: - return application.icon.isEmpty() ? QStringLiteral("application-x-executable") : application.icon; + return application.icon.isEmpty() ? "application-x-executable"_L1 : application.icon; case BlockedApplicationRole: return application.blocked; @@ -218,20 +189,7 @@ QVariant ExcludedApplicationsModel::data(const QModelIndex &modelIndex, int role int ExcludedApplicationsModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return d->applications.size(); + return m_applications.size(); } -bool ExcludedApplicationsModel::enabled() const -{ - return d->enabled; -} - -void ExcludedApplicationsModel::setEnabled(bool enabled) -{ - d->enabled = enabled; - Q_EMIT enabledChanged(enabled); -} - -// #include - -#include "moc_ExcludedApplicationsModel.cpp" +#include "moc_excludedapplicationsmodel.cpp" diff --git a/kcms/recentFiles/ExcludedApplicationsModel.h b/kcms/recentFiles/excludedapplicationsmodel.h similarity index 80% rename from kcms/recentFiles/ExcludedApplicationsModel.h rename to kcms/recentFiles/excludedapplicationsmodel.h index b61ef6167f..4123f39f92 100644 --- a/kcms/recentFiles/ExcludedApplicationsModel.h +++ b/kcms/recentFiles/excludedapplicationsmodel.h @@ -8,7 +8,7 @@ #include -#include +#include "kactivitymanagerd_plugins_settings.h" /** * ExcludedApplicationsModel @@ -17,8 +17,6 @@ class ExcludedApplicationsModel : public QAbstractListModel { Q_OBJECT - Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged) - public: explicit ExcludedApplicationsModel(QObject *parent = nullptr); ~ExcludedApplicationsModel() override; @@ -37,18 +35,22 @@ public: Q_SIGNALS: void changed(bool changed); void defaulted(bool isDefault); - void enabledChanged(bool enabled); public Q_SLOTS: void toggleApplicationBlocked(int index); - void setEnabled(bool); - bool enabled() const; - void load(); void save(); void defaults(); private: - D_PTR; + struct ApplicationData { + QString name; + QString title; + QString icon; + bool blocked; + }; + + QList m_applications; + KActivityManagerdPluginsSettings *m_settings; }; diff --git a/kcms/recentFiles/kcm_recentFiles.cpp b/kcms/recentFiles/kcm_recentFiles.cpp deleted file mode 100644 index 1db0985df6..0000000000 --- a/kcms/recentFiles/kcm_recentFiles.cpp +++ /dev/null @@ -1,231 +0,0 @@ -/* - SPDX-FileCopyrightText: 2012-2016 Ivan Cukic - SPDX-FileCopyrightText: 2022 Méven Car - - SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL -*/ -#include "kcm_recentFiles.h" -#include "kactivitymanagerd_plugins_settings.h" -#include "resourcescoring_interface.h" - -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include "ExcludedApplicationsModel.h" -#include "ui_RecentFiles.h" - -#include - -#include "recentFiles-kcm-features.h" - -#include "common/dbus/common.h" -#include "kactivitiesdata.h" -#include "kcms-recentfiles-debug.h" - -K_PLUGIN_FACTORY_WITH_JSON(KActivityManagerKCMFactory, "kcm_recentFiles.json", registerPlugin(); registerPlugin();) - -class RecentFilesKcm::Private : public Ui::RecentFiles -{ -public: - KActivityManagerdPluginsSettings *pluginConfig; - - ExcludedApplicationsModel *excludedApplicationsModel; - - explicit Private(QObject *parent) - : pluginConfig(new KActivityManagerdPluginsSettings(parent)) - , excludedApplicationsModel(new ExcludedApplicationsModel(parent)) - { - } - - void setDefaultIndicatorVisible(QWidget *widget, bool visible) - { - widget->setProperty("_kde_highlight_neutral", visible); - widget->update(); - } - - void updateUiDefaultIndicator(bool visible) - { - setDefaultIndicatorVisible(radioDontRememberApplications, visible && radioDontRememberApplications->isChecked()); - setDefaultIndicatorVisible(radioRememberSpecificApplications, visible && radioRememberSpecificApplications->isChecked()); - } -}; - -RecentFilesKcm::RecentFilesKcm(QObject *parent, const KPluginMetaData &data) - : KCModule(parent, data) - , d(this) -{ - d->setupUi(widget()); - - // 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(widget()); - - connect(menu->addAction(i18n("Forget the last hour")), &QAction::triggered, this, &RecentFilesKcm::forgetLastHour); - connect(menu->addAction(i18n("Forget the last two hours")), &QAction::triggered, this, &RecentFilesKcm::forgetTwoHours); - connect(menu->addAction(i18n("Forget a day")), &QAction::triggered, this, &RecentFilesKcm::forgetDay); - connect(menu->addAction(i18n("Forget everything")), &QAction::triggered, this, &RecentFilesKcm::forgetAll); - - d->buttonClearRecentHistory->setMenu(menu); - - // Excluded applications - - d->excludedApplicationsModel = new ExcludedApplicationsModel(this); - connect(d->excludedApplicationsModel, &ExcludedApplicationsModel::changed, this, &RecentFilesKcm::unmanagedWidgetChangeState); - connect(d->excludedApplicationsModel, &ExcludedApplicationsModel::defaulted, this, &RecentFilesKcm::unmanagedWidgetDefaultState); - - d->viewExcludeddApplications->setClearColor(QGuiApplication::palette().window().color()); - d->viewExcludeddApplications->rootContext()->setContextProperty(QStringLiteral("applicationModel"), d->excludedApplicationsModel); - d->viewExcludeddApplications->setSource(QUrl::fromLocalFile(KAMD_KCM_DATADIR + QStringLiteral("/qml/recentFiles/ExcludedApplicationView.qml"))); - - // React to changes - - connect(d->radioRememberSpecificApplications, &QAbstractButton::toggled, d->excludedApplicationsModel, &ExcludedApplicationsModel::setEnabled); - connect(d->radioRememberSpecificApplications, &QAbstractButton::toggled, d->kcfg_blockedByDefault, &QCheckBox::setEnabled); - - // By default the KCModule (and eventually the kconfigdialogmanager) use - // the index of checked radio button as the value of the setting. In this - // case however we have a mismatch, the radio button "Do not remember" - // (radioDontRememberApplications) has index 1 but in the WhatToRemember - // enum has the value 2! So... - // 1. Let kconfigwidgets know that this QGroupBox will be using a custom - // property to indicate the setting's value ("kcfg_value") - d->kcfg_whatToRemember->setProperty("kcfg_property", QByteArray("kcfg_value")); - // 2. Every time any radio button is clicked, we need to reset the - // kcfg_value and potentially set the dialog to "needs saving" state - // NOTE: Do not use "toggled" since it fires for two buttons each time! - connect(d->radioRememberSpecificApplications, &QAbstractButton::clicked, this, &RecentFilesKcm::whatToRememberWidgetChanged); - connect(d->radioRememberAllApplications, &QAbstractButton::clicked, this, &RecentFilesKcm::whatToRememberWidgetChanged); - connect(d->radioDontRememberApplications, &QAbstractButton::clicked, this, &RecentFilesKcm::whatToRememberWidgetChanged); - - // Initial state - - d->excludedApplicationsModel->setEnabled(false); - d->messageWidget->setVisible(false); - - connect(this, &RecentFilesKcm::defaultsIndicatorsVisibleChanged, this, [this]() { - d->updateUiDefaultIndicator(defaultsIndicatorsVisible()); - for (KConfigDialogManager *config : configs()) { - config->setDefaultsIndicatorsVisible(defaultsIndicatorsVisible()); - } - }); - - addConfig(d->pluginConfig, widget()); -} - -RecentFilesKcm::~RecentFilesKcm() -{ -} - -void RecentFilesKcm::defaults() -{ - d->excludedApplicationsModel->defaults(); - // Click and not setChecked to trigger whatToRememberWidgetChanged() - d->radioRememberAllApplications->click(); - - KCModule::defaults(); -} - -void RecentFilesKcm::load() -{ - d->excludedApplicationsModel->load(); - - KCModule::load(); - - auto wtr = d->pluginConfig->whatToRemember(); - d->radioRememberSpecificApplications->setChecked(wtr == SpecificApplications); - d->radioDontRememberApplications->setChecked(wtr == NoApplications); - d->radioRememberAllApplications->setChecked(wtr == AllApplications); - - d->excludedApplicationsModel->setEnabled(d->radioRememberSpecificApplications->isChecked()); - d->kcfg_blockedByDefault->setEnabled(d->radioRememberSpecificApplications->isChecked()); - - d->updateUiDefaultIndicator(defaultsIndicatorsVisible()); -} - -void RecentFilesKcm::whatToRememberWidgetChanged(bool) -{ - // See ctor for details: tl;dr: reset the what-to-rememeber value - // and set the dialog to "changed" (if save is needed) - // clang-format off - const auto whatToRemember = - d->radioRememberSpecificApplications->isChecked() ? SpecificApplications : - d->radioDontRememberApplications->isChecked() ? NoApplications : - /* otherwise */ AllApplications; - // clang-format on - qCDebug(LOG_KCMS_RECENTFILES) << "whatToRememberWidgetChangeState: " << whatToRemember; - d->kcfg_whatToRemember->setProperty("kcfg_value", whatToRemember); - setNeedsSave(whatToRemember != d->pluginConfig->whatToRemember()); - - d->updateUiDefaultIndicator(defaultsIndicatorsVisible()); -} - -void RecentFilesKcm::save() -{ - d->excludedApplicationsModel->save(); - - KCModule::save(); -} - -void RecentFilesKcm::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 RecentFilesKcm::forgetLastHour() -{ - forget(1, QStringLiteral("h")); -} - -void RecentFilesKcm::forgetTwoHours() -{ - forget(2, QStringLiteral("h")); -} - -void RecentFilesKcm::forgetDay() -{ - forget(1, QStringLiteral("d")); -} - -void RecentFilesKcm::forgetAll() -{ - forget(0, QStringLiteral("everything")); -} - -void RecentFilesKcm::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()); - } -} - -#include "kcm_recentFiles.moc" - -#include "moc_kcm_recentFiles.cpp" diff --git a/kcms/recentFiles/kcm_recentFiles.h b/kcms/recentFiles/kcm_recentFiles.h deleted file mode 100644 index e2d23b2ff2..0000000000 --- a/kcms/recentFiles/kcm_recentFiles.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - SPDX-FileCopyrightText: 2012-2016 Ivan Cukic - SPDX-FileCopyrightText: 2022 Méven Car - - SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL -*/ - -#pragma once - -#include -#include - -#include - -class KCoreConfigSkeleton; - -/** - * RecentFilesKcm - */ -class RecentFilesKcm : public KCModule -{ - Q_OBJECT -public: - explicit RecentFilesKcm(QObject *parent, const KPluginMetaData &data); - ~RecentFilesKcm() override; - - KCoreConfigSkeleton *pluginConfig(); - -public Q_SLOTS: - void defaults() override; - void load() override; - void save() override; - -private Q_SLOTS: - void forget(int count, const QString &what); - void forgetLastHour(); - void forgetTwoHours(); - void forgetDay(); - void forgetAll(); - - void spinKeepHistoryValueChanged(int value); - void whatToRememberWidgetChanged(bool checked); - -private: - enum WhatToRemember { - AllApplications = 0, - SpecificApplications = 1, - NoApplications = 2, - }; - - D_PTR; -}; diff --git a/kcms/recentFiles/kcm_recentfiles.cpp b/kcms/recentFiles/kcm_recentfiles.cpp new file mode 100644 index 0000000000..57bc9cbeab --- /dev/null +++ b/kcms/recentFiles/kcm_recentfiles.cpp @@ -0,0 +1,108 @@ +/* + SPDX-FileCopyrightText: 2012-2016 Ivan Cukic + SPDX-FileCopyrightText: 2022 Méven Car + SPDX-FileCopyrightText: 2026 James Graham + + SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL +*/ + +#include "kcm_recentfiles.h" + +#include "resourcescoring_interface.h" + +using namespace Qt::StringLiterals; + +K_PLUGIN_CLASS_WITH_JSON(RecentFilesKcm, "kcm_recentfiles.json") + +namespace +{ +constexpr inline auto ActivityManagerDBusKey = "org.kde.ActivityManager"_L1; +constexpr inline auto ResourceScoringPathKey = "/ActivityManager/Resources/Scoring"_L1; +} + +RecentFilesKcm::RecentFilesKcm(QObject *parent, const KPluginMetaData &data) + : KQuickConfigModule(parent, data) + , m_settings(new KActivityManagerdPluginsSettings(this)) + , m_excludedApplicationsModel(new ExcludedApplicationsModel(this)) +{ + connect(m_excludedApplicationsModel, &ExcludedApplicationsModel::changed, this, [this](bool changed) { + if (changed) { + setNeedsSave(true); + } + }); +} + +int RecentFilesKcm::whatToRemember() const +{ + return m_settings->whatToRemember(); +} + +void RecentFilesKcm::setWhatToRemember(int whatToRemember) +{ + if (whatToRemember == m_settings->whatToRemember()) { + return; + } + m_settings->setWhatToRemember(whatToRemember); + setNeedsSave(true); + Q_EMIT whatToRememberChanged(); +} + +int RecentFilesKcm::keepHistoryFor() const +{ + return m_settings->keepHistoryFor(); +} + +void RecentFilesKcm::setKeepHistoryFor(int keepHistoryFor) +{ + if (keepHistoryFor == m_settings->keepHistoryFor()) { + return; + } + m_settings->setKeepHistoryFor(keepHistoryFor); + setNeedsSave(true); + Q_EMIT keepHistoryForChanged(); +} + +bool RecentFilesKcm::blockByDefault() const +{ + return m_settings->blockedByDefault(); +} + +void RecentFilesKcm::setBlockByDefault(bool blockByDefault) +{ + if (blockByDefault == m_settings->blockedByDefault()) { + return; + } + m_settings->setBlockedByDefault(blockByDefault); + setNeedsSave(true); + Q_EMIT blockByDefaultChanged(); +} + +ExcludedApplicationsModel *RecentFilesKcm::excludedApplicationsModel() const +{ + return m_excludedApplicationsModel; +} + +void RecentFilesKcm::defaults() +{ + m_excludedApplicationsModel->defaults(); + setWhatToRemember(0); +} + +void RecentFilesKcm::load() +{ + m_excludedApplicationsModel->load(); +} + +void RecentFilesKcm::save() +{ + m_excludedApplicationsModel->save(); + m_settings->save(); +} + +void RecentFilesKcm::forget(int count, const QString &what) +{ + org::kde::ActivityManager::ResourcesScoring rankingsservice(ActivityManagerDBusKey, ResourceScoringPathKey, QDBusConnection::sessionBus()); + rankingsservice.DeleteRecentStats(QString(), count, what); +} + +#include "kcm_recentfiles.moc" diff --git a/kcms/recentFiles/kcm_recentfiles.h b/kcms/recentFiles/kcm_recentfiles.h new file mode 100644 index 0000000000..9d570a3489 --- /dev/null +++ b/kcms/recentFiles/kcm_recentfiles.h @@ -0,0 +1,63 @@ +/* + SPDX-FileCopyrightText: 2012-2016 Ivan Cukic + SPDX-FileCopyrightText: 2022 Méven Car + SPDX-FileCopyrightText: 2026 James Graham + + SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL +*/ + +#pragma once + +#include + +#include "excludedapplicationsmodel.h" +#include "kactivitymanagerd_plugins_settings.h" + +/** + * RecentFilesKcm + */ +class RecentFilesKcm : public KQuickConfigModule +{ + Q_OBJECT + + Q_PROPERTY(int keepHistoryFor READ keepHistoryFor WRITE setKeepHistoryFor NOTIFY keepHistoryForChanged) + + Q_PROPERTY(int whatToRemember READ whatToRemember WRITE setWhatToRemember NOTIFY whatToRememberChanged) + + Q_PROPERTY(bool blockByDefault READ blockByDefault WRITE setBlockByDefault NOTIFY blockByDefaultChanged) + + Q_PROPERTY(ExcludedApplicationsModel *excludedApplicationsModel READ excludedApplicationsModel CONSTANT) + +public: + enum WhatToRemember { + AllApplications = 0, + SpecificApplications = 1, + NoApplications = 2, + }; + + explicit RecentFilesKcm(QObject *parent, const KPluginMetaData &data); + + int whatToRemember() const; + void setWhatToRemember(int whatToRemember); + int keepHistoryFor() const; + void setKeepHistoryFor(int keepHistoryFor); + bool blockByDefault() const; + void setBlockByDefault(bool blockByDefault); + + ExcludedApplicationsModel *excludedApplicationsModel() const; + + void defaults() override; + void load() override; + void save() override; + + Q_INVOKABLE void forget(int count, const QString &what); + +Q_SIGNALS: + void whatToRememberChanged(); + void keepHistoryForChanged(); + void blockByDefaultChanged(); + +private: + KActivityManagerdPluginsSettings *m_settings; + ExcludedApplicationsModel *m_excludedApplicationsModel; +}; diff --git a/kcms/recentFiles/kcm_recentFiles.json b/kcms/recentFiles/kcm_recentfiles.json similarity index 100% rename from kcms/recentFiles/kcm_recentFiles.json rename to kcms/recentFiles/kcm_recentfiles.json diff --git a/kcms/recentFiles/common/dbus/org.kde.ActivityManager.Features.xml b/kcms/recentFiles/org.kde.ActivityManager.Features.xml similarity index 100% rename from kcms/recentFiles/common/dbus/org.kde.ActivityManager.Features.xml rename to kcms/recentFiles/org.kde.ActivityManager.Features.xml diff --git a/kcms/recentFiles/common/dbus/org.kde.ActivityManager.ResourceScoring.xml b/kcms/recentFiles/org.kde.ActivityManager.ResourceScoring.xml similarity index 100% rename from kcms/recentFiles/common/dbus/org.kde.ActivityManager.ResourceScoring.xml rename to kcms/recentFiles/org.kde.ActivityManager.ResourceScoring.xml diff --git a/kcms/recentFiles/qml/recentFiles/ExcludedApplicationView.qml b/kcms/recentFiles/qml/recentFiles/ExcludedApplicationView.qml deleted file mode 100644 index f07078c4db..0000000000 --- a/kcms/recentFiles/qml/recentFiles/ExcludedApplicationView.qml +++ /dev/null @@ -1,56 +0,0 @@ -/* vim:set foldenable foldmethod=marker: - - SPDX-FileCopyrightText: 2012 Ivan Cukic - SPDX-FileCopyrightText: 2025 Nate Graham - - SPDX-License-Identifier: GPL-2.0-or-later -*/ - -import QtQuick -import QtQuick.Layouts -import QtQuick.Controls as QQC2 - -import org.kde.kirigami as Kirigami - -QQC2.ScrollView { - id: scrollview - - readonly property bool narrowMode: width < Kirigami.Units.gridUnit * 30 - - enabled: applicationModel.enabled - - Kirigami.StyleHints.showFramedBackground: true - - GridLayout { - id: grid - - // The delegate brings its own - rowSpacing: 0 - columnSpacing: 0 - - columns: scrollview.narrowMode ? 1 : 4 - - clip: true - - Repeater { - model: applicationModel - delegate: QQC2.CheckDelegate { - Layout.preferredWidth: Math.round(scrollview.availableWidth/ grid.columns) - 1 - Layout.preferredHeight: scrollview.narrowMode ? -1 : Kirigami.Units.gridUnit * 5 - - hoverEnabled: applicationModel.enabled - - display: scrollview.narrowMode ? QQC2.AbstractButton.TextBesideIcon : QQC2.ItemDelegate.TextUnderIcon - icon.name: model.icon - icon.height: Kirigami.Settings.isMobile || display === QQC2.ItemDelegate.TextUnderIcon ? Kirigami.Units.iconSizes.medium : Kirigami.Units.iconSizes.smallMedium - text: model.title - - opacity: model.blocked ? 0.3 : 1.0 - Behavior on opacity { NumberAnimation { duration: Kirigami.Units.shortDuration } } - - checked: !model.blocked - onToggled: applicationModel.toggleApplicationBlocked(model.index) - } - } - } -} diff --git a/kcms/recentFiles/recentFiles-kcm-features.h.cmake b/kcms/recentFiles/recentFiles-kcm-features.h.cmake deleted file mode 100644 index 0f867f97c8..0000000000 --- a/kcms/recentFiles/recentFiles-kcm-features.h.cmake +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef KCM_CONFIG_FEATURES_H_ -#define KCM_CONFIG_FEATURES_H_ - -#cmakedefine KAMD_KCM_DATADIR "@KAMD_KCM_DATADIR@" - -#endif diff --git a/kcms/recentFiles/ui/ExcludedApplicationView.qml b/kcms/recentFiles/ui/ExcludedApplicationView.qml new file mode 100644 index 0000000000..abc6a9cbba --- /dev/null +++ b/kcms/recentFiles/ui/ExcludedApplicationView.qml @@ -0,0 +1,59 @@ +/* vim:set foldenable foldmethod=marker: + + SPDX-FileCopyrightText: 2012 Ivan Cukic + SPDX-FileCopyrightText: 2025 Nate Graham + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +pragma ComponentBehavior: Bound + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls as QQC2 + +import org.kde.kirigami as Kirigami + +QQC2.ScrollView { + id: root + + required property var model + + required property real pageWidth + + implicitWidth: grid.cellWidth * (pageWidth < Kirigami.Units.gridUnit * 55 ? 2 : 4) + leftPadding: Kirigami.Units.largeSpacing + bottomPadding: Kirigami.Units.largeSpacing + + Kirigami.StyleHints.showFramedBackground: true + + GridView { + id: grid + cellWidth: Kirigami.Units.gridUnit * 10 + cellHeight: Kirigami.Units.gridUnit * 5 + + model: root.model + delegate: QQC2.CheckDelegate { + id: applicationDelegate + required property int index + required property string title + required property string iconSource + required property bool blocked + + width: GridView.view.cellWidth + height: GridView.view.cellHeight + hoverEnabled: root.enabled + + display: QQC2.ItemDelegate.TextUnderIcon + icon.name: applicationDelegate.iconSource + icon.height: Kirigami.Settings.isMobile || display === QQC2.ItemDelegate.TextUnderIcon ? Kirigami.Units.iconSizes.medium : Kirigami.Units.iconSizes.smallMedium + text: applicationDelegate.title + + opacity: applicationDelegate.blocked ? 0.3 : 1.0 + Behavior on opacity { NumberAnimation { duration: Kirigami.Units.shortDuration } } + + checked: !applicationDelegate.blocked + onToggled: root.model.toggleApplicationBlocked(applicationDelegate.index) + } + } +} diff --git a/kcms/recentFiles/ui/RecentFiles.ui b/kcms/recentFiles/ui/RecentFiles.ui deleted file mode 100644 index 13db9b197f..0000000000 --- a/kcms/recentFiles/ui/RecentFiles.ui +++ /dev/null @@ -1,167 +0,0 @@ - - - RecentFiles - - - - 0 - 0 - 629 - 500 - - - - - - - Cleared the activity history. - - - KMessageWidget::Positive - - - - - - - - - - Qt::AlignHCenter|Qt::AlignTop - - - - - Keep history: - - - - - - - - - - - - Clear History - - - - - - - - - - - - - - - true - - - - - - For a&ll applications - - - true - - - - - - - &Do not remember - - - - - - - O&nly for specific applications: - - - - - - - - - - Remember opened documents: - - - - - - - - - - 0 - 0 - - - - - 0 - 200 - - - - QQuickWidget::SizeRootObjectToView - - - - - - - 6 - - - - - Exclude applications not on the list - - - - - - - - - - KMessageWidget - QFrame -
kmessagewidget.h
-
- - QQuickWidget - QWidget -
QtQuickWidgets/QQuickWidget
-
-
- - - - radioRememberSpecificApplications - toggled(bool) - kcfg_blockedByDefault - setEnabled(bool) - - - 352 - 167 - - - 252 - 481 - - - - -
diff --git a/kcms/recentFiles/ui/main.qml b/kcms/recentFiles/ui/main.qml new file mode 100644 index 0000000000..bfa0339191 --- /dev/null +++ b/kcms/recentFiles/ui/main.qml @@ -0,0 +1,130 @@ +/* + * SPDX-FileCopyrightText: 2026 James Graham + * + * GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL + */ + +import QtQuick +import QtQuick.Controls as QQC2 +import QtQuick.Layouts + +import org.kde.kirigami.forms as Forms +import org.kde.kcmutils as KCMUtils + +import org.kde.plasma.private.kcm_recentfiles as RecentFiles + +KCMUtils.SimpleKCM { + id: root + + Forms.Form { + Forms.FormGroup { + Forms.FormEntry { + title: i18ndc("kcm_recentFiles", "@label", "Keep History:") + contentItem: RowLayout { + QQC2.SpinBox { + from: 0 + to: 999 + value: root.KCMUtils.ConfigModule.keepHistoryFor + onValueModified: root.KCMUtils.ConfigModule.keepHistoryFor = value + + readonly property regexp numberExtractionRegExp: /\D*?(-?\d*\.?\d*)\D*$/ + textFromValue: (value) => { + return i18ndcp("kcm_recentFiles", "@option The number of months to remember recent file history", "For %1 month", "For %1 months", value) + } + valueFromText: (text, locale) => { + return Number.fromLocaleString(locale, numberExtractionRegExp.exec(text)[1]) + } + } + QQC2.ComboBox { + displayText: i18ndc("kcm_recentFiles", "@label", "Clear history") + textRole: "name" + valueRole: "value" + model: [ + { + name: i18ndc("kcm_recentFiles", "@option", "Forget the last hour"), + value: 0, + amount: 1, + type: "h" + }, + { + name: i18ndc("kcm_recentFiles", "@option", "Forget the last two hours"), + value: 1, + amount: 2, + type: "h" + }, + { + name: i18ndc("kcm_recentFiles", "@option", "Forget the last day"), + value: 2, + amount: 1, + type: "d" + }, + { + name: i18ndc("kcm_recentFiles", "@option", "Forget everything"), + value: 3, + amount: 0, + type: "everything" + } + ] + + onActivated: console.warn(currentValue, model[currentValue].amount, model[currentValue].type) + } + } + } + QQC2.ButtonGroup { + id: applicationHistoryGroup + } + Forms.FormEntry { + title: i18ndc("kcm_recentFiles", "@label", "Remember opened documents:") + contentItem: QQC2.RadioButton { + text: i18nc("@option:radio", "For all applications") + checked: root.KCMUtils.ConfigModule.whatToRemember === 0 + onToggled: if (checked) { + root.KCMUtils.ConfigModule.whatToRemember = 0 + } + + QQC2.ButtonGroup.group: applicationHistoryGroup + } + } + Forms.FormEntry { + contentItem: QQC2.RadioButton { + text: i18nc("@option:radio", "Do not remember") + checked: root.KCMUtils.ConfigModule.whatToRemember === 2 + onToggled: if (checked) { + root.KCMUtils.ConfigModule.whatToRemember = 2 + } + + QQC2.ButtonGroup.group: applicationHistoryGroup + } + } + Forms.FormEntry { + contentItem: QQC2.RadioButton { + text: i18nc("@option:radio", "Only for specific applications") + checked: root.KCMUtils.ConfigModule.whatToRemember === 1 + onToggled: if (checked) { + root.KCMUtils.ConfigModule.whatToRemember = 1 + } + + QQC2.ButtonGroup.group: applicationHistoryGroup + } + } + Forms.FormEntry { + fullWidth: true + contentItem: ExcludedApplicationView { + Layout.fillWidth: true + enabled: root.KCMUtils.ConfigModule.whatToRemember === 1 + model: root.KCMUtils.ConfigModule.excludedApplicationsModel + pageWidth: root.width + } + } + Forms.FormEntry { + fullWidth: true + contentItem: QQC2.CheckBox { + enabled: root.KCMUtils.ConfigModule.whatToRemember === 1 + text: i18nc("@option:radio", "Exclude applications not on the list") + checked: root.KCMUtils.ConfigModule.blockByDefault + onToggled: root.KCMUtils.ConfigModule.blockByDefault = !root.KCMUtils.ConfigModule.blockByDefault + } + } + } + } +} diff --git a/kcms/recentFiles/utils/d_ptr.h b/kcms/recentFiles/utils/d_ptr.h deleted file mode 100644 index b2d848790b..0000000000 --- a/kcms/recentFiles/utils/d_ptr.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - SPDX-FileCopyrightText: 2012-2016 Ivan Cukic - - SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL -*/ - -#pragma once - -#include - -namespace kamd -{ -namespace utils -{ -template -class d_ptr -{ -private: - std::unique_ptr d; - -public: - d_ptr(); - - template - d_ptr(Args &&...); - - ~d_ptr(); - - T *operator->() const; -}; - -#define D_PTR \ - class Private; \ - friend class Private; \ - const ::kamd::utils::d_ptr d - -} // namespace utils -} // namespace kamd diff --git a/kcms/recentFiles/utils/d_ptr_implementation.h b/kcms/recentFiles/utils/d_ptr_implementation.h deleted file mode 100644 index bad2ce6201..0000000000 --- a/kcms/recentFiles/utils/d_ptr_implementation.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - SPDX-FileCopyrightText: 2012-2016 Ivan Cukic - - SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL -*/ - -#pragma once - -#include - -namespace kamd -{ -namespace utils -{ -template -d_ptr::d_ptr() - : d(new T()) -{ -} - -template -template -d_ptr::d_ptr(Args &&...args) - : d(new T(std::forward(args)...)) -{ -} - -template -d_ptr::~d_ptr() -{ -} - -template -T *d_ptr::operator->() const -{ - return d.get(); -} - -} // namespace utils -} // namespace kamd