PluginManager: Remove hardcoded list of plugins that cannot be disabled

Instead add an optional attribute "required" to the plugin spec. Since
the locator plugin and find plugin are gone, and I don't see a reason to
prevent disabling the text editor plugin, only Core plugin gets the new
attribute set.

Change-Id: I7a380026ea46173cf00afff4213ca1b3a2578434
Reviewed-by: Daniel Teske <daniel.teske@digia.com>
This commit is contained in:
Eike Ziller
2014-07-03 17:41:24 +02:00
parent 9c6f559156
commit ac31d3c67e
9 changed files with 40 additions and 33 deletions

View File

@@ -31,8 +31,8 @@
\section2 Main Tag \section2 Main Tag
The root tag is \c plugin. It has the mandatory attributes \c name The root tag is \c plugin. It has the mandatory attributes \c name
and \c version, and the optional attributes \c compatVersion, \c experimental and \c version, and the optional attributes \c compatVersion, \c experimental,
and \c disabledByDefault. \c disabledByDefault and \c required.
\table \table
\header \header
\li Tag \li Tag
@@ -79,6 +79,12 @@
If set, the respective plugin is not loaded by default but must be explicitly If set, the respective plugin is not loaded by default but must be explicitly
enabled by the user. This should be done for plugins which are not expected enabled by the user. This should be done for plugins which are not expected
to be used by so many people as to justify the additional resource consumption. to be used by so many people as to justify the additional resource consumption.
\row
\li required
\li Optional. Can be \c true or \c false, defaults to \c false.
Is used as a hint for the \gui{About Plugins...} dialog, that the user may not
manually disable this plugin. Only used for the Core plugin.
\endtable \endtable
\section2 Plugin-describing Tags \section2 Plugin-describing Tags

View File

@@ -270,6 +270,11 @@ bool PluginSpec::isAvailableForHostPlatform() const
return d->platformSpecification.isEmpty() || d->platformSpecification.exactMatch(PluginManager::platformName()); return d->platformSpecification.isEmpty() || d->platformSpecification.exactMatch(PluginManager::platformName());
} }
bool PluginSpec::isRequired() const
{
return d->required;
}
/*! /*!
Returns whether the plugin has its experimental flag set. Returns whether the plugin has its experimental flag set.
*/ */
@@ -465,6 +470,7 @@ namespace {
const char PLUGIN_NAME[] = "name"; const char PLUGIN_NAME[] = "name";
const char PLUGIN_VERSION[] = "version"; const char PLUGIN_VERSION[] = "version";
const char PLUGIN_COMPATVERSION[] = "compatVersion"; const char PLUGIN_COMPATVERSION[] = "compatVersion";
const char PLUGIN_REQUIRED[] = "required";
const char PLUGIN_EXPERIMENTAL[] = "experimental"; const char PLUGIN_EXPERIMENTAL[] = "experimental";
const char PLUGIN_DISABLED_BY_DEFAULT[] = "disabledByDefault"; const char PLUGIN_DISABLED_BY_DEFAULT[] = "disabledByDefault";
const char VENDOR[] = "vendor"; const char VENDOR[] = "vendor";
@@ -490,17 +496,17 @@ namespace {
\internal \internal
*/ */
PluginSpecPrivate::PluginSpecPrivate(PluginSpec *spec) PluginSpecPrivate::PluginSpecPrivate(PluginSpec *spec)
: : required(false),
experimental(false), experimental(false),
disabledByDefault(false), disabledByDefault(false),
enabledInSettings(true), enabledInSettings(true),
disabledIndirectly(false), disabledIndirectly(false),
forceEnabled(false), forceEnabled(false),
forceDisabled(false), forceDisabled(false),
plugin(0), plugin(0),
state(PluginSpec::Invalid), state(PluginSpec::Invalid),
hasError(false), hasError(false),
q(spec) q(spec)
{ {
} }
@@ -647,8 +653,9 @@ void PluginSpecPrivate::readPluginSpec(QXmlStreamReader &reader)
} else if (compatVersion.isEmpty()) { } else if (compatVersion.isEmpty()) {
compatVersion = version; compatVersion = version;
} }
disabledByDefault = readBooleanValue(reader, PLUGIN_DISABLED_BY_DEFAULT); required = readBooleanValue(reader, PLUGIN_REQUIRED);
experimental = readBooleanValue(reader, PLUGIN_EXPERIMENTAL); experimental = readBooleanValue(reader, PLUGIN_EXPERIMENTAL);
disabledByDefault = readBooleanValue(reader, PLUGIN_DISABLED_BY_DEFAULT);
if (reader.hasError()) if (reader.hasError())
return; return;
if (experimental) if (experimental)

View File

@@ -93,6 +93,7 @@ public:
QString category() const; QString category() const;
QRegExp platformSpecification() const; QRegExp platformSpecification() const;
bool isAvailableForHostPlatform() const; bool isAvailableForHostPlatform() const;
bool isRequired() const;
bool isExperimental() const; bool isExperimental() const;
bool isDisabledByDefault() const; bool isDisabledByDefault() const;
bool isEnabledInSettings() const; bool isEnabledInSettings() const;

View File

@@ -65,6 +65,7 @@ public:
QString name; QString name;
QString version; QString version;
QString compatVersion; QString compatVersion;
bool required;
bool experimental; bool experimental;
bool disabledByDefault; bool disabledByDefault;
QString vendor; QString vendor;

View File

@@ -108,10 +108,6 @@ PluginView::PluginView(QWidget *parent)
m_errorIcon = QIcon(QLatin1String(":/extensionsystem/images/error.png")); m_errorIcon = QIcon(QLatin1String(":/extensionsystem/images/error.png"));
m_notLoadedIcon = QIcon(QLatin1String(":/extensionsystem/images/notloaded.png")); m_notLoadedIcon = QIcon(QLatin1String(":/extensionsystem/images/notloaded.png"));
// cannot disable these
m_whitelist << QString::fromLatin1("Core") << QString::fromLatin1("Locator")
<< QString::fromLatin1("Find") << QString::fromLatin1("TextEditor");
connect(PluginManager::instance(), SIGNAL(pluginsChanged()), this, SLOT(updateList())); connect(PluginManager::instance(), SIGNAL(pluginsChanged()), this, SLOT(updateList()));
connect(m_categoryWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), connect(m_categoryWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
this, SLOT(selectPlugin(QTreeWidgetItem*))); this, SLOT(selectPlugin(QTreeWidgetItem*)));
@@ -238,13 +234,13 @@ int PluginView::parsePluginSpecs(QTreeWidgetItem *parentItem, Qt::CheckState &gr
pluginItem->setData(C_LOAD, Qt::CheckStateRole, Qt::Unchecked); pluginItem->setData(C_LOAD, Qt::CheckStateRole, Qt::Unchecked);
pluginItem->setFlags(Qt::ItemIsSelectable); pluginItem->setFlags(Qt::ItemIsSelectable);
pluginItem->setToolTip(C_LOAD, tr("Plugin is not vailable for this platform.")); pluginItem->setToolTip(C_LOAD, tr("Plugin is not vailable for this platform."));
} else if (!m_whitelist.contains(spec->name())) { } else if (spec->isRequired()){
pluginItem->setData(C_LOAD, Qt::CheckStateRole, state);
pluginItem->setToolTip(C_LOAD, tr("Load on startup"));
} else {
pluginItem->setData(C_LOAD, Qt::CheckStateRole, Qt::Checked); pluginItem->setData(C_LOAD, Qt::CheckStateRole, Qt::Checked);
pluginItem->setFlags(Qt::ItemIsSelectable); pluginItem->setFlags(Qt::ItemIsSelectable);
pluginItem->setToolTip(C_LOAD, tr("Plugin is required.")); pluginItem->setToolTip(C_LOAD, tr("Plugin is required."));
} else {
pluginItem->setData(C_LOAD, Qt::CheckStateRole, state);
pluginItem->setToolTip(C_LOAD, tr("Load on startup"));
} }
m_specToItem.insert(spec, pluginItem); m_specToItem.insert(spec, pluginItem);
@@ -340,16 +336,10 @@ void PluginView::updatePluginSettings(QTreeWidgetItem *item, int column)
PluginSpec *spec = collection->plugins().at(i); PluginSpec *spec = collection->plugins().at(i);
QTreeWidgetItem *child = m_specToItem.value(spec); QTreeWidgetItem *child = m_specToItem.value(spec);
if (!spec->isAvailableForHostPlatform()) { if (spec->isAvailableForHostPlatform() && !spec->isRequired()) {
child->setData(C_LOAD, Qt::CheckStateRole, Qt::Unchecked);
child->setFlags(Qt::ItemIsSelectable);
} else if (!m_whitelist.contains(spec->name())) {
spec->setEnabled(loadOnStartup); spec->setEnabled(loadOnStartup);
Qt::CheckState state = (loadOnStartup ? Qt::Checked : Qt::Unchecked); Qt::CheckState state = (loadOnStartup ? Qt::Checked : Qt::Unchecked);
child->setData(C_LOAD, Qt::CheckStateRole, state); child->setData(C_LOAD, Qt::CheckStateRole, state);
} else {
child->setData(C_LOAD, Qt::CheckStateRole, Qt::Checked);
child->setFlags(Qt::ItemIsSelectable);
} }
} }
updatePluginDependencies(); updatePluginDependencies();
@@ -364,7 +354,7 @@ void PluginView::updatePluginDependencies()
{ {
foreach (PluginSpec *spec, PluginManager::loadQueue()) { foreach (PluginSpec *spec, PluginManager::loadQueue()) {
bool disableIndirectly = false; bool disableIndirectly = false;
if (m_whitelist.contains(spec->name())) if (spec->isRequired())
continue; continue;
QHashIterator<PluginDependency, PluginSpec *> it(spec->dependencySpecs()); QHashIterator<PluginDependency, PluginSpec *> it(spec->dependencySpecs());

View File

@@ -79,7 +79,6 @@ private:
QList<QTreeWidgetItem*> m_items; QList<QTreeWidgetItem*> m_items;
QHash<PluginSpec*, QTreeWidgetItem*> m_specToItem; QHash<PluginSpec*, QTreeWidgetItem*> m_specToItem;
QStringList m_whitelist;
QIcon m_okIcon; QIcon m_okIcon;
QIcon m_errorIcon; QIcon m_errorIcon;
QIcon m_notLoadedIcon; QIcon m_notLoadedIcon;

View File

@@ -1,4 +1,4 @@
<plugin name=\"Core\" version=\"$$QTCREATOR_VERSION\" compatVersion=\"$$QTCREATOR_COMPAT_VERSION\"> <plugin name=\"Core\" version=\"$$QTCREATOR_VERSION\" compatVersion=\"$$QTCREATOR_COMPAT_VERSION\" required=\"true\">
<vendor>Digia Plc</vendor> <vendor>Digia Plc</vendor>
<copyright>(C) 2014 Digia Plc</copyright> <copyright>(C) 2014 Digia Plc</copyright>
<license> <license>

View File

@@ -1,2 +1,2 @@
<plugin name="test" version="3.1.4_10"> <plugin name="test" version="3.1.4_10" required="true">
</plugin> </plugin>

View File

@@ -74,6 +74,7 @@ void tst_PluginSpec::read()
QCOMPARE(spec.name, QString("test")); QCOMPARE(spec.name, QString("test"));
QCOMPARE(spec.version, QString("1.0.1")); QCOMPARE(spec.version, QString("1.0.1"));
QCOMPARE(spec.compatVersion, QString("1.0.0")); QCOMPARE(spec.compatVersion, QString("1.0.0"));
QCOMPARE(spec.required, false);
QCOMPARE(spec.experimental, false); QCOMPARE(spec.experimental, false);
QCOMPARE(spec.enabledInSettings, true); QCOMPARE(spec.enabledInSettings, true);
QCOMPARE(spec.vendor, QString("Digia Plc")); QCOMPARE(spec.vendor, QString("Digia Plc"));
@@ -90,9 +91,11 @@ void tst_PluginSpec::read()
QCOMPARE(spec.dependencies, QList<PluginDependency>() << dep1 << dep2); QCOMPARE(spec.dependencies, QList<PluginDependency>() << dep1 << dep2);
// test missing compatVersion behavior // test missing compatVersion behavior
// and 'required' attribute
QVERIFY(spec.read("testspecs/spec2.xml")); QVERIFY(spec.read("testspecs/spec2.xml"));
QCOMPARE(spec.version, QString("3.1.4_10")); QCOMPARE(spec.version, QString("3.1.4_10"));
QCOMPARE(spec.compatVersion, QString("3.1.4_10")); QCOMPARE(spec.compatVersion, QString("3.1.4_10"));
QCOMPARE(spec.required, true);
} }
void tst_PluginSpec::readError() void tst_PluginSpec::readError()