diff options
| author | Duong Do Minh Chau <[email protected]> | 2020-11-12 16:38:44 +0700 |
|---|---|---|
| committer | Elvis Angelaccio <[email protected]> | 2020-12-28 20:18:31 +0000 |
| commit | a512176b4bdbf0f0471a9b9089f4a936c14e2732 (patch) | |
| tree | 51f1ecf98d29b9994af950d9ca2fb0085f29e337 /src/settings/services | |
| parent | b339ac1b5f22efb57619c738eb39268c3e00948d (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.knsrc | 9 | ||||
| -rw-r--r-- | src/settings/services/servicemenuinstaller/CMakeLists.txt | 15 | ||||
| -rwxr-xr-x | src/settings/services/servicemenuinstaller/Messages.sh | 2 | ||||
| -rw-r--r-- | src/settings/services/servicemenuinstaller/servicemenuinstaller.cpp | 462 | ||||
| -rw-r--r-- | src/settings/services/servicessettingspage.cpp | 287 | ||||
| -rw-r--r-- | src/settings/services/servicessettingspage.h | 69 | ||||
| -rw-r--r-- | src/settings/services/test/service_menu_deinstallation_test.rb | 112 | ||||
| -rw-r--r-- | src/settings/services/test/service_menu_installation_test.rb | 106 | ||||
| -rw-r--r-- | src/settings/services/test/test_helper.rb | 18 | ||||
| -rwxr-xr-x | src/settings/services/test/test_run.rb | 11 |
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__)) |
