Fix PluginView to handle dependencies when disabling plugins

Reviewed-by: con
This commit is contained in:
Lasse Holmstedt
2010-05-19 16:29:47 +02:00
parent 7948147410
commit 5570764103
7 changed files with 67 additions and 31 deletions

View File

@@ -585,6 +585,17 @@ void PluginManager::profilingReport(const char *what, const PluginSpec *spec)
d->profilingReport(what, spec); d->profilingReport(what, spec);
} }
/*!
\fn void PluginManager::loadQueue()
Returns a list of plugins in load order.
*/
QList<PluginSpec *> PluginManager::loadQueue()
{
return d->loadQueue();
}
//============PluginManagerPrivate=========== //============PluginManagerPrivate===========
/*! /*!
@@ -786,13 +797,10 @@ bool PluginManagerPrivate::loadQueue(PluginSpec *spec, QList<PluginSpec *> &queu
circularityCheckQueue.append(spec); circularityCheckQueue.append(spec);
// check if we have the dependencies // check if we have the dependencies
if (spec->state() == PluginSpec::Invalid || spec->state() == PluginSpec::Read) { if (spec->state() == PluginSpec::Invalid || spec->state() == PluginSpec::Read) {
if (!spec->isDisabledIndirectly() && spec->isEnabled()) { queue.append(spec);
spec->d->hasError = true;
spec->d->errorString += "\n";
spec->d->errorString += PluginManager::tr("Cannot load plugin because dependencies are not resolved");
}
return false; return false;
} }
// add dependencies // add dependencies
foreach (PluginSpec *depSpec, spec->dependencySpecs()) { foreach (PluginSpec *depSpec, spec->dependencySpecs()) {
if (!loadQueue(depSpec, queue, circularityCheckQueue)) { if (!loadQueue(depSpec, queue, circularityCheckQueue)) {
@@ -814,7 +822,11 @@ bool PluginManagerPrivate::loadQueue(PluginSpec *spec, QList<PluginSpec *> &queu
*/ */
void PluginManagerPrivate::loadPlugin(PluginSpec *spec, PluginSpec::State destState) void PluginManagerPrivate::loadPlugin(PluginSpec *spec, PluginSpec::State destState)
{ {
if (spec->hasError() || spec->isDisabledIndirectly()) if (spec->hasError() || spec->state() != destState-1)
return;
// don't load disabled plugins.
if ((spec->isDisabledIndirectly() || !spec->isEnabled()) && destState == PluginSpec::Loaded)
return; return;
switch (destState) { switch (destState) {
@@ -927,6 +939,9 @@ void PluginManagerPrivate::resolveDependencies()
foreach (PluginSpec *spec, pluginSpecs) { foreach (PluginSpec *spec, pluginSpecs) {
spec->d->resolveDependencies(pluginSpecs); spec->d->resolveDependencies(pluginSpecs);
} }
foreach (PluginSpec *spec, loadQueue()) {
spec->d->disableIndirectlyIfDependencyDisabled();
}
} }
// Look in argument descriptions of the specs for the option. // Look in argument descriptions of the specs for the option.

View File

@@ -91,6 +91,7 @@ public:
} }
// Plugin operations // Plugin operations
QList<PluginSpec *> loadQueue();
void loadPlugins(); void loadPlugins();
QStringList pluginPaths() const; QStringList pluginPaths() const;
void setPluginPaths(const QStringList &paths); void setPluginPaths(const QStringList &paths);

View File

@@ -500,6 +500,11 @@ void PluginSpec::setEnabled(bool value)
d->enabled = value; d->enabled = value;
} }
void PluginSpec::setDisabledIndirectly(bool value)
{
d->disabledIndirectly = value;
}
/*! /*!
\fn bool PluginSpecPrivate::reportError(const QString &err) \fn bool PluginSpecPrivate::reportError(const QString &err)
\internal \internal
@@ -799,11 +804,7 @@ bool PluginSpecPrivate::resolveDependencies(const QList<PluginSpec *> &specs)
foreach (PluginSpec *spec, specs) { foreach (PluginSpec *spec, specs) {
if (spec->provides(dependency.name, dependency.version)) { if (spec->provides(dependency.name, dependency.version)) {
found = spec; found = spec;
if (!spec->isEnabled() || spec->isDisabledIndirectly())
disabledIndirectly = true;
spec->d->addProvidesForPlugin(q); spec->d->addProvidesForPlugin(q);
break; break;
} }
} }
@@ -822,12 +823,26 @@ bool PluginSpecPrivate::resolveDependencies(const QList<PluginSpec *> &specs)
dependencySpecs = resolvedDependencies; dependencySpecs = resolvedDependencies;
if (enabled && !disabledIndirectly) state = PluginSpec::Resolved;
state = PluginSpec::Resolved;
return true; return true;
} }
void PluginSpecPrivate::disableIndirectlyIfDependencyDisabled()
{
disabledIndirectly = false;
if (!enabled)
return;
foreach (PluginSpec *dependencySpec, dependencySpecs) {
if (dependencySpec->isDisabledIndirectly() || !dependencySpec->isEnabled()) {
disabledIndirectly = true;
break;
}
}
}
/*! /*!
\fn bool PluginSpecPrivate::loadLibrary() \fn bool PluginSpecPrivate::loadLibrary()
\internal \internal

View File

@@ -92,6 +92,7 @@ public:
QString filePath() const; QString filePath() const;
void setEnabled(bool value); void setEnabled(bool value);
void setDisabledIndirectly(bool value);
QStringList arguments() const; QStringList arguments() const;
void setArguments(const QStringList &arguments); void setArguments(const QStringList &arguments);

View File

@@ -92,6 +92,8 @@ public:
// add/remove from providesSpecs // add/remove from providesSpecs
void addProvidesForPlugin(PluginSpec *dependent); void addProvidesForPlugin(PluginSpec *dependent);
void removeProvidesForPlugin(PluginSpec *dependent); void removeProvidesForPlugin(PluginSpec *dependent);
void disableIndirectlyIfDependencyDisabled();
private: private:
PluginSpec *q; PluginSpec *q;

View File

@@ -177,8 +177,7 @@ void PluginView::updateList()
defaultCollectionItem->setToolTip(C_LOAD, tr("Load on Startup")); defaultCollectionItem->setToolTip(C_LOAD, tr("Load on Startup"));
defaultCollectionItem->setData(0, Qt::UserRole, qVariantFromValue(defaultCollection)); defaultCollectionItem->setData(0, Qt::UserRole, qVariantFromValue(defaultCollection));
foreach (PluginSpec *spec, m_specToItem.keys()) updatePluginDependencies();
toggleRelatedPlugins(spec, spec->isEnabled() && !spec->isDisabledIndirectly());
m_ui->categoryWidget->clear(); m_ui->categoryWidget->clear();
if (!m_items.isEmpty()) { if (!m_items.isEmpty()) {
@@ -301,7 +300,7 @@ void PluginView::updatePluginSettings(QTreeWidgetItem *item, int column)
if (column == C_LOAD) { if (column == C_LOAD) {
spec->setEnabled(loadOnStartup); spec->setEnabled(loadOnStartup);
toggleRelatedPlugins(spec, loadOnStartup); updatePluginDependencies();
if (item->parent()) { if (item->parent()) {
PluginCollection *collection = item->parent()->data(0, Qt::UserRole).value<PluginCollection *>(); PluginCollection *collection = item->parent()->data(0, Qt::UserRole).value<PluginCollection *>();
@@ -332,33 +331,36 @@ void PluginView::updatePluginSettings(QTreeWidgetItem *item, int column)
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);
toggleRelatedPlugins(spec, loadOnStartup);
} else { } else {
child->setData(C_LOAD, Qt::CheckStateRole, Qt::Checked); child->setData(C_LOAD, Qt::CheckStateRole, Qt::Checked);
child->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); child->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
} }
} }
updatePluginDependencies();
emit pluginSettingsChanged(collection->plugins().first()); emit pluginSettingsChanged(collection->plugins().first());
} }
m_allowCheckStateUpdate = true; m_allowCheckStateUpdate = true;
} }
void PluginView::toggleRelatedPlugins(PluginSpec *modifiedPlugin, bool isPluginEnabled) void PluginView::updatePluginDependencies()
{ {
foreach (PluginSpec *spec, PluginManager::instance()->loadQueue()) {
for(int i = 0; i < modifiedPlugin->providesForSpecs().length(); ++i) { bool disableIndirectly = false;
PluginSpec *spec = modifiedPlugin->providesForSpecs().at(i); foreach(const PluginSpec *depSpec, spec->dependencySpecs()) {
QTreeWidgetItem *childItem = m_specToItem.value(spec); if (!depSpec->isEnabled() || depSpec->isDisabledIndirectly()) {
disableIndirectly = true;
if (childItem->isDisabled() != !isPluginEnabled) { break;
childItem->setDisabled(!isPluginEnabled); }
if (childItem->parent() && !childItem->parent()->isExpanded())
childItem->parent()->setExpanded(true);
toggleRelatedPlugins(spec, isPluginEnabled);
} }
QTreeWidgetItem *childItem = m_specToItem.value(spec);
childItem->setDisabled(disableIndirectly);
if (disableIndirectly == spec->isDisabledIndirectly())
continue;
spec->setDisabledIndirectly(disableIndirectly);
if (childItem->parent() && !childItem->parent()->isExpanded())
childItem->parent()->setExpanded(true);
} }
} }

View File

@@ -77,7 +77,7 @@ private slots:
private: private:
enum ParsedState { ParsedNone = 1, ParsedPartial = 2, ParsedAll = 4, ParsedWithErrors = 8}; enum ParsedState { ParsedNone = 1, ParsedPartial = 2, ParsedAll = 4, ParsedWithErrors = 8};
QIcon iconForState(int state); QIcon iconForState(int state);
void toggleRelatedPlugins(PluginSpec *spec, bool isPluginEnabled = true); void updatePluginDependencies();
int parsePluginSpecs(QTreeWidgetItem *parentItem, Qt::CheckState &groupState, QList<PluginSpec*> plugins); int parsePluginSpecs(QTreeWidgetItem *parentItem, Qt::CheckState &groupState, QList<PluginSpec*> plugins);
Internal::Ui::PluginView *m_ui; Internal::Ui::PluginView *m_ui;