/****************************************************************************
**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtDeclarative module of the Qt Toolkit.
**
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <private/qdeclarativetypenamecache_p.h>
#include <private/qdeclarativeengine_p.h>
-#ifdef Q_OS_SYMBIAN
-#include "private/qcore_symbian_p.h"
-#endif
-
QT_BEGIN_NAMESPACE
DEFINE_BOOL_CONFIG_OPTION(qmlImportTrace, QML_IMPORT_TRACE)
return s1 > s2;
}
+QString resolveLocalUrl(const QString &url, const QString &relative)
+{
+ if (relative.contains(QLatin1Char(':'))) {
+ // contains a host name
+ return QUrl(url).resolved(QUrl(relative)).toString();
+ } else if (relative.isEmpty()) {
+ return url;
+ } else if (relative.at(0) == QLatin1Char('/') || !url.contains(QLatin1Char('/'))) {
+ return relative;
+ } else {
+ if (relative == QLatin1String("."))
+ return url.left(url.lastIndexOf(QLatin1Char('/')) + 1);
+ else if (relative.startsWith(QLatin1String("./")))
+ return url.left(url.lastIndexOf(QLatin1Char('/')) + 1) + relative.mid(2);
+ return url.left(url.lastIndexOf(QLatin1Char('/')) + 1) + relative;
+ }
+}
+
+
+
typedef QMap<QString, QString> StringStringMap;
Q_GLOBAL_STATIC(StringStringMap, qmlEnginePluginsWithRegisteredTypes); // stores the uri
class QDeclarativeImportedNamespace
{
public:
- QStringList uris;
- QStringList urls;
- QList<int> majversions;
- QList<int> minversions;
- QList<bool> isLibrary;
- QList<QDeclarativeDirComponents> qmlDirComponents;
-
-
- bool find_helper(int i, const QByteArray& type, int *vmajor, int *vminor,
- QDeclarativeType** type_return, QUrl* url_return,
- QUrl *base = 0, bool *typeRecursionDetected = 0);
- bool find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return,
- QUrl* url_return, QUrl *base = 0, QString *errorString = 0);
+ struct Data {
+ QString uri;
+ QString url;
+ int majversion;
+ int minversion;
+ bool isLibrary;
+ QDeclarativeDirComponents qmlDirComponents;
+ QDeclarativeDirScripts qmlDirScripts;
+ };
+ QList<Data> imports;
+
+
+ bool find_helper(QDeclarativeTypeLoader *typeLoader, const Data &data, const QString& type, int *vmajor, int *vminor,
+ QDeclarativeType** type_return, QString* url_return,
+ QString *base = 0, bool *typeRecursionDetected = 0);
+ bool find(QDeclarativeTypeLoader *typeLoader, const QString& type, int *vmajor, int *vminor, QDeclarativeType** type_return,
+ QString* url_return, QString *base = 0, QList<QDeclarativeError> *errors = 0);
};
class QDeclarativeImportsPrivate {
public:
- QDeclarativeImportsPrivate();
+ QDeclarativeImportsPrivate(QDeclarativeTypeLoader *loader);
~QDeclarativeImportsPrivate();
bool importExtension(const QString &absoluteFilePath, const QString &uri,
QDeclarativeImportDatabase *database, QDeclarativeDirComponents* components,
- QString *errorString);
+ QDeclarativeDirScripts *scripts,
+ QList<QDeclarativeError> *errors);
QString resolvedUri(const QString &dir_arg, QDeclarativeImportDatabase *database);
bool add(const QDeclarativeDirComponents &qmldircomponentsnetwork,
const QString& uri_arg, const QString& prefix,
- int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType,
- QDeclarativeImportDatabase *database, QString *errorString);
- bool find(const QByteArray& type, int *vmajor, int *vminor,
- QDeclarativeType** type_return, QUrl* url_return, QString *errorString);
+ int vmaj, int vmin, QDeclarativeScript::Import::Type importType,
+ QDeclarativeImportDatabase *database, QList<QDeclarativeError> *errors);
+ bool find(const QString& type, int *vmajor, int *vminor,
+ QDeclarativeType** type_return, QString* url_return, QList<QDeclarativeError> *errors);
QDeclarativeImportedNamespace *findNamespace(const QString& type);
- QUrl base;
+ QUrl baseUrl;
+ QString base;
int ref;
QSet<QString> qmlDirFilesForWhichPluginsHaveBeenLoaded;
QDeclarativeImportedNamespace unqualifiedset;
QHash<QString,QDeclarativeImportedNamespace* > set;
+ QDeclarativeTypeLoader *typeLoader;
};
/*!
return *this;
}
-QDeclarativeImports::QDeclarativeImports()
-: d(new QDeclarativeImportsPrivate)
+QDeclarativeImports::QDeclarativeImports(QDeclarativeTypeLoader *typeLoader)
+ : d(new QDeclarativeImportsPrivate(typeLoader))
{
}
*/
void QDeclarativeImports::setBaseUrl(const QUrl& url)
{
- d->base = url;
+ d->baseUrl = url;
+ d->base = url.toString();
}
/*!
*/
QUrl QDeclarativeImports::baseUrl() const
{
- return d->base;
+ return d->baseUrl;
}
-static QDeclarativeTypeNameCache *
-cacheForNamespace(QDeclarativeEngine *engine, const QDeclarativeImportedNamespace &set,
- QDeclarativeTypeNameCache *cache)
+void QDeclarativeImports::populateCache(QDeclarativeTypeNameCache *cache, QDeclarativeEngine *engine) const
{
- if (!cache)
- cache = new QDeclarativeTypeNameCache(engine);
-
- QList<QDeclarativeType *> types = QDeclarativeMetaType::qmlTypes();
+ const QDeclarativeImportedNamespace &set = d->unqualifiedset;
- for (int ii = 0; ii < set.uris.count(); ++ii) {
- QByteArray base = set.uris.at(ii).toUtf8() + '/';
- int major = set.majversions.at(ii);
- int minor = set.minversions.at(ii);
+ for (int ii = set.imports.count() - 1; ii >= 0; --ii) {
+ const QDeclarativeImportedNamespace::Data &data = set.imports.at(ii);
+ QDeclarativeTypeModule *module = QDeclarativeMetaType::typeModule(data.uri, data.majversion);
+ if (module)
+ cache->m_anonymousImports.append(QDeclarativeTypeModuleVersion(module, data.minversion));
+ }
- foreach (QDeclarativeType *type, types) {
- if (type->qmlTypeName().startsWith(base) &&
- type->qmlTypeName().lastIndexOf('/') == (base.length() - 1) &&
- type->availableInVersion(major,minor))
- {
- QString name = QString::fromUtf8(type->qmlTypeName().mid(base.length()));
+ for (QHash<QString,QDeclarativeImportedNamespace* >::ConstIterator iter = d->set.begin();
+ iter != d->set.end();
+ ++iter) {
+
+ const QDeclarativeImportedNamespace &set = *iter.value();
+ for (int ii = set.imports.count() - 1; ii >= 0; --ii) {
+ const QDeclarativeImportedNamespace::Data &data = set.imports.at(ii);
+ QDeclarativeTypeModule *module = QDeclarativeMetaType::typeModule(data.uri, data.majversion);
+ if (module) {
+ QDeclarativeTypeNameCache::Import &import = cache->m_namedImports[iter.key()];
+ import.modules.append(QDeclarativeTypeModuleVersion(module, data.minversion));
+ }
- cache->add(name, type);
+ QDeclarativeMetaType::ModuleApi moduleApi = QDeclarativeMetaType::moduleApi(data.uri, data.majversion, data.minversion);
+ if (moduleApi.script || moduleApi.qobject) {
+ QDeclarativeTypeNameCache::Import &import = cache->m_namedImports[iter.key()];
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
+ import.moduleApi = ep->moduleApiInstance(moduleApi);
}
}
}
-
- return cache;
}
-void QDeclarativeImports::populateCache(QDeclarativeTypeNameCache *cache, QDeclarativeEngine *engine) const
+QList<QDeclarativeImports::ScriptReference> QDeclarativeImports::resolvedScripts() const
{
+ QList<QDeclarativeImports::ScriptReference> scripts;
+
const QDeclarativeImportedNamespace &set = d->unqualifiedset;
- for (QHash<QString,QDeclarativeImportedNamespace* >::ConstIterator iter = d->set.begin();
- iter != d->set.end(); ++iter) {
+ for (int ii = set.imports.count() - 1; ii >= 0; --ii) {
+ const QDeclarativeImportedNamespace::Data &data = set.imports.at(ii);
- QDeclarativeTypeNameCache::Data *d = cache->data(iter.key());
- if (d) {
- if (!d->typeNamespace)
- cacheForNamespace(engine, *(*iter), d->typeNamespace);
- } else {
- QDeclarativeTypeNameCache *nc = cacheForNamespace(engine, *(*iter), 0);
- cache->add(iter.key(), nc);
- nc->release();
+ foreach (const QDeclarativeDirParser::Script &script, data.qmlDirScripts) {
+ ScriptReference ref;
+ ref.nameSpace = script.nameSpace;
+ ref.location = QUrl(data.url).resolved(QUrl(script.fileName));
+ scripts.append(ref);
}
}
- cacheForNamespace(engine, set, cache);
+ for (QHash<QString,QDeclarativeImportedNamespace* >::ConstIterator iter = d->set.constBegin();
+ iter != d->set.constEnd();
+ ++iter) {
+ const QDeclarativeImportedNamespace &set = *iter.value();
+
+ for (int ii = set.imports.count() - 1; ii >= 0; --ii) {
+ const QDeclarativeImportedNamespace::Data &data = set.imports.at(ii);
+
+ foreach (const QDeclarativeDirParser::Script &script, data.qmlDirScripts) {
+ ScriptReference ref;
+ ref.nameSpace = script.nameSpace;
+ ref.qualifier = iter.key();
+ ref.location = QUrl(data.url).resolved(QUrl(script.fileName));
+ scripts.append(ref);
+ }
+ }
+ }
+
+ return scripts;
}
/*!
\sa addImport()
*/
-bool QDeclarativeImports::resolveType(const QByteArray& type,
- QDeclarativeType** type_return, QUrl* url_return, int *vmaj, int *vmin,
- QDeclarativeImportedNamespace** ns_return, QString *errorString) const
+bool QDeclarativeImports::resolveType(const QString& type,
+ QDeclarativeType** type_return, QString* url_return, int *vmaj, int *vmin,
+ QDeclarativeImportedNamespace** ns_return, QList<QDeclarativeError> *errors) const
{
- QDeclarativeImportedNamespace* ns = d->findNamespace(QString::fromUtf8(type));
+ QDeclarativeImportedNamespace* ns = d->findNamespace(type);
if (ns) {
if (ns_return)
*ns_return = ns;
return true;
}
if (type_return || url_return) {
- if (d->find(type,vmaj,vmin,type_return,url_return, errorString)) {
+ if (d->find(type,vmaj,vmin,type_return,url_return, errors)) {
if (qmlImportTrace()) {
if (type_return && *type_return && url_return && !url_return->isEmpty())
qDebug().nospace() << "QDeclarativeImports(" << qPrintable(baseUrl().toString()) << ")" << "::resolveType: "
If either return pointer is 0, the corresponding search is not done.
*/
-bool QDeclarativeImports::resolveType(QDeclarativeImportedNamespace* ns, const QByteArray& type,
- QDeclarativeType** type_return, QUrl* url_return,
+bool QDeclarativeImports::resolveType(QDeclarativeImportedNamespace* ns, const QString& type,
+ QDeclarativeType** type_return, QString* url_return,
int *vmaj, int *vmin) const
{
- return ns->find(type,vmaj,vmin,type_return,url_return);
+ return ns->find(d->typeLoader,type,vmaj,vmin,type_return,url_return);
}
-bool QDeclarativeImportedNamespace::find_helper(int i, const QByteArray& type, int *vmajor, int *vminor,
- QDeclarativeType** type_return, QUrl* url_return,
- QUrl *base, bool *typeRecursionDetected)
+bool QDeclarativeImportedNamespace::find_helper(QDeclarativeTypeLoader *typeLoader, const Data &data, const QString& type, int *vmajor, int *vminor,
+ QDeclarativeType** type_return, QString* url_return,
+ QString *base, bool *typeRecursionDetected)
{
- int vmaj = majversions.at(i);
- int vmin = minversions.at(i);
-
- QByteArray qt = uris.at(i).toUtf8();
- qt += '/';
- qt += type;
-
- QDeclarativeType *t = QDeclarativeMetaType::qmlType(qt,vmaj,vmin);
- if (t) {
- if (vmajor) *vmajor = vmaj;
- if (vminor) *vminor = vmin;
- if (type_return)
- *type_return = t;
- return true;
+ int vmaj = data.majversion;
+ int vmin = data.minversion;
+
+ if (vmaj >= 0 && vmin >= 0) {
+ QString qt = data.uri + QLatin1Char('/') + type;
+ QDeclarativeType *t = QDeclarativeMetaType::qmlType(qt,vmaj,vmin);
+ if (t) {
+ if (vmajor) *vmajor = vmaj;
+ if (vminor) *vminor = vmin;
+ if (type_return)
+ *type_return = t;
+ return true;
+ }
}
- QUrl url = QUrl(urls.at(i) + QLatin1Char('/') + QString::fromUtf8(type) + QLatin1String(".qml"));
- QDeclarativeDirComponents qmldircomponents = qmlDirComponents.at(i);
-
+ const QDeclarativeDirComponents &qmldircomponents = data.qmlDirComponents;
bool typeWasDeclaredInQmldir = false;
if (!qmldircomponents.isEmpty()) {
- const QString typeName = QString::fromUtf8(type);
foreach (const QDeclarativeDirParser::Component &c, qmldircomponents) {
- if (c.typeName == typeName) {
+ if (c.typeName == type) {
typeWasDeclaredInQmldir = true;
-
// importing version -1 means import ALL versions
- if ((vmaj == -1) || (c.majorVersion < vmaj || (c.majorVersion == vmaj && vmin >= c.minorVersion))) {
- QUrl candidate = url.resolved(QUrl(c.fileName));
+ if ((vmaj == -1) || (c.majorVersion == vmaj && vmin >= c.minorVersion)) {
+ QString url(data.url + type + QLatin1String(".qml"));
+ QString candidate = resolveLocalUrl(url, c.fileName);
if (c.internal && base) {
- if (base->resolved(QUrl(c.fileName)) != candidate)
+ if (resolveLocalUrl(*base, c.fileName) != candidate)
continue; // failed attempt to access an internal type
}
if (base && *base == candidate) {
}
}
- if (!typeWasDeclaredInQmldir && !isLibrary.at(i)) {
+ if (!typeWasDeclaredInQmldir && !data.isLibrary) {
// XXX search non-files too! (eg. zip files, see QT-524)
- QFileInfo f(QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url));
- if (f.exists()) {
+ QString url(data.url + type + QLatin1String(".qml"));
+ QString file = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url);
+ if (!typeLoader->absoluteFilePath(file).isEmpty()) {
if (base && *base == url) { // no recursion
if (typeRecursionDetected)
*typeRecursionDetected = true;
return false;
}
-QDeclarativeImportsPrivate::QDeclarativeImportsPrivate()
-: ref(1)
+QDeclarativeImportsPrivate::QDeclarativeImportsPrivate(QDeclarativeTypeLoader *loader)
+ : ref(1), typeLoader(loader)
{
}
delete s;
}
-bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath, const QString &uri,
- QDeclarativeImportDatabase *database,
- QDeclarativeDirComponents* components, QString *errorString)
+bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath, const QString &uri,
+ QDeclarativeImportDatabase *database,
+ QDeclarativeDirComponents* components,
+ QDeclarativeDirScripts* scripts,
+ QList<QDeclarativeError> *errors)
{
- QFile file(absoluteFilePath);
- QString filecontent;
- if (!QDeclarative_isFileCaseCorrect(absoluteFilePath)) {
- if (errorString)
- *errorString = QDeclarativeImportDatabase::tr("cannot load module \"%1\": File name case mismatch for \"%2\"").arg(uri).arg(absoluteFilePath);
- return false;
- } else if (file.open(QFile::ReadOnly)) {
- filecontent = QString::fromUtf8(file.readAll());
- if (qmlImportTrace())
- qDebug().nospace() << "QDeclarativeImports(" << qPrintable(base.toString()) << "::importExtension: "
- << "loaded " << absoluteFilePath;
- } else {
- if (errorString)
- *errorString = QDeclarativeImportDatabase::tr("module \"%1\" definition \"%2\" not readable").arg(uri).arg(absoluteFilePath);
+ const QDeclarativeDirParser *qmldirParser = typeLoader->qmlDirParser(absoluteFilePath);
+ if (qmldirParser->hasError()) {
+ if (errors) {
+ const QList<QDeclarativeError> qmldirErrors = qmldirParser->errors(uri);
+ for (int i = 0; i < qmldirErrors.size(); ++i)
+ errors->prepend(qmldirErrors.at(i));
+ }
return false;
}
- QDir dir = QFileInfo(file).dir();
- QDeclarativeDirParser qmldirParser;
- qmldirParser.setSource(filecontent);
- qmldirParser.parse();
+ if (qmlImportTrace())
+ qDebug().nospace() << "QDeclarativeImports(" << qPrintable(base) << "::importExtension: "
+ << "loaded " << absoluteFilePath;
if (! qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(absoluteFilePath)) {
qmlDirFilesForWhichPluginsHaveBeenLoaded.insert(absoluteFilePath);
+ QString qmldirPath = absoluteFilePath;
+ int slash = absoluteFilePath.lastIndexOf(QLatin1Char('/'));
+ if (slash > 0)
+ qmldirPath.truncate(slash);
+ foreach (const QDeclarativeDirParser::Plugin &plugin, qmldirParser->plugins()) {
- foreach (const QDeclarativeDirParser::Plugin &plugin, qmldirParser.plugins()) {
-
- QString resolvedFilePath = database->resolvePlugin(dir, plugin.path, plugin.name);
-#if defined(QT_LIBINFIX) && defined(Q_OS_SYMBIAN)
- if (resolvedFilePath.isEmpty()) {
- // In case of libinfixed build, attempt to load libinfixed version, too.
- QString infixedPluginName = plugin.name + QLatin1String(QT_LIBINFIX);
- resolvedFilePath = database->resolvePlugin(dir, plugin.path, infixedPluginName);
- }
-#endif
+ QString resolvedFilePath = database->resolvePlugin(typeLoader, qmldirPath, plugin.path, plugin.name);
if (!resolvedFilePath.isEmpty()) {
- if (!database->importPlugin(resolvedFilePath, uri, errorString)) {
- if (errorString)
- *errorString = QDeclarativeImportDatabase::tr("plugin cannot be loaded for module \"%1\": %2").arg(uri).arg(*errorString);
+ if (!database->importPlugin(resolvedFilePath, uri, errors)) {
+ if (errors) {
+ // XXX TODO: should we leave the import plugin error alone?
+ // Here, we pop it off the top and coalesce it into this error's message.
+ // The reason is that the lower level may add url and line/column numbering information.
+ QDeclarativeError poppedError = errors->takeFirst();
+ QDeclarativeError error;
+ error.setDescription(QDeclarativeImportDatabase::tr("plugin cannot be loaded for module \"%1\": %2").arg(uri).arg(poppedError.description()));
+ error.setUrl(QUrl::fromLocalFile(absoluteFilePath));
+ errors->prepend(error);
+ }
return false;
}
} else {
- if (errorString)
- *errorString = QDeclarativeImportDatabase::tr("module \"%1\" plugin \"%2\" not found").arg(uri).arg(plugin.name);
+ if (errors) {
+ QDeclarativeError error;
+ error.setDescription(QDeclarativeImportDatabase::tr("module \"%1\" plugin \"%2\" not found").arg(uri).arg(plugin.name));
+ error.setUrl(QUrl::fromLocalFile(absoluteFilePath));
+ errors->prepend(error);
+ }
return false;
}
}
}
if (components)
- *components = qmldirParser.components();
+ *components = qmldirParser->components();
+ if (scripts)
+ *scripts = qmldirParser->scripts();
return true;
}
bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomponentsnetwork,
const QString& uri_arg, const QString& prefix, int vmaj, int vmin,
- QDeclarativeScriptParser::Import::Type importType,
- QDeclarativeImportDatabase *database, QString *errorString)
+ QDeclarativeScript::Import::Type importType,
+ QDeclarativeImportDatabase *database, QList<QDeclarativeError> *errors)
{
+ static QLatin1String Slash_qmldir("/qmldir");
+ static QLatin1Char Slash('/');
+
QDeclarativeDirComponents qmldircomponents = qmldircomponentsnetwork;
+ QDeclarativeDirScripts qmldirscripts;
QString uri = uri_arg;
QDeclarativeImportedNamespace *s;
if (prefix.isEmpty()) {
if (!s)
set.insert(prefix,(s=new QDeclarativeImportedNamespace));
}
-
QString url = uri;
bool versionFound = false;
- if (importType == QDeclarativeScriptParser::Import::Library) {
- url.replace(QLatin1Char('.'), QLatin1Char('/'));
+ if (importType == QDeclarativeScript::Import::Library) {
+
+ Q_ASSERT(vmaj >= 0 && vmin >= 0); // Versions are always specified for libraries
+
+ url.replace(QLatin1Char('.'), Slash);
bool found = false;
QString dir;
-
+ QString qmldir;
// step 1: search for extension with fully encoded version number
- if (vmaj >= 0 && vmin >= 0) {
- foreach (const QString &p, database->fileImportPath) {
- dir = p+QLatin1Char('/')+url;
+ foreach (const QString &p, database->fileImportPath) {
+ dir = p+Slash+url;
- QFileInfo fi(dir+QString(QLatin1String(".%1.%2")).arg(vmaj).arg(vmin)+QLatin1String("/qmldir"));
- const QString absoluteFilePath = fi.absoluteFilePath();
+ QFileInfo fi(dir+QString(QLatin1String(".%1.%2")).arg(vmaj).arg(vmin)+QLatin1String("/qmldir"));
+ const QString absoluteFilePath = fi.absoluteFilePath();
- if (fi.isFile()) {
- found = true;
+ if (fi.isFile()) {
+ found = true;
+ const QString absolutePath = fi.absolutePath();
+ if (absolutePath.at(0) == QLatin1Char(':'))
+ url = QLatin1String("qrc://") + absolutePath.mid(1);
+ else
url = QUrl::fromLocalFile(fi.absolutePath()).toString();
- uri = resolvedUri(dir, database);
- if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, errorString))
- return false;
- break;
- }
+ uri = resolvedUri(dir, database);
+ if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, &qmldirscripts, errors))
+ return false;
+ break;
}
}
+
+ // TODO: Should this search be omitted if found == true?
+
// step 2: search for extension with encoded version major
- if (vmaj >= 0 && vmin >= 0) {
- foreach (const QString &p, database->fileImportPath) {
- dir = p+QLatin1Char('/')+url;
+ foreach (const QString &p, database->fileImportPath) {
+ dir = p+Slash+url;
- QFileInfo fi(dir+QString(QLatin1String(".%1")).arg(vmaj)+QLatin1String("/qmldir"));
- const QString absoluteFilePath = fi.absoluteFilePath();
+ QFileInfo fi(dir+QString(QLatin1String(".%1")).arg(vmaj)+QLatin1String("/qmldir"));
+ const QString absoluteFilePath = fi.absoluteFilePath();
- if (fi.isFile()) {
- found = true;
+ if (fi.isFile()) {
+ found = true;
+ const QString absolutePath = fi.absolutePath();
+ if (absolutePath.at(0) == QLatin1Char(':'))
+ url = QLatin1String("qrc://") + absolutePath.mid(1);
+ else
url = QUrl::fromLocalFile(fi.absolutePath()).toString();
- uri = resolvedUri(dir, database);
- if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, errorString))
- return false;
- break;
- }
+ uri = resolvedUri(dir, database);
+ if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, &qmldirscripts, errors))
+ return false;
+ break;
}
}
+
if (!found) {
// step 3: search for extension without version number
foreach (const QString &p, database->fileImportPath) {
- dir = p+QLatin1Char('/')+url;
+ dir = p+Slash+url;
+ qmldir = dir+Slash_qmldir;
- QFileInfo fi(dir+QLatin1String("/qmldir"));
- const QString absoluteFilePath = fi.absoluteFilePath();
-
- if (fi.isFile()) {
+ QString absoluteFilePath = typeLoader->absoluteFilePath(qmldir);
+ if (!absoluteFilePath.isEmpty()) {
found = true;
-
- url = QUrl::fromLocalFile(fi.absolutePath()).toString();
+ QString absolutePath = absoluteFilePath.left(absoluteFilePath.lastIndexOf(Slash)+1);
+ if (absolutePath.at(0) == QLatin1Char(':'))
+ url = QLatin1String("qrc://") + absolutePath.mid(1);
+ else
+ url = QUrl::fromLocalFile(absolutePath).toString();
uri = resolvedUri(dir, database);
- if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, errorString))
+ if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, &qmldirscripts, errors))
return false;
break;
}
}
}
- if (QDeclarativeMetaType::isModule(uri.toUtf8(), vmaj, vmin))
+ if (QDeclarativeMetaType::isModule(uri, vmaj, vmin))
versionFound = true;
- if (!versionFound && qmldircomponents.isEmpty()) {
- if (errorString) {
- bool anyversion = QDeclarativeMetaType::isModule(uri.toUtf8(), -1, -1);
- if (anyversion)
- *errorString = QDeclarativeImportDatabase::tr("module \"%1\" version %2.%3 is not installed").arg(uri_arg).arg(vmaj).arg(vmin);
+ if (!versionFound && qmldircomponents.isEmpty() && qmldirscripts.isEmpty()) {
+ if (errors) {
+ QDeclarativeError error; // we don't set the url or line or column as these will be set by the loader.
+ if (QDeclarativeMetaType::isAnyModule(uri))
+ error.setDescription(QDeclarativeImportDatabase::tr("module \"%1\" version %2.%3 is not installed").arg(uri_arg).arg(vmaj).arg(vmin));
else
- *errorString = QDeclarativeImportDatabase::tr("module \"%1\" is not installed").arg(uri_arg);
+ error.setDescription(QDeclarativeImportDatabase::tr("module \"%1\" is not installed").arg(uri_arg));
+ errors->prepend(error);
}
return false;
}
} else {
-
- if (importType == QDeclarativeScriptParser::Import::File && qmldircomponents.isEmpty()) {
- QUrl importUrl = base.resolved(QUrl(uri + QLatin1String("/qmldir")));
+ if (importType == QDeclarativeScript::Import::File && qmldircomponents.isEmpty()) {
+ QString importUrl = resolveLocalUrl(base, uri + Slash_qmldir);
QString localFileOrQrc = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(importUrl);
if (!localFileOrQrc.isEmpty()) {
- QString dir = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(base.resolved(QUrl(uri)));
- QFileInfo dirinfo(dir);
- if (dir.isEmpty() || !dirinfo.exists() || !dirinfo.isDir()) {
- if (errorString)
- *errorString = QDeclarativeImportDatabase::tr("\"%1\": no such directory").arg(uri_arg);
+ QString dir = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(resolveLocalUrl(base, uri));
+ if (!typeLoader->directoryExists(dir)) {
+ if (errors) {
+ QDeclarativeError error; // we don't set the line or column as these will be set by the loader.
+ error.setDescription(QDeclarativeImportDatabase::tr("\"%1\": no such directory").arg(uri_arg));
+ error.setUrl(QUrl(importUrl));
+ errors->prepend(error);
+ }
return false; // local import dirs must exist
}
- uri = resolvedUri(QDeclarativeEnginePrivate::urlToLocalFileOrQrc(base.resolved(QUrl(uri))), database);
- if (uri.endsWith(QLatin1Char('/')))
+ uri = resolvedUri(dir, database);
+ if (uri.endsWith(Slash))
uri.chop(1);
- if (QFile::exists(localFileOrQrc)) {
- if (!importExtension(localFileOrQrc,uri,database,&qmldircomponents,errorString))
+ if (!typeLoader->absoluteFilePath(localFileOrQrc).isEmpty()) {
+ if (!importExtension(localFileOrQrc,uri,database,&qmldircomponents,&qmldirscripts,errors))
return false;
}
} else {
if (prefix.isEmpty()) {
// directory must at least exist for valid import
- QString localFileOrQrc = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(base.resolved(QUrl(uri)));
- QFileInfo dirinfo(localFileOrQrc);
- if (localFileOrQrc.isEmpty() || !dirinfo.exists() || !dirinfo.isDir()) {
- if (errorString) {
+ QString localFileOrQrc = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(resolveLocalUrl(base, uri));
+ if (!typeLoader->directoryExists(localFileOrQrc)) {
+ if (errors) {
+ QDeclarativeError error; // we don't set the line or column as these will be set by the loader.
if (localFileOrQrc.isEmpty())
- *errorString = QDeclarativeImportDatabase::tr("import \"%1\" has no qmldir and no namespace").arg(uri);
+ error.setDescription(QDeclarativeImportDatabase::tr("import \"%1\" has no qmldir and no namespace").arg(uri));
else
- *errorString = QDeclarativeImportDatabase::tr("\"%1\": no such directory").arg(uri);
+ error.setDescription(QDeclarativeImportDatabase::tr("\"%1\": no such directory").arg(uri));
+ error.setUrl(QUrl(importUrl));
+ errors->prepend(error);
}
return false;
}
}
}
- url = base.resolved(QUrl(url)).toString();
- if (url.endsWith(QLatin1Char('/')))
- url.chop(1);
+ url = resolveLocalUrl(base, url);
}
- if (!versionFound && vmaj > -1 && vmin > -1 && !qmldircomponents.isEmpty()) {
- QList<QDeclarativeDirParser::Component>::ConstIterator it = qmldircomponents.begin();
- int lowest_maj = INT_MAX;
+ if (!versionFound && (vmaj > -1) && (vmin > -1) && !qmldircomponents.isEmpty()) {
int lowest_min = INT_MAX;
- int highest_maj = INT_MIN;
int highest_min = INT_MIN;
- for (; it != qmldircomponents.end(); ++it) {
- if (it->majorVersion > highest_maj || (it->majorVersion == highest_maj && it->minorVersion > highest_min)) {
- highest_maj = it->majorVersion;
- highest_min = it->minorVersion;
- }
- if (it->majorVersion < lowest_maj || (it->majorVersion == lowest_maj && it->minorVersion < lowest_min)) {
- lowest_maj = it->majorVersion;
- lowest_min = it->minorVersion;
+
+ QList<QDeclarativeDirParser::Component>::const_iterator cend = qmldircomponents.constEnd();
+ for (QList<QDeclarativeDirParser::Component>::const_iterator cit = qmldircomponents.constBegin(); cit != cend; ++cit) {
+ if (cit->majorVersion == vmaj) {
+ lowest_min = qMin(lowest_min, cit->minorVersion);
+ highest_min = qMax(highest_min, cit->minorVersion);
}
}
- if (lowest_maj > vmaj || (lowest_maj == vmaj && lowest_min > vmin)
- || highest_maj < vmaj || (highest_maj == vmaj && highest_min < vmin))
- {
- *errorString = QDeclarativeImportDatabase::tr("module \"%1\" version %2.%3 is not installed").arg(uri_arg).arg(vmaj).arg(vmin);
+
+ if (lowest_min > vmin || highest_min < vmin) {
+ if (errors) {
+ QDeclarativeError error; // we don't set the url or line or column information, as these will be set by the loader.
+ error.setDescription(QDeclarativeImportDatabase::tr("module \"%1\" version %2.%3 is not installed").arg(uri_arg).arg(vmaj).arg(vmin));
+ errors->prepend(error);
+ }
return false;
}
}
- s->uris.prepend(uri);
- s->urls.prepend(url);
- s->majversions.prepend(vmaj);
- s->minversions.prepend(vmin);
- s->isLibrary.prepend(importType == QDeclarativeScriptParser::Import::Library);
- s->qmlDirComponents.prepend(qmldircomponents);
+ if (!url.endsWith(Slash))
+ url += Slash;
+
+ QMap<QString, QDeclarativeDirParser::Script> scripts;
+
+ if (!qmldirscripts.isEmpty()) {
+ // Verify that we haven't imported these scripts already
+ QList<QDeclarativeImportedNamespace::Data>::const_iterator end = s->imports.constEnd();
+ for (QList<QDeclarativeImportedNamespace::Data>::const_iterator it = s->imports.constBegin(); it != end; ++it) {
+ if (it->uri == uri) {
+ QDeclarativeError error;
+ error.setDescription(QDeclarativeImportDatabase::tr("\"%1\" is ambiguous. Found in %2 and in %3").arg(uri).arg(url).arg(it->url));
+ errors->prepend(error);
+ return false;
+ }
+ }
+
+ QList<QDeclarativeDirParser::Script>::const_iterator send = qmldirscripts.constEnd();
+ for (QList<QDeclarativeDirParser::Script>::const_iterator sit = qmldirscripts.constBegin(); sit != send; ++sit) {
+ // Only include scripts that match our requested version
+ if (((vmaj == -1) || (sit->majorVersion == vmaj)) &&
+ ((vmin == -1) || (sit->minorVersion <= vmin))) {
+
+ // Load the highest version that matches
+ QMap<QString, QDeclarativeDirParser::Script>::iterator it = scripts.find(sit->nameSpace);
+ if (it == scripts.end() || (it->minorVersion < sit->minorVersion)) {
+ scripts.insert(sit->nameSpace, *sit);
+ }
+ }
+ }
+ }
+
+ QDeclarativeImportedNamespace::Data data;
+ data.uri = uri;
+ data.url = url;
+ data.majversion = vmaj;
+ data.minversion = vmin;
+ data.isLibrary = importType == QDeclarativeScript::Import::Library;
+ data.qmlDirComponents = qmldircomponents;
+ data.qmlDirScripts = scripts.values();
+
+ s->imports.prepend(data);
+
return true;
}
-bool QDeclarativeImportsPrivate::find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return,
- QUrl* url_return, QString *errorString)
+bool QDeclarativeImportsPrivate::find(const QString& type, int *vmajor, int *vminor, QDeclarativeType** type_return,
+ QString* url_return, QList<QDeclarativeError> *errors)
{
QDeclarativeImportedNamespace *s = 0;
- int slash = type.indexOf('/');
+ int slash = type.indexOf(QLatin1Char('/'));
if (slash >= 0) {
- QString namespaceName = QString::fromUtf8(type.left(slash));
+ QString namespaceName = type.left(slash);
s = set.value(namespaceName);
if (!s) {
- if (errorString)
- *errorString = QDeclarativeImportDatabase::tr("- %1 is not a namespace").arg(namespaceName);
+ if (errors) {
+ QDeclarativeError error;
+ error.setDescription(QDeclarativeImportDatabase::tr("- %1 is not a namespace").arg(namespaceName));
+ errors->prepend(error);
+ }
return false;
}
- int nslash = type.indexOf('/',slash+1);
+ int nslash = type.indexOf(QLatin1Char('/'),slash+1);
if (nslash > 0) {
- if (errorString)
- *errorString = QDeclarativeImportDatabase::tr("- nested namespaces not allowed");
+ if (errors) {
+ QDeclarativeError error;
+ error.setDescription(QDeclarativeImportDatabase::tr("- nested namespaces not allowed"));
+ errors->prepend(error);
+ }
return false;
}
} else {
s = &unqualifiedset;
}
- QByteArray unqualifiedtype = slash < 0 ? type : type.mid(slash+1); // common-case opt (QString::mid works fine, but slower)
+ QString unqualifiedtype = slash < 0 ? type : type.mid(slash+1); // common-case opt (QString::mid works fine, but slower)
if (s) {
- if (s->find(unqualifiedtype,vmajor,vminor,type_return,url_return, &base, errorString))
+ if (s->find(typeLoader,unqualifiedtype,vmajor,vminor,type_return,url_return, &base, errors))
return true;
- if (s->urls.count() == 1 && !s->isLibrary[0] && url_return && s != &unqualifiedset) {
+ if (s->imports.count() == 1 && !s->imports.at(0).isLibrary && url_return && s != &unqualifiedset) {
// qualified, and only 1 url
- *url_return = QUrl(s->urls[0]+QLatin1Char('/')).resolved(QUrl(QString::fromUtf8(unqualifiedtype) + QLatin1String(".qml")));
+ *url_return = resolveLocalUrl(s->imports.at(0).url, unqualifiedtype + QLatin1String(".qml"));
return true;
}
}
return set.value(type);
}
-bool QDeclarativeImportedNamespace::find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return,
- QUrl* url_return, QUrl *base, QString *errorString)
+bool QDeclarativeImportedNamespace::find(QDeclarativeTypeLoader *typeLoader, const QString& type, int *vmajor, int *vminor, QDeclarativeType** type_return,
+ QString* url_return, QString *base, QList<QDeclarativeError> *errors)
{
bool typeRecursionDetected = false;
- for (int i=0; i<urls.count(); ++i) {
- if (find_helper(i, type, vmajor, vminor, type_return, url_return, base, &typeRecursionDetected)) {
+ for (int i=0; i<imports.count(); ++i) {
+ if (find_helper(typeLoader, imports.at(i), type, vmajor, vminor, type_return, url_return, base, &typeRecursionDetected)) {
if (qmlCheckTypes()) {
// check for type clashes
- for (int j = i+1; j<urls.count(); ++j) {
- if (find_helper(j, type, vmajor, vminor, 0, 0, base)) {
- if (errorString) {
- QString u1 = urls.at(i);
- QString u2 = urls.at(j);
+ for (int j = i+1; j<imports.count(); ++j) {
+ if (find_helper(typeLoader, imports.at(j), type, vmajor, vminor, 0, 0, base)) {
+ if (errors) {
+ QString u1 = imports.at(i).url;
+ QString u2 = imports.at(j).url;
if (base) {
- QString b = base->toString();
+ QString b = *base;
int slash = b.lastIndexOf(QLatin1Char('/'));
if (slash >= 0) {
b = b.left(slash+1);
}
}
- if (u1 != u2)
- *errorString
- = QDeclarativeImportDatabase::tr("is ambiguous. Found in %1 and in %2")
- .arg(u1).arg(u2);
- else
- *errorString
- = QDeclarativeImportDatabase::tr("is ambiguous. Found in %1 in version %2.%3 and %4.%5")
- .arg(u1)
- .arg(majversions.at(i)).arg(minversions.at(i))
- .arg(majversions.at(j)).arg(minversions.at(j));
+ QDeclarativeError error;
+ if (u1 != u2) {
+ error.setDescription(QDeclarativeImportDatabase::tr("is ambiguous. Found in %1 and in %2").arg(u1).arg(u2));
+ } else {
+ error.setDescription(QDeclarativeImportDatabase::tr("is ambiguous. Found in %1 in version %2.%3 and %4.%5")
+ .arg(u1)
+ .arg(imports.at(i).majversion).arg(imports.at(i).minversion)
+ .arg(imports.at(j).majversion).arg(imports.at(j).minversion));
+ }
+ errors->prepend(error);
}
return false;
}
return true;
}
}
- if (errorString) {
+ if (errors) {
+ QDeclarativeError error;
if (typeRecursionDetected)
- *errorString = QDeclarativeImportDatabase::tr("is instantiated recursively");
+ error.setDescription(QDeclarativeImportDatabase::tr("is instantiated recursively"));
else
- *errorString = QDeclarativeImportDatabase::tr("is not a type");
+ error.setDescription(QDeclarativeImportDatabase::tr("is not a type"));
+ errors->prepend(error);
}
return false;
}
#ifndef QT_NO_SETTINGS
QString installImportsPath = QLibraryInfo::location(QLibraryInfo::ImportsPath);
-
-#if defined(Q_OS_SYMBIAN)
- // Append imports path for all available drives in Symbian
- if (installImportsPath.at(1) != QChar(QLatin1Char(':'))) {
- QString tempPath = installImportsPath;
- if (tempPath.at(tempPath.length() - 1) != QDir::separator()) {
- tempPath += QDir::separator();
- }
- RFs& fs = qt_s60GetRFs();
- TPtrC tempPathPtr(reinterpret_cast<const TText*> (tempPath.constData()));
- TFindFile finder(fs);
- TInt err = finder.FindByDir(tempPathPtr, tempPathPtr);
- while (err == KErrNone) {
- QString foundDir(reinterpret_cast<const QChar *>(finder.File().Ptr()),
- finder.File().Length());
- foundDir = QDir(foundDir).canonicalPath();
- addImportPath(foundDir);
- err = finder.Find();
- }
- } else {
- addImportPath(installImportsPath);
- }
-#else
addImportPath(installImportsPath);
-#endif
-
#endif // QT_NO_SETTINGS
// env import paths
QByteArray envImportPath = qgetenv("QML_IMPORT_PATH");
if (!envImportPath.isEmpty()) {
-#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+#if defined(Q_OS_WIN)
QLatin1Char pathSep(';');
#else
QLatin1Char pathSep(':');
*/
bool QDeclarativeImports::addImport(QDeclarativeImportDatabase *importDb,
const QString& uri, const QString& prefix, int vmaj, int vmin,
- QDeclarativeScriptParser::Import::Type importType,
+ QDeclarativeScript::Import::Type importType,
const QDeclarativeDirComponents &qmldircomponentsnetwork,
- QString *errorString)
+ QList<QDeclarativeError> *errors)
{
if (qmlImportTrace())
qDebug().nospace() << "QDeclarativeImports(" << qPrintable(baseUrl().toString()) << ")" << "::addImport: "
<< uri << " " << vmaj << '.' << vmin << " "
- << (importType==QDeclarativeScriptParser::Import::Library? "Library" : "File")
+ << (importType==QDeclarativeScript::Import::Library? "Library" : "File")
<< " as " << prefix;
- return d->add(qmldircomponentsnetwork, uri, prefix, vmaj, vmin, importType, importDb, errorString);
+ return d->add(qmldircomponentsnetwork, uri, prefix, vmaj, vmin, importType, importDb, errors);
}
/*!
\a qmldirPath is the location of the qmldir file.
*/
-QString QDeclarativeImportDatabase::resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath,
+QString QDeclarativeImportDatabase::resolvePlugin(QDeclarativeTypeLoader *typeLoader,
+ const QString &qmldirPath, const QString &qmldirPluginPath,
const QString &baseName, const QStringList &suffixes,
const QString &prefix)
{
foreach (const QString &pluginPath, searchPaths) {
QString resolvedPath;
-
if (pluginPath == QLatin1String(".")) {
- if (qmldirPluginPathIsRelative)
- resolvedPath = qmldirPath.absoluteFilePath(qmldirPluginPath);
+ if (qmldirPluginPathIsRelative && !qmldirPluginPath.isEmpty() && qmldirPluginPath != QLatin1String("."))
+ resolvedPath = QDir::cleanPath(qmldirPath + QLatin1Char('/') + qmldirPluginPath);
else
- resolvedPath = qmldirPath.absolutePath();
+ resolvedPath = qmldirPath;
} else {
- resolvedPath = pluginPath;
+ if (QDir::isRelativePath(pluginPath))
+ resolvedPath = QDir::cleanPath(qmldirPath + QLatin1Char('/') + pluginPath);
+ else
+ resolvedPath = pluginPath;
}
// hack for resources, should probably go away
if (resolvedPath.startsWith(QLatin1Char(':')))
resolvedPath = QCoreApplication::applicationDirPath();
- QDir dir(resolvedPath);
+ if (!resolvedPath.endsWith(QLatin1Char('/')))
+ resolvedPath += QLatin1Char('/');
+
foreach (const QString &suffix, suffixes) {
QString pluginFileName = prefix;
pluginFileName += baseName;
pluginFileName += suffix;
- QFileInfo fileInfo(dir, pluginFileName);
-
- if (fileInfo.exists())
- return fileInfo.absoluteFilePath();
+ QString absolutePath = typeLoader->absoluteFilePath(resolvedPath + pluginFileName);
+ if (!absolutePath.isEmpty())
+ return absolutePath;
}
}
if (qmlImportTrace())
qDebug() << "QDeclarativeImportDatabase::resolvePlugin: Could not resolve plugin" << baseName
- << "in" << qmldirPath.absolutePath();
+ << "in" << qmldirPath;
return QString();
}
\row \i AIX \i \c .a
\row \i HP-UX \i \c .sl, \c .so (HP-UXi)
\row \i Mac OS X \i \c .dylib, \c .bundle, \c .so
- \row \i Symbian \i \c .dll
\endtable
Version number on unix are ignored.
*/
-QString QDeclarativeImportDatabase::resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath,
+QString QDeclarativeImportDatabase::resolvePlugin(QDeclarativeTypeLoader *typeLoader,
+ const QString &qmldirPath, const QString &qmldirPluginPath,
const QString &baseName)
{
#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
- return resolvePlugin(qmldirPath, qmldirPluginPath, baseName,
+ return resolvePlugin(typeLoader, qmldirPath, qmldirPluginPath, baseName,
QStringList()
# ifdef QT_DEBUG
<< QLatin1String("d.dll") // try a qmake-style debug build first
# endif
<< QLatin1String(".dll"));
-#elif defined(Q_OS_SYMBIAN)
- return resolvePlugin(qmldirPath, qmldirPluginPath, baseName,
- QStringList()
- << QLatin1String(".dll")
- << QLatin1String(".qtplugin"));
#else
# if defined(Q_OS_DARWIN)
- return resolvePlugin(qmldirPath, qmldirPluginPath, baseName,
+ return resolvePlugin(typeLoader, qmldirPath, qmldirPluginPath, baseName,
QStringList()
# ifdef QT_DEBUG
<< QLatin1String("_debug.dylib") // try a qmake-style debug build first
// Examples of valid library names:
// libfoo.so
- return resolvePlugin(qmldirPath, qmldirPluginPath, baseName, validSuffixList, QLatin1String("lib"));
+ return resolvePlugin(typeLoader, qmldirPath, qmldirPluginPath, baseName, validSuffixList, QLatin1String("lib"));
# endif
#endif
/*!
\internal
*/
-bool QDeclarativeImportDatabase::importPlugin(const QString &filePath, const QString &uri, QString *errorString)
+bool QDeclarativeImportDatabase::importPlugin(const QString &filePath, const QString &uri, QList<QDeclarativeError> *errors)
{
if (qmlImportTrace())
qDebug().nospace() << "QDeclarativeImportDatabase::importPlugin: " << uri << " from " << filePath;
if (!engineInitialized || !typesRegistered) {
if (!QDeclarative_isFileCaseCorrect(absoluteFilePath)) {
- if (errorString)
- *errorString = tr("File name case mismatch for \"%2\"").arg(absoluteFilePath);
+ if (errors) {
+ QDeclarativeError error;
+ error.setDescription(tr("File name case mismatch for \"%1\"").arg(absoluteFilePath));
+ errors->prepend(error);
+ }
return false;
}
QPluginLoader loader(absoluteFilePath);
if (!loader.load()) {
- if (errorString)
- *errorString = loader.errorString();
+ if (errors) {
+ QDeclarativeError error;
+ error.setDescription(loader.errorString());
+ errors->prepend(error);
+ }
return false;
}
- if (QDeclarativeExtensionInterface *iface = qobject_cast<QDeclarativeExtensionInterface *>(loader.instance())) {
+ QObject *instance = loader.instance();
+ if (QDeclarativeTypesExtensionInterface *iface = qobject_cast<QDeclarativeExtensionInterface *>(instance)) {
const QByteArray bytes = uri.toUtf8();
const char *moduleId = bytes.constData();
if (!typesRegistered) {
- // ### this code should probably be protected with a mutex.
+ // XXX thread this code should probably be protected with a mutex.
qmlEnginePluginsWithRegisteredTypes()->insert(absoluteFilePath, uri);
iface->registerTypes(moduleId);
}
if (!engineInitialized) {
- // things on the engine (eg. adding new global objects) have to be done for every engine.
-
- // protect against double initialization
+ // things on the engine (eg. adding new global objects) have to be done for every
+ // engine.
+ // XXX protect against double initialization
initializedPlugins.insert(absoluteFilePath);
- iface->initializeEngine(engine, moduleId);
+
+ QDeclarativeExtensionInterface *eiface =
+ qobject_cast<QDeclarativeExtensionInterface *>(instance);
+ if (eiface) {
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
+ ep->typeLoader.initializeEngine(eiface, moduleId);
+ }
}
} else {
- if (errorString)
- *errorString = loader.errorString();
+ if (errors) {
+ QDeclarativeError error;
+ error.setDescription(loader.errorString());
+ errors->prepend(error);
+ }
return false;
}
}
#endif
}
-
QT_END_NAMESPACE