Git commit cdaebc21b8fcde2001cc1fcd3239534cd904e65c by Elvis Angelaccio. Committed on 19/12/2016 at 15:58. Pushed by elvisangelaccio into branch 'master'.
Introduce settings page to configure plugins This commit adds a page in the settings dialog where the user can enable/disable plugins. The page contains a QTreeWidget which is not supported by KConfigDialog out of the box, so some glue-code is necessary to properly handle the Apply/Default buttons. ArkSettings stores a list of disabled plugins (by default, all plugins are enabled). If a plugin is not valid because of missing executables, the respective item in the view is disabled and a warning is displayed in a tooltip. Differential Revision: D3716 Task: T1984 GUI: M +2 -0 kerfuffle/CMakeLists.txt M +4 -0 kerfuffle/ark.kcfg M +6 -1 kerfuffle/plugin.cpp M +6 -0 kerfuffle/plugin.h M +3 -7 kerfuffle/pluginmanager.cpp A +108 -0 kerfuffle/pluginsettingspage.cpp [License: BSD] A +59 -0 kerfuffle/pluginsettingspage.h [License: BSD] A +38 -0 kerfuffle/pluginsettingspage.ui M +2 -0 part/part.cpp https://commits.kde.org/ark/cdaebc21b8fcde2001cc1fcd3239534cd904e65c diff --git a/kerfuffle/CMakeLists.txt b/kerfuffle/CMakeLists.txt index 4bc4c441..8f846f6e 100644 --- a/kerfuffle/CMakeLists.txt +++ b/kerfuffle/CMakeLists.txt @@ -22,6 +22,7 @@ set(kerfuffle_SRCS mimetypes.cpp plugin.cpp pluginmanager.cpp + pluginsettingspage.cpp archiveentry.cpp options.cpp ) @@ -33,6 +34,7 @@ ki18n_wrap_ui(kerfuffle_SRCS extractiondialog.ui extractionsettingspage.ui generalsettingspage.ui + pluginsettingspage.ui previewsettingspage.ui propertiesdialog.ui compressionoptionswidget.ui diff --git a/kerfuffle/ark.kcfg b/kerfuffle/ark.kcfg index 2910cf7e..4777bfb6 100644 --- a/kerfuffle/ark.kcfg +++ b/kerfuffle/ark.kcfg @@ -46,6 +46,10 @@ <default>true</default> </entry> </group> + <group name="Plugins"> + <entry name="disabledPlugins" type="StringList"> + </entry> + </group> <group name="Preview"> <entry name="limitPreviewFileSize" type="Bool"> <label>Whether to limit the preview according to file size.</label> diff --git a/kerfuffle/plugin.cpp b/kerfuffle/plugin.cpp index 4503492e..7c179b6a 100644 --- a/kerfuffle/plugin.cpp +++ b/kerfuffle/plugin.cpp @@ -93,9 +93,14 @@ KPluginMetaData Plugin::metaData() const return m_metaData; } +bool Plugin::hasRequiredExecutables() const +{ + return findExecutables(readOnlyExecutables()); +} + bool Plugin::isValid() const { - return isEnabled() && m_metaData.isValid() && findExecutables(readOnlyExecutables()); + return isEnabled() && m_metaData.isValid() && hasRequiredExecutables(); } bool Plugin::findExecutables(const QStringList &executables) diff --git a/kerfuffle/plugin.h b/kerfuffle/plugin.h index 17da7670..7558e6a8 100644 --- a/kerfuffle/plugin.h +++ b/kerfuffle/plugin.h @@ -86,6 +86,12 @@ public: KPluginMetaData metaData() const; /** + * @return Whether the executables required for a functional plugin are installed. + * This is true if all the read-only executables are found in the path. + */ + bool hasRequiredExecutables() const; + + /** * @return Whether the plugin is ready to be used. * This implies isEnabled(), while an enabled plugin may not be valid. * A read-write plugin downgraded to read-only is still valid. diff --git a/kerfuffle/pluginmanager.cpp b/kerfuffle/pluginmanager.cpp index 13edf1a0..883724e8 100644 --- a/kerfuffle/pluginmanager.cpp +++ b/kerfuffle/pluginmanager.cpp @@ -26,6 +26,8 @@ */ #include "pluginmanager.h" +#include "ark_debug.h" +#include "settings.h" #include <KConfigGroup> #include <KPluginLoader> @@ -195,12 +197,6 @@ QVector<Plugin*> PluginManager::filterBy(const QVector<Plugin*> &plugins, const void PluginManager::loadPlugins() { const QVector<KPluginMetaData> plugins = KPluginLoader::findPlugins(QStringLiteral("kerfuffle")); - // This class might be used from executables other than ark (e.g. the tests), - // so we need to specify the name of the config file. - // TODO: once we have a GUI in the settings dialog, - // use this group to write whether a plugin gets disabled. - const KConfigGroup conf(KSharedConfig::openConfig(QStringLiteral("arkrc")), "EnabledPlugins"); - QSet<QString> addedPlugins; foreach (const KPluginMetaData &metaData, plugins) { const auto pluginId = metaData.pluginId(); @@ -210,7 +206,7 @@ void PluginManager::loadPlugins() } Plugin *plugin = new Plugin(this, metaData); - plugin->setEnabled(conf.readEntry(pluginId, true)); + plugin->setEnabled(!ArkSettings::disabledPlugins().contains(pluginId)); addedPlugins << pluginId; m_plugins << plugin; } diff --git a/kerfuffle/pluginsettingspage.cpp b/kerfuffle/pluginsettingspage.cpp new file mode 100644 index 00000000..a3cbf168 --- /dev/null +++ b/kerfuffle/pluginsettingspage.cpp @@ -0,0 +1,108 @@ +/* + * ark -- archiver for the KDE project + * + * Copyright (C) 2016 Elvis Angelaccio <[email protected]> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "pluginsettingspage.h" +#include "ark_debug.h" + +#include <QTreeWidget> + +#include <KConfigDialogManager> + +namespace Kerfuffle +{ + +PluginSettingsPage::PluginSettingsPage(QWidget *parent, const QString &name, const QString &iconName) + : SettingsPage(parent, name, iconName) +{ + setupUi(this); + + foreach (const auto plugin, m_pluginManager.installedPlugins()) { + const auto metaData = plugin->metaData(); + auto item = new QTreeWidgetItem(kcfg_disabledPlugins); + item->setData(0, Qt::UserRole, QVariant::fromValue(plugin)); + item->setText(0, metaData.name()); + item->setText(1, metaData.description()); + item->setCheckState(0, plugin->isEnabled() ? Qt::Checked : Qt::Unchecked); + if (!plugin->isEnabled()) { + m_toBeDisabled << metaData.pluginId(); + } + if (!plugin->hasRequiredExecutables()) { + item->setDisabled(true); + for (int i : {0, 1}) { + item->setToolTip(i, i18n("The plugin cannot be used because one or more required executables are missing. Check your installation.")); + } + } + } + + kcfg_disabledPlugins->resizeColumnToContents(0); + connect(kcfg_disabledPlugins, &QTreeWidget::itemChanged, this, &PluginSettingsPage::slotItemChanged); + + // Set the custom property that KConfigDialogManager will use to update the settings. + kcfg_disabledPlugins->setProperty("kcfg_property", QByteArray("disabledPlugins")); + // Tell KConfigDialogManager to monitor the itemChanged signal for a QTreeWidget instance in the dialog. + KConfigDialogManager::changedMap()->insert(QString::fromLatin1(QTreeWidget::staticMetaObject.className()), + SIGNAL(itemChanged(QTreeWidgetItem*,int))); +} + +void PluginSettingsPage::slotSettingsChanged() +{ + m_toBeDisabled.clear(); +} + +void PluginSettingsPage::slotDefaultsButtonClicked() +{ + // KConfigDialogManager doesn't know how to reset the QTreeWidget, we need to do it manually. + QTreeWidgetItemIterator iterator(kcfg_disabledPlugins); + while (*iterator) { + auto item = *iterator; + // By default every plugin is enabled. + item->setCheckState(0, Qt::Checked); + iterator++; + } +} + +void PluginSettingsPage::slotItemChanged(QTreeWidgetItem *item) +{ + auto plugin = item->data(0, Qt::UserRole).value<Plugin*>(); + if (!plugin) { + return; + } + + const auto pluginId = plugin->metaData().pluginId(); + plugin->setEnabled(item->checkState(0) == Qt::Checked); + // If unchecked, add to the list of plugins that will be disabled. + m_toBeDisabled.removeAll(pluginId); + if (!plugin->isEnabled()) { + m_toBeDisabled << pluginId; + } + // Enable the Apply button by setting the property. + qCDebug(ARK) << "Going to disable the following plugins:" << m_toBeDisabled; + kcfg_disabledPlugins->setProperty("disabledPlugins", m_toBeDisabled); +} + +} + diff --git a/kerfuffle/pluginsettingspage.h b/kerfuffle/pluginsettingspage.h new file mode 100644 index 00000000..2b5390ab --- /dev/null +++ b/kerfuffle/pluginsettingspage.h @@ -0,0 +1,59 @@ +/* + * ark -- archiver for the KDE project + * + * Copyright (C) 2016 Elvis Angelaccio <[email protected]> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PLUGINSETTINGSPAGE_H +#define PLUGINSETTINGSPAGE_H + +#include "settingspage.h" +#include "pluginmanager.h" +#include "ui_pluginsettingspage.h" + +class QTreeWidgetItem; + +namespace Kerfuffle +{ +class KERFUFFLE_EXPORT PluginSettingsPage : public SettingsPage, public Ui::PluginSettingsPage +{ + Q_OBJECT + +public: + explicit PluginSettingsPage(QWidget *parent = Q_NULLPTR, const QString &name = QString(), const QString &iconName = QString()); + +public slots: + void slotSettingsChanged() Q_DECL_OVERRIDE; + void slotDefaultsButtonClicked() Q_DECL_OVERRIDE; + +private slots: + void slotItemChanged(QTreeWidgetItem *item); + +private: + QStringList m_toBeDisabled; // List of plugins that will be disabled upon clicking the Apply button. + PluginManager m_pluginManager; +}; +} + +#endif diff --git a/kerfuffle/pluginsettingspage.ui b/kerfuffle/pluginsettingspage.ui new file mode 100644 index 00000000..2b35eff1 --- /dev/null +++ b/kerfuffle/pluginsettingspage.ui @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>PluginSettingsPage</class> + <widget class="QWidget" name="PluginSettingsPage"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>547</width> + <height>487</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QTreeWidget" name="kcfg_disabledPlugins"> + <property name="rootIsDecorated"> + <bool>false</bool> + </property> + <property name="columnCount"> + <number>2</number> + </property> + <column> + <property name="text"> + <string extracomment="@title:column">Name</string> + </property> + </column> + <column> + <property name="text"> + <string extracomment="@title:column">Description</string> + </property> + </column> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/part/part.cpp b/part/part.cpp index 8246492d..21cc3476 100644 --- a/part/part.cpp +++ b/part/part.cpp @@ -40,6 +40,7 @@ #include "settings.h" #include "previewsettingspage.h" #include "propertiesdialog.h" +#include "pluginsettingspage.h" #include "pluginmanager.h" #include <KAboutData> @@ -797,6 +798,7 @@ QList<Kerfuffle::SettingsPage*> Part::settingsPages(QWidget *parent) const QList<SettingsPage*> pages; pages.append(new GeneralSettingsPage(parent, i18nc("@title:tab", "General Settings"), QStringLiteral("go-home"))); pages.append(new ExtractionSettingsPage(parent, i18nc("@title:tab", "Extraction Settings"), QStringLiteral("archive-extract"))); + pages.append(new PluginSettingsPage(parent, i18nc("@title:tab", "Plugin Settings"), QStringLiteral("plugins"))); pages.append(new PreviewSettingsPage(parent, i18nc("@title:tab", "Preview Settings"), QStringLiteral("document-preview-archive"))); return pages;
