/****************************************************************************
**
-** 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)
int minversion;
bool isLibrary;
QDeclarativeDirComponents qmlDirComponents;
+ QDeclarativeDirScripts qmlDirScripts;
};
QList<Data> imports;
bool importExtension(const QString &absoluteFilePath, const QString &uri,
QDeclarativeImportDatabase *database, QDeclarativeDirComponents* components,
+ 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,
+ 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);
++iter) {
const QDeclarativeImportedNamespace &set = *iter.value();
- QDeclarativeTypeNameCache::Import &import = cache->m_namedImports[iter.key()];
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)
+ if (module) {
+ QDeclarativeTypeNameCache::Import &import = cache->m_namedImports[iter.key()];
import.modules.append(QDeclarativeTypeModuleVersion(module, data.minversion));
+ }
- QDeclarativeMetaType::ModuleApi moduleApi = QDeclarativeMetaType::moduleApi(data.uri.toUtf8(), data.majversion, data.minversion);
+ 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);
- QDeclarativeMetaType::ModuleApiInstance *a = ep->moduleApiInstances.value(moduleApi);
- if (!a) {
- a = new QDeclarativeMetaType::ModuleApiInstance;
- a->scriptCallback = moduleApi.script;
- a->qobjectCallback = moduleApi.qobject;
- ep->moduleApiInstances.insert(moduleApi, a);
- }
- import.moduleApi = a;
+ import.moduleApi = ep->moduleApiInstance(moduleApi);
}
}
}
+}
+
+QList<QDeclarativeImports::ScriptReference> QDeclarativeImports::resolvedScripts() const
+{
+ QList<QDeclarativeImports::ScriptReference> scripts;
+
+ const QDeclarativeImportedNamespace &set = d->unqualifiedset;
+
+ 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.location = QUrl(data.url).resolved(QUrl(script.fileName));
+ scripts.append(ref);
+ }
+ }
+
+ 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;
}
/*!
delete s;
}
-bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath, const QString &uri,
- QDeclarativeImportDatabase *database,
- QDeclarativeDirComponents* components, QList<QDeclarativeError> *errors)
+bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath, const QString &uri,
+ QDeclarativeImportDatabase *database,
+ QDeclarativeDirComponents* components,
+ QDeclarativeDirScripts* scripts,
+ QList<QDeclarativeError> *errors)
{
const QDeclarativeDirParser *qmldirParser = typeLoader->qmlDirParser(absoluteFilePath);
if (qmldirParser->hasError()) {
foreach (const QDeclarativeDirParser::Plugin &plugin, qmldirParser->plugins()) {
QString resolvedFilePath = database->resolvePlugin(typeLoader, qmldirPath, 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
if (!resolvedFilePath.isEmpty()) {
if (!database->importPlugin(resolvedFilePath, uri, errors)) {
if (errors) {
if (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,
+ 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()) {
}
QString url = uri;
bool versionFound = false;
- if (importType == QDeclarativeScriptParser::Import::Library) {
+ if (importType == QDeclarativeScript::Import::Library) {
Q_ASSERT(vmaj >= 0 && vmin >= 0); // Versions are always specified for libraries
if (fi.isFile()) {
found = true;
- url = QUrl::fromLocalFile(fi.absolutePath()).toString();
+ 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, errors))
+ 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
foreach (const QString &p, database->fileImportPath) {
dir = p+Slash+url;
if (fi.isFile()) {
found = true;
- url = QUrl::fromLocalFile(fi.absolutePath()).toString();
+ 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, errors))
+ if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, &qmldirscripts, errors))
return false;
break;
}
if (!absoluteFilePath.isEmpty()) {
found = true;
QString absolutePath = absoluteFilePath.left(absoluteFilePath.lastIndexOf(Slash)+1);
- url = QLatin1String("file://") + absolutePath;
+ 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, errors))
+ if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, &qmldirscripts, errors))
return false;
break;
}
if (QDeclarativeMetaType::isModule(uri, vmaj, vmin))
versionFound = true;
- if (!versionFound && qmldircomponents.isEmpty()) {
+ 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))
return false;
}
} else {
- if (importType == QDeclarativeScriptParser::Import::File && qmldircomponents.isEmpty()) {
+ if (importType == QDeclarativeScript::Import::File && qmldircomponents.isEmpty()) {
QString importUrl = resolveLocalUrl(base, uri + Slash_qmldir);
QString localFileOrQrc = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(importUrl);
if (!localFileOrQrc.isEmpty()) {
if (uri.endsWith(Slash))
uri.chop(1);
if (!typeLoader->absoluteFilePath(localFileOrQrc).isEmpty()) {
- if (!importExtension(localFileOrQrc,uri,database,&qmldircomponents,errors))
+ if (!importExtension(localFileOrQrc,uri,database,&qmldircomponents,&qmldirscripts,errors))
return false;
}
} else {
url = resolveLocalUrl(base, url);
}
- if (!versionFound && vmaj > -1 && vmin > -1 && !qmldircomponents.isEmpty()) {
- QList<QDeclarativeDirParser::Component>::ConstIterator it = qmldircomponents.begin();
+ if (!versionFound && (vmaj > -1) && (vmin > -1) && !qmldircomponents.isEmpty()) {
int lowest_min = INT_MAX;
int highest_min = INT_MIN;
- for (; it != qmldircomponents.end(); ++it) {
- if (it->majorVersion == vmaj) {
- lowest_min = qMin(lowest_min, it->minorVersion);
- highest_min = qMax(highest_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_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.
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 == QDeclarativeScriptParser::Import::Library;
+ data.isLibrary = importType == QDeclarativeScript::Import::Library;
data.qmlDirComponents = qmldircomponents;
+ data.qmlDirScripts = scripts.values();
+
s->imports.prepend(data);
return true;
#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,
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, errors);
\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.
<< QLatin1String("d.dll") // try a qmake-style debug build first
# endif
<< QLatin1String(".dll"));
-#elif defined(Q_OS_SYMBIAN)
- return resolvePlugin(typeLoader, qmldirPath, qmldirPluginPath, baseName,
- QStringList()
- << QLatin1String(".dll")
- << QLatin1String(".qtplugin"));
#else
# if defined(Q_OS_DARWIN)
if (!QDeclarative_isFileCaseCorrect(absoluteFilePath)) {
if (errors) {
QDeclarativeError error;
- error.setDescription(tr("File name case mismatch for \"%2\"").arg(absoluteFilePath));
+ error.setDescription(tr("File name case mismatch for \"%1\"").arg(absoluteFilePath));
errors->prepend(error);
}
return false;
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 (errors) {