7#include <private/qqmlextensionplugin_p.h>
8#include <private/qqmltypeloader_p.h>
9#include <private/qqmlglobal_p.h>
11#include <QtCore/qobject.h>
12#include <QtCore/qpluginloader.h>
13#include <QtCore/qdir.h>
14#include <QtCore/qloggingcategory.h>
15#include <QtCore/qjsonarray.h>
17#include <unordered_map>
24 std::unique_ptr<QPluginLoader>
loader;
35 using Container = std::unordered_map<QString, QmlPlugin>;
76 <<
"Found plugin with old IID, this will be unsupported in upcoming Qt releases:"
107static bool unloadPlugin(
const std::pair<const QString, QmlPlugin> &plugin)
109 const auto &
loader = plugin.second.loader;
113#if QT_CONFIG(library)
114 if (
auto extensionPlugin = qobject_cast<QQmlExtensionPlugin *>(
loader->instance()))
115 extensionPlugin->unregisterTypes();
132 for (
const auto &plugin : std::as_const(*plugins))
156 if (
it->second.loader !=
nullptr)
162QString QQmlPluginImporter::truncateToDirectory(
const QString &qmldirFilePath)
164 const int slash = qmldirFilePath.lastIndexOf(u
'/');
165 return slash > 0 ? qmldirFilePath.left(slash) : qmldirFilePath;
168void QQmlPluginImporter::finalizePlugin(
QObject *instance,
const QString &pluginId) {
173 database->initializedPlugins.
insert(pluginId);
174 if (
auto *extensionIface = qobject_cast<QQmlExtensionInterface *>(instance))
176 else if (
auto *engineIface = qobject_cast<QQmlEngineExtensionInterface *>(instance))
191 if (!typesRegistered) {
212 if (!database->initializedPlugins.
contains(pluginId))
213 finalizePlugin(instance, pluginId);
224 const bool engineInitialized = database->initializedPlugins.
contains(pluginId);
229 if (!engineInitialized || !typesRegistered) {
231 if (!typesRegistered && optional) {
234 importVersion, errors)) {
246 database->initializedPlugins.
insert(pluginId);
247 return importVersion;
253#if QT_CONFIG(library)
254 if (!typesRegistered) {
267 error.setDescription(
268 QQmlImportDatabase::tr(
"File name case mismatch for \"%1\"")
277 if (!plugin.loader->load()) {
280 error.setDescription(plugin.loader->errorString());
286 instance = plugin.loader->instance();
287 plugins->insert(std::make_pair(pluginId, std::move(plugin)));
292 importVersion, errors)
304 instance =
it->second.loader->instance();
321 if (!engineInitialized)
322 finalizePlugin(instance, pluginId);
370#elif defined(Q_OS_DARWIN)
386 # if defined(Q_OS_ANDROID)
393 QStringList searchPaths = database->filePluginPath;
395 if (!qmldirPluginPathIsRelative)
396 searchPaths.prepend(qmldirPluginPath);
398 for (
const QString &pluginPath :
std::as_const(searchPaths)) {
401 if (qmldirPluginPathIsRelative && !qmldirPluginPath.
isEmpty()
403 resolvedBasePath =
QDir::cleanPath(qmldirPath + u
'/' + qmldirPluginPath);
405 resolvedBasePath = qmldirPath;
411 resolvedBasePath = pluginPath;
418 if (!resolvedBasePath.
endsWith(u
'/'))
419 resolvedBasePath += u
'/';
421 QString resolvedPath = resolvedBasePath + prefix + baseName;
422 for (
const QString &suffix : suffixes) {
428#if defined(Q_OS_ANDROID)
433 QString pluginName = qmldirPath.
mid(21) + u
'/' + baseName;
436 for (
const QString &suffix : suffixes) {
439 qWarning(
"The implicit resolving of Qml plugin locations using the URI "
440 "embedded in the filename has been deprecated. Please use the "
441 "modern CMake API to create QML modules or set the name of "
442 "QML plugin in qmldir file, that matches the name of plugin "
443 "on file system. The correct plugin name is '%s'.",
452 qCDebug(
lcQmlImport) <<
"resolvePlugin" <<
"Could not resolve dynamic plugin with base name"
453 << baseName <<
"in" << qmldirPath
454 <<
" file does not exist";
471 if (qobject_cast<QQmlEngineExtensionPlugin *>(instance)
472 || qobject_cast<QQmlExtensionPlugin *>(instance)) {
475 if (metaTagsUriList.
isEmpty()) {
478 error.setDescription(QQmlImportDatabase::tr(
479 "static plugin for module \"%1\" with name \"%2\" "
480 "has no metadata URI")
482 instance->metaObject()->className())));
490 if (versionUris.contains(metaTagUri.toString())) {
501 const auto qmldirPlugins = qmldir->
plugins();
502 const int qmldirPluginCount = qmldirPlugins.
size();
509 const bool canUseUris = qmldirPluginCount == 1
513 if (!database->modulesForWhichPluginsHaveBeenLoaded.
contains(moduleId)) {
520 int dynamicPluginsFound = 0;
521 int staticPluginsFound = 0;
524 const QString resolvedFilePath = resolvePlugin(plugin.path, plugin.name);
526 if (!canUseUris && resolvedFilePath.
isEmpty())
534 ++dynamicPluginsFound;
535 else if (!resolvedFilePath.
isEmpty())
539 if (dynamicPluginsFound < qmldirPluginCount) {
547 if (!populatePluginDataVector(pluginPairs, versionUris))
550 for (
const QString &versionUri : versionUris) {
551 for (
const StaticPluginData &pair : std::as_const(pluginPairs)) {
553 if (versionUri == metaTagUri.toString()) {
554 staticPluginsFound++;
555 QObject *instance = pair.plugin.instance();
564 error.setDescription(
565 QQmlImportDatabase::tr(
566 "static plugin for module \"%1\" with "
567 "name \"%2\" cannot be loaded: %3")
569 instance->metaObject()->className()),
578 <<
"importExtension" <<
"loaded static plugin " << versionUri;
584 if (staticPluginsFound > 0)
589 if ((dynamicPluginsFound + staticPluginsFound) < qmldirPluginCount) {
592 if (qmldirPluginCount > 1 && staticPluginsFound > 0) {
593 error.setDescription(QQmlImportDatabase::tr(
594 "could not resolve all plugins for module \"%1\"")
597 error.setDescription(QQmlImportDatabase::tr(
598 "module \"%1\" plugin \"%2\" not found")
599 .
arg(uri, qmldirPlugins[dynamicPluginsFound].
name));
607 database->modulesForWhichPluginsHaveBeenLoaded.
insert(moduleId);
const PluginMap::Container & operator*() const
PluginMap::Container * operator->()
const PluginMap::Container * operator->() const
PluginMap::Container & operator*()
PluginMapPtr(PluginMap *map)
std::unordered_map< QString, QmlPlugin > Container
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
static QString applicationDirPath()
Returns the directory that contains the application executable.
static bool isRelativePath(const QString &path)
Returns true if path is relative; returns false if it is absolute.
static QString cleanPath(const QString &path)
Returns path with directory separators normalized (that is, platform-native separators converted to "...
\inmodule QtCore \reentrant
QString absoluteFilePath() const
Returns an absolute path including the file name.
QString absolutePath() const
Returns a file's path absolute path.
\inmodule QtCore\reentrant
bool isEmpty() const
Returns true if the object is empty.
qsizetype size() const noexcept
bool isEmpty() const noexcept
void prepend(rvalue_ref t)
void append(parameter_type t)
static QList< QStaticPlugin > staticPlugins()
Returns a list of QStaticPlugins held by the plugin loader.
The QQmlError class encapsulates a QML error.
QString description() const
Returns the error description.
static QTypeRevision lockModule(const QString &uri, const QString &typeNamespace, QTypeRevision version, QList< QQmlError > *errors)
static QString versionString(QTypeRevision version, ImportVersion importVersion)
static QTypeRevision validVersion(QTypeRevision version=QTypeRevision())
QTypeRevision importStaticPlugin(QObject *instance, const QString &pluginId)
static bool removePlugin(const QString &pluginId)
QTypeRevision importPlugins()
QTypeRevision importDynamicPlugin(const QString &filePath, const QString &pluginId, bool optional)
static QStringList plugins()
QString typeNamespace() const
QString qmldirLocation() const
QQmlDirPlugins plugins() const
QString absoluteFilePath(const QString &path)
Returns the absolute filename of path via a directory cache.
void initializeEngine(QQmlEngineExtensionInterface *, const char *)
bool contains(const T &value) const
iterator insert(const T &value)
\macro QT_RESTRICTED_CAST_FROM_ASCII
qsizetype lastIndexOf(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
QString & replace(qsizetype i, qsizetype len, QChar after)
qsizetype size() const
Returns the number of characters in this string.
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QString mid(qsizetype position, qsizetype n=-1) const
Returns a string that contains n characters of this string, starting at the specified position index.
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
QString & insert(qsizetype i, QChar c)
QByteArray toUtf8() const &
static QString static QString asprintf(const char *format,...) Q_ATTRIBUTE_FORMAT_PRINTF(1
constexpr bool isValid() const
Returns true if the major version or the minor version is known, otherwise false.
static QUrl fromLocalFile(const QString &localfile)
Returns a QUrl representation of localFile, interpreted as a local file.
QMap< QString, QString > map
[6]
QSet< QString >::iterator it
Combined button and popup list for selecting options.
DBusConnection const char DBusError * error
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
#define qCDebug(category,...)
#define Q_DECLARE_LOGGING_CATEGORY(name)
bool QQml_isFileCaseCorrect(const QString &fileName, int lengthIn)
Returns true if the case of fileName is equivalent to the file case of fileName on disk,...
#define QQmlEngineExtensionInterface_iid
#define QQmlExtensionInterface_iid
#define QQmlExtensionInterface_iid_old
const QLoggingCategory & lcQmlImport()
void qmlClearEnginePlugins()
static QStringList versionUriList(const QString &uri, QTypeRevision version)
static QVector< QStaticPlugin > makePlugins()
static bool unloadPlugin(const std::pair< const QString, QmlPlugin > &plugin)
static QString absolutePath(const QString &path)
#define qPrintable(string)
QLatin1StringView QLatin1String
#define QStringLiteral(str)
static QString absoluteFilePath(const Options *options, const QString &relativeFileName)
char * toString(const MyType &t)
[31]
\inmodule QtCore \reentrant
std::unique_ptr< QPluginLoader > loader