2022-08-19 15:59:36 +02:00
|
|
|
// Copyright (C) 2016 The Qt Company Ltd.
|
2023-01-04 08:52:22 +01:00
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
2008-12-02 14:09:21 +01:00
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
#include "pluginspec.h"
|
2010-01-11 09:45:20 +01:00
|
|
|
|
2023-01-23 18:23:53 +01:00
|
|
|
#include "extensionsystemtr.h"
|
2008-12-02 12:01:29 +01:00
|
|
|
#include "iplugin.h"
|
|
|
|
|
#include "pluginmanager.h"
|
2023-01-23 18:23:53 +01:00
|
|
|
#include "pluginspec_p.h"
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2016-06-22 16:41:55 +02:00
|
|
|
#include <utils/algorithm.h>
|
2020-06-18 08:35:33 +03:00
|
|
|
#include <utils/hostosinfo.h>
|
2017-07-21 14:50:23 +02:00
|
|
|
#include <utils/qtcassert.h>
|
2017-07-27 10:27:20 +02:00
|
|
|
#include <utils/stringutils.h>
|
2016-06-22 16:41:55 +02:00
|
|
|
|
2014-08-26 17:30:25 +02:00
|
|
|
#include <QCoreApplication>
|
|
|
|
|
#include <QDebug>
|
2012-02-15 10:42:41 +01:00
|
|
|
#include <QDir>
|
|
|
|
|
#include <QFile>
|
|
|
|
|
#include <QFileInfo>
|
2014-08-26 17:29:38 +02:00
|
|
|
#include <QJsonArray>
|
|
|
|
|
#include <QJsonDocument>
|
|
|
|
|
#include <QJsonObject>
|
|
|
|
|
#include <QJsonValue>
|
2014-08-26 17:30:25 +02:00
|
|
|
#include <QPluginLoader>
|
2009-02-19 15:32:50 +01:00
|
|
|
|
2021-12-06 05:11:04 +01:00
|
|
|
using namespace ExtensionSystem::Internal;
|
|
|
|
|
|
|
|
|
|
namespace ExtensionSystem {
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
/*!
|
|
|
|
|
\class ExtensionSystem::PluginDependency
|
2020-06-12 15:27:18 +02:00
|
|
|
\inheaderfile extensionsystem/pluginspec.h
|
2020-02-07 10:35:04 +01:00
|
|
|
\inmodule QtCreator
|
2020-06-12 15:27:18 +02:00
|
|
|
|
2013-06-05 14:29:24 +02:00
|
|
|
\brief The PluginDependency class contains the name and required compatible
|
|
|
|
|
version number of a plugin's dependency.
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2014-08-26 17:29:38 +02:00
|
|
|
This reflects the data of a dependency object in the plugin's meta data.
|
|
|
|
|
The name and version are used to resolve the dependency. That is,
|
2013-09-06 11:46:55 +02:00
|
|
|
a plugin with the given name and
|
2008-12-02 12:01:29 +01:00
|
|
|
plugin \c {compatibility version <= dependency version <= plugin version} is searched for.
|
|
|
|
|
|
|
|
|
|
See also ExtensionSystem::IPlugin for more information about plugin dependencies and
|
|
|
|
|
version matching.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
\variable ExtensionSystem::PluginDependency::name
|
|
|
|
|
String identifier of the plugin.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
\variable ExtensionSystem::PluginDependency::version
|
|
|
|
|
Version string that a plugin must match to fill this dependency.
|
|
|
|
|
*/
|
|
|
|
|
|
2011-01-11 14:01:08 +01:00
|
|
|
/*!
|
|
|
|
|
\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.
|
2015-03-04 09:25:08 +02:00
|
|
|
\value Test
|
|
|
|
|
Dependency needs to be force-loaded for running tests of the plugin.
|
2011-01-11 14:01:08 +01:00
|
|
|
*/
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
/*!
|
|
|
|
|
\class ExtensionSystem::PluginSpec
|
2020-06-12 15:27:18 +02:00
|
|
|
\inheaderfile extensionsystem/pluginspec.h
|
2020-02-07 10:35:04 +01:00
|
|
|
\inmodule QtCreator
|
2020-06-12 15:27:18 +02:00
|
|
|
|
2014-08-26 17:29:38 +02:00
|
|
|
\brief The PluginSpec class contains the information of the plugin's embedded meta data
|
|
|
|
|
and information about the plugin's current state.
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
The plugin spec is also filled with more information as the plugin
|
2009-06-12 13:07:15 +02:00
|
|
|
goes through its loading process (see PluginSpec::State).
|
2008-12-02 12:01:29 +01:00
|
|
|
If an error occurs, the plugin spec is the place to look for the
|
|
|
|
|
error details.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
\enum ExtensionSystem::PluginSpec::State
|
2013-09-06 11:46:55 +02:00
|
|
|
The State enum indicates the states the plugin goes through while
|
|
|
|
|
it is being loaded.
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
The state gives a hint on what went wrong in case of an error.
|
|
|
|
|
|
|
|
|
|
\value Invalid
|
2014-08-26 17:29:38 +02:00
|
|
|
Starting point: Even the plugin meta data was not read.
|
2008-12-02 12:01:29 +01:00
|
|
|
\value Read
|
2014-08-26 17:29:38 +02:00
|
|
|
The plugin meta data has been successfully read, and its
|
2008-12-02 12:01:29 +01:00
|
|
|
information is available via the PluginSpec.
|
|
|
|
|
\value Resolved
|
|
|
|
|
The dependencies given in the description file have been
|
2013-10-07 13:34:40 +02:00
|
|
|
successfully found, and are available via the dependencySpecs() function.
|
2008-12-02 12:01:29 +01:00
|
|
|
\value Loaded
|
|
|
|
|
The plugin's library is loaded and the plugin instance created
|
|
|
|
|
(available through plugin()).
|
|
|
|
|
\value Initialized
|
2013-10-07 13:34:40 +02:00
|
|
|
The plugin instance's IPlugin::initialize() function has been called
|
2008-12-02 12:01:29 +01:00
|
|
|
and returned a success value.
|
|
|
|
|
\value Running
|
|
|
|
|
The plugin's dependencies are successfully initialized and
|
|
|
|
|
extensionsInitialized has been called. The loading process is
|
|
|
|
|
complete.
|
|
|
|
|
\value Stopped
|
2013-10-07 13:34:40 +02:00
|
|
|
The plugin has been shut down, i.e. the plugin's IPlugin::aboutToShutdown() function has been called.
|
2008-12-02 12:01:29 +01:00
|
|
|
\value Deleted
|
|
|
|
|
The plugin instance has been deleted.
|
|
|
|
|
*/
|
2011-01-11 14:01:08 +01:00
|
|
|
|
2020-02-07 10:35:04 +01:00
|
|
|
/*!
|
|
|
|
|
\class ExtensionSystem::PluginArgumentDescription
|
2020-06-12 15:27:18 +02:00
|
|
|
\inheaderfile extensionsystem/pluginspec.h
|
2020-02-07 10:35:04 +01:00
|
|
|
\inmodule QtCreator
|
2020-06-12 15:27:18 +02:00
|
|
|
|
2020-02-07 10:35:04 +01:00
|
|
|
\brief The PluginArgumentDescriptions class holds a list of descriptions of
|
|
|
|
|
command line arguments that a plugin processes.
|
|
|
|
|
|
|
|
|
|
\sa PluginSpec::argumentDescriptions()
|
|
|
|
|
*/
|
|
|
|
|
|
2011-01-11 14:01:08 +01:00
|
|
|
/*!
|
2020-02-07 10:35:04 +01:00
|
|
|
\fn uint ExtensionSystem::qHash(const ExtensionSystem::PluginDependency &value)
|
2011-01-11 14:01:08 +01:00
|
|
|
\internal
|
|
|
|
|
*/
|
2022-07-13 09:27:18 +02:00
|
|
|
size_t qHash(const PluginDependency &value)
|
2011-01-11 14:01:08 +01:00
|
|
|
{
|
|
|
|
|
return qHash(value.name);
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
/*!
|
|
|
|
|
\internal
|
|
|
|
|
*/
|
2011-01-11 14:01:08 +01:00
|
|
|
bool PluginDependency::operator==(const PluginDependency &other) const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2011-01-11 14:01:08 +01:00
|
|
|
return name == other.name && version == other.version && type == other.type;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2016-06-22 13:44:19 +02:00
|
|
|
static QString typeString(PluginDependency::Type type)
|
|
|
|
|
{
|
|
|
|
|
switch (type) {
|
|
|
|
|
case PluginDependency::Optional:
|
2016-06-23 12:17:22 +02:00
|
|
|
return QString(", optional");
|
2016-06-22 13:44:19 +02:00
|
|
|
case PluginDependency::Test:
|
2016-06-23 12:17:22 +02:00
|
|
|
return QString(", test");
|
|
|
|
|
case PluginDependency::Required:
|
|
|
|
|
default:
|
|
|
|
|
return QString();
|
2016-06-22 13:44:19 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-07 10:35:04 +01:00
|
|
|
/*!
|
|
|
|
|
\internal
|
|
|
|
|
*/
|
2016-06-22 13:44:19 +02:00
|
|
|
QString PluginDependency::toString() const
|
|
|
|
|
{
|
|
|
|
|
return name + " (" + version + typeString(type) + ")";
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
/*!
|
|
|
|
|
\internal
|
|
|
|
|
*/
|
|
|
|
|
PluginSpec::PluginSpec()
|
|
|
|
|
: d(new PluginSpecPrivate(this))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
\internal
|
|
|
|
|
*/
|
|
|
|
|
PluginSpec::~PluginSpec()
|
|
|
|
|
{
|
|
|
|
|
delete d;
|
2018-07-19 23:19:33 +02:00
|
|
|
d = nullptr;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
2020-02-07 10:35:04 +01:00
|
|
|
Returns the plugin name. This is valid after the PluginSpec::Read state is
|
|
|
|
|
reached.
|
2008-12-02 12:01:29 +01:00
|
|
|
*/
|
|
|
|
|
QString PluginSpec::name() const
|
|
|
|
|
{
|
|
|
|
|
return d->name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
2020-02-07 10:35:04 +01:00
|
|
|
Returns the plugin version. This is valid after the PluginSpec::Read state
|
|
|
|
|
is reached.
|
2008-12-02 12:01:29 +01:00
|
|
|
*/
|
|
|
|
|
QString PluginSpec::version() const
|
|
|
|
|
{
|
|
|
|
|
return d->version;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
2020-02-07 10:35:04 +01:00
|
|
|
Returns the plugin compatibility version. This is valid after the
|
|
|
|
|
PluginSpec::Read state is reached.
|
2008-12-02 12:01:29 +01:00
|
|
|
*/
|
|
|
|
|
QString PluginSpec::compatVersion() const
|
|
|
|
|
{
|
|
|
|
|
return d->compatVersion;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
2020-02-07 10:35:04 +01:00
|
|
|
Returns the plugin vendor. This is valid after the PluginSpec::Read
|
|
|
|
|
state is reached.
|
2008-12-02 12:01:29 +01:00
|
|
|
*/
|
|
|
|
|
QString PluginSpec::vendor() const
|
|
|
|
|
{
|
|
|
|
|
return d->vendor;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
2020-02-07 10:35:04 +01:00
|
|
|
Returns the plugin copyright. This is valid after the PluginSpec::Read
|
|
|
|
|
state is reached.
|
2008-12-02 12:01:29 +01:00
|
|
|
*/
|
|
|
|
|
QString PluginSpec::copyright() const
|
|
|
|
|
{
|
|
|
|
|
return d->copyright;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
2020-02-07 10:35:04 +01:00
|
|
|
Returns the plugin license. This is valid after the PluginSpec::Read
|
|
|
|
|
state is reached.
|
2008-12-02 12:01:29 +01:00
|
|
|
*/
|
|
|
|
|
QString PluginSpec::license() const
|
|
|
|
|
{
|
|
|
|
|
return d->license;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
2020-02-07 10:35:04 +01:00
|
|
|
Returns the plugin description. This is valid after the PluginSpec::Read
|
|
|
|
|
state is reached.
|
2008-12-02 12:01:29 +01:00
|
|
|
*/
|
|
|
|
|
QString PluginSpec::description() const
|
|
|
|
|
{
|
|
|
|
|
return d->description;
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-14 12:29:08 +01:00
|
|
|
/*!
|
|
|
|
|
Returns the plugin's long description. This is valid after the PluginSpec::Read
|
|
|
|
|
state is reached.
|
|
|
|
|
*/
|
|
|
|
|
QString PluginSpec::longDescription() const
|
|
|
|
|
{
|
|
|
|
|
return d->longDescription;
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
/*!
|
2020-02-07 10:35:04 +01:00
|
|
|
Returns the plugin URL where you can find more information about the plugin.
|
2013-09-06 11:46:55 +02:00
|
|
|
This is valid after the PluginSpec::Read state is reached.
|
2008-12-02 12:01:29 +01:00
|
|
|
*/
|
|
|
|
|
QString PluginSpec::url() const
|
|
|
|
|
{
|
|
|
|
|
return d->url;
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-12 16:02:23 +01:00
|
|
|
/*!
|
2020-02-07 10:35:04 +01:00
|
|
|
Returns the category that the plugin belongs to. Categories are used to
|
|
|
|
|
group plugins together in the UI.
|
2010-03-12 16:02:23 +01:00
|
|
|
Returns an empty string if the plugin does not belong to a category.
|
|
|
|
|
*/
|
|
|
|
|
QString PluginSpec::category() const
|
|
|
|
|
{
|
|
|
|
|
return d->category;
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-25 06:38:11 +02:00
|
|
|
QString PluginSpec::revision() const
|
|
|
|
|
{
|
|
|
|
|
const QJsonValue revision = metaData().value("Revision");
|
|
|
|
|
if (revision.isString())
|
|
|
|
|
return revision.toString();
|
|
|
|
|
return QString();
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-28 16:29:08 +02:00
|
|
|
/*!
|
2020-06-09 07:46:57 +02:00
|
|
|
Returns a QRegularExpression matching the platforms this plugin works on.
|
|
|
|
|
An empty pattern implies all platforms.
|
2013-08-28 16:29:08 +02:00
|
|
|
\since 3.0
|
|
|
|
|
*/
|
|
|
|
|
|
2020-06-09 07:46:57 +02:00
|
|
|
QRegularExpression PluginSpec::platformSpecification() const
|
2013-08-28 16:29:08 +02:00
|
|
|
{
|
|
|
|
|
return d->platformSpecification;
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-07 10:35:04 +01:00
|
|
|
/*!
|
|
|
|
|
Returns whether the plugin works on the host platform.
|
|
|
|
|
*/
|
2014-07-03 13:47:03 +02:00
|
|
|
bool PluginSpec::isAvailableForHostPlatform() const
|
|
|
|
|
{
|
2020-06-09 07:46:57 +02:00
|
|
|
return d->platformSpecification.pattern().isEmpty()
|
|
|
|
|
|| d->platformSpecification.match(PluginManager::platformName()).hasMatch();
|
2014-07-03 13:47:03 +02:00
|
|
|
}
|
|
|
|
|
|
2020-02-07 10:35:04 +01:00
|
|
|
/*!
|
|
|
|
|
Returns whether the plugin is required.
|
|
|
|
|
*/
|
2014-07-03 17:41:24 +02:00
|
|
|
bool PluginSpec::isRequired() const
|
|
|
|
|
{
|
|
|
|
|
return d->required;
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-12 16:02:23 +01:00
|
|
|
/*!
|
2013-09-06 11:46:55 +02:00
|
|
|
Returns whether the plugin has its experimental flag set.
|
2010-03-30 16:54:29 +02:00
|
|
|
*/
|
|
|
|
|
bool PluginSpec::isExperimental() const
|
|
|
|
|
{
|
|
|
|
|
return d->experimental;
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-26 14:46:29 +02:00
|
|
|
/*!
|
2015-03-31 09:55:50 +02:00
|
|
|
Returns whether the plugin is enabled by default.
|
|
|
|
|
A plugin might be disabled because the plugin is experimental, or because
|
2020-02-07 10:35:04 +01:00
|
|
|
the installation settings define it as disabled by default.
|
2011-10-26 14:46:29 +02:00
|
|
|
*/
|
2015-03-31 09:55:50 +02:00
|
|
|
bool PluginSpec::isEnabledByDefault() const
|
2011-10-26 14:46:29 +02:00
|
|
|
{
|
2015-03-31 09:55:50 +02:00
|
|
|
return d->enabledByDefault;
|
2011-10-26 14:46:29 +02:00
|
|
|
}
|
|
|
|
|
|
2010-03-30 16:54:29 +02:00
|
|
|
/*!
|
2015-03-31 09:55:50 +02:00
|
|
|
Returns whether the plugin should be loaded at startup,
|
|
|
|
|
taking into account the default enabled state, and the user's settings.
|
2013-09-06 11:46:55 +02:00
|
|
|
|
2020-02-07 10:35:04 +01:00
|
|
|
\note This function might return \c false even if the plugin is loaded
|
|
|
|
|
as a requirement of another enabled plugin.
|
|
|
|
|
|
|
|
|
|
\sa isEffectivelyEnabled()
|
2010-03-12 16:02:23 +01:00
|
|
|
*/
|
2015-03-31 09:55:50 +02:00
|
|
|
bool PluginSpec::isEnabledBySettings() const
|
2010-03-12 16:02:23 +01:00
|
|
|
{
|
2015-03-31 09:55:50 +02:00
|
|
|
return d->enabledBySettings;
|
2010-03-12 16:02:23 +01:00
|
|
|
}
|
|
|
|
|
|
2013-02-12 13:19:15 +01:00
|
|
|
/*!
|
2013-09-06 11:46:55 +02:00
|
|
|
Returns whether the plugin is loaded at startup.
|
2020-02-07 10:35:04 +01:00
|
|
|
\sa isEnabledBySettings()
|
2013-02-12 13:19:15 +01:00
|
|
|
*/
|
|
|
|
|
bool PluginSpec::isEffectivelyEnabled() const
|
|
|
|
|
{
|
2015-03-31 17:42:14 +02:00
|
|
|
if (!isAvailableForHostPlatform())
|
2013-08-28 16:29:08 +02:00
|
|
|
return false;
|
2015-03-31 17:42:14 +02:00
|
|
|
if (isForceEnabled() || isEnabledIndirectly())
|
|
|
|
|
return true;
|
|
|
|
|
if (isForceDisabled())
|
|
|
|
|
return false;
|
|
|
|
|
return isEnabledBySettings();
|
2013-02-12 13:19:15 +01:00
|
|
|
}
|
|
|
|
|
|
2010-05-12 14:34:36 +02:00
|
|
|
/*!
|
2020-02-07 10:35:04 +01:00
|
|
|
Returns \c true if loading was not done due to user unselecting this
|
|
|
|
|
plugin or its dependencies.
|
2010-05-12 14:34:36 +02:00
|
|
|
*/
|
2015-03-31 17:42:14 +02:00
|
|
|
bool PluginSpec::isEnabledIndirectly() const
|
2010-03-12 16:02:23 +01:00
|
|
|
{
|
2015-03-31 17:42:14 +02:00
|
|
|
return d->enabledIndirectly;
|
2010-03-12 16:02:23 +01:00
|
|
|
}
|
|
|
|
|
|
2013-02-12 13:19:15 +01:00
|
|
|
/*!
|
2020-02-07 10:35:04 +01:00
|
|
|
Returns whether the plugin is enabled via the \c -load option on the
|
|
|
|
|
command line.
|
2013-02-12 13:19:15 +01:00
|
|
|
*/
|
|
|
|
|
bool PluginSpec::isForceEnabled() const
|
|
|
|
|
{
|
|
|
|
|
return d->forceEnabled;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
2020-02-07 10:35:04 +01:00
|
|
|
Returns whether the plugin is disabled via the \c -noload option on the
|
|
|
|
|
command line.
|
2013-02-12 13:19:15 +01:00
|
|
|
*/
|
|
|
|
|
bool PluginSpec::isForceDisabled() const
|
|
|
|
|
{
|
|
|
|
|
return d->forceDisabled;
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
/*!
|
|
|
|
|
The plugin dependencies. This is valid after the PluginSpec::Read state is reached.
|
|
|
|
|
*/
|
2015-01-13 14:53:04 +01:00
|
|
|
QVector<PluginDependency> PluginSpec::dependencies() const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
|
return d->dependencies;
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-07 10:35:04 +01:00
|
|
|
/*!
|
|
|
|
|
Returns the plugin meta data.
|
|
|
|
|
*/
|
2017-02-08 14:31:55 +01:00
|
|
|
QJsonObject PluginSpec::metaData() const
|
|
|
|
|
{
|
|
|
|
|
return d->metaData;
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
/*!
|
|
|
|
|
Returns a list of descriptions of command line arguments the plugin processes.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
PluginSpec::PluginArgumentDescriptions PluginSpec::argumentDescriptions() const
|
|
|
|
|
{
|
|
|
|
|
return d->argumentDescriptions;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
2020-02-07 10:35:04 +01:00
|
|
|
Returns the absolute path to the directory containing the plugin.
|
2008-12-02 12:01:29 +01:00
|
|
|
*/
|
|
|
|
|
QString PluginSpec::location() const
|
|
|
|
|
{
|
|
|
|
|
return d->location;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
2020-02-07 10:35:04 +01:00
|
|
|
Returns the absolute path to the plugin.
|
2008-12-02 12:01:29 +01:00
|
|
|
*/
|
|
|
|
|
QString PluginSpec::filePath() const
|
|
|
|
|
{
|
|
|
|
|
return d->filePath;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
2020-02-07 10:35:04 +01:00
|
|
|
Returns command line arguments specific to the plugin. Set at startup.
|
2008-12-02 12:01:29 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
QStringList PluginSpec::arguments() const
|
|
|
|
|
{
|
|
|
|
|
return d->arguments;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
2013-09-06 11:46:55 +02:00
|
|
|
Sets the command line arguments specific to the plugin to \a arguments.
|
2008-12-02 12:01:29 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void PluginSpec::setArguments(const QStringList &arguments)
|
|
|
|
|
{
|
|
|
|
|
d->arguments = arguments;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
2013-09-06 11:46:55 +02:00
|
|
|
Adds \a argument to the command line arguments specific to the plugin.
|
2008-12-02 12:01:29 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void PluginSpec::addArgument(const QString &argument)
|
|
|
|
|
{
|
|
|
|
|
d->arguments.push_back(argument);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
2020-02-07 10:35:04 +01:00
|
|
|
Returns the state in which the plugin currently is.
|
2008-12-02 12:01:29 +01:00
|
|
|
See the description of the PluginSpec::State enum for details.
|
|
|
|
|
*/
|
|
|
|
|
PluginSpec::State PluginSpec::state() const
|
|
|
|
|
{
|
|
|
|
|
return d->state;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
2020-02-07 10:35:04 +01:00
|
|
|
Returns whether an error occurred while reading or starting the plugin.
|
2008-12-02 12:01:29 +01:00
|
|
|
*/
|
|
|
|
|
bool PluginSpec::hasError() const
|
|
|
|
|
{
|
|
|
|
|
return d->hasError;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
2020-02-07 10:35:04 +01:00
|
|
|
Returns a detailed, possibly multi-line, error description in case of an
|
|
|
|
|
error.
|
2008-12-02 12:01:29 +01:00
|
|
|
*/
|
|
|
|
|
QString PluginSpec::errorString() const
|
|
|
|
|
{
|
|
|
|
|
return d->errorString;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
2013-09-06 11:46:55 +02:00
|
|
|
Returns whether this plugin can be used to fill in a dependency of the given
|
2008-12-02 12:01:29 +01:00
|
|
|
\a pluginName and \a version.
|
|
|
|
|
|
|
|
|
|
\sa PluginSpec::dependencies()
|
|
|
|
|
*/
|
|
|
|
|
bool PluginSpec::provides(const QString &pluginName, const QString &version) const
|
|
|
|
|
{
|
|
|
|
|
return d->provides(pluginName, version);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
2020-02-07 10:35:04 +01:00
|
|
|
Returns the corresponding IPlugin instance, if the plugin library has
|
|
|
|
|
already been successfully loaded. That is, the PluginSpec::Loaded state
|
|
|
|
|
is reached.
|
2008-12-02 12:01:29 +01:00
|
|
|
*/
|
|
|
|
|
IPlugin *PluginSpec::plugin() const
|
|
|
|
|
{
|
|
|
|
|
return d->plugin;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
Returns the list of dependencies, already resolved to existing plugin specs.
|
|
|
|
|
Valid if PluginSpec::Resolved state is reached.
|
|
|
|
|
|
|
|
|
|
\sa PluginSpec::dependencies()
|
|
|
|
|
*/
|
2011-01-11 14:01:08 +01:00
|
|
|
QHash<PluginDependency, PluginSpec *> PluginSpec::dependencySpecs() const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
|
return d->dependencySpecs;
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-07 10:35:04 +01:00
|
|
|
/*!
|
|
|
|
|
Returns whether the plugin requires any of the plugins specified by
|
|
|
|
|
\a plugins.
|
|
|
|
|
*/
|
2016-06-22 16:41:55 +02:00
|
|
|
bool PluginSpec::requiresAny(const QSet<PluginSpec *> &plugins) const
|
|
|
|
|
{
|
|
|
|
|
return Utils::anyOf(d->dependencySpecs.keys(), [this, &plugins](const PluginDependency &dep) {
|
|
|
|
|
return dep.type == PluginDependency::Required
|
|
|
|
|
&& plugins.contains(d->dependencySpecs.value(dep));
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-07 10:35:04 +01:00
|
|
|
/*!
|
|
|
|
|
Sets whether the plugin should be loaded at startup to \a value.
|
|
|
|
|
|
|
|
|
|
\sa isEnabledBySettings()
|
|
|
|
|
*/
|
2018-05-14 12:18:19 +02:00
|
|
|
void PluginSpec::setEnabledBySettings(bool value)
|
|
|
|
|
{
|
|
|
|
|
d->setEnabledBySettings(value);
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-23 14:11:29 +02:00
|
|
|
PluginSpec *PluginSpec::read(const QString &filePath)
|
|
|
|
|
{
|
|
|
|
|
auto spec = new PluginSpec;
|
|
|
|
|
if (!spec->d->read(filePath)) { // not a Qt Creator plugin
|
|
|
|
|
delete spec;
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
return spec;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-27 16:19:10 +02:00
|
|
|
PluginSpec *PluginSpec::read(const QStaticPlugin &plugin)
|
|
|
|
|
{
|
|
|
|
|
auto spec = new PluginSpec;
|
|
|
|
|
if (!spec->d->read(plugin)) { // not a Qt Creator plugin
|
|
|
|
|
delete spec;
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
return spec;
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
//==========PluginSpecPrivate==================
|
|
|
|
|
|
|
|
|
|
namespace {
|
2014-08-26 17:29:38 +02:00
|
|
|
const char PLUGIN_METADATA[] = "MetaData";
|
|
|
|
|
const char PLUGIN_NAME[] = "Name";
|
|
|
|
|
const char PLUGIN_VERSION[] = "Version";
|
|
|
|
|
const char PLUGIN_COMPATVERSION[] = "CompatVersion";
|
|
|
|
|
const char PLUGIN_REQUIRED[] = "Required";
|
|
|
|
|
const char PLUGIN_EXPERIMENTAL[] = "Experimental";
|
|
|
|
|
const char PLUGIN_DISABLED_BY_DEFAULT[] = "DisabledByDefault";
|
|
|
|
|
const char VENDOR[] = "Vendor";
|
|
|
|
|
const char COPYRIGHT[] = "Copyright";
|
|
|
|
|
const char LICENSE[] = "License";
|
|
|
|
|
const char DESCRIPTION[] = "Description";
|
2022-12-14 12:29:08 +01:00
|
|
|
const char LONGDESCRIPTION[] = "LongDescription";
|
2014-08-26 17:29:38 +02:00
|
|
|
const char URL[] = "Url";
|
|
|
|
|
const char CATEGORY[] = "Category";
|
|
|
|
|
const char PLATFORM[] = "Platform";
|
|
|
|
|
const char DEPENDENCIES[] = "Dependencies";
|
|
|
|
|
const char DEPENDENCY_NAME[] = "Name";
|
|
|
|
|
const char DEPENDENCY_VERSION[] = "Version";
|
|
|
|
|
const char DEPENDENCY_TYPE[] = "Type";
|
2011-11-02 16:45:13 +01:00
|
|
|
const char DEPENDENCY_TYPE_SOFT[] = "optional";
|
|
|
|
|
const char DEPENDENCY_TYPE_HARD[] = "required";
|
2015-03-04 09:25:08 +02:00
|
|
|
const char DEPENDENCY_TYPE_TEST[] = "test";
|
2014-08-26 17:29:38 +02:00
|
|
|
const char ARGUMENTS[] = "Arguments";
|
|
|
|
|
const char ARGUMENT_NAME[] = "Name";
|
|
|
|
|
const char ARGUMENT_PARAMETER[] = "Parameter";
|
|
|
|
|
const char ARGUMENT_DESCRIPTION[] = "Description";
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
/*!
|
|
|
|
|
\internal
|
|
|
|
|
*/
|
|
|
|
|
PluginSpecPrivate::PluginSpecPrivate(PluginSpec *spec)
|
2017-01-03 15:28:42 +01:00
|
|
|
: q(spec)
|
2022-04-27 16:19:10 +02:00
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
void PluginSpecPrivate::reset()
|
|
|
|
|
{
|
|
|
|
|
name.clear();
|
|
|
|
|
version.clear();
|
|
|
|
|
compatVersion.clear();
|
|
|
|
|
vendor.clear();
|
|
|
|
|
copyright.clear();
|
|
|
|
|
license.clear();
|
|
|
|
|
description.clear();
|
2022-12-14 12:29:08 +01:00
|
|
|
longDescription.clear();
|
2022-04-27 16:19:10 +02:00
|
|
|
url.clear();
|
|
|
|
|
category.clear();
|
|
|
|
|
location.clear();
|
|
|
|
|
filePath.clear();
|
|
|
|
|
state = PluginSpec::Invalid;
|
|
|
|
|
hasError = false;
|
|
|
|
|
errorString.clear();
|
|
|
|
|
dependencies.clear();
|
|
|
|
|
metaData = QJsonObject();
|
|
|
|
|
loader.reset();
|
|
|
|
|
staticPlugin.reset();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
\internal
|
2014-08-26 17:29:38 +02:00
|
|
|
Returns false if the file does not represent a Qt Creator plugin.
|
2008-12-02 12:01:29 +01:00
|
|
|
*/
|
|
|
|
|
bool PluginSpecPrivate::read(const QString &fileName)
|
|
|
|
|
{
|
2014-08-26 17:29:38 +02:00
|
|
|
qCDebug(pluginLog) << "\nReading meta data of" << fileName;
|
2022-04-27 16:19:10 +02:00
|
|
|
reset();
|
2014-08-26 17:29:38 +02:00
|
|
|
QFileInfo fileInfo(fileName);
|
2008-12-02 12:01:29 +01:00
|
|
|
location = fileInfo.absolutePath();
|
|
|
|
|
filePath = fileInfo.absoluteFilePath();
|
2022-04-27 16:19:10 +02:00
|
|
|
loader.emplace();
|
|
|
|
|
if (Utils::HostOsInfo::isMacHost())
|
|
|
|
|
loader->setLoadHints(QLibrary::ExportExternalSymbolsHint);
|
|
|
|
|
loader->setFileName(filePath);
|
|
|
|
|
if (loader->fileName().isEmpty()) {
|
2014-08-26 17:29:38 +02:00
|
|
|
qCDebug(pluginLog) << "Cannot open file";
|
|
|
|
|
return false;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
2014-08-26 17:29:38 +02:00
|
|
|
|
2022-04-27 16:19:10 +02:00
|
|
|
if (!readMetaData(loader->metaData()))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
state = PluginSpec::Read;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool PluginSpecPrivate::read(const QStaticPlugin &plugin)
|
|
|
|
|
{
|
|
|
|
|
qCDebug(pluginLog) << "\nReading meta data of static plugin";
|
|
|
|
|
reset();
|
|
|
|
|
staticPlugin = plugin;
|
|
|
|
|
if (!readMetaData(plugin.metaData()))
|
2014-08-26 17:29:38 +02:00
|
|
|
return false;
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
state = PluginSpec::Read;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-31 09:55:50 +02:00
|
|
|
void PluginSpecPrivate::setEnabledBySettings(bool value)
|
2010-03-12 16:02:23 +01:00
|
|
|
{
|
2015-03-31 09:55:50 +02:00
|
|
|
enabledBySettings = value;
|
2010-03-12 16:02:23 +01:00
|
|
|
}
|
|
|
|
|
|
2015-03-31 09:55:50 +02:00
|
|
|
void PluginSpecPrivate::setEnabledByDefault(bool value)
|
2011-10-26 14:46:29 +02:00
|
|
|
{
|
2015-03-31 09:55:50 +02:00
|
|
|
enabledByDefault = value;
|
2011-10-26 14:46:29 +02:00
|
|
|
}
|
|
|
|
|
|
2015-03-31 09:55:50 +02:00
|
|
|
void PluginSpecPrivate::setForceEnabled(bool value)
|
2013-02-12 13:19:15 +01:00
|
|
|
{
|
2015-03-31 09:55:50 +02:00
|
|
|
forceEnabled = value;
|
2013-02-12 13:19:15 +01:00
|
|
|
if (value)
|
2015-03-31 09:55:50 +02:00
|
|
|
forceDisabled = false;
|
2013-02-12 13:19:15 +01:00
|
|
|
}
|
|
|
|
|
|
2015-03-31 09:55:50 +02:00
|
|
|
void PluginSpecPrivate::setForceDisabled(bool value)
|
2013-02-12 13:19:15 +01:00
|
|
|
{
|
|
|
|
|
if (value)
|
2015-03-31 09:55:50 +02:00
|
|
|
forceEnabled = false;
|
|
|
|
|
forceDisabled = value;
|
2013-02-12 13:19:15 +01:00
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
/*!
|
|
|
|
|
\internal
|
|
|
|
|
*/
|
|
|
|
|
bool PluginSpecPrivate::reportError(const QString &err)
|
|
|
|
|
{
|
|
|
|
|
errorString = err;
|
|
|
|
|
hasError = true;
|
2014-08-26 17:29:38 +02:00
|
|
|
return true;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2014-08-26 17:29:38 +02:00
|
|
|
static inline QString msgValueMissing(const char *key)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2023-01-23 18:23:53 +01:00
|
|
|
return Tr::tr("\"%1\" is missing").arg(QLatin1String(key));
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2014-08-26 17:29:38 +02:00
|
|
|
static inline QString msgValueIsNotAString(const char *key)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2023-01-23 18:23:53 +01:00
|
|
|
return Tr::tr("Value for key \"%1\" is not a string")
|
2014-08-26 17:29:38 +02:00
|
|
|
.arg(QLatin1String(key));
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2014-08-26 17:29:38 +02:00
|
|
|
static inline QString msgValueIsNotABool(const char *key)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2023-01-23 18:23:53 +01:00
|
|
|
return Tr::tr("Value for key \"%1\" is not a bool")
|
2014-08-26 17:29:38 +02:00
|
|
|
.arg(QLatin1String(key));
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2014-08-26 17:29:38 +02:00
|
|
|
static inline QString msgValueIsNotAObjectArray(const char *key)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2023-01-23 18:23:53 +01:00
|
|
|
return Tr::tr("Value for key \"%1\" is not an array of objects")
|
2014-08-26 17:29:38 +02:00
|
|
|
.arg(QLatin1String(key));
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2014-08-26 17:29:38 +02:00
|
|
|
static inline QString msgValueIsNotAMultilineString(const char *key)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2023-01-23 18:23:53 +01:00
|
|
|
return Tr::tr("Value for key \"%1\" is not a string and not an array of strings")
|
2014-08-26 17:29:38 +02:00
|
|
|
.arg(QLatin1String(key));
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2014-08-26 17:29:38 +02:00
|
|
|
static inline QString msgInvalidFormat(const char *key, const QString &content)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2023-01-23 18:23:53 +01:00
|
|
|
return Tr::tr("Value \"%2\" for key \"%1\" has invalid format")
|
2014-08-26 17:29:38 +02:00
|
|
|
.arg(QLatin1String(key), content);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
\internal
|
|
|
|
|
*/
|
2017-02-08 14:31:55 +01:00
|
|
|
bool PluginSpecPrivate::readMetaData(const QJsonObject &pluginMetaData)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2017-02-08 14:31:55 +01:00
|
|
|
qCDebug(pluginLog) << "MetaData:" << QJsonDocument(pluginMetaData).toJson();
|
2014-08-26 17:29:38 +02:00
|
|
|
QJsonValue value;
|
2017-02-08 14:31:55 +01:00
|
|
|
value = pluginMetaData.value(QLatin1String("IID"));
|
2014-08-26 17:29:38 +02:00
|
|
|
if (!value.isString()) {
|
|
|
|
|
qCDebug(pluginLog) << "Not a plugin (no string IID found)";
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if (value.toString() != PluginManager::pluginIID()) {
|
|
|
|
|
qCDebug(pluginLog) << "Plugin ignored (IID does not match)";
|
|
|
|
|
return false;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2017-02-08 14:31:55 +01:00
|
|
|
value = pluginMetaData.value(QLatin1String(PLUGIN_METADATA));
|
2022-02-16 14:32:48 +01:00
|
|
|
if (!value.isObject()) {
|
2023-01-23 18:23:53 +01:00
|
|
|
return reportError(::ExtensionSystem::Tr::tr("Plugin meta data not found"));
|
2022-02-16 14:32:48 +01:00
|
|
|
}
|
2017-02-08 14:31:55 +01:00
|
|
|
metaData = value.toObject();
|
2014-08-26 17:29:38 +02:00
|
|
|
|
2017-02-08 14:31:55 +01:00
|
|
|
value = metaData.value(QLatin1String(PLUGIN_NAME));
|
2014-08-26 17:29:38 +02:00
|
|
|
if (value.isUndefined())
|
|
|
|
|
return reportError(msgValueMissing(PLUGIN_NAME));
|
|
|
|
|
if (!value.isString())
|
|
|
|
|
return reportError(msgValueIsNotAString(PLUGIN_NAME));
|
|
|
|
|
name = value.toString();
|
|
|
|
|
|
2017-02-08 14:31:55 +01:00
|
|
|
value = metaData.value(QLatin1String(PLUGIN_VERSION));
|
2014-08-26 17:29:38 +02:00
|
|
|
if (value.isUndefined())
|
|
|
|
|
return reportError(msgValueMissing(PLUGIN_VERSION));
|
|
|
|
|
if (!value.isString())
|
|
|
|
|
return reportError(msgValueIsNotAString(PLUGIN_VERSION));
|
|
|
|
|
version = value.toString();
|
|
|
|
|
if (!isValidVersion(version))
|
|
|
|
|
return reportError(msgInvalidFormat(PLUGIN_VERSION, version));
|
|
|
|
|
|
2017-02-08 14:31:55 +01:00
|
|
|
value = metaData.value(QLatin1String(PLUGIN_COMPATVERSION));
|
2014-08-26 17:29:38 +02:00
|
|
|
if (!value.isUndefined() && !value.isString())
|
|
|
|
|
return reportError(msgValueIsNotAString(PLUGIN_COMPATVERSION));
|
|
|
|
|
compatVersion = value.toString(version);
|
|
|
|
|
if (!value.isUndefined() && !isValidVersion(compatVersion))
|
|
|
|
|
return reportError(msgInvalidFormat(PLUGIN_COMPATVERSION, compatVersion));
|
|
|
|
|
|
2017-02-08 14:31:55 +01:00
|
|
|
value = metaData.value(QLatin1String(PLUGIN_REQUIRED));
|
2014-08-26 17:29:38 +02:00
|
|
|
if (!value.isUndefined() && !value.isBool())
|
|
|
|
|
return reportError(msgValueIsNotABool(PLUGIN_REQUIRED));
|
|
|
|
|
required = value.toBool(false);
|
|
|
|
|
qCDebug(pluginLog) << "required =" << required;
|
|
|
|
|
|
2017-02-08 14:31:55 +01:00
|
|
|
value = metaData.value(QLatin1String(PLUGIN_EXPERIMENTAL));
|
2014-08-26 17:29:38 +02:00
|
|
|
if (!value.isUndefined() && !value.isBool())
|
|
|
|
|
return reportError(msgValueIsNotABool(PLUGIN_EXPERIMENTAL));
|
|
|
|
|
experimental = value.toBool(false);
|
|
|
|
|
qCDebug(pluginLog) << "experimental =" << experimental;
|
|
|
|
|
|
2017-02-08 14:31:55 +01:00
|
|
|
value = metaData.value(QLatin1String(PLUGIN_DISABLED_BY_DEFAULT));
|
2014-08-26 17:29:38 +02:00
|
|
|
if (!value.isUndefined() && !value.isBool())
|
|
|
|
|
return reportError(msgValueIsNotABool(PLUGIN_DISABLED_BY_DEFAULT));
|
2015-03-31 09:55:50 +02:00
|
|
|
enabledByDefault = !value.toBool(false);
|
|
|
|
|
qCDebug(pluginLog) << "enabledByDefault =" << enabledByDefault;
|
2014-08-26 17:29:38 +02:00
|
|
|
|
|
|
|
|
if (experimental)
|
2015-03-31 09:55:50 +02:00
|
|
|
enabledByDefault = false;
|
|
|
|
|
enabledBySettings = enabledByDefault;
|
2014-08-26 17:29:38 +02:00
|
|
|
|
2017-02-08 14:31:55 +01:00
|
|
|
value = metaData.value(QLatin1String(VENDOR));
|
2014-08-26 17:29:38 +02:00
|
|
|
if (!value.isUndefined() && !value.isString())
|
|
|
|
|
return reportError(msgValueIsNotAString(VENDOR));
|
|
|
|
|
vendor = value.toString();
|
|
|
|
|
|
2017-02-08 14:31:55 +01:00
|
|
|
value = metaData.value(QLatin1String(COPYRIGHT));
|
2014-08-26 17:29:38 +02:00
|
|
|
if (!value.isUndefined() && !value.isString())
|
|
|
|
|
return reportError(msgValueIsNotAString(COPYRIGHT));
|
|
|
|
|
copyright = value.toString();
|
|
|
|
|
|
2017-02-08 14:31:55 +01:00
|
|
|
value = metaData.value(QLatin1String(DESCRIPTION));
|
2017-07-27 10:27:20 +02:00
|
|
|
if (!value.isUndefined() && !Utils::readMultiLineString(value, &description))
|
2014-08-26 17:29:38 +02:00
|
|
|
return reportError(msgValueIsNotAString(DESCRIPTION));
|
|
|
|
|
|
2022-12-14 12:29:08 +01:00
|
|
|
value = metaData.value(QLatin1String(LONGDESCRIPTION));
|
|
|
|
|
if (!value.isUndefined() && !Utils::readMultiLineString(value, &longDescription))
|
|
|
|
|
return reportError(msgValueIsNotAString(LONGDESCRIPTION));
|
|
|
|
|
|
2017-02-08 14:31:55 +01:00
|
|
|
value = metaData.value(QLatin1String(URL));
|
2014-08-26 17:29:38 +02:00
|
|
|
if (!value.isUndefined() && !value.isString())
|
|
|
|
|
return reportError(msgValueIsNotAString(URL));
|
|
|
|
|
url = value.toString();
|
|
|
|
|
|
2017-02-08 14:31:55 +01:00
|
|
|
value = metaData.value(QLatin1String(CATEGORY));
|
2014-08-26 17:29:38 +02:00
|
|
|
if (!value.isUndefined() && !value.isString())
|
|
|
|
|
return reportError(msgValueIsNotAString(CATEGORY));
|
|
|
|
|
category = value.toString();
|
|
|
|
|
|
2017-02-08 14:31:55 +01:00
|
|
|
value = metaData.value(QLatin1String(LICENSE));
|
2017-07-27 10:27:20 +02:00
|
|
|
if (!value.isUndefined() && !Utils::readMultiLineString(value, &license))
|
2014-08-26 17:29:38 +02:00
|
|
|
return reportError(msgValueIsNotAMultilineString(LICENSE));
|
|
|
|
|
|
2017-02-08 14:31:55 +01:00
|
|
|
value = metaData.value(QLatin1String(PLATFORM));
|
2014-08-26 17:29:38 +02:00
|
|
|
if (!value.isUndefined() && !value.isString())
|
|
|
|
|
return reportError(msgValueIsNotAString(PLATFORM));
|
|
|
|
|
const QString platformSpec = value.toString().trimmed();
|
|
|
|
|
if (!platformSpec.isEmpty()) {
|
|
|
|
|
platformSpecification.setPattern(platformSpec);
|
2022-02-16 14:32:48 +01:00
|
|
|
if (!platformSpecification.isValid()) {
|
2023-01-23 18:23:53 +01:00
|
|
|
return reportError(::ExtensionSystem::Tr::tr("Invalid platform specification \"%1\": %2")
|
2022-02-16 14:32:48 +01:00
|
|
|
.arg(platformSpec, platformSpecification.errorString()));
|
|
|
|
|
}
|
2013-01-08 11:55:52 +01:00
|
|
|
}
|
|
|
|
|
|
2017-02-08 14:31:55 +01:00
|
|
|
value = metaData.value(QLatin1String(DEPENDENCIES));
|
2014-08-26 17:29:38 +02:00
|
|
|
if (!value.isUndefined() && !value.isArray())
|
|
|
|
|
return reportError(msgValueIsNotAObjectArray(DEPENDENCIES));
|
|
|
|
|
if (!value.isUndefined()) {
|
2020-02-14 08:51:08 +01:00
|
|
|
const QJsonArray array = value.toArray();
|
|
|
|
|
for (const QJsonValue &v : array) {
|
2014-08-26 17:29:38 +02:00
|
|
|
if (!v.isObject())
|
|
|
|
|
return reportError(msgValueIsNotAObjectArray(DEPENDENCIES));
|
|
|
|
|
QJsonObject dependencyObject = v.toObject();
|
|
|
|
|
PluginDependency dep;
|
|
|
|
|
value = dependencyObject.value(QLatin1String(DEPENDENCY_NAME));
|
2022-02-16 14:32:48 +01:00
|
|
|
if (value.isUndefined()) {
|
|
|
|
|
return reportError(
|
2023-01-23 18:23:53 +01:00
|
|
|
::ExtensionSystem::Tr::tr("Dependency: %1")
|
2022-02-16 14:32:48 +01:00
|
|
|
.arg(msgValueMissing(DEPENDENCY_NAME)));
|
|
|
|
|
}
|
|
|
|
|
if (!value.isString()) {
|
|
|
|
|
return reportError(
|
2023-01-23 18:23:53 +01:00
|
|
|
::ExtensionSystem::Tr::tr("Dependency: %1")
|
2022-02-16 14:32:48 +01:00
|
|
|
.arg(msgValueIsNotAString(DEPENDENCY_NAME)));
|
|
|
|
|
}
|
2014-08-26 17:29:38 +02:00
|
|
|
dep.name = value.toString();
|
|
|
|
|
value = dependencyObject.value(QLatin1String(DEPENDENCY_VERSION));
|
2022-02-16 14:32:48 +01:00
|
|
|
if (!value.isUndefined() && !value.isString()) {
|
|
|
|
|
return reportError(
|
2023-01-23 18:23:53 +01:00
|
|
|
::ExtensionSystem::Tr::tr("Dependency: %1")
|
2022-02-16 14:32:48 +01:00
|
|
|
.arg(msgValueIsNotAString(DEPENDENCY_VERSION)));
|
|
|
|
|
}
|
2014-08-26 17:29:38 +02:00
|
|
|
dep.version = value.toString();
|
2022-02-16 14:32:48 +01:00
|
|
|
if (!isValidVersion(dep.version)) {
|
|
|
|
|
return reportError(
|
2023-01-23 18:23:53 +01:00
|
|
|
::ExtensionSystem::Tr::tr("Dependency: %1")
|
2022-02-16 14:32:48 +01:00
|
|
|
.arg(msgInvalidFormat(DEPENDENCY_VERSION, dep.version)));
|
|
|
|
|
}
|
2014-08-26 17:29:38 +02:00
|
|
|
dep.type = PluginDependency::Required;
|
|
|
|
|
value = dependencyObject.value(QLatin1String(DEPENDENCY_TYPE));
|
2022-02-16 14:32:48 +01:00
|
|
|
if (!value.isUndefined() && !value.isString()) {
|
|
|
|
|
return reportError(
|
2023-01-23 18:23:53 +01:00
|
|
|
::ExtensionSystem::Tr::tr("Dependency: %1")
|
2022-02-16 14:32:48 +01:00
|
|
|
.arg(msgValueIsNotAString(DEPENDENCY_TYPE)));
|
|
|
|
|
}
|
2014-08-26 17:29:38 +02:00
|
|
|
if (!value.isUndefined()) {
|
|
|
|
|
const QString typeValue = value.toString();
|
|
|
|
|
if (typeValue.toLower() == QLatin1String(DEPENDENCY_TYPE_HARD)) {
|
|
|
|
|
dep.type = PluginDependency::Required;
|
|
|
|
|
} else if (typeValue.toLower() == QLatin1String(DEPENDENCY_TYPE_SOFT)) {
|
|
|
|
|
dep.type = PluginDependency::Optional;
|
2015-03-04 09:25:08 +02:00
|
|
|
} else if (typeValue.toLower() == QLatin1String(DEPENDENCY_TYPE_TEST)) {
|
|
|
|
|
dep.type = PluginDependency::Test;
|
2014-08-26 17:29:38 +02:00
|
|
|
} else {
|
2022-02-16 14:32:48 +01:00
|
|
|
return reportError(
|
2023-01-23 18:23:53 +01:00
|
|
|
::ExtensionSystem::Tr::tr(
|
2022-02-16 14:32:48 +01:00
|
|
|
"Dependency: \"%1\" must be \"%2\" or \"%3\" (is \"%4\").")
|
|
|
|
|
.arg(QLatin1String(DEPENDENCY_TYPE),
|
|
|
|
|
QLatin1String(DEPENDENCY_TYPE_HARD),
|
|
|
|
|
QLatin1String(DEPENDENCY_TYPE_SOFT),
|
|
|
|
|
typeValue));
|
2014-08-26 17:29:38 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
dependencies.append(dep);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-08 14:31:55 +01:00
|
|
|
value = metaData.value(QLatin1String(ARGUMENTS));
|
2014-08-26 17:29:38 +02:00
|
|
|
if (!value.isUndefined() && !value.isArray())
|
|
|
|
|
return reportError(msgValueIsNotAObjectArray(ARGUMENTS));
|
|
|
|
|
if (!value.isUndefined()) {
|
2020-02-14 08:51:08 +01:00
|
|
|
const QJsonArray array = value.toArray();
|
|
|
|
|
for (const QJsonValue &v : array) {
|
2014-08-26 17:29:38 +02:00
|
|
|
if (!v.isObject())
|
|
|
|
|
return reportError(msgValueIsNotAObjectArray(ARGUMENTS));
|
|
|
|
|
QJsonObject argumentObject = v.toObject();
|
|
|
|
|
PluginArgumentDescription arg;
|
|
|
|
|
value = argumentObject.value(QLatin1String(ARGUMENT_NAME));
|
2022-02-16 14:32:48 +01:00
|
|
|
if (value.isUndefined()) {
|
|
|
|
|
return reportError(
|
2023-01-23 18:23:53 +01:00
|
|
|
::ExtensionSystem::Tr::tr("Argument: %1")
|
2022-02-16 14:32:48 +01:00
|
|
|
.arg(msgValueMissing(ARGUMENT_NAME)));
|
|
|
|
|
}
|
|
|
|
|
if (!value.isString()) {
|
|
|
|
|
return reportError(
|
2023-01-23 18:23:53 +01:00
|
|
|
::ExtensionSystem::Tr::tr("Argument: %1")
|
2022-02-16 14:32:48 +01:00
|
|
|
.arg(msgValueIsNotAString(ARGUMENT_NAME)));
|
|
|
|
|
}
|
2014-08-26 17:29:38 +02:00
|
|
|
arg.name = value.toString();
|
2022-02-16 14:32:48 +01:00
|
|
|
if (arg.name.isEmpty()) {
|
|
|
|
|
return reportError(
|
2023-01-23 18:23:53 +01:00
|
|
|
::ExtensionSystem::Tr::tr("Argument: \"%1\" is empty")
|
2022-02-16 14:32:48 +01:00
|
|
|
.arg(QLatin1String(ARGUMENT_NAME)));
|
|
|
|
|
}
|
2014-08-26 17:29:38 +02:00
|
|
|
value = argumentObject.value(QLatin1String(ARGUMENT_DESCRIPTION));
|
2022-02-16 14:32:48 +01:00
|
|
|
if (!value.isUndefined() && !value.isString()) {
|
|
|
|
|
return reportError(
|
2023-01-23 18:23:53 +01:00
|
|
|
::ExtensionSystem::Tr::tr("Argument: %1")
|
2022-02-16 14:32:48 +01:00
|
|
|
.arg(msgValueIsNotAString(ARGUMENT_DESCRIPTION)));
|
|
|
|
|
}
|
2014-08-26 17:29:38 +02:00
|
|
|
arg.description = value.toString();
|
|
|
|
|
value = argumentObject.value(QLatin1String(ARGUMENT_PARAMETER));
|
2022-02-16 14:32:48 +01:00
|
|
|
if (!value.isUndefined() && !value.isString()) {
|
|
|
|
|
return reportError(
|
2023-01-23 18:23:53 +01:00
|
|
|
::ExtensionSystem::Tr::tr("Argument: %1")
|
2022-02-16 14:32:48 +01:00
|
|
|
.arg(msgValueIsNotAString(ARGUMENT_PARAMETER)));
|
|
|
|
|
}
|
2014-08-26 17:29:38 +02:00
|
|
|
arg.parameter = value.toString();
|
|
|
|
|
argumentDescriptions.append(arg);
|
|
|
|
|
qCDebug(pluginLog) << "Argument:" << arg.name << "Parameter:" << arg.parameter
|
|
|
|
|
<< "Description:" << arg.description;
|
2011-01-11 14:01:08 +01:00
|
|
|
}
|
|
|
|
|
}
|
2014-08-26 17:29:38 +02:00
|
|
|
|
|
|
|
|
return true;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
\internal
|
|
|
|
|
*/
|
|
|
|
|
bool PluginSpecPrivate::provides(const QString &pluginName, const QString &pluginVersion) const
|
|
|
|
|
{
|
|
|
|
|
if (QString::compare(pluginName, name, Qt::CaseInsensitive) != 0)
|
|
|
|
|
return false;
|
|
|
|
|
return (versionCompare(version, pluginVersion) >= 0) && (versionCompare(compatVersion, pluginVersion) <= 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
\internal
|
|
|
|
|
*/
|
2020-06-09 07:46:57 +02:00
|
|
|
const QRegularExpression &PluginSpecPrivate::versionRegExp()
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2020-06-09 07:46:57 +02:00
|
|
|
static const QRegularExpression reg("^([0-9]+)(?:[.]([0-9]+))?(?:[.]([0-9]+))?(?:_([0-9]+))?$");
|
2008-12-02 12:01:29 +01:00
|
|
|
return reg;
|
|
|
|
|
}
|
|
|
|
|
/*!
|
|
|
|
|
\internal
|
|
|
|
|
*/
|
|
|
|
|
bool PluginSpecPrivate::isValidVersion(const QString &version)
|
|
|
|
|
{
|
2020-06-09 07:46:57 +02:00
|
|
|
return versionRegExp().match(version).hasMatch();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
\internal
|
|
|
|
|
*/
|
|
|
|
|
int PluginSpecPrivate::versionCompare(const QString &version1, const QString &version2)
|
|
|
|
|
{
|
2020-06-09 07:46:57 +02:00
|
|
|
const QRegularExpressionMatch match1 = versionRegExp().match(version1);
|
|
|
|
|
const QRegularExpressionMatch match2 = versionRegExp().match(version2);
|
|
|
|
|
if (!match1.hasMatch())
|
2008-12-02 12:01:29 +01:00
|
|
|
return 0;
|
2020-06-09 07:46:57 +02:00
|
|
|
if (!match2.hasMatch())
|
2008-12-02 12:01:29 +01:00
|
|
|
return 0;
|
|
|
|
|
for (int i = 0; i < 4; ++i) {
|
2020-06-09 07:46:57 +02:00
|
|
|
const int number1 = match1.captured(i + 1).toInt();
|
|
|
|
|
const int number2 = match2.captured(i + 1).toInt();
|
2008-12-02 12:01:29 +01:00
|
|
|
if (number1 < number2)
|
|
|
|
|
return -1;
|
|
|
|
|
if (number1 > number2)
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
\internal
|
|
|
|
|
*/
|
2019-05-27 14:12:11 +02:00
|
|
|
bool PluginSpecPrivate::resolveDependencies(const QVector<PluginSpec *> &specs)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
|
if (hasError)
|
|
|
|
|
return false;
|
|
|
|
|
if (state == PluginSpec::Resolved)
|
|
|
|
|
state = PluginSpec::Read; // Go back, so we just re-resolve the dependencies.
|
|
|
|
|
if (state != PluginSpec::Read) {
|
2023-01-23 18:23:53 +01:00
|
|
|
errorString = ::ExtensionSystem::Tr::tr("Resolving dependencies failed because state != Read");
|
2008-12-02 12:01:29 +01:00
|
|
|
hasError = true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2011-01-11 14:01:08 +01:00
|
|
|
QHash<PluginDependency, PluginSpec *> resolvedDependencies;
|
2022-10-07 14:46:06 +02:00
|
|
|
for (const PluginDependency &dependency : std::as_const(dependencies)) {
|
2016-06-22 16:41:55 +02:00
|
|
|
PluginSpec * const found = Utils::findOrDefault(specs, [&dependency](PluginSpec *spec) {
|
|
|
|
|
return spec->provides(dependency.name, dependency.version);
|
|
|
|
|
});
|
2008-12-02 12:01:29 +01:00
|
|
|
if (!found) {
|
2011-01-11 14:01:08 +01:00
|
|
|
if (dependency.type == PluginDependency::Required) {
|
|
|
|
|
hasError = true;
|
|
|
|
|
if (!errorString.isEmpty())
|
|
|
|
|
errorString.append(QLatin1Char('\n'));
|
2023-01-23 18:23:53 +01:00
|
|
|
errorString.append(::ExtensionSystem::Tr::tr("Could not resolve dependency '%1(%2)'")
|
2022-12-07 01:01:14 +01:00
|
|
|
.arg(dependency.name, dependency.version));
|
2011-01-11 14:01:08 +01:00
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
continue;
|
|
|
|
|
}
|
2011-01-11 14:01:08 +01:00
|
|
|
resolvedDependencies.insert(dependency, found);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
if (hasError)
|
|
|
|
|
return false;
|
2010-03-12 16:02:23 +01:00
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
dependencySpecs = resolvedDependencies;
|
2010-03-12 16:02:23 +01:00
|
|
|
|
2010-05-19 16:29:47 +02:00
|
|
|
state = PluginSpec::Resolved;
|
2010-03-12 16:02:23 +01:00
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-16 13:50:24 +02:00
|
|
|
// returns the plugins that it actually indirectly enabled
|
2019-05-27 14:12:11 +02:00
|
|
|
QVector<PluginSpec *> PluginSpecPrivate::enableDependenciesIndirectly(bool enableTestDependencies)
|
2010-05-19 16:29:47 +02:00
|
|
|
{
|
2015-03-31 17:42:14 +02:00
|
|
|
if (!q->isEffectivelyEnabled()) // plugin not enabled, nothing to do
|
2017-08-16 13:50:24 +02:00
|
|
|
return {};
|
2019-05-27 14:12:11 +02:00
|
|
|
QVector<PluginSpec *> enabled;
|
2019-07-24 13:43:54 +02:00
|
|
|
for (auto it = dependencySpecs.cbegin(), end = dependencySpecs.cend(); it != end; ++it) {
|
2017-08-16 13:50:24 +02:00
|
|
|
if (it.key().type != PluginDependency::Required
|
|
|
|
|
&& (!enableTestDependencies || it.key().type != PluginDependency::Test))
|
2011-01-11 14:01:08 +01:00
|
|
|
continue;
|
|
|
|
|
PluginSpec *dependencySpec = it.value();
|
2017-08-16 13:50:24 +02:00
|
|
|
if (!dependencySpec->isEffectivelyEnabled()) {
|
2015-03-31 17:42:14 +02:00
|
|
|
dependencySpec->d->enabledIndirectly = true;
|
2017-08-16 13:50:24 +02:00
|
|
|
enabled << dependencySpec;
|
|
|
|
|
}
|
2010-05-19 16:29:47 +02:00
|
|
|
}
|
2017-08-16 13:50:24 +02:00
|
|
|
return enabled;
|
2010-05-19 16:29:47 +02:00
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
/*!
|
|
|
|
|
\internal
|
|
|
|
|
*/
|
|
|
|
|
bool PluginSpecPrivate::loadLibrary()
|
|
|
|
|
{
|
|
|
|
|
if (hasError)
|
|
|
|
|
return false;
|
|
|
|
|
if (state != PluginSpec::Resolved) {
|
|
|
|
|
if (state == PluginSpec::Loaded)
|
|
|
|
|
return true;
|
2023-01-23 18:23:53 +01:00
|
|
|
errorString =
|
|
|
|
|
::ExtensionSystem::Tr::tr("Loading the library failed because state != Resolved");
|
2008-12-02 12:01:29 +01:00
|
|
|
hasError = true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2022-04-27 16:19:10 +02:00
|
|
|
if (loader && !loader->load()) {
|
2008-12-02 12:01:29 +01:00
|
|
|
hasError = true;
|
2022-04-27 16:19:10 +02:00
|
|
|
errorString = QDir::toNativeSeparators(filePath) + QString::fromLatin1(": ")
|
|
|
|
|
+ loader->errorString();
|
2008-12-02 12:01:29 +01:00
|
|
|
return false;
|
|
|
|
|
}
|
2022-04-27 16:19:10 +02:00
|
|
|
auto *pluginObject = loader ? qobject_cast<IPlugin *>(loader->instance())
|
|
|
|
|
: qobject_cast<IPlugin *>(staticPlugin->instance());
|
2008-12-02 12:01:29 +01:00
|
|
|
if (!pluginObject) {
|
|
|
|
|
hasError = true;
|
2023-01-23 18:23:53 +01:00
|
|
|
errorString =
|
|
|
|
|
::ExtensionSystem::Tr::tr("Plugin is not valid (does not derive from IPlugin)");
|
2022-04-27 16:19:10 +02:00
|
|
|
if (loader)
|
|
|
|
|
loader->unload();
|
2008-12-02 12:01:29 +01:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
state = PluginSpec::Loaded;
|
|
|
|
|
plugin = pluginObject;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
\internal
|
|
|
|
|
*/
|
|
|
|
|
bool PluginSpecPrivate::initializePlugin()
|
|
|
|
|
{
|
|
|
|
|
if (hasError)
|
|
|
|
|
return false;
|
|
|
|
|
if (state != PluginSpec::Loaded) {
|
|
|
|
|
if (state == PluginSpec::Initialized)
|
|
|
|
|
return true;
|
2023-01-23 18:23:53 +01:00
|
|
|
errorString = ::ExtensionSystem::Tr::tr(
|
|
|
|
|
"Initializing the plugin failed because state != Loaded");
|
2008-12-02 12:01:29 +01:00
|
|
|
hasError = true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if (!plugin) {
|
2023-01-23 18:23:53 +01:00
|
|
|
errorString = ::ExtensionSystem::Tr::tr(
|
|
|
|
|
"Internal error: have no plugin instance to initialize");
|
2008-12-02 12:01:29 +01:00
|
|
|
hasError = true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
QString err;
|
|
|
|
|
if (!plugin->initialize(arguments, &err)) {
|
2023-01-23 18:23:53 +01:00
|
|
|
errorString = ::ExtensionSystem::Tr::tr("Plugin initialization failed: %1").arg(err);
|
2008-12-02 12:01:29 +01:00
|
|
|
hasError = true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
state = PluginSpec::Initialized;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
\internal
|
|
|
|
|
*/
|
|
|
|
|
bool PluginSpecPrivate::initializeExtensions()
|
|
|
|
|
{
|
|
|
|
|
if (hasError)
|
|
|
|
|
return false;
|
|
|
|
|
if (state != PluginSpec::Initialized) {
|
|
|
|
|
if (state == PluginSpec::Running)
|
|
|
|
|
return true;
|
2023-01-23 18:23:53 +01:00
|
|
|
errorString = ::ExtensionSystem::Tr::tr(
|
|
|
|
|
"Cannot perform extensionsInitialized because state != Initialized");
|
2008-12-02 12:01:29 +01:00
|
|
|
hasError = true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if (!plugin) {
|
2023-01-23 18:23:53 +01:00
|
|
|
errorString = ::ExtensionSystem::Tr::tr(
|
|
|
|
|
"Internal error: have no plugin instance to perform extensionsInitialized");
|
2008-12-02 12:01:29 +01:00
|
|
|
hasError = true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
plugin->extensionsInitialized();
|
|
|
|
|
state = PluginSpec::Running;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-02 10:47:33 +01:00
|
|
|
/*!
|
|
|
|
|
\internal
|
|
|
|
|
*/
|
|
|
|
|
bool PluginSpecPrivate::delayedInitialize()
|
|
|
|
|
{
|
|
|
|
|
if (hasError)
|
|
|
|
|
return false;
|
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
2013-01-08 03:32:53 +02:00
|
|
|
if (state != PluginSpec::Running)
|
2012-02-02 10:47:33 +01:00
|
|
|
return false;
|
|
|
|
|
if (!plugin) {
|
2023-01-23 18:23:53 +01:00
|
|
|
errorString = ::ExtensionSystem::Tr::tr(
|
|
|
|
|
"Internal error: have no plugin instance to perform delayedInitialize");
|
2012-02-02 10:47:33 +01:00
|
|
|
hasError = true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return plugin->delayedInitialize();
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
/*!
|
|
|
|
|
\internal
|
|
|
|
|
*/
|
2010-07-13 13:36:47 +02:00
|
|
|
IPlugin::ShutdownFlag PluginSpecPrivate::stop()
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
|
if (!plugin)
|
2010-07-13 13:36:47 +02:00
|
|
|
return IPlugin::SynchronousShutdown;
|
2008-12-02 12:01:29 +01:00
|
|
|
state = PluginSpec::Stopped;
|
2010-07-13 13:36:47 +02:00
|
|
|
return plugin->aboutToShutdown();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
\internal
|
|
|
|
|
*/
|
|
|
|
|
void PluginSpecPrivate::kill()
|
|
|
|
|
{
|
|
|
|
|
if (!plugin)
|
|
|
|
|
return;
|
|
|
|
|
delete plugin;
|
2018-07-19 23:19:33 +02:00
|
|
|
plugin = nullptr;
|
2008-12-02 12:01:29 +01:00
|
|
|
state = PluginSpec::Deleted;
|
|
|
|
|
}
|
2021-12-06 05:11:04 +01:00
|
|
|
|
|
|
|
|
} // ExtensionSystem
|