diff --git a/autotests/alternativesmodeltest.h b/autotests/alternativesmodeltest.h --- a/autotests/alternativesmodeltest.h +++ b/autotests/alternativesmodeltest.h @@ -27,6 +27,7 @@ void runJobTest(); void bigBufferTest(); void disablePluginTest(); + void blacklistTest(); }; #endif diff --git a/autotests/alternativesmodeltest.cpp b/autotests/alternativesmodeltest.cpp --- a/autotests/alternativesmodeltest.cpp +++ b/autotests/alternativesmodeltest.cpp @@ -58,6 +58,8 @@ model.setInputData(input); model.setPluginType(QStringLiteral("Export")); + model.setDisabledPlugins({}); + Purpose::Configuration* conf = model.configureJob(saveAsRow(&model)); QVERIFY(!conf->isReady()); QVERIFY(!conf->createJob()); @@ -94,6 +96,7 @@ }; model.setInputData(input); model.setPluginType(QStringLiteral("Export")); + model.setDisabledPlugins({}); Purpose::Configuration* conf = model.configureJob(saveAsRow(&model)); QVERIFY(conf->isReady()); @@ -126,6 +129,7 @@ }; model.setInputData(input); model.setPluginType(QStringLiteral("Export")); + model.setDisabledPlugins({}); for (int i = 0; i < model.rowCount(); ++i) { plugins << model.index(i).data(Purpose::AlternativesModel::PluginIdRole).toString(); @@ -149,3 +153,43 @@ // "cleanup" group.writeEntry("disabled", QStringList()); } + +void AlternativesModelTest::blacklistTest() +{ + const auto listPlugins = [](const QStringList &blacklist = QStringList()) { + QStringList plugins; + Purpose::AlternativesModel model; + QJsonObject input = QJsonObject { + {QStringLiteral("urls"), QJsonArray {QStringLiteral("http://kde.org")} }, + {QStringLiteral("mimeType"), QStringLiteral("dummy/thing") } + }; + model.setInputData(input); + model.setPluginType(QStringLiteral("Export")); + if (!blacklist.isEmpty()) { + model.setDisabledPlugins(blacklist); + } + + for (int i = 0; i < model.rowCount(); ++i) { + plugins << model.index(i).data(Purpose::AlternativesModel::PluginIdRole).toString(); + } + return plugins; + }; + + auto plugins = listPlugins(); + QVERIFY(plugins.contains(QStringLiteral("kdeconnectplugin"))); + + plugins = listPlugins({QStringLiteral("kdeconnectplugin")}); + QVERIFY(!plugins.contains(QStringLiteral("kdeconnectplugin"))); + + plugins = listPlugins({QStringLiteral("saveasplugin")}); + QVERIFY(plugins.contains(QStringLiteral("kdeconnectplugin"))); + + // Admin settings have precedence + QStandardPaths::setTestModeEnabled(true); + auto config = KSharedConfig::openConfig(QStringLiteral("purposerc")); + auto group = config->group("plugins"); + group.writeEntry("disabled", QStringList{ QStringLiteral("kdeconnectplugin") }); + + plugins = listPlugins({QStringLiteral("saveasplugin")}); + QVERIFY(!plugins.contains(QStringLiteral("kdeconnectplugin"))); +} diff --git a/src/alternativesmodel.h b/src/alternativesmodel.h --- a/src/alternativesmodel.h +++ b/src/alternativesmodel.h @@ -39,6 +39,7 @@ Q_OBJECT Q_PROPERTY(QString pluginType READ pluginType WRITE setPluginType NOTIFY pluginTypeChanged) Q_PROPERTY(QJsonObject inputData READ inputData WRITE setInputData NOTIFY inputDataChanged) +Q_PROPERTY(QStringList disabledPlugins READ disabledPlugins WRITE setDisabledPlugins NOTIFY disabledPluginsChanged) public: enum Roles { PluginIdRole = Qt::UserRole+1, @@ -54,6 +55,9 @@ QString pluginType() const; void setPluginType(const QString& pluginType); + QStringList disabledPlugins() const; + void setDisabledPlugins(const QStringList& pluginIds); + /** * This shouldn't require to have the job actually running on the same process as the app. * @@ -71,6 +75,7 @@ Q_SIGNALS: void inputDataChanged(); void pluginTypeChanged(); + void disabledPluginsChanged(); private: void initializeModel(); diff --git a/src/alternativesmodel.cpp b/src/alternativesmodel.cpp --- a/src/alternativesmodel.cpp +++ b/src/alternativesmodel.cpp @@ -38,6 +38,8 @@ using namespace Purpose; +static const QStringList s_defaultDisabledPlugins = {QStringLiteral("saveasplugin")}; + typedef bool (*matchFunction)(const QString& constraint, const QJsonValue& value); static bool defaultMatch(const QString& constraint, const QJsonValue& value) @@ -78,6 +80,7 @@ QVector m_plugins; QJsonObject m_inputData; QString m_pluginType; + QStringList m_disabledPlugins = s_defaultDisabledPlugins; QJsonObject m_pluginTypeData; bool isPluginAcceptable(const KPluginMetaData &meta, const QStringList &disabledPlugins) const { @@ -87,7 +90,7 @@ return false; } - if (disabledPlugins.contains(meta.pluginId())) { + if (disabledPlugins.contains(meta.pluginId()) || m_disabledPlugins.contains(meta.pluginId())) { //qDebug() << "disabled plugin" << meta.name() << meta.pluginId(); return false; } @@ -163,6 +166,25 @@ Q_EMIT pluginTypeChanged(); } +QStringList AlternativesModel::disabledPlugins() const +{ + Q_D(const AlternativesModel); + return d->m_disabledPlugins; +} + +void AlternativesModel::setDisabledPlugins(const QStringList &pluginIds) +{ + Q_D(AlternativesModel); + if (pluginIds == d->m_disabledPlugins) + return; + + d->m_disabledPlugins = pluginIds; + + initializeModel(); + + Q_EMIT disabledPluginsChanged(); +} + QString AlternativesModel::pluginType() const { Q_D(const AlternativesModel);