┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
path: root/src/settings/services
diff options
context:
space:
mode:
authorDuong Do Minh Chau <[email protected]>2020-11-12 16:38:44 +0700
committerElvis Angelaccio <[email protected]>2020-12-28 20:18:31 +0000
commita512176b4bdbf0f0471a9b9089f4a936c14e2732 (patch)
tree51f1ecf98d29b9994af950d9ca2fb0085f29e337 /src/settings/services
parentb339ac1b5f22efb57619c738eb39268c3e00948d (diff)
Add options to hide some context menu entries
This commit add options to hide the following context menu entries: - Add to Places - Copy Location - Duplicate Here - Open in New Tab and Open in New Tabs - Open in New Window - Sort By - View Mode The Services settings page is renamed to Context Menu ShowCopyMoveMenu option is moved from GeneralSettings to ContextMenuSettings BUG: 314594
Diffstat (limited to 'src/settings/services')
-rw-r--r--src/settings/services/servicemenu.knsrc9
-rw-r--r--src/settings/services/servicemenuinstaller/CMakeLists.txt15
-rwxr-xr-xsrc/settings/services/servicemenuinstaller/Messages.sh2
-rw-r--r--src/settings/services/servicemenuinstaller/servicemenuinstaller.cpp462
-rw-r--r--src/settings/services/servicessettingspage.cpp287
-rw-r--r--src/settings/services/servicessettingspage.h69
-rw-r--r--src/settings/services/test/service_menu_deinstallation_test.rb112
-rw-r--r--src/settings/services/test/service_menu_installation_test.rb106
-rw-r--r--src/settings/services/test/test_helper.rb18
-rwxr-xr-xsrc/settings/services/test/test_run.rb11
10 files changed, 0 insertions, 1091 deletions
diff --git a/src/settings/services/servicemenu.knsrc b/src/settings/services/servicemenu.knsrc
deleted file mode 100644
index 0d1c103f6..000000000
--- a/src/settings/services/servicemenu.knsrc
+++ /dev/null
@@ -1,9 +0,0 @@
-[KNewStuff2]
-ProvidersUrl=https://download.kde.org/ocs/providers.xml
-Categories=Dolphin Service Menus
-ChecksumPolicy=ifpossible
-SignaturePolicy=ifpossible
-TargetDir=servicemenu-download
-Uncompress=never
-InstallationCommand=servicemenuinstaller install %f
-UninstallCommand=servicemenuinstaller uninstall %f
diff --git a/src/settings/services/servicemenuinstaller/CMakeLists.txt b/src/settings/services/servicemenuinstaller/CMakeLists.txt
deleted file mode 100644
index 46b159079..000000000
--- a/src/settings/services/servicemenuinstaller/CMakeLists.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-remove_definitions(-DTRANSLATION_DOMAIN=\"dolphin\")
-add_definitions(-DTRANSLATION_DOMAIN=\"dolphin_servicemenuinstaller\")
-
-add_executable(servicemenuinstaller servicemenuinstaller.cpp)
-target_link_libraries(servicemenuinstaller PRIVATE
- Qt5::Core
- Qt5::Gui
- KF5::I18n
- KF5::CoreAddons
-)
-
-if(HAVE_PACKAGEKIT)
- target_link_libraries(servicemenuinstaller PRIVATE PK::packagekitqt5)
-endif()
-install(TARGETS servicemenuinstaller ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
diff --git a/src/settings/services/servicemenuinstaller/Messages.sh b/src/settings/services/servicemenuinstaller/Messages.sh
deleted file mode 100755
index 5012eead6..000000000
--- a/src/settings/services/servicemenuinstaller/Messages.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-#! /usr/bin/env bash
-$XGETTEXT `find . -name \*.cpp` -o $podir/dolphin_servicemenuinstaller.pot
diff --git a/src/settings/services/servicemenuinstaller/servicemenuinstaller.cpp b/src/settings/services/servicemenuinstaller/servicemenuinstaller.cpp
deleted file mode 100644
index 91da3d256..000000000
--- a/src/settings/services/servicemenuinstaller/servicemenuinstaller.cpp
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
- * SPDX-FileCopyrightText: 2019 Alexander Potashev <[email protected]>
- *
- * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
- */
-
-#include <QDebug>
-#include <QProcess>
-#include <QTimer>
-#include <QStandardPaths>
-#include <QDir>
-#include <QDirIterator>
-#include <QCommandLineParser>
-#include <QMimeDatabase>
-#include <QUrl>
-#include <QGuiApplication>
-#include <KLocalizedString>
-#include <KShell>
-
-#include "../../../config-packagekit.h"
-
-Q_GLOBAL_STATIC_WITH_ARGS(QStringList, binaryPackages, ({QLatin1String("application/vnd.debian.binary-package"),
- QLatin1String("application/x-rpm"),
- QLatin1String("application/x-xz"),
- QLatin1String("application/zstd")}))
-
-enum PackageOperation {
- Install,
- Uninstall
-};
-
-#ifdef HAVE_PACKAGEKIT
-#include <PackageKit/Daemon>
-#include <PackageKit/Details>
-#include <PackageKit/Transaction>
-#else
-#include <QDesktopServices>
-#endif
-
-// @param msg Error that gets logged to CLI
-Q_NORETURN void fail(const QString &str)
-{
- qCritical() << str;
- const QStringList args = {"--detailederror" ,i18n("Dolphin service menu installation failed"), str};
- QProcess::startDetached("kdialog", args);
-
- exit(1);
-}
-
-QString getServiceMenusDir()
-{
- const QString dataLocation = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
- return QDir(dataLocation).absoluteFilePath("kservices5/ServiceMenus");
-}
-
-#ifdef HAVE_PACKAGEKIT
-void packageKitInstall(const QString &fileName)
-{
- PackageKit::Transaction *transaction = PackageKit::Daemon::installFile(fileName, PackageKit::Transaction::TransactionFlagNone);
-
- const auto exitWithError = [=](PackageKit::Transaction::Error, const QString &details) {
- fail(details);
- };
-
- QObject::connect(transaction, &PackageKit::Transaction::finished,
- [=](PackageKit::Transaction::Exit status, uint) {
- if (status == PackageKit::Transaction::ExitSuccess) {
- exit(0);
- }
- // Fallback error handling
- QTimer::singleShot(500, [=](){
- fail(i18n("Failed to install \"%1\", exited with status \"%2\"",
- fileName, QVariant::fromValue(status).toString()));
- });
- });
- QObject::connect(transaction, &PackageKit::Transaction::errorCode, exitWithError);
-}
-
-void packageKitUninstall(const QString &fileName)
-{
- const auto exitWithError = [=](PackageKit::Transaction::Error, const QString &details) {
- fail(details);
- };
- const auto uninstallLambda = [=](PackageKit::Transaction::Exit status, uint) {
- if (status == PackageKit::Transaction::ExitSuccess) {
- exit(0);
- }
- };
-
- PackageKit::Transaction *transaction = PackageKit::Daemon::getDetailsLocal(fileName);
- QObject::connect(transaction, &PackageKit::Transaction::details,
- [=](const PackageKit::Details &details) {
- PackageKit::Transaction *transaction = PackageKit::Daemon::removePackage(details.packageId());
- QObject::connect(transaction, &PackageKit::Transaction::finished, uninstallLambda);
- QObject::connect(transaction, &PackageKit::Transaction::errorCode, exitWithError);
- });
-
- QObject::connect(transaction, &PackageKit::Transaction::errorCode, exitWithError);
- // Fallback error handling
- QObject::connect(transaction, &PackageKit::Transaction::finished,
- [=](PackageKit::Transaction::Exit status, uint) {
- if (status != PackageKit::Transaction::ExitSuccess) {
- QTimer::singleShot(500, [=]() {
- fail(i18n("Failed to uninstall \"%1\", exited with status \"%2\"",
- fileName, QVariant::fromValue(status).toString()));
- });
- }
- });
- }
-#endif
-
-Q_NORETURN void packageKit(PackageOperation operation, const QString &fileName)
-{
-#ifdef HAVE_PACKAGEKIT
- QFileInfo fileInfo(fileName);
- if (!fileInfo.exists()) {
- fail(i18n("The file does not exist!"));
- }
- const QString absPath = fileInfo.absoluteFilePath();
- if (operation == PackageOperation::Install) {
- packageKitInstall(absPath);
- } else {
- packageKitUninstall(absPath);
- }
- QGuiApplication::exec(); // For event handling, no return after signals finish
- fail(i18n("Unknown error when installing package"));
-#else
- Q_UNUSED(operation)
- QDesktopServices::openUrl(QUrl(fileName));
- exit(0);
-#endif
-}
-
-struct UncompressCommand
-{
- QString command;
- QStringList args1;
- QStringList args2;
-};
-
-enum ScriptExecution{
- Process,
- Konsole
-};
-
-void runUncompress(const QString &inputPath, const QString &outputPath)
-{
- QVector<QPair<QStringList, UncompressCommand>> mimeTypeToCommand;
- mimeTypeToCommand.append({{"application/x-tar", "application/tar", "application/x-gtar", "multipart/x-tar"},
- UncompressCommand({"tar", {"-xf"}, {"-C"}})});
- mimeTypeToCommand.append({{"application/x-gzip", "application/gzip",
- "application/x-gzip-compressed-tar", "application/gzip-compressed-tar",
- "application/x-gzip-compressed", "application/gzip-compressed",
- "application/tgz", "application/x-compressed-tar",
- "application/x-compressed-gtar", "file/tgz",
- "multipart/x-tar-gz", "application/x-gunzip", "application/gzipped",
- "gzip/document"},
- UncompressCommand({"tar", {"-zxf"}, {"-C"}})});
- mimeTypeToCommand.append({{"application/bzip", "application/bzip2", "application/x-bzip",
- "application/x-bzip2", "application/bzip-compressed",
- "application/bzip2-compressed", "application/x-bzip-compressed",
- "application/x-bzip2-compressed", "application/bzip-compressed-tar",
- "application/bzip2-compressed-tar", "application/x-bzip-compressed-tar",
- "application/x-bzip2-compressed-tar", "application/x-bz2"},
- UncompressCommand({"tar", {"-jxf"}, {"-C"}})});
- mimeTypeToCommand.append({{"application/zip", "application/x-zip", "application/x-zip-compressed",
- "multipart/x-zip"},
- UncompressCommand({"unzip", {}, {"-d"}})});
-
- const auto mime = QMimeDatabase().mimeTypeForFile(inputPath).name();
-
- UncompressCommand command{};
- for (const auto &pair : qAsConst(mimeTypeToCommand)) {
- if (pair.first.contains(mime)) {
- command = pair.second;
- break;
- }
- }
-
- if (command.command.isEmpty()) {
- fail(i18n("Unsupported archive type %1: %2", mime, inputPath));
- }
-
- QProcess process;
- process.start(
- command.command,
- QStringList() << command.args1 << inputPath << command.args2 << outputPath,
- QIODevice::NotOpen);
- if (!process.waitForStarted()) {
- fail(i18n("Failed to run uncompressor command for %1", inputPath));
- }
-
- if (!process.waitForFinished()) {
- fail(
- i18n("Process did not finish in reasonable time: %1 %2", process.program(), process.arguments().join(" ")));
- }
-
- if (process.exitStatus() != QProcess::NormalExit || process.exitCode() != 0) {
- fail(i18n("Failed to uncompress %1", inputPath));
- }
-}
-
-QString findRecursive(const QString &dir, const QString &basename)
-{
- QDirIterator it(dir, QStringList{basename}, QDir::Files, QDirIterator::Subdirectories);
- while (it.hasNext()) {
- return QFileInfo(it.next()).canonicalFilePath();
- }
-
- return QString();
-}
-
-bool runScriptOnce(const QString &path, const QStringList &args, ScriptExecution execution)
-{
- QProcess process;
- process.setWorkingDirectory(QFileInfo(path).absolutePath());
-
- const static bool konsoleAvailable = !QStandardPaths::findExecutable("konsole").isEmpty();
- if (konsoleAvailable && execution == ScriptExecution::Konsole) {
- QString bashCommand = KShell::quoteArg(path) + ' ';
- if (!args.isEmpty()) {
- bashCommand.append(args.join(' '));
- }
- bashCommand.append("|| $SHELL");
- // If the install script fails a shell opens and the user can fix the problem
- // without an error konsole closes
- process.start("konsole", QStringList() << "-e" << "bash" << "-c" << bashCommand, QIODevice::NotOpen);
- } else {
- process.start(path, args, QIODevice::NotOpen);
- }
- if (!process.waitForStarted()) {
- fail(i18n("Failed to run installer script %1", path));
- }
-
- // Wait until installer exits, without timeout
- if (!process.waitForFinished(-1)) {
- qWarning() << "Failed to wait on installer:" << process.program() << process.arguments().join(" ");
- return false;
- }
-
- if (process.exitStatus() != QProcess::NormalExit || process.exitCode() != 0) {
- qWarning() << "Installer script exited with error:" << process.program() << process.arguments().join(" ");
- return false;
- }
-
- return true;
-}
-
-// If hasArgVariants is true, run "path".
-// If hasArgVariants is false, run "path argVariants[i]" until successful.
-bool runScriptVariants(const QString &path, bool hasArgVariants, const QStringList &argVariants, QString &errorText)
-{
- QFile file(path);
- if (!file.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner)) {
- errorText = i18n("Failed to set permissions on %1: %2", path, file.errorString());
- return false;
- }
-
- qInfo() << "[servicemenuinstaller]: Trying to run installer/uninstaller" << path;
- if (hasArgVariants) {
- for (const auto &arg : argVariants) {
- if (runScriptOnce(path, {arg}, ScriptExecution::Process)) {
- return true;
- }
- }
- } else if (runScriptOnce(path, {}, ScriptExecution::Konsole)) {
- return true;
- }
-
- errorText = i18nc(
- "%2 = comma separated list of arguments",
- "Installer script %1 failed, tried arguments \"%2\".", path, argVariants.join(i18nc("Separator between arguments", "\", \"")));
- return false;
-}
-
-QString generateDirPath(const QString &archive)
-{
- return QStringLiteral("%1-dir").arg(archive);
-}
-
-bool cmdInstall(const QString &archive, QString &errorText)
-{
- const auto serviceDir = getServiceMenusDir();
- if (!QDir().mkpath(serviceDir)) {
- // TODO Cannot get error string because of this bug: https://bugreports.qt.io/browse/QTBUG-1483
- errorText = i18n("Failed to create path %1", serviceDir);
- return false;
- }
-
- if (archive.endsWith(QLatin1String(".desktop"))) {
- // Append basename to destination directory
- const auto dest = QDir(serviceDir).absoluteFilePath(QFileInfo(archive).fileName());
- if (QFileInfo::exists(dest)) {
- QFile::remove(dest);
- }
- qInfo() << "Single-File Service-Menu" << archive << dest;
-
- QFile source(archive);
- if (!source.copy(dest)) {
- errorText = i18n("Failed to copy .desktop file %1 to %2: %3", archive, dest, source.errorString());
- return false;
- }
- } else {
- if (binaryPackages->contains(QMimeDatabase().mimeTypeForFile(archive).name())) {
- packageKit(PackageOperation::Install, archive);
- }
- const QString dir = generateDirPath(archive);
- if (QFile::exists(dir)) {
- if (!QDir(dir).removeRecursively()) {
- errorText = i18n("Failed to remove directory %1", dir);
- return false;
- }
- }
-
- if (QDir().mkdir(dir)) {
- errorText = i18n("Failed to create directory %1", dir);
- }
-
- runUncompress(archive, dir);
-
- // Try "install-it" first
- QString installItPath;
- const QStringList basenames1 = {"install-it.sh", "install-it"};
- for (const auto &basename : basenames1) {
- const auto path = findRecursive(dir, basename);
- if (!path.isEmpty()) {
- installItPath = path;
- break;
- }
- }
-
- if (!installItPath.isEmpty()) {
- return runScriptVariants(installItPath, false, QStringList{}, errorText);
- }
-
- // If "install-it" is missing, try "install"
- QString installerPath;
- const QStringList basenames2 = {"installKDE4.sh", "installKDE4", "install.sh", "install"};
- for (const auto &basename : basenames2) {
- const auto path = findRecursive(dir, basename);
- if (!path.isEmpty()) {
- installerPath = path;
- break;
- }
- }
-
- if (!installerPath.isEmpty()) {
- // Try to run script without variants first
- if (!runScriptVariants(installerPath, false, {}, errorText)) {
- return runScriptVariants(installerPath, true, {"--local", "--local-install", "--install"}, errorText);
- }
- return true;
- }
-
- fail(i18n("Failed to find an installation script in %1", dir));
- }
-
- return true;
-}
-
-bool cmdUninstall(const QString &archive, QString &errorText)
-{
- const auto serviceDir = getServiceMenusDir();
- if (archive.endsWith(QLatin1String(".desktop"))) {
- // Append basename to destination directory
- const auto dest = QDir(serviceDir).absoluteFilePath(QFileInfo(archive).fileName());
- QFile file(dest);
- if (!file.remove()) {
- errorText = i18n("Failed to remove .desktop file %1: %2", dest, file.errorString());
- return false;
- }
- } else {
- if (binaryPackages->contains(QMimeDatabase().mimeTypeForFile(archive).name())) {
- packageKit(PackageOperation::Uninstall, archive);
- }
- const QString dir = generateDirPath(archive);
-
- // Try "deinstall" first
- QString deinstallPath;
- const QStringList basenames1 = {"uninstall.sh", "uninstal", "deinstall.sh", "deinstall"};
- for (const auto &basename : basenames1) {
- const auto path = findRecursive(dir, basename);
- if (!path.isEmpty()) {
- deinstallPath = path;
- break;
- }
- }
-
- if (!deinstallPath.isEmpty()) {
- const bool ok = runScriptVariants(deinstallPath, false, {}, errorText);
- if (!ok) {
- return ok;
- }
- } else {
- // If "deinstall" is missing, try "install --uninstall"
- QString installerPath;
- const QStringList basenames2 = {"install-it.sh", "install-it", "installKDE4.sh",
- "installKDE4", "install.sh", "install"};
- for (const auto &basename : basenames2) {
- const auto path = findRecursive(dir, basename);
- if (!path.isEmpty()) {
- installerPath = path;
- break;
- }
- }
-
- if (!installerPath.isEmpty()) {
- const bool ok = runScriptVariants(installerPath, true,
- {"--remove", "--delete", "--uninstall", "--deinstall"}, errorText);
- if (!ok) {
- return ok;
- }
- } else {
- fail(i18n("Failed to find an uninstallation script in %1", dir));
- }
- }
-
- QDir dirObject(dir);
- if (!dirObject.removeRecursively()) {
- errorText = i18n("Failed to remove directory %1", dir);
- return false;
- }
- }
-
- return true;
-}
-
-int main(int argc, char *argv[])
-{
- QGuiApplication app(argc, argv);
-
- QCommandLineParser parser;
- parser.addPositionalArgument(QStringLiteral("command"), i18nc("@info:shell", "Command to execute: install or uninstall."));
- parser.addPositionalArgument(QStringLiteral("path"), i18nc("@info:shell", "Path to archive."));
- parser.process(app);
-
- const QStringList args = parser.positionalArguments();
- if (args.isEmpty()) {
- fail(i18n("Command is required."));
- }
- if (args.size() == 1) {
- fail(i18n("Path to archive is required."));
- }
-
- const QString cmd = args[0];
- const QString archive = args[1];
-
- QString errorText;
- if (cmd == QLatin1String("install")) {
- if (!cmdInstall(archive, errorText)) {
- fail(errorText);
- }
- } else if (cmd == QLatin1String("uninstall")) {
- if (!cmdUninstall(archive, errorText)) {
- fail(errorText);
- }
- } else {
- fail(i18n("Unsupported command %1", cmd));
- }
-
- return 0;
-}
diff --git a/src/settings/services/servicessettingspage.cpp b/src/settings/services/servicessettingspage.cpp
deleted file mode 100644
index fa064d8a1..000000000
--- a/src/settings/services/servicessettingspage.cpp
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * SPDX-FileCopyrightText: 2009-2010 Peter Penz <[email protected]>
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- */
-
-#include "servicessettingspage.h"
-
-#include "dolphin_generalsettings.h"
-#include "dolphin_versioncontrolsettings.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";
-}
-
-ServicesSettingsPage::ServicesSettingsPage(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, &ServicesSettingsPage::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());
-}
-
-ServicesSettingsPage::~ServicesSettingsPage() = default;
-
-void ServicesSettingsPage::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)) {
- GeneralSettings::setShowCopyMoveMenu(checked);
- GeneralSettings::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 ServicesSettingsPage::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 ServicesSettingsPage::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,
- GeneralSettings::showCopyMoveMenu());
-
- m_sortModel->sort(Qt::DisplayRole);
-
- m_initialized = true;
- }
- SettingsPageBase::showEvent(event);
-}
-
-void ServicesSettingsPage::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 ServicesSettingsPage::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 ServicesSettingsPage::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 ServicesSettingsPage::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);
-}
-
diff --git a/src/settings/services/servicessettingspage.h b/src/settings/services/servicessettingspage.h
deleted file mode 100644
index b569852ae..000000000
--- a/src/settings/services/servicessettingspage.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * SPDX-FileCopyrightText: 2009-2010 Peter Penz <[email protected]>
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- */
-#ifndef SERVICESSETTINGSPAGE_H
-#define SERVICESSETTINGSPAGE_H
-
-#include "settings/settingspagebase.h"
-
-#include <QString>
-
-class QListView;
-class QSortFilterProxyModel;
-class ServiceModel;
-class QLineEdit;
-
-/**
- * @brief Page for the 'Services' settings of the Dolphin settings dialog.
- */
-class ServicesSettingsPage : public SettingsPageBase
-{
- Q_OBJECT
-
-public:
- explicit ServicesSettingsPage(QWidget* parent);
- ~ServicesSettingsPage() override;
-
- /** @see SettingsPageBase::applySettings() */
- void applySettings() override;
-
- /** @see SettingsPageBase::restoreDefaults() */
- void restoreDefaults() override;
-
-protected:
- void showEvent(QShowEvent* event) override;
-
-private slots:
- /**
- * Loads locally installed services.
- */
- void loadServices();
-
-private:
- /**
- * Loads installed version control systems.
- */
- void loadVersionControlSystems();
-
- bool isInServicesList(const QString &service) const;
-
- /**
- * Adds a row to the model of m_listView.
- */
- void addRow(const QString &icon,
- const QString &text,
- const QString &value,
- bool checked);
-
-private:
- bool m_initialized;
- ServiceModel *m_serviceModel;
- QSortFilterProxyModel *m_sortModel;
- QListView* m_listView;
- QLineEdit *m_searchLineEdit;
- QStringList m_enabledVcsPlugins;
-};
-
-#endif
diff --git a/src/settings/services/test/service_menu_deinstallation_test.rb b/src/settings/services/test/service_menu_deinstallation_test.rb
deleted file mode 100644
index bf44b7b7f..000000000
--- a/src/settings/services/test/service_menu_deinstallation_test.rb
+++ /dev/null
@@ -1,112 +0,0 @@
-#!/usr/bin/env ruby
-
-# SPDX-FileCopyrightText: 2019 Harald Sitter <[email protected]>
-#
-# SPDX-License-Identifier: GPL-2.0-or-later
-
-require_relative 'test_helper'
-
-require 'tmpdir'
-
-class ServiceMenuDeinstallationTest < Test::Unit::TestCase
- def setup
- @tmpdir = Dir.mktmpdir("dolphintest-#{self.class.to_s.tr(':', '_')}")
- @pwdir = Dir.pwd
- Dir.chdir(@tmpdir)
-
- ENV['XDG_DATA_HOME'] = File.join(@tmpdir, 'data')
- end
-
- def teardown
- Dir.chdir(@pwdir)
- FileUtils.rm_rf(@tmpdir)
-
- ENV.delete('XDG_DATA_HOME')
- end
-
- def test_run_deinstall
- service_dir = File.join(Dir.pwd, 'share/servicemenu-download')
- archive_base = "#{service_dir}/foo.zip"
- archive_dir = "#{archive_base}-dir/foo-1.1/"
- FileUtils.mkpath(archive_dir)
- File.write("#{archive_dir}/deinstall.sh", <<-DEINSTALL_SH)
-#!/bin/sh
-set -e
-cat deinstall.sh
-touch #{@tmpdir}/deinstall.sh-run
- DEINSTALL_SH
- File.write("#{archive_dir}/install.sh", <<-INSTALL_SH)
-#!/bin/sh
-set -e
-cat install.sh
-touch #{@tmpdir}/install.sh-run
- INSTALL_SH
-
- assert(system('servicemenuinstaller', 'uninstall', archive_base))
-
- # deinstaller should be run
- # installer should not be run
- # archive_dir should have been correctly removed
-
- assert_path_exist('deinstall.sh-run')
- assert_path_not_exist('install.sh-run')
- assert_path_not_exist(archive_dir)
- end
-
- def test_run_install_with_arg
- service_dir = File.join(Dir.pwd, 'share/servicemenu-download')
- archive_base = "#{service_dir}/foo.zip"
- archive_dir = "#{archive_base}-dir/foo-1.1/"
- FileUtils.mkpath(archive_dir)
-
- File.write("#{archive_dir}/install.sh", <<-INSTALL_SH)
-#!/bin/sh
-if [ "$@" = "--uninstall" ]; then
- touch #{@tmpdir}/install.sh-run
- exit 0
-fi
-exit 1
- INSTALL_SH
-
- assert(system('servicemenuinstaller', 'uninstall', archive_base))
-
- assert_path_not_exist('deinstall.sh-run')
- assert_path_exist('install.sh-run')
- assert_path_not_exist(archive_dir)
- end
-
- # no scripts in sight
- def test_run_fail
- service_dir = File.join(Dir.pwd, 'share/servicemenu-download')
- archive_base = "#{service_dir}/foo.zip"
- archive_dir = "#{archive_base}-dir/foo-1.1/"
- FileUtils.mkpath(archive_dir)
-
- refute(system('servicemenuinstaller', 'uninstall', archive_base))
-
- # I am unsure if deinstallation really should keep the files around. But
- # that's how it behaved originally so it's supposedly intentional
- # - sitter, 2019
- assert_path_exist(archive_dir)
- end
-
- # For desktop files things are a bit special. There is one in .local/share/servicemenu-download
- # and another in the actual ServiceMenus dir. The latter gets removed by the
- # script, the former by KNS.
- def test_run_desktop
- service_dir = File.join(Dir.pwd, 'share/servicemenu-download')
- downloaded_file = "#{service_dir}/foo.desktop"
- FileUtils.mkpath(service_dir)
- FileUtils.touch(downloaded_file)
-
- menu_dir = "#{ENV['XDG_DATA_HOME']}/kservices5/ServiceMenus/"
- installed_file = "#{menu_dir}/foo.desktop"
- FileUtils.mkpath(menu_dir)
- FileUtils.touch(installed_file)
-
- assert(system('servicemenuinstaller', 'uninstall', downloaded_file))
-
- assert_path_exist(downloaded_file)
- assert_path_not_exist(installed_file)
- end
-end
diff --git a/src/settings/services/test/service_menu_installation_test.rb b/src/settings/services/test/service_menu_installation_test.rb
deleted file mode 100644
index 7c05a40e3..000000000
--- a/src/settings/services/test/service_menu_installation_test.rb
+++ /dev/null
@@ -1,106 +0,0 @@
-#!/usr/bin/env ruby
-
-# SPDX-FileCopyrightText: 2019 Harald Sitter <[email protected]>
-#
-# SPDX-License-Identifier: GPL-2.0-or-later
-
-require_relative 'test_helper'
-
-require 'tmpdir'
-
-class ServiceMenuInstallationTest < Test::Unit::TestCase
- def setup
- @tmpdir = Dir.mktmpdir("dolphintest-#{self.class.to_s.tr(':', '_')}")
- @pwdir = Dir.pwd
- Dir.chdir(@tmpdir)
-
- ENV['XDG_DATA_HOME'] = File.join(@tmpdir, 'data')
- end
-
- def teardown
- Dir.chdir(@pwdir)
- FileUtils.rm_rf(@tmpdir)
-
- ENV.delete('XDG_DATA_HOME')
- end
-
- def test_run_install
- service_dir = File.join(Dir.pwd, 'share/servicemenu-download')
- FileUtils.mkpath(service_dir)
- archive = "#{service_dir}/foo.tar"
-
- archive_dir = 'foo' # relative so tar cf is relative without fuzz
- FileUtils.mkpath(archive_dir)
- File.write("#{archive_dir}/install-it.sh", <<-INSTALL_IT_SH)
-#!/bin/sh
-touch #{@tmpdir}/install-it.sh-run
-INSTALL_IT_SH
- File.write("#{archive_dir}/install.sh", <<-INSTALL_SH)
-#!/bin/sh
-touch #{@tmpdir}/install.sh-run
- INSTALL_SH
- assert(system('tar', '-cf', archive, archive_dir))
-
- assert(system('servicemenuinstaller', 'install', archive))
-
- tar_dir = "#{service_dir}/foo.tar-dir"
- tar_extract_dir = "#{service_dir}/foo.tar-dir/foo"
- assert_path_exist(tar_dir)
- assert_path_exist(tar_extract_dir)
- assert_path_exist("#{tar_extract_dir}/install-it.sh")
- assert_path_exist("#{tar_extract_dir}/install.sh")
- end
-
- def test_run_install_with_arg
- service_dir = File.join(Dir.pwd, 'share/servicemenu-download')
- FileUtils.mkpath(service_dir)
- archive = "#{service_dir}/foo.tar"
-
- archive_dir = 'foo' # relative so tar cf is relative without fuzz
- FileUtils.mkpath(archive_dir)
- File.write("#{archive_dir}/install.sh", <<-INSTALL_SH)
-#!/bin/sh
-if [ "$@" = "--install" ]; then
- touch #{@tmpdir}/install.sh-run
- exit 0
-fi
-exit 1
- INSTALL_SH
- assert(system('tar', '-cf', archive, archive_dir))
-
- assert(system('servicemenuinstaller', 'install', archive))
-
- tar_dir = "#{service_dir}/foo.tar-dir"
- tar_extract_dir = "#{service_dir}/foo.tar-dir/foo"
- assert_path_exist(tar_dir)
- assert_path_exist(tar_extract_dir)
- assert_path_not_exist("#{tar_extract_dir}/install-it.sh")
- assert_path_exist("#{tar_extract_dir}/install.sh")
- end
-
- def test_run_fail
- service_dir = File.join(Dir.pwd, 'share/servicemenu-download')
- FileUtils.mkpath(service_dir)
- archive = "#{service_dir}/foo.tar"
-
- archive_dir = 'foo' # relative so tar cf is relative without fuzz
- FileUtils.mkpath(archive_dir)
- assert(system('tar', '-cf', archive, archive_dir))
-
- refute(system('servicemenuinstaller', 'install', archive))
- end
-
- def test_run_desktop
- service_dir = File.join(Dir.pwd, 'share/servicemenu-download')
- downloaded_file = "#{service_dir}/foo.desktop"
- FileUtils.mkpath(service_dir)
- FileUtils.touch(downloaded_file)
-
- installed_file = "#{ENV['XDG_DATA_HOME']}/kservices5/ServiceMenus/foo.desktop"
-
- assert(system('servicemenuinstaller', 'install', downloaded_file))
-
- assert_path_exist(downloaded_file)
- assert_path_exist(installed_file)
- end
-end
diff --git a/src/settings/services/test/test_helper.rb b/src/settings/services/test/test_helper.rb
deleted file mode 100644
index b4e4dded2..000000000
--- a/src/settings/services/test/test_helper.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# SPDX-FileCopyrightText: 2019 Harald Sitter <[email protected]>
-#
-# SPDX-License-Identifier: GPL-2.0-or-later
-
-$LOAD_PATH.unshift(File.absolute_path('../', __dir__)) # ../
-
-def __test_method_name__
- return @method_name if defined?(:@method_name)
- index = 0
- caller = ''
- until caller.start_with?('test_')
- caller = caller_locations(index, 1)[0].label
- index += 1
- end
- caller
-end
-
-require 'test/unit'
diff --git a/src/settings/services/test/test_run.rb b/src/settings/services/test/test_run.rb
deleted file mode 100755
index ab298a0b0..000000000
--- a/src/settings/services/test/test_run.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/usr/bin/env ruby
-
-# SPDX-FileCopyrightText: 2019 Harald Sitter <[email protected]>
-#
-# SPDX-License-Identifier: GPL-2.0-or-later
-# This is a fancy wrapper around test_helper to prevent the collector from
-# loading the helper twice as it would occur if we ran the helper directly.
-
-require_relative 'test_helper'
-
-Test::Unit::AutoRunner.run(true, File.absolute_path(__dir__))