┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
path: root/src/settings/contextmenu/contextmenusettingspage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/settings/contextmenu/contextmenusettingspage.cpp')
-rw-r--r--src/settings/contextmenu/contextmenusettingspage.cpp346
1 files changed, 346 insertions, 0 deletions
diff --git a/src/settings/contextmenu/contextmenusettingspage.cpp b/src/settings/contextmenu/contextmenusettingspage.cpp
new file mode 100644
index 000000000..4f126d3e2
--- /dev/null
+++ b/src/settings/contextmenu/contextmenusettingspage.cpp
@@ -0,0 +1,346 @@
+/*
+ * SPDX-FileCopyrightText: 2009-2010 Peter Penz <[email protected]>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "contextmenusettingspage.h"
+
+#include "dolphin_generalsettings.h"
+#include "dolphin_versioncontrolsettings.h"
+#include "dolphin_contextmenusettings.h"
+#include "settings/serviceitemdelegate.h"
+#include "settings/servicemodel.h"
+
+#include <KDesktopFile>
+#include <KLocalizedString>
+#include <KMessageBox>
+#include <KNS3/Button>
+#include <KPluginMetaData>
+#include <KService>
+#include <KServiceTypeTrader>
+#include <KDesktopFileActions>
+
+#include <QGridLayout>
+#include <QLabel>
+#include <QListWidget>
+#include <QScroller>
+#include <QShowEvent>
+#include <QSortFilterProxyModel>
+#include <QLineEdit>
+
+namespace
+{
+ const bool ShowDeleteDefault = false;
+ const char VersionControlServicePrefix[] = "_version_control_";
+ const char DeleteService[] = "_delete";
+ const char CopyToMoveToService[] ="_copy_to_move_to";
+ const char AddToPlacesService[] = "_add_to_places";
+ const char SortByService[] = "_sort_by";
+ const char ViewModeService[] = "_view_mode";
+ const char OpenInNewTabService[] = "_open_in_new_tab";
+ const char OpenInNewWindowService[] = "_open_in_new_window";
+ const char CopyLocationService[] = "_copy_location";
+ const char DuplicateHereService[] = "_duplicate_here";
+}
+
+ContextMenuSettingsPage::ContextMenuSettingsPage(QWidget* parent) :
+ SettingsPageBase(parent),
+ m_initialized(false),
+ m_serviceModel(nullptr),
+ m_sortModel(nullptr),
+ m_listView(nullptr),
+ m_enabledVcsPlugins()
+{
+ QVBoxLayout* topLayout = new QVBoxLayout(this);
+
+ QLabel* label = new QLabel(i18nc("@label:textbox",
+ "Select which services should "
+ "be shown in the context menu:"), this);
+ label->setWordWrap(true);
+ m_searchLineEdit = new QLineEdit(this);
+ m_searchLineEdit->setPlaceholderText(i18nc("@label:textbox", "Search..."));
+ connect(m_searchLineEdit, &QLineEdit::textChanged, this, [this](const QString &filter){
+ m_sortModel->setFilterFixedString(filter);
+ });
+
+ m_listView = new QListView(this);
+ QScroller::grabGesture(m_listView->viewport(), QScroller::TouchGesture);
+
+ auto *delegate = new ServiceItemDelegate(m_listView, m_listView);
+ m_serviceModel = new ServiceModel(this);
+ m_sortModel = new QSortFilterProxyModel(this);
+ m_sortModel->setSourceModel(m_serviceModel);
+ m_sortModel->setSortRole(Qt::DisplayRole);
+ m_sortModel->setSortLocaleAware(true);
+ m_sortModel->setFilterRole(Qt::DisplayRole);
+ m_sortModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
+ m_listView->setModel(m_sortModel);
+ m_listView->setItemDelegate(delegate);
+ m_listView->setVerticalScrollMode(QListView::ScrollPerPixel);
+ connect(m_listView, &QListView::clicked, this, &ContextMenuSettingsPage::changed);
+
+#ifndef Q_OS_WIN
+ auto *downloadButton = new KNS3::Button(i18nc("@action:button", "Download New Services..."),
+ QStringLiteral("servicemenu.knsrc"),
+ this);
+ connect(downloadButton, &KNS3::Button::dialogFinished, this, [this](const KNS3::Entry::List &changedEntries) {
+ if (!changedEntries.isEmpty()) {
+ m_serviceModel->clear();
+ loadServices();
+ }
+ });
+
+#endif
+
+ topLayout->addWidget(label);
+ topLayout->addWidget(m_searchLineEdit);
+ topLayout->addWidget(m_listView);
+#ifndef Q_OS_WIN
+ topLayout->addWidget(downloadButton);
+#endif
+
+ m_enabledVcsPlugins = VersionControlSettings::enabledPlugins();
+ std::sort(m_enabledVcsPlugins.begin(), m_enabledVcsPlugins.end());
+}
+
+ContextMenuSettingsPage::~ContextMenuSettingsPage() {
+}
+
+void ContextMenuSettingsPage::applySettings()
+{
+ if (!m_initialized) {
+ return;
+ }
+
+ KConfig config(QStringLiteral("kservicemenurc"), KConfig::NoGlobals);
+ KConfigGroup showGroup = config.group("Show");
+
+ QStringList enabledPlugins;
+
+ const QAbstractItemModel *model = m_listView->model();
+ for (int i = 0; i < model->rowCount(); ++i) {
+ const QModelIndex index = model->index(i, 0);
+ const QString service = model->data(index, ServiceModel::DesktopEntryNameRole).toString();
+ const bool checked = model->data(index, Qt::CheckStateRole).toBool();
+
+ if (service.startsWith(VersionControlServicePrefix)) {
+ if (checked) {
+ enabledPlugins.append(model->data(index, Qt::DisplayRole).toString());
+ }
+ } else if (service == QLatin1String(DeleteService)) {
+ KSharedConfig::Ptr globalConfig = KSharedConfig::openConfig(QStringLiteral("kdeglobals"), KConfig::NoGlobals);
+ KConfigGroup configGroup(globalConfig, "KDE");
+ configGroup.writeEntry("ShowDeleteCommand", checked);
+ configGroup.sync();
+ } else if (service == QLatin1String(CopyToMoveToService)) {
+ ContextMenuSettings::setShowCopyMoveMenu(checked);
+ ContextMenuSettings::self()->save();
+ } else if (service == QLatin1String(AddToPlacesService)) {
+ ContextMenuSettings::setShowAddToPlaces(checked);
+ ContextMenuSettings::self()->save();
+ } else if (service == QLatin1String(SortByService)) {
+ ContextMenuSettings::setShowSortBy(checked);
+ ContextMenuSettings::self()->save();
+ } else if (service == QLatin1String(ViewModeService)) {
+ ContextMenuSettings::setShowViewMode(checked);
+ ContextMenuSettings::self()->save();
+ } else if (service == QLatin1String(OpenInNewTabService)) {
+ ContextMenuSettings::setShowOpenInNewTab(checked);
+ ContextMenuSettings::self()->save();
+ } else if (service == QLatin1String(OpenInNewWindowService)) {
+ ContextMenuSettings::setShowOpenInNewWindow(checked);
+ ContextMenuSettings::self()->save();
+ } else if (service == QLatin1String(CopyLocationService)) {
+ ContextMenuSettings::setShowCopyLocation(checked);
+ ContextMenuSettings::self()->save();
+ } else if (service == QLatin1String(DuplicateHereService)) {
+ ContextMenuSettings::setShowDuplicateHere(checked);
+ ContextMenuSettings::self()->save();
+ } else {
+ showGroup.writeEntry(service, checked);
+ }
+ }
+
+ showGroup.sync();
+
+ if (m_enabledVcsPlugins != enabledPlugins) {
+ VersionControlSettings::setEnabledPlugins(enabledPlugins);
+ VersionControlSettings::self()->save();
+
+ KMessageBox::information(window(),
+ i18nc("@info", "Dolphin must be restarted to apply the "
+ "updated version control systems settings."),
+ QString(), // default title
+ QStringLiteral("ShowVcsRestartInformation"));
+ }
+}
+
+void ContextMenuSettingsPage::restoreDefaults()
+{
+ QAbstractItemModel* model = m_listView->model();
+ for (int i = 0; i < model->rowCount(); ++i) {
+ const QModelIndex index = model->index(i, 0);
+ const QString service = model->data(index, ServiceModel::DesktopEntryNameRole).toString();
+
+ const bool checked = !service.startsWith(VersionControlServicePrefix)
+ && service != QLatin1String(DeleteService)
+ && service != QLatin1String(CopyToMoveToService);
+ model->setData(index, checked, Qt::CheckStateRole);
+ }
+}
+
+void ContextMenuSettingsPage::showEvent(QShowEvent* event)
+{
+ if (!event->spontaneous() && !m_initialized) {
+ loadServices();
+
+ loadVersionControlSystems();
+
+ // Add "Show 'Delete' command" as service
+ KSharedConfig::Ptr globalConfig = KSharedConfig::openConfig(QStringLiteral("kdeglobals"), KConfig::IncludeGlobals);
+ KConfigGroup configGroup(globalConfig, "KDE");
+ addRow(QStringLiteral("edit-delete"),
+ i18nc("@option:check", "Delete"),
+ DeleteService,
+ configGroup.readEntry("ShowDeleteCommand", ShowDeleteDefault));
+
+ // Add "Show 'Copy To' and 'Move To' commands" as service
+ addRow(QStringLiteral("edit-copy"),
+ i18nc("@option:check", "'Copy To' and 'Move To' commands"),
+ CopyToMoveToService,
+ ContextMenuSettings::showCopyMoveMenu());
+
+ // Add other built-in actions
+ addRow(QStringLiteral("bookmark-new"),
+ i18nc("@option:check", "Add to Places"),
+ AddToPlacesService,
+ ContextMenuSettings::showAddToPlaces());
+ addRow(QStringLiteral("view-sort"),
+ i18nc("@option:check", "Sort By"),
+ SortByService,
+ ContextMenuSettings::showSortBy());
+ addRow(QStringLiteral("view-list-icons"),
+ i18nc("@option:check", "View Mode"),
+ ViewModeService,
+ ContextMenuSettings::showViewMode());
+ addRow(QStringLiteral("folder-new"),
+ i18nc("@option:check", "'Open in New Tab' and 'Open in New Tabs'"),
+ OpenInNewTabService,
+ ContextMenuSettings::showOpenInNewTab());
+ addRow(QStringLiteral("window-new"),
+ i18nc("@option:check", "Open in New Window"),
+ OpenInNewWindowService,
+ ContextMenuSettings::showOpenInNewWindow());
+ addRow(QStringLiteral("edit-copy"),
+ i18nc("@option:check", "Copy Location"),
+ CopyLocationService,
+ ContextMenuSettings::showCopyLocation());
+ addRow(QStringLiteral("edit-copy"),
+ i18nc("@option:check", "Duplicate Here"),
+ DuplicateHereService,
+ ContextMenuSettings::showDuplicateHere());
+
+ m_sortModel->sort(Qt::DisplayRole);
+
+ m_initialized = true;
+ }
+ SettingsPageBase::showEvent(event);
+}
+
+void ContextMenuSettingsPage::loadServices()
+{
+ const KConfig config(QStringLiteral("kservicemenurc"), KConfig::NoGlobals);
+ const KConfigGroup showGroup = config.group("Show");
+
+ // Load generic services
+ const KService::List entries = KServiceTypeTrader::self()->query(QStringLiteral("KonqPopupMenu/Plugin"));
+ for (const KService::Ptr &service : entries) {
+ const QString file = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kservices5/" % service->entryPath());
+ const QList<KServiceAction> serviceActions = KDesktopFileActions::userDefinedServices(file, true);
+
+ const KDesktopFile desktopFile(file);
+ const QString subMenuName = desktopFile.desktopGroup().readEntry("X-KDE-Submenu");
+
+ for (const KServiceAction &action : serviceActions) {
+ const QString serviceName = action.name();
+ const bool addService = !action.noDisplay() && !action.isSeparator() && !isInServicesList(serviceName);
+
+ if (addService) {
+ const QString itemName = subMenuName.isEmpty()
+ ? action.text()
+ : i18nc("@item:inmenu", "%1: %2", subMenuName, action.text());
+ const bool checked = showGroup.readEntry(serviceName, true);
+ addRow(action.icon(), itemName, serviceName, checked);
+ }
+ }
+ }
+
+ // Load service plugins that implement the KFileItemActionPlugin interface
+ const KService::List pluginServices = KServiceTypeTrader::self()->query(QStringLiteral("KFileItemAction/Plugin"));
+ for (const KService::Ptr &service : pluginServices) {
+ const QString desktopEntryName = service->desktopEntryName();
+ if (!isInServicesList(desktopEntryName)) {
+ const bool checked = showGroup.readEntry(desktopEntryName, true);
+ addRow(service->icon(), service->name(), desktopEntryName, checked);
+ }
+ }
+
+ // Load JSON-based plugins that implement the KFileItemActionPlugin interface
+ const auto jsonPlugins = KPluginLoader::findPlugins(QStringLiteral("kf5/kfileitemaction"), [](const KPluginMetaData& metaData) {
+ return metaData.serviceTypes().contains(QLatin1String("KFileItemAction/Plugin"));
+ });
+
+ for (const auto &jsonMetadata : jsonPlugins) {
+ const QString desktopEntryName = jsonMetadata.pluginId();
+ if (!isInServicesList(desktopEntryName)) {
+ const bool checked = showGroup.readEntry(desktopEntryName, true);
+ addRow(jsonMetadata.iconName(), jsonMetadata.name(), desktopEntryName, checked);
+ }
+ }
+
+ m_sortModel->sort(Qt::DisplayRole);
+ m_searchLineEdit->setFocus(Qt::OtherFocusReason);
+}
+
+void ContextMenuSettingsPage::loadVersionControlSystems()
+{
+ const QStringList enabledPlugins = VersionControlSettings::enabledPlugins();
+
+ // Create a checkbox for each available version control plugin
+ const KService::List pluginServices = KServiceTypeTrader::self()->query(QStringLiteral("FileViewVersionControlPlugin"));
+ for (const auto &plugin : pluginServices) {
+ const QString pluginName = plugin->name();
+ addRow(QStringLiteral("code-class"),
+ pluginName,
+ VersionControlServicePrefix + pluginName,
+ enabledPlugins.contains(pluginName));
+ }
+
+ m_sortModel->sort(Qt::DisplayRole);
+}
+
+bool ContextMenuSettingsPage::isInServicesList(const QString &service) const
+{
+ for (int i = 0; i < m_serviceModel->rowCount(); ++i) {
+ const QModelIndex index = m_serviceModel->index(i, 0);
+ if (m_serviceModel->data(index, ServiceModel::DesktopEntryNameRole).toString() == service) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void ContextMenuSettingsPage::addRow(const QString &icon,
+ const QString &text,
+ const QString &value,
+ bool checked)
+{
+ m_serviceModel->insertRow(0);
+
+ const QModelIndex index = m_serviceModel->index(0, 0);
+ m_serviceModel->setData(index, icon, Qt::DecorationRole);
+ m_serviceModel->setData(index, text, Qt::DisplayRole);
+ m_serviceModel->setData(index, value, ServiceModel::DesktopEntryNameRole);
+ m_serviceModel->setData(index, checked, Qt::CheckStateRole);
+}