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.cpp153
1 files changed, 119 insertions, 34 deletions
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index cb8c2bd3b5..1a27a487bd 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -38,6 +38,7 @@
#include <private/qqmlcustomparser_p.h>
#include <private/qhashedstring_p.h>
#include <private/qqmlimport_p.h>
+#include <private/qqmlcompiler_p.h>
#include <QtCore/qdebug.h>
#include <QtCore/qstringlist.h>
@@ -217,12 +218,10 @@ public:
void QQmlType::SingletonInstanceInfo::init(QQmlEngine *e)
{
QV4::ExecutionEngine *v4 = QV8Engine::getV4(e->handle());
+ v4->pushGlobalContext();
if (scriptCallback && scriptApi(e).isUndefined()) {
- v4->pushGlobalContext();
setScriptApi(e, scriptCallback(e, e));
- v4->popContext();
} else if (qobjectCallback && !qobjectApi(e)) {
- v4->pushGlobalContext();
QObject *o = qobjectCallback(e, e);
setQObjectApi(e, o);
if (!o) {
@@ -230,14 +229,12 @@ void QQmlType::SingletonInstanceInfo::init(QQmlEngine *e)
}
// if this object can use a property cache, create it now
QQmlData::ensurePropertyCache(e, o);
- v4->popContext();
} else if (!url.isEmpty() && !qobjectApi(e)) {
- v4->pushGlobalContext();
QQmlComponent component(e, url, QQmlComponent::PreferSynchronous);
QObject *o = component.create();
setQObjectApi(e, o);
- v4->popContext();
}
+ v4->popContext();
}
void QQmlType::SingletonInstanceInfo::destroy(QQmlEngine *e)
@@ -245,7 +242,12 @@ void QQmlType::SingletonInstanceInfo::destroy(QQmlEngine *e)
// cleans up the engine-specific singleton instances if they exist.
scriptApis.remove(e);
QObject *o = qobjectApis.take(e);
- delete o;
+ if (o) {
+ QQmlData *ddata = QQmlData::get(o, false);
+ if (ddata && ddata->indestructible)
+ return;
+ delete o;
+ }
}
void QQmlType::SingletonInstanceInfo::setQObjectApi(QQmlEngine *e, QObject *o)
@@ -258,7 +260,7 @@ QObject *QQmlType::SingletonInstanceInfo::qobjectApi(QQmlEngine *e) const
return qobjectApis.value(e);
}
-void QQmlType::SingletonInstanceInfo::setScriptApi(QQmlEngine *e, QJSValue v)
+void QQmlType::SingletonInstanceInfo::setScriptApi(QQmlEngine *e, const QJSValue &v)
{
scriptApis.insert(e, v);
}
@@ -477,6 +479,29 @@ QQmlType *QQmlType::superType() const
return d->superType;
}
+QQmlType *QQmlType::resolveCompositeBaseType(QQmlEnginePrivate *engine) const
+{
+ Q_ASSERT(isComposite());
+ if (!engine)
+ return 0;
+ QQmlTypeData *td = engine->typeLoader.getType(sourceUrl());
+ if (!td || !td->isComplete())
+ return 0;
+ QQmlCompiledData *cd = td->compiledData();
+ const QMetaObject *mo = cd->rootPropertyCache->firstCppMetaObject();
+ return QQmlMetaType::qmlType(mo);
+}
+
+int QQmlType::resolveCompositeEnumValue(QQmlEnginePrivate *engine, const QString &name, bool *ok) const
+{
+ Q_ASSERT(isComposite());
+ *ok = false;
+ QQmlType *type = resolveCompositeBaseType(engine);
+ if (!type)
+ return -1;
+ return type->enumValue(engine, name, ok);
+}
+
static void clone(QMetaObjectBuilder &builder, const QMetaObject *mo,
const QMetaObject *ignoreStart, const QMetaObject *ignoreEnd)
{
@@ -842,18 +867,26 @@ int QQmlType::metaObjectRevision() const
return d->revision;
}
-QQmlAttachedPropertiesFunc QQmlType::attachedPropertiesFunction() const
+QQmlAttachedPropertiesFunc QQmlType::attachedPropertiesFunction(QQmlEnginePrivate *engine) const
{
- if (d->regType != CppType)
- return 0;
- return d->extraData.cd->attachedPropertiesFunc;
+ if (d->regType == CppType)
+ return d->extraData.cd->attachedPropertiesFunc;
+
+ QQmlType *base = 0;
+ if (d->regType == CompositeType)
+ base = resolveCompositeBaseType(engine);
+ return base ? base->attachedPropertiesFunction(engine) : 0;
}
-const QMetaObject *QQmlType::attachedPropertiesType() const
+const QMetaObject *QQmlType::attachedPropertiesType(QQmlEnginePrivate *engine) const
{
- if (d->regType != CppType)
- return 0;
- return d->extraData.cd->attachedPropertiesType;
+ if (d->regType == CppType)
+ return d->extraData.cd->attachedPropertiesType;
+
+ QQmlType *base = 0;
+ if (d->regType == CompositeType)
+ base = resolveCompositeBaseType(engine);
+ return base ? base->attachedPropertiesType(engine) : 0;
}
/*
@@ -861,11 +894,15 @@ This is the id passed to qmlAttachedPropertiesById(). This is different from th
for the case that a single class is registered under two or more names (eg. Item in
Qt 4.7 and QtQuick 1.0).
*/
-int QQmlType::attachedPropertiesId() const
+int QQmlType::attachedPropertiesId(QQmlEnginePrivate *engine) const
{
- if (d->regType != CppType)
- return 0;
- return d->extraData.cd->attachedPropertiesId;
+ if (d->regType == CppType)
+ return d->extraData.cd->attachedPropertiesId;
+
+ QQmlType *base = 0;
+ if (d->regType == CompositeType)
+ base = resolveCompositeBaseType(engine);
+ return base ? base->attachedPropertiesId(engine) : 0;
}
int QQmlType::parserStatusCast() const
@@ -911,9 +948,11 @@ QUrl QQmlType::sourceUrl() const
return QUrl();
}
-int QQmlType::enumValue(const QHashedStringRef &name, bool *ok) const
+int QQmlType::enumValue(QQmlEnginePrivate *engine, const QHashedStringRef &name, bool *ok) const
{
Q_ASSERT(ok);
+ if (isComposite())
+ return resolveCompositeEnumValue(engine, name.toString(), ok);
*ok = true;
d->initEnums();
@@ -926,9 +965,11 @@ int QQmlType::enumValue(const QHashedStringRef &name, bool *ok) const
return -1;
}
-int QQmlType::enumValue(const QHashedCStringRef &name, bool *ok) const
+int QQmlType::enumValue(QQmlEnginePrivate *engine, const QHashedCStringRef &name, bool *ok) const
{
Q_ASSERT(ok);
+ if (isComposite())
+ return resolveCompositeEnumValue(engine, name.toUtf16(), ok);
*ok = true;
d->initEnums();
@@ -941,9 +982,11 @@ int QQmlType::enumValue(const QHashedCStringRef &name, bool *ok) const
return -1;
}
-int QQmlType::enumValue(const QV4::String *name, bool *ok) const
+int QQmlType::enumValue(QQmlEnginePrivate *engine, const QV4::String *name, bool *ok) const
{
Q_ASSERT(ok);
+ if (isComposite())
+ return resolveCompositeEnumValue(engine, name->toQString(), ok);
*ok = true;
d->initEnums();
@@ -1110,7 +1153,9 @@ void qmlClearTypeRegistrations() // Declared in qqml.h
data->uriToModule.clear();
QQmlEnginePrivate::baseModulesUninitialized = true; //So the engine re-registers its types
+#ifndef QT_NO_LIBRARY
qmlClearEnginePlugins();
+#endif
}
int registerAutoParentFunction(QQmlPrivate::RegisterAutoParent &autoparent)
@@ -1440,8 +1485,8 @@ bool QQmlMetaType::isAnyModule(const QString &uri)
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
- for (QQmlMetaTypeData::TypeModules::ConstIterator iter = data->uriToModule.begin();
- iter != data->uriToModule.end(); ++iter) {
+ for (QQmlMetaTypeData::TypeModules::ConstIterator iter = data->uriToModule.cbegin();
+ iter != data->uriToModule.cend(); ++iter) {
if ((*iter)->module() == uri)
return true;
}
@@ -1538,25 +1583,25 @@ int QQmlMetaType::listType(int id)
return 0;
}
-int QQmlMetaType::attachedPropertiesFuncId(const QMetaObject *mo)
+int QQmlMetaType::attachedPropertiesFuncId(QQmlEnginePrivate *engine, const QMetaObject *mo)
{
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
QQmlType *type = data->metaObjectToType.value(mo);
- if (type && type->attachedPropertiesFunction())
- return type->attachedPropertiesId();
+ if (type && type->attachedPropertiesFunction(engine))
+ return type->attachedPropertiesId(engine);
else
return -1;
}
-QQmlAttachedPropertiesFunc QQmlMetaType::attachedPropertiesFuncById(int id)
+QQmlAttachedPropertiesFunc QQmlMetaType::attachedPropertiesFuncById(QQmlEnginePrivate *engine, int id)
{
if (id < 0)
return 0;
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
- return data->types.at(id)->attachedPropertiesFunction();
+ return data->types.at(id)->attachedPropertiesFunction(engine);
}
QMetaProperty QQmlMetaType::defaultProperty(const QMetaObject *metaObject)
@@ -1718,7 +1763,7 @@ QQmlType *QQmlMetaType::qmlType(const QHashedStringRef &name, const QHashedStrin
QQmlMetaTypeData *data = metaTypeData();
QQmlMetaTypeData::Names::ConstIterator it = data->nameToType.constFind(name);
- while (it != data->nameToType.end() && it.key() == name) {
+ while (it != data->nameToType.cend() && it.key() == name) {
// XXX version_major<0 just a kludge for QQmlPropertyPrivate::initProperty
if (version_major < 0 || module.isEmpty() || (*it)->availableInVersion(module, version_major,version_minor))
return (*it);
@@ -1752,7 +1797,7 @@ QQmlType *QQmlMetaType::qmlType(const QMetaObject *metaObject, const QHashedStri
QQmlMetaTypeData *data = metaTypeData();
QQmlMetaTypeData::MetaObjects::const_iterator it = data->metaObjectToType.constFind(metaObject);
- while (it != data->metaObjectToType.end() && it.key() == metaObject) {
+ while (it != data->metaObjectToType.cend() && it.key() == metaObject) {
QQmlType *t = *it;
if (version_major < 0 || module.isEmpty() || t->availableInVersion(module, version_major,version_minor))
return t;
@@ -1823,8 +1868,9 @@ QList<QString> QQmlMetaType::qmlTypeNames()
QQmlMetaTypeData *data = metaTypeData();
QList<QString> names;
- QQmlMetaTypeData::Names::ConstIterator it = data->nameToType.begin();
- while (it != data->nameToType.end()) {
+ names.reserve(data->nameToType.count());
+ QQmlMetaTypeData::Names::ConstIterator it = data->nameToType.cbegin();
+ while (it != data->nameToType.cend()) {
names += (*it)->qmlTypeName();
++it;
}
@@ -1885,4 +1931,43 @@ const QQmlPrivate::CachedQmlUnit *QQmlMetaType::findCachedCompilationUnit(const
return 0;
}
+/*!
+ Returns the pretty QML type name (e.g. 'Item' instead of 'QtQuickItem') for the given object.
+ */
+QString QQmlMetaType::prettyTypeName(const QObject *object)
+{
+ QString typeName;
+
+ if (!object)
+ return typeName;
+
+ const QQmlType *type = QQmlMetaType::qmlType(object->metaObject());
+ if (type) {
+ typeName = type->qmlTypeName();
+ const int lastSlash = typeName.lastIndexOf(QLatin1Char('/'));
+ if (lastSlash != -1)
+ typeName = typeName.mid(lastSlash + 1);
+ } else {
+ typeName = QString::fromUtf8(object->metaObject()->className());
+ int marker = typeName.indexOf(QLatin1String("_QMLTYPE_"));
+ if (marker != -1)
+ typeName = typeName.left(marker);
+
+ marker = typeName.indexOf(QLatin1String("_QML_"));
+ if (marker != -1) {
+ typeName = typeName.left(marker);
+ typeName += QLatin1Char('*');
+ type = QQmlMetaType::qmlType(QMetaType::type(typeName.toLatin1()));
+ if (type) {
+ typeName = type->qmlTypeName();
+ const int lastSlash = typeName.lastIndexOf(QLatin1Char('/'));
+ if (lastSlash != -1)
+ typeName = typeName.mid(lastSlash + 1);
+ }
+ }
+ }
+
+ return typeName;
+}
+
QT_END_NAMESPACE