forked from qt-creator/qt-creator
Fix PluginView to handle dependencies when disabling plugins
Reviewed-by: con
This commit is contained in:
@@ -585,6 +585,17 @@ void PluginManager::profilingReport(const char *what, const PluginSpec *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===========
|
||||
|
||||
/*!
|
||||
@@ -786,13 +797,10 @@ bool PluginManagerPrivate::loadQueue(PluginSpec *spec, QList<PluginSpec *> &queu
|
||||
circularityCheckQueue.append(spec);
|
||||
// check if we have the dependencies
|
||||
if (spec->state() == PluginSpec::Invalid || spec->state() == PluginSpec::Read) {
|
||||
if (!spec->isDisabledIndirectly() && spec->isEnabled()) {
|
||||
spec->d->hasError = true;
|
||||
spec->d->errorString += "\n";
|
||||
spec->d->errorString += PluginManager::tr("Cannot load plugin because dependencies are not resolved");
|
||||
}
|
||||
queue.append(spec);
|
||||
return false;
|
||||
}
|
||||
|
||||
// add dependencies
|
||||
foreach (PluginSpec *depSpec, spec->dependencySpecs()) {
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
switch (destState) {
|
||||
@@ -927,6 +939,9 @@ void PluginManagerPrivate::resolveDependencies()
|
||||
foreach (PluginSpec *spec, pluginSpecs) {
|
||||
spec->d->resolveDependencies(pluginSpecs);
|
||||
}
|
||||
foreach (PluginSpec *spec, loadQueue()) {
|
||||
spec->d->disableIndirectlyIfDependencyDisabled();
|
||||
}
|
||||
}
|
||||
|
||||
// Look in argument descriptions of the specs for the option.
|
||||
|
||||
@@ -91,6 +91,7 @@ public:
|
||||
}
|
||||
|
||||
// Plugin operations
|
||||
QList<PluginSpec *> loadQueue();
|
||||
void loadPlugins();
|
||||
QStringList pluginPaths() const;
|
||||
void setPluginPaths(const QStringList &paths);
|
||||
|
||||
@@ -500,6 +500,11 @@ void PluginSpec::setEnabled(bool value)
|
||||
d->enabled = value;
|
||||
}
|
||||
|
||||
void PluginSpec::setDisabledIndirectly(bool value)
|
||||
{
|
||||
d->disabledIndirectly = value;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn bool PluginSpecPrivate::reportError(const QString &err)
|
||||
\internal
|
||||
@@ -799,11 +804,7 @@ bool PluginSpecPrivate::resolveDependencies(const QList<PluginSpec *> &specs)
|
||||
foreach (PluginSpec *spec, specs) {
|
||||
if (spec->provides(dependency.name, dependency.version)) {
|
||||
found = spec;
|
||||
if (!spec->isEnabled() || spec->isDisabledIndirectly())
|
||||
disabledIndirectly = true;
|
||||
|
||||
spec->d->addProvidesForPlugin(q);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -822,12 +823,26 @@ bool PluginSpecPrivate::resolveDependencies(const QList<PluginSpec *> &specs)
|
||||
|
||||
dependencySpecs = resolvedDependencies;
|
||||
|
||||
if (enabled && !disabledIndirectly)
|
||||
state = PluginSpec::Resolved;
|
||||
|
||||
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()
|
||||
\internal
|
||||
|
||||
@@ -92,6 +92,7 @@ public:
|
||||
QString filePath() const;
|
||||
|
||||
void setEnabled(bool value);
|
||||
void setDisabledIndirectly(bool value);
|
||||
|
||||
QStringList arguments() const;
|
||||
void setArguments(const QStringList &arguments);
|
||||
|
||||
@@ -92,6 +92,8 @@ public:
|
||||
// add/remove from providesSpecs
|
||||
void addProvidesForPlugin(PluginSpec *dependent);
|
||||
void removeProvidesForPlugin(PluginSpec *dependent);
|
||||
void disableIndirectlyIfDependencyDisabled();
|
||||
|
||||
|
||||
private:
|
||||
PluginSpec *q;
|
||||
|
||||
@@ -177,8 +177,7 @@ void PluginView::updateList()
|
||||
defaultCollectionItem->setToolTip(C_LOAD, tr("Load on Startup"));
|
||||
defaultCollectionItem->setData(0, Qt::UserRole, qVariantFromValue(defaultCollection));
|
||||
|
||||
foreach (PluginSpec *spec, m_specToItem.keys())
|
||||
toggleRelatedPlugins(spec, spec->isEnabled() && !spec->isDisabledIndirectly());
|
||||
updatePluginDependencies();
|
||||
|
||||
m_ui->categoryWidget->clear();
|
||||
if (!m_items.isEmpty()) {
|
||||
@@ -301,7 +300,7 @@ void PluginView::updatePluginSettings(QTreeWidgetItem *item, int column)
|
||||
if (column == C_LOAD) {
|
||||
|
||||
spec->setEnabled(loadOnStartup);
|
||||
toggleRelatedPlugins(spec, loadOnStartup);
|
||||
updatePluginDependencies();
|
||||
|
||||
if (item->parent()) {
|
||||
PluginCollection *collection = item->parent()->data(0, Qt::UserRole).value<PluginCollection *>();
|
||||
@@ -332,33 +331,36 @@ void PluginView::updatePluginSettings(QTreeWidgetItem *item, int column)
|
||||
spec->setEnabled(loadOnStartup);
|
||||
Qt::CheckState state = (loadOnStartup ? Qt::Checked : Qt::Unchecked);
|
||||
child->setData(C_LOAD, Qt::CheckStateRole, state);
|
||||
toggleRelatedPlugins(spec, loadOnStartup);
|
||||
} else {
|
||||
child->setData(C_LOAD, Qt::CheckStateRole, Qt::Checked);
|
||||
child->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||
}
|
||||
}
|
||||
updatePluginDependencies();
|
||||
emit pluginSettingsChanged(collection->plugins().first());
|
||||
}
|
||||
|
||||
m_allowCheckStateUpdate = true;
|
||||
}
|
||||
|
||||
void PluginView::toggleRelatedPlugins(PluginSpec *modifiedPlugin, bool isPluginEnabled)
|
||||
void PluginView::updatePluginDependencies()
|
||||
{
|
||||
|
||||
for(int i = 0; i < modifiedPlugin->providesForSpecs().length(); ++i) {
|
||||
PluginSpec *spec = modifiedPlugin->providesForSpecs().at(i);
|
||||
foreach (PluginSpec *spec, PluginManager::instance()->loadQueue()) {
|
||||
bool disableIndirectly = false;
|
||||
foreach(const PluginSpec *depSpec, spec->dependencySpecs()) {
|
||||
if (!depSpec->isEnabled() || depSpec->isDisabledIndirectly()) {
|
||||
disableIndirectly = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
QTreeWidgetItem *childItem = m_specToItem.value(spec);
|
||||
childItem->setDisabled(disableIndirectly);
|
||||
|
||||
if (disableIndirectly == spec->isDisabledIndirectly())
|
||||
continue;
|
||||
spec->setDisabledIndirectly(disableIndirectly);
|
||||
|
||||
if (childItem->isDisabled() != !isPluginEnabled) {
|
||||
childItem->setDisabled(!isPluginEnabled);
|
||||
if (childItem->parent() && !childItem->parent()->isExpanded())
|
||||
childItem->parent()->setExpanded(true);
|
||||
|
||||
|
||||
toggleRelatedPlugins(spec, isPluginEnabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ private slots:
|
||||
private:
|
||||
enum ParsedState { ParsedNone = 1, ParsedPartial = 2, ParsedAll = 4, ParsedWithErrors = 8};
|
||||
QIcon iconForState(int state);
|
||||
void toggleRelatedPlugins(PluginSpec *spec, bool isPluginEnabled = true);
|
||||
void updatePluginDependencies();
|
||||
int parsePluginSpecs(QTreeWidgetItem *parentItem, Qt::CheckState &groupState, QList<PluginSpec*> plugins);
|
||||
|
||||
Internal::Ui::PluginView *m_ui;
|
||||
|
||||
Reference in New Issue
Block a user