diff --git a/kerfuffle/CMakeLists.txt b/kerfuffle/CMakeLists.txt
--- a/kerfuffle/CMakeLists.txt
+++ b/kerfuffle/CMakeLists.txt
@@ -22,6 +22,7 @@
mimetypes.cpp
plugin.cpp
pluginmanager.cpp
+ pluginsettingspage.cpp
archiveentry.cpp
options.cpp
)
@@ -33,6 +34,7 @@
extractiondialog.ui
extractionsettingspage.ui
generalsettingspage.ui
+ pluginsettingspage.ui
previewsettingspage.ui
propertiesdialog.ui
compressionoptionswidget.ui
diff --git a/kerfuffle/ark.kcfg b/kerfuffle/ark.kcfg
--- a/kerfuffle/ark.kcfg
+++ b/kerfuffle/ark.kcfg
@@ -46,6 +46,10 @@
true
+
+
+
+
diff --git a/kerfuffle/plugin.h b/kerfuffle/plugin.h
--- a/kerfuffle/plugin.h
+++ b/kerfuffle/plugin.h
@@ -86,6 +86,12 @@
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/plugin.cpp b/kerfuffle/plugin.cpp
--- a/kerfuffle/plugin.cpp
+++ b/kerfuffle/plugin.cpp
@@ -93,9 +93,14 @@
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/pluginmanager.cpp b/kerfuffle/pluginmanager.cpp
--- a/kerfuffle/pluginmanager.cpp
+++ b/kerfuffle/pluginmanager.cpp
@@ -26,6 +26,8 @@
*/
#include "pluginmanager.h"
+#include "ark_debug.h"
+#include "settings.h"
#include
#include
@@ -195,12 +197,6 @@
void PluginManager::loadPlugins()
{
const QVector 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 addedPlugins;
foreach (const KPluginMetaData &metaData, plugins) {
const auto pluginId = metaData.pluginId();
@@ -210,7 +206,7 @@
}
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.h b/kerfuffle/pluginsettingspage.h
new file mode 100644
--- /dev/null
+++ b/kerfuffle/pluginsettingspage.h
@@ -0,0 +1,59 @@
+/*
+ * ark -- archiver for the KDE project
+ *
+ * Copyright (C) 2016 Elvis Angelaccio
+ *
+ * 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.cpp b/kerfuffle/pluginsettingspage.cpp
new file mode 100644
--- /dev/null
+++ b/kerfuffle/pluginsettingspage.cpp
@@ -0,0 +1,108 @@
+/*
+ * ark -- archiver for the KDE project
+ *
+ * Copyright (C) 2016 Elvis Angelaccio
+ *
+ * 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
+
+#include
+
+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();
+ 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.ui b/kerfuffle/pluginsettingspage.ui
new file mode 100644
--- /dev/null
+++ b/kerfuffle/pluginsettingspage.ui
@@ -0,0 +1,38 @@
+
+
+ PluginSettingsPage
+
+
+
+ 0
+ 0
+ 547
+ 487
+
+
+
+
+
+
+ false
+
+
+ 2
+
+
+
+ Name
+
+
+
+
+ Description
+
+
+
+
+
+
+
+
+
diff --git a/part/part.cpp b/part/part.cpp
--- 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
@@ -797,6 +798,7 @@
QList 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;