X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fdeclarative%2Fqml%2Fqdeclarativeimport.cpp;h=8bdcef94779011aceede06f0eeccdb285d619b83;hb=45b14259fc0cf704692df1c00da511527d1fba1d;hp=539f1b8584b2fc4c96706e1972dd98e2f4835ddf;hpb=a63cc12645b173be7b2442edb8c40e958563833b;p=profile%2Fivi%2Fqtdeclarative.git diff --git a/src/declarative/qml/qdeclarativeimport.cpp b/src/declarative/qml/qdeclarativeimport.cpp index 539f1b8..8bdcef9 100644 --- a/src/declarative/qml/qdeclarativeimport.cpp +++ b/src/declarative/qml/qdeclarativeimport.cpp @@ -1,8 +1,7 @@ /**************************************************************************** ** -** 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. ** @@ -35,6 +34,7 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -51,10 +51,6 @@ #include #include -#ifdef Q_OS_SYMBIAN -#include "private/qcore_symbian_p.h" -#endif - QT_BEGIN_NAMESPACE DEFINE_BOOL_CONFIG_OPTION(qmlImportTrace, QML_IMPORT_TRACE) @@ -98,6 +94,7 @@ public: int minversion; bool isLibrary; QDeclarativeDirComponents qmlDirComponents; + QDeclarativeDirScripts qmlDirScripts; }; QList imports; @@ -116,12 +113,13 @@ public: bool importExtension(const QString &absoluteFilePath, const QString &uri, QDeclarativeImportDatabase *database, QDeclarativeDirComponents* components, + QDeclarativeDirScripts *scripts, QList *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 *errors); bool find(const QString& type, int *vmajor, int *vminor, QDeclarativeType** type_return, QString* url_return, QList *errors); @@ -203,29 +201,60 @@ void QDeclarativeImports::populateCache(QDeclarativeTypeNameCache *cache, QDecla ++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::resolvedScripts() const +{ + QList 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::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; } /*! @@ -363,9 +392,11 @@ QDeclarativeImportsPrivate::~QDeclarativeImportsPrivate() delete s; } -bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath, const QString &uri, - QDeclarativeImportDatabase *database, - QDeclarativeDirComponents* components, QList *errors) +bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath, const QString &uri, + QDeclarativeImportDatabase *database, + QDeclarativeDirComponents* components, + QDeclarativeDirScripts* scripts, + QList *errors) { const QDeclarativeDirParser *qmldirParser = typeLoader->qmlDirParser(absoluteFilePath); if (qmldirParser->hasError()) { @@ -391,13 +422,6 @@ bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath 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) { @@ -426,6 +450,8 @@ bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath if (components) *components = qmldirParser->components(); + if (scripts) + *scripts = qmldirParser->scripts(); return true; } @@ -463,13 +489,14 @@ QString QDeclarativeImportsPrivate::resolvedUri(const QString &dir_arg, QDeclara 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 *errors) { static QLatin1String Slash_qmldir("/qmldir"); static QLatin1Char Slash('/'); QDeclarativeDirComponents qmldircomponents = qmldircomponentsnetwork; + QDeclarativeDirScripts qmldirscripts; QString uri = uri_arg; QDeclarativeImportedNamespace *s; if (prefix.isEmpty()) { @@ -481,7 +508,7 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp } 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 @@ -500,14 +527,20 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp 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; @@ -518,9 +551,13 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp 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; } @@ -537,9 +574,12 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp 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; } @@ -549,7 +589,7 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp 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)) @@ -561,7 +601,7 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp 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()) { @@ -579,7 +619,7 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp 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 { @@ -605,16 +645,18 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp url = resolveLocalUrl(base, url); } - if (!versionFound && vmaj > -1 && vmin > -1 && !qmldircomponents.isEmpty()) { - QList::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::const_iterator cend = qmldircomponents.constEnd(); + for (QList::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. @@ -628,13 +670,44 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp if (!url.endsWith(Slash)) url += Slash; + QMap scripts; + + if (!qmldirscripts.isEmpty()) { + // Verify that we haven't imported these scripts already + QList::const_iterator end = s->imports.constEnd(); + for (QList::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::const_iterator send = qmldirscripts.constEnd(); + for (QList::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::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; @@ -760,38 +833,13 @@ QDeclarativeImportDatabase::QDeclarativeImportDatabase(QDeclarativeEngine *e) #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 (tempPath.constData())); - TFindFile finder(fs); - TInt err = finder.FindByDir(tempPathPtr, tempPathPtr); - while (err == KErrNone) { - QString foundDir(reinterpret_cast(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(':'); @@ -824,14 +872,14 @@ QDeclarativeImportDatabase::~QDeclarativeImportDatabase() */ 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 *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); @@ -908,7 +956,6 @@ QString QDeclarativeImportDatabase::resolvePlugin(QDeclarativeTypeLoader *typeLo \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. @@ -924,11 +971,6 @@ QString QDeclarativeImportDatabase::resolvePlugin(QDeclarativeTypeLoader *typeLo << 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) @@ -1076,7 +1118,7 @@ bool QDeclarativeImportDatabase::importPlugin(const QString &filePath, const QSt 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; @@ -1092,22 +1134,29 @@ bool QDeclarativeImportDatabase::importPlugin(const QString &filePath, const QSt return false; } - if (QDeclarativeExtensionInterface *iface = qobject_cast(loader.instance())) { + QObject *instance = loader.instance(); + if (QDeclarativeTypesExtensionInterface *iface = qobject_cast(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(instance); + if (eiface) { + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); + ep->typeLoader.initializeEngine(eiface, moduleId); + } } } else { if (errors) {