aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlimport.cpp
diff options
context:
space:
mode:
authorAlan Alpert <416365416c@gmail.com>2012-12-16 21:24:14 -0800
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-02-18 12:54:15 +0100
commit4d3a64c5e65a781acb4acf4ba641456da28bd1e4 (patch)
tree10d1374401131a7d22146cdf7029307aea9efe7b /src/qml/qml/qqmlimport.cpp
parent58471eb3f267dbee728b1c13f87458f2ee509bfa (diff)
Add Composite Types to QQmlType
When a composite type is loaded from a QML file, it now generates a QQmlType entry in QQmlMetaTypeData. Change-Id: I9b127dff7955456aacb25138fa6ea8efb7bb9221 Reviewed-by: Christopher Adams <chris.adams@jollamobile.com> Reviewed-by: Alan Alpert <aalpert@rim.com>
Diffstat (limited to 'src/qml/qml/qqmlimport.cpp')
-rw-r--r--src/qml/qml/qqmlimport.cpp107
1 files changed, 65 insertions, 42 deletions
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index 52d07b23ec..95b59f93f4 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -124,6 +124,39 @@ bool isPathAbsolute(const QString &path)
#endif
}
+// If the type does not already exist as a file import, add the type and return the new type
+QQmlType *getTypeForUrl(const QString &urlString, const QHashedStringRef& typeName, QList<QQmlError> *errors)
+{
+ QUrl url(urlString);
+ QQmlType *ret = QQmlMetaType::qmlType(url);
+ if (!ret) { //QQmlType not yet existing for composite type
+ int dot = typeName.indexOf(QLatin1Char('.'));
+ QHashedStringRef unqualifiedtype = dot < 0 ? typeName : QHashedStringRef(typeName.constData() + dot + 1, typeName.length() - dot - 1);
+
+ //XXX: The constData of the string ref is pointing somewhere unsafe in qmlregister, so we need to create a temporary copy
+ QByteArray buf(unqualifiedtype.toUtf8().constData());
+
+ QQmlPrivate::RegisterCompositeType reg = {
+ url,
+ "", //Empty URI indicates loaded via file imports
+ -1,
+ -1,
+ buf.constData()
+ };
+ ret = QQmlMetaType::qmlTypeFromIndex(QQmlPrivate::qmlregister(QQmlPrivate::CompositeRegistration, &reg));
+ }
+ if (!ret) {//Usually when a type name is "found" but invalid
+ //qDebug() << ret << urlString << QQmlMetaType::qmlType(url);
+ if (!errors) // Cannot list errors properly, just quit
+ qFatal(QQmlMetaType::typeRegistrationFailures().join('\n').toLatin1().constData());
+ QQmlError error;
+ error.setDescription(QQmlMetaType::typeRegistrationFailures().join('\n'));
+ errors->prepend(error);
+ }
+ return ret;
+
+}
+
}
typedef QMap<QString, QString> StringStringMap;
@@ -150,8 +183,7 @@ public:
static QQmlDirScripts getVersionedScripts(const QQmlDirScripts &qmldirscripts, int vmaj, int vmin);
bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef &type,
- int *vmajor, int *vminor,
- QQmlType** type_return, QString* url_return,
+ int *vmajor, int *vminor, QQmlType** type_return,
QString *base = 0, bool *typeRecursionDetected = 0) const;
};
QList<Import *> imports;
@@ -159,8 +191,7 @@ public:
Import *findImport(const QString &uri);
bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef& type,
- int *vmajor, int *vminor,
- QQmlType** type_return, QString* url_return,
+ int *vmajor, int *vminor, QQmlType** type_return,
QString *base = 0, QList<QQmlError> *errors = 0);
// Prefix when used as a qualified import. Otherwise empty.
@@ -194,8 +225,7 @@ public:
QList<QQmlError> *errors);
bool resolveType(const QHashedStringRef &type, int *vmajor, int *vminor,
- QQmlType** type_return, QString* url_return,
- QList<QQmlError> *errors);
+ QQmlType** type_return, QList<QQmlError> *errors);
QUrl baseUrl;
QString base;
@@ -379,9 +409,8 @@ QString QQmlImports::completeQmldirPath(const QString &uri, const QString &base,
The given (namespace qualified) \a type is resolved to either
\list
- \li a QQmlImportNamespace stored at \a ns_return,
- \li a QQmlType stored at \a type_return, or
- \li a component located at \a url_return.
+ \li a QQmlImportNamespace stored at \a ns_return, or
+ \li a QQmlType stored at \a type_return,
\endlist
If any return pointer is 0, the corresponding search is not done.
@@ -389,7 +418,7 @@ QString QQmlImports::completeQmldirPath(const QString &uri, const QString &base,
\sa addFileImport(), addLibraryImport
*/
bool QQmlImports::resolveType(const QHashedStringRef &type,
- QQmlType** type_return, QString* url_return, int *vmaj, int *vmin,
+ QQmlType** type_return, int *vmaj, int *vmin,
QQmlImportNamespace** ns_return, QList<QQmlError> *errors) const
{
QQmlImportNamespace* ns = d->findQualifiedNamespace(type);
@@ -398,19 +427,16 @@ bool QQmlImports::resolveType(const QHashedStringRef &type,
*ns_return = ns;
return true;
}
- if (type_return || url_return) {
- if (d->resolveType(type,vmaj,vmin,type_return,url_return, errors)) {
+ if (type_return) {
+ if (d->resolveType(type,vmaj,vmin,type_return, errors)) {
if (qmlImportTrace()) {
#define RESOLVE_TYPE_DEBUG qDebug().nospace() << "QQmlImports(" << qPrintable(baseUrl().toString()) \
<< ')' << "::resolveType: " << type.toString() << " => "
- if (type_return && *type_return && url_return && !url_return->isEmpty())
- RESOLVE_TYPE_DEBUG << (*type_return)->typeName() << ' ' << *url_return << " TYPE/URL";
- if (type_return && *type_return)
+ if (type_return && *type_return && (*type_return)->isComposite())
+ RESOLVE_TYPE_DEBUG << (*type_return)->typeName() << ' ' << (*type_return)->sourceUrl() << " TYPE/URL";
+ else if (type_return && *type_return)
RESOLVE_TYPE_DEBUG << (*type_return)->typeName() << " TYPE";
- if (url_return && !url_return->isEmpty())
- RESOLVE_TYPE_DEBUG << *url_return << " URL";
-
#undef RESOLVE_TYPE_DEBUG
}
return true;
@@ -469,23 +495,21 @@ QQmlDirScripts QQmlImportNamespace::Import::getVersionedScripts(const QQmlDirScr
\internal
Searching \e only in the namespace \a ns (previously returned in a call to
- resolveType(), \a type is found and returned to either
- a QQmlType stored at \a type_return, or
- a component located at \a url_return.
+ resolveType(), \a type is found and returned to
+ a QQmlType stored at \a type_return. If the type is from a QML file, the returned
+ type will be a CompositeType.
- If either return pointer is 0, the corresponding search is not done.
+ If the return pointer is 0, the corresponding search is not done.
*/
bool QQmlImports::resolveType(QQmlImportNamespace* ns, const QHashedStringRef &type,
- QQmlType** type_return, QString* url_return,
- int *vmaj, int *vmin) const
+ QQmlType** type_return, int *vmaj, int *vmin) const
{
- return ns->resolveType(d->typeLoader,type,vmaj,vmin,type_return,url_return);
+ return ns->resolveType(d->typeLoader,type,vmaj,vmin,type_return);
}
bool QQmlImportNamespace::Import::resolveType(QQmlTypeLoader *typeLoader,
const QHashedStringRef& type, int *vmajor, int *vminor,
- QQmlType** type_return, QString* url_return,
- QString *base, bool *typeRecursionDetected) const
+ QQmlType** type_return, QString *base, bool *typeRecursionDetected) const
{
if (majversion >= 0 && minversion >= 0) {
QQmlType *t = QQmlMetaType::qmlType(type, uri, majversion, minversion);
@@ -530,9 +554,9 @@ bool QQmlImportNamespace::Import::resolveType(QQmlTypeLoader *typeLoader,
}
if (candidate != end) {
- if (url_return)
- *url_return = componentUrl;
- return true;
+ if (type_return)
+ *type_return = getTypeForUrl(componentUrl, type, 0);
+ return (*type_return != 0);
}
} else if (!isLibrary) {
QString qmlUrl = url + QString::fromRawData(type.constData(), type.length()) + dotqml_string;
@@ -550,9 +574,9 @@ bool QQmlImportNamespace::Import::resolveType(QQmlTypeLoader *typeLoader,
if (typeRecursionDetected)
*typeRecursionDetected = true;
} else {
- if (url_return)
- *url_return = qmlUrl;
- return true;
+ if (type_return)
+ *type_return = getTypeForUrl(qmlUrl, type, 0);
+ return (*type_return) != 0;
}
}
}
@@ -561,8 +585,7 @@ bool QQmlImportNamespace::Import::resolveType(QQmlTypeLoader *typeLoader,
}
bool QQmlImportsPrivate::resolveType(const QHashedStringRef& type, int *vmajor, int *vminor,
- QQmlType** type_return, QString* url_return,
- QList<QQmlError> *errors)
+ QQmlType** type_return, QList<QQmlError> *errors)
{
QQmlImportNamespace *s = 0;
int dot = type.indexOf(Dot);
@@ -591,12 +614,12 @@ bool QQmlImportsPrivate::resolveType(const QHashedStringRef& type, int *vmajor,
}
QHashedStringRef unqualifiedtype = dot < 0 ? type : QHashedStringRef(type.constData()+dot+1, type.length()-dot-1);
if (s) {
- if (s->resolveType(typeLoader,unqualifiedtype,vmajor,vminor,type_return,url_return, &base, errors))
+ if (s->resolveType(typeLoader,unqualifiedtype,vmajor,vminor,type_return, &base, errors))
return true;
- if (s->imports.count() == 1 && !s->imports.at(0)->isLibrary && url_return && s != &unqualifiedset) {
+ if (s->imports.count() == 1 && !s->imports.at(0)->isLibrary && type_return && s != &unqualifiedset) {
// qualified, and only 1 url
- *url_return = resolveLocalUrl(s->imports.at(0)->url, unqualifiedtype.toString() + QLatin1String(".qml"));
- return true;
+ *type_return = getTypeForUrl(resolveLocalUrl(s->imports.at(0)->url, unqualifiedtype.toString() + QLatin1String(".qml")), type, errors);
+ return (*type_return != 0);
}
}
@@ -615,18 +638,18 @@ QQmlImportNamespace::Import *QQmlImportNamespace::findImport(const QString &uri)
bool QQmlImportNamespace::resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef &type,
int *vmajor, int *vminor, QQmlType** type_return,
- QString* url_return, QString *base, QList<QQmlError> *errors)
+ QString *base, QList<QQmlError> *errors)
{
bool typeRecursionDetected = false;
for (int i=0; i<imports.count(); ++i) {
const Import *import = imports.at(i);
- if (import->resolveType(typeLoader, type, vmajor, vminor, type_return, url_return,
+ if (import->resolveType(typeLoader, type, vmajor, vminor, type_return,
base, &typeRecursionDetected)) {
if (qmlCheckTypes()) {
// check for type clashes
for (int j = i+1; j<imports.count(); ++j) {
const Import *import2 = imports.at(j);
- if (import2->resolveType(typeLoader, type, vmajor, vminor, 0, 0, base)) {
+ if (import2->resolveType(typeLoader, type, vmajor, vminor, 0, base)) {
if (errors) {
QString u1 = import->url;
QString u2 = import2->url;