aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlmetatype.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/qml/qqmlmetatype.cpp')
-rw-r--r--src/qml/qml/qqmlmetatype.cpp87
1 files changed, 77 insertions, 10 deletions
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index f9583e7a59..342d1dc69c 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -63,6 +63,7 @@
#include <qvector.h>
#include <ctype.h>
+#include "qqmlcomponent.h"
QT_BEGIN_NAMESPACE
@@ -77,6 +78,10 @@ struct QQmlMetaTypeData
Names nameToType;
typedef QHash<QUrl, QQmlType *> Files; //For file imported composite types only
Files urlToType;
+ Files urlToNonFileImportType; // For non-file imported composite and composite
+ // singleton types. This way we can locate any
+ // of them by url, even if it was registered as
+ // a module via qmlRegisterCompositeType.
typedef QHash<const QMetaObject *, QQmlType *> MetaObjects;
MetaObjects metaObjectToType;
typedef QHash<int, QQmlMetaType::StringConverter> StringConverters;
@@ -225,6 +230,10 @@ void QQmlType::SingletonInstanceInfo::init(QQmlEngine *e)
setScriptApi(e, scriptCallback(e, e));
} else if (qobjectCallback && !qobjectApi(e)) {
setQObjectApi(e, qobjectCallback(e, e));
+ } else if (!url.isEmpty() && !qobjectApi(e)) {
+ QQmlComponent component(e, url, QQmlComponent::PreferSynchronous);
+ QObject *o = component.create();
+ setQObjectApi(e, o);
}
v4->popContext();
}
@@ -279,6 +288,7 @@ QQmlTypePrivate::QQmlTypePrivate(QQmlType::RegistrationType type)
extraData.cd->propertyValueInterceptorCast = -1;
break;
case QQmlType::SingletonType:
+ case QQmlType::CompositeSingletonType:
extraData.sd = new QQmlSingletonTypeData;
extraData.sd->singletonInstanceInfo = 0;
break;
@@ -300,6 +310,7 @@ QQmlTypePrivate::~QQmlTypePrivate()
delete extraData.cd;
break;
case QQmlType::SingletonType:
+ case QQmlType::CompositeSingletonType:
delete extraData.sd->singletonInstanceInfo;
delete extraData.sd;
break;
@@ -351,6 +362,22 @@ QQmlType::QQmlType(int index, const QString &elementName, const QQmlPrivate::Reg
= (type.qobjectApi && type.version >= 1) ? type.instanceMetaObject : 0;
}
+QQmlType::QQmlType(int index, const QString &elementName, const QQmlPrivate::RegisterCompositeSingletonType &type)
+ : d(new QQmlTypePrivate(CompositeSingletonType))
+{
+ d->elementName = elementName;
+ d->module = QString::fromUtf8(type.uri);
+
+ d->version_maj = type.versionMajor;
+ d->version_min = type.versionMinor;
+
+ d->index = index;
+
+ d->extraData.sd->singletonInstanceInfo = new SingletonInstanceInfo;
+ d->extraData.sd->singletonInstanceInfo->url = type.url;
+ d->extraData.sd->singletonInstanceInfo->typeName = QString::fromUtf8(type.typeName);
+}
+
QQmlType::QQmlType(int index, const QString &elementName, const QQmlPrivate::RegisterType &type)
: d(new QQmlTypePrivate(CppType))
{
@@ -650,7 +677,7 @@ void QQmlTypePrivate::insertEnums(const QMetaObject *metaObject) const
QByteArray QQmlType::typeName() const
{
- if (d->regType == SingletonType)
+ if (d->regType == SingletonType || d->regType == CompositeSingletonType)
return d->extraData.sd->singletonInstanceInfo->typeName.toUtf8();
else if (d->baseMetaObject)
return d->baseMetaObject->className();
@@ -710,7 +737,7 @@ void QQmlType::create(QObject **out, void **memory, size_t additionalMemory) con
QQmlType::SingletonInstanceInfo *QQmlType::singletonInstanceInfo() const
{
- if (d->regType != SingletonType)
+ if (d->regType != SingletonType && d->regType != CompositeSingletonType)
return 0;
return d->extraData.sd->singletonInstanceInfo;
}
@@ -757,7 +784,7 @@ bool QQmlType::isExtendedType() const
bool QQmlType::isSingleton() const
{
- return d->regType == SingletonType;
+ return d->regType == SingletonType || d->regType == CompositeSingletonType;
}
bool QQmlType::isInterface() const
@@ -767,7 +794,12 @@ bool QQmlType::isInterface() const
bool QQmlType::isComposite() const
{
- return d->regType == CompositeType;
+ return d->regType == CompositeType || d->regType == CompositeSingletonType;
+}
+
+bool QQmlType::isCompositeSingleton() const
+{
+ return d->regType == CompositeSingletonType;
}
int QQmlType::typeId() const
@@ -869,9 +901,12 @@ int QQmlType::index() const
QUrl QQmlType::sourceUrl() const
{
- if (d->regType != CompositeType)
+ if (d->regType == CompositeType)
+ return d->extraData.fd->url;
+ else if (d->regType == CompositeSingletonType)
+ return d->extraData.sd->singletonInstanceInfo->url;
+ else
return QUrl();
- return d->extraData.fd->url;
}
int QQmlType::enumValue(const QHashedStringRef &name, bool *ok) const
@@ -1006,7 +1041,6 @@ QList<QQmlType*> QQmlTypeModule::singletonTypes(int minor) const
return retn;
}
-
QQmlTypeModuleVersion::QQmlTypeModuleVersion()
: m_module(0), m_minor(0)
{
@@ -1070,6 +1104,7 @@ void qmlClearTypeRegistrations() // Declared in qqml.h
data->idToType.clear();
data->nameToType.clear();
data->urlToType.clear();
+ data->urlToNonFileImportType.clear();
data->metaObjectToType.clear();
data->uriToModule.clear();
@@ -1123,6 +1158,8 @@ QString registrationTypeString(QQmlType::RegistrationType typeType)
typeStr = QStringLiteral("element");
else if (typeType == QQmlType::SingletonType)
typeStr = QStringLiteral("singleton type");
+ else if (typeType == QQmlType::CompositeSingletonType)
+ typeStr = QStringLiteral("composite singleton type");
else
typeStr = QStringLiteral("type");
return typeStr;
@@ -1254,6 +1291,31 @@ int registerSingletonType(const QQmlPrivate::RegisterSingletonType &type)
return index;
}
+int registerCompositeSingletonType(const QQmlPrivate::RegisterCompositeSingletonType &type)
+{
+ // Assumes URL is absolute and valid. Checking of user input should happen before the URL enters type.
+ QWriteLocker lock(metaTypeDataLock());
+ QQmlMetaTypeData *data = metaTypeData();
+ QString typeName = QString::fromUtf8(type.typeName);
+ bool fileImport = false;
+ if (*(type.uri) == '\0')
+ fileImport = true;
+ if (!checkRegistration(QQmlType::CompositeSingletonType, data, fileImport ? 0 : type.uri, typeName))
+ return -1;
+
+ int index = data->types.count();
+
+ QQmlType *dtype = new QQmlType(index, typeName, type);
+
+ data->types.append(dtype);
+ addTypeToData(dtype, data);
+
+ QQmlMetaTypeData::Files *files = fileImport ? &(data->urlToType) : &(data->urlToNonFileImportType);
+ files->insertMulti(type.url, dtype);
+
+ return index;
+}
+
int registerCompositeType(const QQmlPrivate::RegisterCompositeType &type)
{
// Assumes URL is absolute and valid. Checking of user input should happen before the URL enters type.
@@ -1272,8 +1334,8 @@ int registerCompositeType(const QQmlPrivate::RegisterCompositeType &type)
data->types.append(dtype);
addTypeToData(dtype, data);
- if (fileImport)
- data->urlToType.insertMulti(type.url, dtype);
+ QQmlMetaTypeData::Files *files = fileImport ? &(data->urlToType) : &(data->urlToNonFileImportType);
+ files->insertMulti(type.url, dtype);
return index;
}
@@ -1295,6 +1357,8 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data)
return registerSingletonType(*reinterpret_cast<RegisterSingletonType *>(data));
} else if (type == CompositeRegistration) {
return registerCompositeType(*reinterpret_cast<RegisterCompositeType *>(data));
+ } else if (type == CompositeSingletonRegistration) {
+ return registerCompositeSingletonType(*reinterpret_cast<RegisterCompositeSingletonType *>(data));
}
return -1;
}
@@ -1708,12 +1772,15 @@ QQmlType *QQmlMetaType::qmlType(int userType)
Returns null if no such type is registered.
*/
-QQmlType *QQmlMetaType::qmlType(const QUrl &url)
+QQmlType *QQmlMetaType::qmlType(const QUrl &url, bool includeNonFileImports /* = false */)
{
QReadLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
QQmlType *type = data->urlToType.value(url);
+ if (!type && includeNonFileImports)
+ type = data->urlToNonFileImportType.value(url);
+
if (type && type->sourceUrl() == url)
return type;
else