summaryrefslogtreecommitdiffstats
path: root/src/declarative/qml
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2009-04-30 03:01:04 (GMT)
committerAaron Kennedy <aaron.kennedy@nokia.com>2009-04-30 03:01:04 (GMT)
commitd85c0c07b72476d801db3f1cb622cb32ab50dcc4 (patch)
tree1fa3a51cfd493fa7cde45f0b61f5f27891e51769 /src/declarative/qml
parent27cce9ae6c889c1803e46e45375ffb411490989d (diff)
downloadQt-d85c0c07b72476d801db3f1cb622cb32ab50dcc4.zip
Qt-d85c0c07b72476d801db3f1cb622cb32ab50dcc4.tar.gz
Qt-d85c0c07b72476d801db3f1cb622cb32ab50dcc4.tar.bz2
Prototype custom parsers for non-xml qml language
ListModel has been ported (under the name ListModel2) to demonstrate. ListModel2 behaves the same as ListModel, except that list "objects" must be called "ListElement" instead of a freeform name.
Diffstat (limited to 'src/declarative/qml')
-rw-r--r--src/declarative/qml/qml.pri1
-rw-r--r--src/declarative/qml/qmlcompiler.cpp128
-rw-r--r--src/declarative/qml/qmlcompiler_p.h1
-rw-r--r--src/declarative/qml/qmlcustomparser.cpp129
-rw-r--r--src/declarative/qml/qmlcustomparser.h46
-rw-r--r--src/declarative/qml/qmlcustomparser_p.h79
-rw-r--r--src/declarative/qml/qmlinstruction_p.h1
-rw-r--r--src/declarative/qml/qmlmetatype.cpp17
-rw-r--r--src/declarative/qml/qmlmetatype.h32
-rw-r--r--src/declarative/qml/qmlvme.cpp5
10 files changed, 378 insertions, 61 deletions
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index 00e3ccb..40b854f 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -33,6 +33,7 @@ HEADERS += qml/qmlparser_p.h \
qml/qmlcomponent.h \
qml/qmlcomponent_p.h \
qml/qmlcustomparser.h \
+ qml/qmlcustomparser_p.h \
qml/qmlpropertyvaluesource.h \
qml/qmlboundsignal_p.h \
qml/qmlxmlparser_p.h \
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index 4cfe1e8..4433286 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -59,6 +59,7 @@
#include <qmlcontext.h>
#include <qmlmetatype.h>
#include <QtCore/qdebug.h>
+#include "private/qmlcustomparser_p.h"
#include "qmlscriptparser_p.h"
@@ -552,6 +553,7 @@ bool QmlCompiler::compileObject(Object *obj, int ctxt)
obj->properties.remove(SIGNALS_NAME);
}
+ int createInstrIdx = output->bytecode.count();
if (obj->type != -1 && output->types.at(obj->type).parser) {
QByteArray data = obj->custom;
int ref = output->indexForByteArray(data);
@@ -567,6 +569,7 @@ bool QmlCompiler::compileObject(Object *obj, int ctxt)
QmlInstruction create;
create.type = QmlInstruction::CreateObject;
create.line = obj->line;
+ create.create.data = -1;
create.create.type = obj->type;
output->bytecode << create;
}
@@ -591,19 +594,48 @@ bool QmlCompiler::compileObject(Object *obj, int ctxt)
}
}
+ bool isCustomParser = output->types.at(obj->type).type &&
+ output->types.at(obj->type).type->customParser() != 0;
+ QList<QmlCustomParserProperty> customProps;
+
foreach(Property *prop, obj->properties) {
if (!ignoreProperties && prop->name == PROPERTIES_NAME) {
} else if (!ignoreSignals && prop->name == SIGNALS_NAME) {
} else if (prop->name.length() >= 3 && prop->name.startsWith("on") &&
('A' <= prop->name.at(2) && 'Z' >= prop->name.at(2))) {
- COMPILE_CHECK(compileSignal(prop, obj));
+ if (!isCustomParser) {
+ COMPILE_CHECK(compileSignal(prop, obj));
+ } else {
+ customProps << QmlCustomParserNodePrivate::fromProperty(prop);
+ }
} else {
- COMPILE_CHECK(compileProperty(prop, obj, ctxt));
+ if (!isCustomParser || (isCustomParser && testProperty(prop, obj))) {
+ COMPILE_CHECK(compileProperty(prop, obj, ctxt));
+ } else {
+ customProps << QmlCustomParserNodePrivate::fromProperty(prop);
+ }
}
}
- if (obj->defaultProperty)
- COMPILE_CHECK(compileProperty(obj->defaultProperty, obj, ctxt));
+ if (obj->defaultProperty) {
+ if(!isCustomParser || (isCustomParser && testProperty(obj->defaultProperty, obj))) {
+ COMPILE_CHECK(compileProperty(obj->defaultProperty, obj, ctxt));
+ } else {
+ customProps << QmlCustomParserNodePrivate::fromProperty(obj->defaultProperty);
+ }
+ }
+
+ if (isCustomParser && !customProps.isEmpty()) {
+ // ### Check for failure
+ bool ok = false;
+ QmlCustomParser *cp = output->types.at(obj->type).type->customParser();
+ QByteArray customData = cp->compile(customProps, &ok);
+ if(!ok)
+ COMPILE_EXCEPTION("Failure compiling custom type");
+ if(!customData.isEmpty())
+ output->bytecode[createInstrIdx].create.data =
+ output->indexForByteArray(customData);
+ }
if (obj->type != -1) {
if (output->types.at(obj->type).component) {
@@ -764,65 +796,61 @@ bool QmlCompiler::compileSignal(Property *prop, Object *obj)
return true;
}
+// Returns true if prop exists on obj, false otherwise
+bool QmlCompiler::testProperty(QmlParser::Property *prop,
+ QmlParser::Object *obj)
+{
+ if(isAttachedProperty(prop->name) || prop->name == "id")
+ return true;
+
+ const QMetaObject *mo = obj->metaObject();
+ if (mo) {
+ if (prop->isDefault) {
+ QMetaProperty p = QmlMetaType::defaultProperty(mo);
+ return p.name() != 0;
+ } else {
+ int idx = mo->indexOfProperty(prop->name.constData());
+ return idx != -1;
+ }
+ }
+
+ return false;
+}
+
bool QmlCompiler::compileProperty(Property *prop, Object *obj, int ctxt)
{
if (prop->values.isEmpty() && !prop->value)
return true;
// First we're going to need a reference to this property
- if (obj->type != -1) {
+ const QMetaObject *mo = obj->metaObject();
+ if (mo && !isAttachedProperty(prop->name)) {
+ if (prop->isDefault) {
+ QMetaProperty p = QmlMetaType::defaultProperty(mo);
+ // XXX
+ // Currently we don't handle enums in the static analysis
+ // so we let them drop through to generateStoreInstruction()
+ if (p.name() && !p.isEnumType()) {
+ prop->index = mo->indexOfProperty(p.name());
+ prop->name = p.name();
- const QMetaObject *mo = obj->metaObject();
- if (mo) {
- if (prop->isDefault) {
- QMetaProperty p = QmlMetaType::defaultProperty(mo);
- // XXX
- // Currently we don't handle enums in the static analysis
- // so we let them drop through to generateStoreInstruction()
- if (p.name() && !p.isEnumType()) {
- prop->index = mo->indexOfProperty(p.name());
- prop->name = p.name();
-
- int t = p.type();
- if (t == QVariant::UserType)
- t = p.userType();
-
- prop->type = t;
- }
- } else {
- prop->index = mo->indexOfProperty(prop->name.constData());
- QMetaProperty p = mo->property(prop->index);
- // XXX
- // Currently we don't handle enums in the static analysis
- // so we let them drop through to generateStoreInstruction()
- if (p.name() && !p.isEnumType()) {
- int t = p.type();
- if (t == QVariant::UserType)
- t = p.userType();
-
- prop->type = t;
- }
- }
- }
- } else {
- const QMetaObject *mo = obj->metaObject();
- if (mo) {
- if (prop->isDefault) {
- QMetaProperty p = QmlMetaType::defaultProperty(mo);
- if (p.name()) {
- prop->index = mo->indexOfProperty(p.name());
- prop->name = p.name();
- }
int t = p.type();
if (t == QVariant::UserType)
t = p.userType();
+
prop->type = t;
- } else {
- prop->index = mo->indexOfProperty(prop->name.constData());
- QMetaProperty p = mo->property(prop->index);
+ }
+ } else {
+ prop->index = mo->indexOfProperty(prop->name.constData());
+ QMetaProperty p = mo->property(prop->index);
+ // XXX
+ // Currently we don't handle enums in the static analysis
+ // so we let them drop through to generateStoreInstruction()
+ if (p.name() && !p.isEnumType()) {
int t = p.type();
if (t == QVariant::UserType)
t = p.userType();
+
prop->type = t;
}
}
@@ -841,7 +869,7 @@ bool QmlCompiler::compileProperty(Property *prop, Object *obj, int ctxt)
COMPILE_CHECK(compileNestedProperty(prop, ctxt));
} else if (QmlMetaType::isQmlList(prop->type) ||
- QmlMetaType::isList(prop->type)) {
+ QmlMetaType::isList(prop->type)) {
COMPILE_CHECK(compileListProperty(prop, obj, ctxt));
diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h
index 2a06f73..9a0ce1c 100644
--- a/src/declarative/qml/qmlcompiler_p.h
+++ b/src/declarative/qml/qmlcompiler_p.h
@@ -139,6 +139,7 @@ private:
bool compileComponentFromRoot(QmlParser::Object *obj, int);
bool compileFetchedObject(QmlParser::Object *obj, int);
bool compileSignal(QmlParser::Property *prop, QmlParser::Object *obj);
+ bool testProperty(QmlParser::Property *prop, QmlParser::Object *obj);
bool compileProperty(QmlParser::Property *prop, QmlParser::Object *obj, int);
bool compileIdProperty(QmlParser::Property *prop,
QmlParser::Object *obj);
diff --git a/src/declarative/qml/qmlcustomparser.cpp b/src/declarative/qml/qmlcustomparser.cpp
index a342ca8..fe0c3a8 100644
--- a/src/declarative/qml/qmlcustomparser.cpp
+++ b/src/declarative/qml/qmlcustomparser.cpp
@@ -40,10 +40,13 @@
****************************************************************************/
#include "qmlcustomparser.h"
-
+#include "qmlcustomparser_p.h"
+#include "qmlparser_p.h"
QT_BEGIN_NAMESPACE
+using namespace QmlParser;
+
/*!
\class QmlCustomParser
\brief The QmlCustomParser class allows you to add new arbitrary types to QML.
@@ -92,5 +95,129 @@ QT_BEGIN_NAMESPACE
the same-named type as this custom parser is defined for).
*/
+QmlCustomParserNode
+QmlCustomParserNodePrivate::fromObject(QmlParser::Object *root)
+{
+ QmlCustomParserNode rootNode;
+ rootNode.d->name = root->typeName;
+
+ for(QHash<QByteArray, Property *>::Iterator iter = root->properties.begin();
+ iter != root->properties.end();
+ ++iter) {
+
+ Property *p = *iter;
+
+ rootNode.d->properties << fromProperty(p);
+ }
+
+ return rootNode;
+}
+
+QmlCustomParserProperty
+QmlCustomParserNodePrivate::fromProperty(QmlParser::Property *p)
+{
+ QmlCustomParserProperty prop;
+ prop.d->name = p->name;
+ prop.d->isList = (p->values.count() > 1);
+
+ for(int ii = 0; ii < p->values.count(); ++ii) {
+ Value *v = p->values.at(ii);
+
+ // We skip fetched properties for now
+ if(v->object && v->object->type == -1)
+ continue;
+
+ if(v->object) {
+ QmlCustomParserNode node = fromObject(v->object);
+ prop.d->values << QVariant::fromValue(node);
+ } else {
+ prop.d->values << QVariant::fromValue(v->primitive);
+ }
+
+ }
+
+ return prop;
+}
+
+QmlCustomParserNode::QmlCustomParserNode()
+: d(new QmlCustomParserNodePrivate)
+{
+}
+
+QmlCustomParserNode::QmlCustomParserNode(const QmlCustomParserNode &other)
+: d(new QmlCustomParserNodePrivate)
+{
+ *this = other;
+}
+
+QmlCustomParserNode &QmlCustomParserNode::operator=(const QmlCustomParserNode &other)
+{
+ d->name = other.d->name;
+ d->properties = other.d->properties;
+ return *this;
+}
+
+QmlCustomParserNode::~QmlCustomParserNode()
+{
+ delete d; d = 0;
+}
+
+QByteArray QmlCustomParserNode::name() const
+{
+ return d->name;
+}
+
+QList<QmlCustomParserProperty> QmlCustomParserNode::properties() const
+{
+ return d->properties;
+}
+
+QmlCustomParserProperty::QmlCustomParserProperty()
+: d(new QmlCustomParserPropertyPrivate)
+{
+}
+
+QmlCustomParserProperty::QmlCustomParserProperty(const QmlCustomParserProperty &other)
+: d(new QmlCustomParserPropertyPrivate)
+{
+ *this = other;
+}
+
+QmlCustomParserProperty &QmlCustomParserProperty::operator=(const QmlCustomParserProperty &other)
+{
+ d->name = other.d->name;
+ d->isList = other.d->isList;
+ d->values = other.d->values;
+ return *this;
+}
+
+QmlCustomParserProperty::~QmlCustomParserProperty()
+{
+ delete d; d = 0;
+}
+
+QByteArray QmlCustomParserProperty::name() const
+{
+ return d->name;
+}
+
+bool QmlCustomParserProperty::isList() const
+{
+ return d->isList;
+}
+
+QList<QVariant> QmlCustomParserProperty::assignedValues() const
+{
+ return d->values;
+}
+
+QByteArray QmlCustomParser::compile(const QList<QmlCustomParserProperty> &, bool *ok)
+{
+ return QByteArray();
+}
+
+void QmlCustomParser::setCustomData(QObject *, const QByteArray &)
+{
+}
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlcustomparser.h b/src/declarative/qml/qmlcustomparser.h
index 9de1be4..0e6a619 100644
--- a/src/declarative/qml/qmlcustomparser.h
+++ b/src/declarative/qml/qmlcustomparser.h
@@ -53,13 +53,55 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
+class QmlCustomParserPropertyPrivate;
+class Q_DECLARATIVE_EXPORT QmlCustomParserProperty
+{
+public:
+ QmlCustomParserProperty();
+ QmlCustomParserProperty(const QmlCustomParserProperty &);
+ QmlCustomParserProperty &operator=(const QmlCustomParserProperty &);
+ ~QmlCustomParserProperty();
+
+ QByteArray name() const;
+
+ bool isList() const;
+ QList<QVariant> assignedValues() const;
+
+private:
+ friend class QmlCustomParserNodePrivate;
+ friend class QmlCustomParserPropertyPrivate;
+ QmlCustomParserPropertyPrivate *d;
+};
+Q_DECLARE_METATYPE(QmlCustomParserProperty);
+
+class QmlCustomParserNodePrivate;
+class Q_DECLARATIVE_EXPORT QmlCustomParserNode
+{
+public:
+ QmlCustomParserNode();
+ QmlCustomParserNode(const QmlCustomParserNode &);
+ QmlCustomParserNode &operator=(const QmlCustomParserNode &);
+ ~QmlCustomParserNode();
+
+ QByteArray name() const;
+
+ QList<QmlCustomParserProperty> properties() const;
+
+private:
+ friend class QmlCustomParserNodePrivate;
+ QmlCustomParserNodePrivate *d;
+};
+Q_DECLARE_METATYPE(QmlCustomParserNode);
+
class Q_DECLARATIVE_EXPORT QmlCustomParser
{
public:
virtual ~QmlCustomParser() {}
virtual QByteArray compile(QXmlStreamReader&, bool *ok)=0;
+ virtual QByteArray compile(const QList<QmlCustomParserProperty> &, bool *ok);
virtual QVariant create(const QByteArray &)=0;
+ virtual void setCustomData(QObject *, const QByteArray &);
struct Register {
Register(const char *name, QmlCustomParser *parser) {
@@ -76,7 +118,11 @@ public:
#define QML_DEFINE_CUSTOM_PARSER_NS(namespacestring, name, parserClass) \
template<> QmlCustomParser::Register QmlCustomParser::Define<parserClass>::instance(namespacestring "/" # name, new parserClass);
+#define QML_DEFINE_CUSTOM_TYPE(TYPE, NAME, CUSTOMTYPE) \
+ template<> QmlPrivate::InstanceType QmlPrivate::Define<TYPE *>::instance(qmlRegisterCustomType<TYPE>(#NAME, #TYPE, new CUSTOMTYPE));
+
QT_END_NAMESPACE
QT_END_HEADER
+
#endif
diff --git a/src/declarative/qml/qmlcustomparser_p.h b/src/declarative/qml/qmlcustomparser_p.h
new file mode 100644
index 0000000..63d148c
--- /dev/null
+++ b/src/declarative/qml/qmlcustomparser_p.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLCUSTOMPARSER_P_H
+#define QMLCUSTOMPARSER_P_H
+
+#include <QtCore/qglobal.h>
+#include "qmlcustomparser.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace QmlParser
+{
+ class Object;
+ class Property;
+};
+
+class QmlCustomParserNodePrivate
+{
+public:
+ QByteArray name;
+ QList<QmlCustomParserProperty> properties;
+
+ static QmlCustomParserNode fromObject(QmlParser::Object *);
+ static QmlCustomParserProperty fromProperty(QmlParser::Property *);
+};
+
+class QmlCustomParserPropertyPrivate
+{
+public:
+ QmlCustomParserPropertyPrivate()
+ : isList(false) {}
+
+ QByteArray name;
+ bool isList;
+ QList<QVariant> values;
+};
+
+QT_END_NAMESPACE
+
+#endif // QMLCUSTOMPARSER_P_H
diff --git a/src/declarative/qml/qmlinstruction_p.h b/src/declarative/qml/qmlinstruction_p.h
index 440b54a..922fc61 100644
--- a/src/declarative/qml/qmlinstruction_p.h
+++ b/src/declarative/qml/qmlinstruction_p.h
@@ -174,6 +174,7 @@ public:
} init;
struct {
int type;
+ int data;
} create;
struct {
int data;
diff --git a/src/declarative/qml/qmlmetatype.cpp b/src/declarative/qml/qmlmetatype.cpp
index 9b99917..fbfeca0 100644
--- a/src/declarative/qml/qmlmetatype.cpp
+++ b/src/declarative/qml/qmlmetatype.cpp
@@ -118,6 +118,7 @@ public:
QmlPrivate::CreateFunc m_extFunc;
const QMetaObject *m_extMetaObject;
int m_index;
+ QmlCustomParser *m_customParser;
mutable volatile bool m_isSetup:1;
mutable QList<QmlProxyMetaObject::ProxyData> m_metaObjects;
mutable QByteArray m_hash;
@@ -126,7 +127,8 @@ public:
QmlTypePrivate::QmlTypePrivate()
: m_isInterface(false), m_iid(0), m_typeId(0), m_listId(0), m_qmlListId(0),
m_opFunc(0), m_baseMetaObject(0), m_attachedPropertiesFunc(0),
- m_parserStatusCast(-1), m_extFunc(0), m_extMetaObject(0), m_index(-1), m_isSetup(false)
+ m_parserStatusCast(-1), m_extFunc(0), m_extMetaObject(0), m_index(-1),
+ m_customParser(0), m_isSetup(false)
{
}
@@ -150,7 +152,8 @@ QmlType::QmlType(int type, int listType, int qmlListType,
const QMetaObject *metaObject,
QmlAttachedPropertiesFunc attachedPropertiesFunc,
int parserStatusCast, QmlPrivate::CreateFunc extFunc,
- const QMetaObject *extMetaObject, int index)
+ const QMetaObject *extMetaObject, int index,
+ QmlCustomParser *customParser)
: d(new QmlTypePrivate)
{
d->m_name = qmlName;
@@ -163,6 +166,7 @@ QmlType::QmlType(int type, int listType, int qmlListType,
d->m_parserStatusCast = parserStatusCast;
d->m_extFunc = extFunc;
d->m_index = index;
+ d->m_customParser = customParser;
if (extMetaObject)
d->m_extMetaObject = extMetaObject;
@@ -272,6 +276,11 @@ QObject *QmlType::create() const
return rv;
}
+QmlCustomParser *QmlType::customParser() const
+{
+ return d->m_customParser;
+}
+
bool QmlType::isInterface() const
{
return d->m_isInterface;
@@ -396,7 +405,7 @@ int QmlMetaType::registerInterface(const QmlPrivate::MetaTypeIds &id,
return index;
}
-int QmlMetaType::registerType(const QmlPrivate::MetaTypeIds &id, QmlPrivate::Func func, const char *cname, const QMetaObject *mo, QmlAttachedPropertiesFunc attach, int pStatus, int object, QmlPrivate::CreateFunc extFunc, const QMetaObject *extmo)
+int QmlMetaType::registerType(const QmlPrivate::MetaTypeIds &id, QmlPrivate::Func func, const char *cname, const QMetaObject *mo, QmlAttachedPropertiesFunc attach, int pStatus, int object, QmlPrivate::CreateFunc extFunc, const QMetaObject *extmo, QmlCustomParser *parser)
{
Q_UNUSED(object);
QWriteLocker lock(metaTypeDataLock());
@@ -414,7 +423,7 @@ int QmlMetaType::registerType(const QmlPrivate::MetaTypeIds &id, QmlPrivate::Fun
QmlType *type = new QmlType(id.typeId, id.listId, id.qmlListId,
func, cname, mo, attach, pStatus, extFunc,
- extmo, index);
+ extmo, index, parser);
data->types.append(type);
data->idToType.insert(type->typeId(), type);
diff --git a/src/declarative/qml/qmlmetatype.h b/src/declarative/qml/qmlmetatype.h
index 83fb60b..99f8e93 100644
--- a/src/declarative/qml/qmlmetatype.h
+++ b/src/declarative/qml/qmlmetatype.h
@@ -59,7 +59,7 @@ class QmlCustomParser;
class Q_DECLARATIVE_EXPORT QmlMetaType
{
public:
- static int registerType(const QmlPrivate::MetaTypeIds &, QmlPrivate::Func, const char *, const QMetaObject *, QmlAttachedPropertiesFunc, int pStatus, int object, QmlPrivate::CreateFunc extFunc, const QMetaObject *extmo);
+ static int registerType(const QmlPrivate::MetaTypeIds &, QmlPrivate::Func, const char *, const QMetaObject *, QmlAttachedPropertiesFunc, int pStatus, int object, QmlPrivate::CreateFunc extFunc, const QMetaObject *extmo, QmlCustomParser *);
static int registerInterface(const QmlPrivate::MetaTypeIds &, QmlPrivate::Func, const char *);
static void registerCustomParser(const char *, QmlCustomParser *);
@@ -121,6 +121,8 @@ public:
QObject *create() const;
+ QmlCustomParser *customParser() const;
+
bool isInterface() const;
int typeId() const;
int qListTypeId() const;
@@ -145,7 +147,7 @@ private:
friend class QmlMetaType;
friend class QmlTypePrivate;
QmlType(int, int, int, QmlPrivate::Func, const char *, int);
- QmlType(int, int, int, QmlPrivate::Func, const char *, const QMetaObject *, QmlAttachedPropertiesFunc, int, QmlPrivate::CreateFunc, const QMetaObject *, int);
+ QmlType(int, int, int, QmlPrivate::Func, const char *, const QMetaObject *, QmlAttachedPropertiesFunc, int, QmlPrivate::CreateFunc, const QMetaObject *, int, QmlCustomParser *);
~QmlType();
QmlTypePrivate *d;
@@ -166,7 +168,7 @@ int qmlRegisterType(const char *typeName)
QmlPrivate::attachedPropertiesFunc<T>(),
QmlPrivate::StaticCastSelector<T,QmlParserStatus>::cast(),
QmlPrivate::StaticCastSelector<T,QObject>::cast(),
- 0, 0);
+ 0, 0, 0);
}
template<typename T>
@@ -184,7 +186,7 @@ int qmlRegisterType(const char *qmlName, const char *typeName)
QmlPrivate::attachedPropertiesFunc<T>(),
QmlPrivate::StaticCastSelector<T,QmlParserStatus>::cast(),
QmlPrivate::StaticCastSelector<T,QObject>::cast(),
- 0, 0);
+ 0, 0, 0);
}
template<typename T, typename E>
@@ -206,7 +208,7 @@ int qmlRegisterExtendedType(const char *typeName)
&T::staticMetaObject, attached,
QmlPrivate::StaticCastSelector<T,QmlParserStatus>::cast(),
QmlPrivate::StaticCastSelector<T,QObject>::cast(),
- &QmlPrivate::CreateParent<E>::create, &E::staticMetaObject);
+ &QmlPrivate::CreateParent<E>::create, &E::staticMetaObject, 0);
}
template<typename T, typename E>
@@ -231,7 +233,7 @@ int qmlRegisterExtendedType(const char *qmlName, const char *typeName)
QmlPrivate::StaticCastSelector<T,QmlParserStatus>::cast(),
QmlPrivate::StaticCastSelector<T,QObject>::cast(),
&QmlPrivate::CreateParent<E>::create,
- &E::staticMetaObject);
+ &E::staticMetaObject, 0);
}
template<typename T>
@@ -249,6 +251,24 @@ int qmlRegisterInterface(const char *typeName)
qobject_interface_iid<T *>());
}
+template<typename T>
+int qmlRegisterCustomType(const char *qmlName, const char *typeName, QmlCustomParser *parser)
+{
+ QByteArray name(typeName);
+ QmlPrivate::MetaTypeIds ids = {
+ qRegisterMetaType<T *>(QByteArray(name + "*").constData()),
+ qRegisterMetaType<T *>(QByteArray("QList<" + name + "*>*").constData()),
+ qRegisterMetaType<T *>(QByteArray("QmlList<" + name + "*>*").constData())
+ };
+
+ return QmlMetaType::registerType(ids, QmlPrivate::list_op<T>, qmlName,
+ &T::staticMetaObject,
+ QmlPrivate::attachedPropertiesFunc<T>(),
+ QmlPrivate::StaticCastSelector<T,QmlParserStatus>::cast(),
+ QmlPrivate::StaticCastSelector<T,QObject>::cast(),
+ 0, 0, parser);
+}
+
void qmlRegisterCustomParser(const char *qmlName, QmlCustomParser *);
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp
index 253e9a7..7b3291e 100644
--- a/src/declarative/qml/qmlvme.cpp
+++ b/src/declarative/qml/qmlvme.cpp
@@ -257,6 +257,11 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in
if (!o)
VME_EXCEPTION("Unable to create object of type" << types.at(instr.create.type).className);
+ if (instr.create.data != -1) {
+ QmlCustomParser *customParser =
+ types.at(instr.create.type).type->customParser();
+ customParser->setCustomData(o, datas.at(instr.create.data));
+ }
if (!stack.isEmpty()) {
QObject *parent = stack.top();
o->setParent(parent);