summaryrefslogtreecommitdiff
path: root/src/libs/extensionsystem/pluginspec.cpp
diff options
context:
space:
mode:
authorcon <qtc-committer@nokia.com>2011-01-11 14:01:08 +0100
committercon <qtc-committer@nokia.com>2011-01-11 15:08:05 +0100
commit4116504c3b5813d9fcbef25f43765303e88148cd (patch)
tree354547605feee0d6e172d22fda2de97d9eaea7ab /src/libs/extensionsystem/pluginspec.cpp
parent1c1acd0c4cee350d65df8c4b439c8b19932c6f6d (diff)
downloadqt-creator-4116504c3b5813d9fcbef25f43765303e88148cd.tar.gz
Allow optional plugin dependencies.
Adds a 'type' attribute to the 'dependency' tag, with possible values 'required' and 'optional'. Optional dependencies may not be linked against. You'll need to use the new dynamic methods in plugin manager (retrieving objects and calling methods by name) if you want to access functionality of optional dependencies.
Diffstat (limited to 'src/libs/extensionsystem/pluginspec.cpp')
-rw-r--r--src/libs/extensionsystem/pluginspec.cpp97
1 files changed, 60 insertions, 37 deletions
diff --git a/src/libs/extensionsystem/pluginspec.cpp b/src/libs/extensionsystem/pluginspec.cpp
index 7b18c1a0aa..b4d968367a 100644
--- a/src/libs/extensionsystem/pluginspec.cpp
+++ b/src/libs/extensionsystem/pluginspec.cpp
@@ -88,6 +88,23 @@
*/
/*!
+ \variable ExtensionSystem::PluginDependency::type
+ Defines whether the dependency is required or optional.
+ \sa ExtensionSystem::PluginDependency::Type
+*/
+
+/*!
+ \enum ExtensionSystem::PluginDependency::Type
+ Whether the dependency is required or optional.
+ \value Required
+ Dependency needs to be there.
+ \value Optional
+ Dependency is not necessarily needed. You need to make sure that
+ the plugin is able to load without this dependency installed, so
+ for example you may not link to the dependency's library.
+*/
+
+/*!
\class ExtensionSystem::PluginSpec
\brief Contains the information of the plugins xml description file and
information about the plugin's current state.
@@ -127,16 +144,26 @@
\value Deleted
The plugin instance has been deleted.
*/
+
using namespace ExtensionSystem;
using namespace ExtensionSystem::Internal;
/*!
+ \fn uint qHash(const ExtensionSystem::PluginDependency &value)
+ \internal
+*/
+uint ExtensionSystem::qHash(const ExtensionSystem::PluginDependency &value)
+{
+ return qHash(value.name);
+}
+
+/*!
\fn bool PluginDependency::operator==(const PluginDependency &other)
\internal
*/
-bool PluginDependency::operator==(const PluginDependency &other)
+bool PluginDependency::operator==(const PluginDependency &other) const
{
- return name == other.name && version == other.version;
+ return name == other.name && version == other.version && type == other.type;
}
/*!
@@ -395,22 +422,11 @@ IPlugin *PluginSpec::plugin() const
\sa PluginSpec::dependencies()
*/
-QList<PluginSpec *> PluginSpec::dependencySpecs() const
+QHash<PluginDependency, PluginSpec *> PluginSpec::dependencySpecs() const
{
return d->dependencySpecs;
}
-/*!
- \fn QList<PluginSpec *> PluginSpec::providesForSpecs() const
- Returns the list of plugins that depend on this one.
-
- \sa PluginSpec::dependencySpecs()
-*/
-QList<PluginSpec *> PluginSpec::providesForSpecs() const
-{
- return d->providesSpecs;
-}
-
//==========PluginSpecPrivate==================
namespace {
@@ -429,6 +445,9 @@ namespace {
const char * const DEPENDENCY = "dependency";
const char * const DEPENDENCY_NAME = "name";
const char * const DEPENDENCY_VERSION = "version";
+ const char * const DEPENDENCY_TYPE = "type";
+ const char * const DEPENDENCY_TYPE_SOFT = "optional";
+ const char * const DEPENDENCY_TYPE_HARD = "required";
const char * const ARGUMENTLIST = "argumentList";
const char * const ARGUMENT = "argument";
const char * const ARGUMENT_NAME = "name";
@@ -726,6 +745,18 @@ void PluginSpecPrivate::readDependencyEntry(QXmlStreamReader &reader)
reader.raiseError(msgInvalidFormat(DEPENDENCY_VERSION));
return;
}
+ dep.type = PluginDependency::Required;
+ if (reader.attributes().hasAttribute(DEPENDENCY_TYPE)) {
+ QString typeValue = reader.attributes().value(DEPENDENCY_TYPE).toString();
+ if (typeValue == QLatin1String(DEPENDENCY_TYPE_HARD)) {
+ dep.type = PluginDependency::Required;
+ } else if (typeValue == QLatin1String(DEPENDENCY_TYPE_SOFT)) {
+ dep.type = PluginDependency::Optional;
+ } else {
+ reader.raiseError(msgInvalidFormat(DEPENDENCY_TYPE));
+ return;
+ }
+ }
dependencies.append(dep);
reader.readNext();
if (reader.tokenType() != QXmlStreamReader::EndElement)
@@ -801,26 +832,27 @@ bool PluginSpecPrivate::resolveDependencies(const QList<PluginSpec *> &specs)
hasError = true;
return false;
}
- QList<PluginSpec *> resolvedDependencies;
+ QHash<PluginDependency, PluginSpec *> resolvedDependencies;
foreach (const PluginDependency &dependency, dependencies) {
PluginSpec *found = 0;
foreach (PluginSpec *spec, specs) {
if (spec->provides(dependency.name, dependency.version)) {
found = spec;
- spec->d->addProvidesForPlugin(q);
break;
}
}
if (!found) {
- hasError = true;
- if (!errorString.isEmpty())
- errorString.append(QLatin1Char('\n'));
- errorString.append(QCoreApplication::translate("PluginSpec", "Could not resolve dependency '%1(%2)'")
- .arg(dependency.name).arg(dependency.version));
+ if (dependency.type == PluginDependency::Required) {
+ hasError = true;
+ if (!errorString.isEmpty())
+ errorString.append(QLatin1Char('\n'));
+ errorString.append(QCoreApplication::translate("PluginSpec", "Could not resolve dependency '%1(%2)'")
+ .arg(dependency.name).arg(dependency.version));
+ }
continue;
}
- resolvedDependencies.append(found);
+ resolvedDependencies.insert(dependency, found);
}
if (hasError)
return false;
@@ -840,7 +872,12 @@ void PluginSpecPrivate::disableIndirectlyIfDependencyDisabled()
if (disabledIndirectly)
return;
- foreach (PluginSpec *dependencySpec, dependencySpecs) {
+ QHashIterator<PluginDependency, PluginSpec *> it(dependencySpecs);
+ while (it.hasNext()) {
+ it.next();
+ if (it.key().type == PluginDependency::Optional)
+ continue;
+ PluginSpec *dependencySpec = it.value();
if (dependencySpec->isDisabledIndirectly() || !dependencySpec->isEnabled()) {
disabledIndirectly = true;
break;
@@ -984,17 +1021,3 @@ void PluginSpecPrivate::kill()
plugin = 0;
state = PluginSpec::Deleted;
}
-
-/*!
- \fn void PluginSpecPrivate::addProvidesForPlugin(PluginSpec *dependent)
- \internal
-*/
-void PluginSpecPrivate::addProvidesForPlugin(PluginSpec *dependent)
-{
- providesSpecs.append(dependent);
-}
-
-void PluginSpecPrivate::removeProvidesForPlugin(PluginSpec *dependent)
-{
- providesSpecs.removeOne(dependent);
-}