From b4ec836efcb36313222e0d758f609439509cf5ba Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Thu, 2 Jul 2009 16:48:08 +1000 Subject: New module handling: allow "import" of built-in types. This will allow, for example, a different set of types to be imported for "import Qt 4.6" than for "import Qt 4.7". --- src/declarative/qml/qmlcompositetypemanager.cpp | 2 +- src/declarative/qml/qmlengine.cpp | 51 ++++++++++++++++++++++--- src/declarative/qml/qmlengine.h | 2 + src/declarative/qml/qmlmetatype.cpp | 4 +- 4 files changed, 51 insertions(+), 8 deletions(-) diff --git a/src/declarative/qml/qmlcompositetypemanager.cpp b/src/declarative/qml/qmlcompositetypemanager.cpp index 1a67bf4..1c29b97 100644 --- a/src/declarative/qml/qmlcompositetypemanager.cpp +++ b/src/declarative/qml/qmlcompositetypemanager.cpp @@ -314,7 +314,7 @@ void QmlCompositeTypeManager::compile(QmlCompositeTypeData *unit) continue; } - ref.type = QmlMetaType::qmlType(type); + ref.type = engine->resolveBuiltInType(unit->imports, type); if (ref.type) { unit->types << ref; continue; diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index dc33b38..fcbda95 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -1578,9 +1578,14 @@ class QmlImportsPrivate { public: void add(const QString& uri, const QString& prefix, int version_major, int version_minor) { - TypeSet *s = set.value(prefix); - if (!s) - set.insert(prefix,(s=new TypeSet)); + TypeSet *s; + if (prefix.isEmpty()) { + s = &unqualifiedset; + } else { + s = set.value(prefix); + if (!s) + set.insert(prefix,(s=new TypeSet)); + } QString url = uri; s->urls.append(url); s->vmaj.append(version_major); @@ -1601,13 +1606,13 @@ public: break; } } else { - s = set.value(""); + s = &unqualifiedset; } - QString unqtype = type.mid(dot+1); + QString unqualifiedtype = type.mid(dot+1); QUrl baseUrl(base); if (s) { for (int i=0; iurls.count(); ++i) { - QUrl url = baseUrl.resolved(QUrl(s->urls.at(i) +"/"+ unqtype + QLatin1String(".qml"))); + QUrl url = baseUrl.resolved(QUrl(s->urls.at(i) +QLatin1String("/")+ unqualifiedtype + QLatin1String(".qml"))); // XXX search non-files too! (eg. zip files, see QT-524) QFileInfo f(url.toLocalFile()); if (f.exists()) @@ -1617,12 +1622,40 @@ public: return baseUrl.resolved(QUrl(type + QLatin1String(".qml"))); } + QmlType *findBuiltin(const QString& base, const QByteArray& type) + { + // XXX import only have one space of imports! + TypeSet *s = 0; + int dot = type.indexOf('.'); + if (dot >= 0) { + while (!s) { + s = set.value(QString::fromLatin1(type.left(dot))); + int ndot = type.indexOf('.',dot+1); + if (ndot > 0) + dot = ndot; + else + break; + } + } else { + s = &unqualifiedset; + } + QByteArray unqualifiedtype = dot < 0 ? type : type.mid(dot+1); // common-case opt (QString::mid works fine, but slower) + if (s) { + for (int i=0; iurls.count(); ++i) { + QmlType *t = QmlMetaType::qmlType(s->urls.at(i).toLatin1()+"/"+unqualifiedtype); + if (t) return t; + } + } + return QmlMetaType::qmlType(type); + } + private: struct TypeSet { QStringList urls; QList vmaj; QList vmin; }; + TypeSet unqualifiedset; QHash set; }; @@ -1650,4 +1683,10 @@ QUrl QmlEngine::resolveType(const Imports& imports, const QString& type) const return imports.d->find(imports.base,type); } +QmlType* QmlEngine::resolveBuiltInType(const Imports& imports, const QByteArray& type) const +{ + return imports.d->findBuiltin(imports.base,type); +} + + QT_END_NAMESPACE diff --git a/src/declarative/qml/qmlengine.h b/src/declarative/qml/qmlengine.h index b74ad21..a07ea96 100644 --- a/src/declarative/qml/qmlengine.h +++ b/src/declarative/qml/qmlengine.h @@ -58,6 +58,7 @@ class QmlEnginePrivate; class QmlImportsPrivate; class QmlExpression; class QmlContext; +class QmlType; class QUrl; class QScriptEngine; class QScriptContext; @@ -88,6 +89,7 @@ public: }; void addImport(Imports*, const QString& uri, const QString& prefix, int version_major, int version_minor) const; QUrl resolveType(const Imports&, const QString& type) const; + QmlType* resolveBuiltInType(const Imports& imports, const QByteArray& type) const; void setNetworkAccessManager(QNetworkAccessManager *); QNetworkAccessManager *networkAccessManager() const; diff --git a/src/declarative/qml/qmlmetatype.cpp b/src/declarative/qml/qmlmetatype.cpp index b15f711..e6c7376 100644 --- a/src/declarative/qml/qmlmetatype.cpp +++ b/src/declarative/qml/qmlmetatype.cpp @@ -423,8 +423,10 @@ int QmlMetaType::registerType(const QmlPrivate::MetaTypeIds &id, QmlPrivate::Fun QmlMetaTypeData *data = metaTypeData(); QString name = QLatin1String(cname); + for (int ii = 0; ii < name.count(); ++ii) { - if (!name.at(ii).isLetterOrNumber()) { + QChar ch = name.at(ii); + if (!ch.isLetterOrNumber() && ch != QChar::fromLatin1('/')) { qWarning("QmlMetaType: Invalid QML name %s", cname); return -1; } -- cgit v0.12