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);
|
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.
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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()) {
|
||||||
|
if (!depSpec->isEnabled() || depSpec->isDisabledIndirectly()) {
|
||||||
|
disableIndirectly = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
QTreeWidgetItem *childItem = m_specToItem.value(spec);
|
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())
|
if (childItem->parent() && !childItem->parent()->isExpanded())
|
||||||
childItem->parent()->setExpanded(true);
|
childItem->parent()->setExpanded(true);
|
||||||
|
|
||||||
|
|
||||||
toggleRelatedPlugins(spec, isPluginEnabled);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user