]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/settings/services/servicessettingspage.cpp
Dolphin: Cleanup service settings page
[dolphin.git] / src / settings / services / servicessettingspage.cpp
index 7da29939930fc06fca5a2a4aa1976b618ddd961c..e18bfb09ec2c6476a62c66235f9e60092052460a 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2009-2010 by Peter Penz <peter.penz@gmx.at>             *
+ *   Copyright (C) 2009-2010 by Peter Penz <peter.penz19@gmail.com>        *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
 
 #include "servicessettingspage.h"
 
+#include "dolphin_generalsettings.h"
 #include "dolphin_versioncontrolsettings.h"
-
-#include <kconfig.h>
-#include <kconfiggroup.h>
-#include <kdesktopfile.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.h>
-#include <kicon.h>
-#include <klocale.h>
-#include <kmessagebox.h>
-#include <knewstuff3/knewstuffbutton.h>
-#include <kservice.h>
-#include <kservicetypetrader.h>
-#include <kstandarddirs.h>
-
-#include <QCheckBox>
+
 #include <QGridLayout>
-#include <QGroupBox>
 #include <QLabel>
 #include <QListWidget>
-#include <QPushButton>
 #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_servicesList(0),
-    m_vcsGroupBox(0),
-    m_vcsPluginsMap(),
+    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);
+                                     "be shown in the context menu:"), this);
     label->setWordWrap(true);
-
-    m_servicesList = new QListWidget(this);
-    m_servicesList->setSortingEnabled(true);
-    m_servicesList->setSelectionMode(QAbstractItemView::NoSelection);
-    connect(m_servicesList, SIGNAL(itemClicked(QListWidgetItem*)),
-            this, SIGNAL(changed()));
-
-    KNS3::Button* downloadButton = new KNS3::Button(i18nc("@action:button", "Download New Services..."),
-                                                    "servicemenu.knsrc",
-                                                    this);
-    connect(downloadButton, SIGNAL(dialogFinished(KNS3::Entry::List)), this, SLOT(loadServices()));
-
-    m_vcsGroupBox = new QGroupBox(i18nc("@title:group", "Version Control Systems"), this);
-    // Only show the version control group box, if a version
-    // control system could be found (see loadVersionControlSystems())
-    m_vcsGroupBox->hide();
+    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);
+    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);
+
+    auto *downloadButton = new KNS3::Button(i18nc("@action:button", "Download New Services..."),
+                                                  QStringLiteral("servicemenu.knsrc"),
+                                                  this);
+    connect(downloadButton, &KNS3::Button::dialogFinished, this, &ServicesSettingsPage::loadServices);
 
     topLayout->addWidget(label);
-    topLayout->addWidget(m_servicesList);
+    topLayout->addWidget(m_searchLineEdit);
+    topLayout->addWidget(m_listView);
     topLayout->addWidget(downloadButton);
-    topLayout->addWidget(m_vcsGroupBox);
 
     m_enabledVcsPlugins = VersionControlSettings::enabledPlugins();
+    std::sort(m_enabledVcsPlugins.begin(), m_enabledVcsPlugins.end());
 }
 
-ServicesSettingsPage::~ServicesSettingsPage()
-{
-}
+ServicesSettingsPage::~ServicesSettingsPage() = default;
 
 void ServicesSettingsPage::applySettings()
 {
-    // Apply service menu settings
-    KConfig config("kservicemenurc", KConfig::NoGlobals);
-    KConfigGroup showGroup = config.group("Show");
-
-    const int count = m_servicesList->count();
-    for (int i = 0; i < count; ++i) {
-        QListWidgetItem* item = m_servicesList->item(i);
-        const bool show = (item->checkState() == Qt::Checked);
-        const QString service = item->data(Qt::UserRole).toString();
-        showGroup.writeEntry(service, show);
+    if (!m_initialized) {
+        return;
     }
 
-    showGroup.sync();
+    KConfig config(QStringLiteral("kservicemenurc"), KConfig::NoGlobals);
+    KConfigGroup showGroup = config.group("Show");
 
-    // Apply version control settings
     QStringList enabledPlugins;
-    QMap<QString, QCheckBox*>::const_iterator it = m_vcsPluginsMap.constBegin();
-    while (it != m_vcsPluginsMap.constEnd()) {
-        if (it.value()->isChecked()) {
-            enabledPlugins.append(it.key());
+
+    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);
         }
-        ++it;
     }
 
+    showGroup.sync();
+
     if (m_enabledVcsPlugins != enabledPlugins) {
         VersionControlSettings::setEnabledPlugins(enabledPlugins);
-        VersionControlSettings::self()->writeConfig();
+        VersionControlSettings::self()->save();
 
         KMessageBox::information(window(),
                                  i18nc("@info", "Dolphin must be restarted to apply the "
                                                 "updated version control systems settings."),
                                  QString(), // default title
-                                 QLatin1String("ShowVcsRestartInformation"));
+                                 QStringLiteral("ShowVcsRestartInformation"));
     }
 }
 
 void ServicesSettingsPage::restoreDefaults()
 {
-    const int count = m_servicesList->count();
-    for (int i = 0; i < count; ++i) {
-        QListWidgetItem* item = m_servicesList->item(i);
-        item->setCheckState(Qt::Checked);
+    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) {
-        QMetaObject::invokeMethod(this, "loadServices", Qt::QueuedConnection);
-        QMetaObject::invokeMethod(this, "loadVersionControlSystems", Qt::QueuedConnection);
+        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);
@@ -143,37 +190,57 @@ void ServicesSettingsPage::showEvent(QShowEvent* event)
 
 void ServicesSettingsPage::loadServices()
 {
-    const KConfig config("kservicemenurc", KConfig::NoGlobals);
+    const KConfig config(QStringLiteral("kservicemenurc"), KConfig::NoGlobals);
     const KConfigGroup showGroup = config.group("Show");
 
-    const KService::List entries = KServiceTypeTrader::self()->query("KonqPopupMenu/Plugin");
-    foreach (const KSharedPtr<KService>& service, entries) {
-        const QString file = KStandardDirs::locate("services", service->entryPath());
-        const QList<KServiceAction> serviceActions =
-                                    KDesktopFileActions::userDefinedServices(file, true);
+    // 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);
 
-        KDesktopFile desktopFile(file);
+        const KDesktopFile desktopFile(file);
         const QString subMenuName = desktopFile.desktopGroup().readEntry("X-KDE-Submenu");
 
-        foreach (const KServiceAction& action, serviceActions) {
-            const QString service = action.name();
-            const bool addService = !action.noDisplay()
-                                    && !action.isSeparator()
-                                    && !isInServicesList(service);
+        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());
-                QListWidgetItem* item = new QListWidgetItem(KIcon(action.icon()),
-                                                            itemName,
-                                                            m_servicesList);
-                item->setData(Qt::UserRole, service);
-                const bool show = showGroup.readEntry(service, true);
-                item->setCheckState(show ? Qt::Checked : Qt::Unchecked);
+                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()
@@ -181,42 +248,40 @@ void ServicesSettingsPage::loadVersionControlSystems()
     const QStringList enabledPlugins = VersionControlSettings::enabledPlugins();
 
     // Create a checkbox for each available version control plugin
-    const KService::List pluginServices = KServiceTypeTrader::self()->query("FileViewVersionControlPlugin");
-    for (KService::List::ConstIterator it = pluginServices.constBegin(); it != pluginServices.constEnd(); ++it) {
-        const QString pluginName = (*it)->name();
-        QCheckBox* checkBox = new QCheckBox(pluginName, m_vcsGroupBox);
-        checkBox->setChecked(enabledPlugins.contains(pluginName));
-        connect(checkBox, SIGNAL(clicked()), this, SIGNAL(changed()));
-        m_vcsPluginsMap.insert(pluginName, checkBox);
-    }
-
-    // Add the checkboxes into a grid layout of 2 columns
-    QGridLayout* layout = new QGridLayout(m_vcsGroupBox);
-    const int maxRows = (m_vcsPluginsMap.count() + 1) / 2;
-
-    int index = 0;
-    QMap<QString, QCheckBox*>::const_iterator it = m_vcsPluginsMap.constBegin();
-    while (it != m_vcsPluginsMap.constEnd()) {
-        const int column = index / maxRows;
-        const int row = index % maxRows;
-        layout->addWidget(it.value(), row, column);
-        ++it;
-        ++index;
+    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_vcsGroupBox->setVisible(!m_vcsPluginsMap.isEmpty());
+    m_sortModel->sort(Qt::DisplayRole);
 }
 
-bool ServicesSettingsPage::isInServicesList(const QStringservice) const
+bool ServicesSettingsPage::isInServicesList(const QString &service) const
 {
-    const int count = m_servicesList->count();
-    for (int i = 0; i < count; ++i) {
-        QListWidgetItem* item = m_servicesList->item(i);
-        if (item->data(Qt::UserRole).toString() == service) {
+    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;
 }
 
-#include "servicessettingspage.moc"
+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);
+}
+