diff options
Diffstat (limited to 'src/declarative/qml')
-rw-r--r-- | src/declarative/qml/qml.h | 4 | ||||
-rw-r--r-- | src/declarative/qml/qmllist.h | 66 | ||||
-rw-r--r-- | src/declarative/qml/qmllistscriptclass.cpp | 57 | ||||
-rw-r--r-- | src/declarative/qml/qmllistscriptclass_p.h | 2 | ||||
-rw-r--r-- | src/declarative/qml/qmlmetaproperty.cpp | 3 | ||||
-rw-r--r-- | src/declarative/qml/qmlmetatype.cpp | 54 | ||||
-rw-r--r-- | src/declarative/qml/qmlmetatype.h | 47 | ||||
-rw-r--r-- | src/declarative/qml/qmlobjectscriptclass.cpp | 2 | ||||
-rw-r--r-- | src/declarative/qml/qmlprivate.h | 163 | ||||
-rw-r--r-- | src/declarative/qml/qmlvme.cpp | 26 |
10 files changed, 258 insertions, 166 deletions
diff --git a/src/declarative/qml/qml.h b/src/declarative/qml/qml.h index 859fd66..c009093 100644 --- a/src/declarative/qml/qml.h +++ b/src/declarative/qml/qml.h @@ -59,11 +59,11 @@ QT_MODULE(Declarative) #define QML_DECLARE_TYPE(TYPE) \ Q_DECLARE_METATYPE(TYPE *) \ - Q_DECLARE_METATYPE(QmlListProperty<TYPE>) \ + Q_DECLARE_METATYPE(QList<TYPE *> *) \ Q_DECLARE_METATYPE(QmlList<TYPE *> *) #define QML_DECLARE_TYPE_HASMETATYPE(TYPE) \ - Q_DECLARE_METATYPE(QmlListProperty<TYPE>) \ + Q_DECLARE_METATYPE(QList<TYPE *> *) \ Q_DECLARE_METATYPE(QmlList<TYPE *> *) #define QML_DECLARE_INTERFACE(INTERFACE) \ diff --git a/src/declarative/qml/qmllist.h b/src/declarative/qml/qmllist.h index b1a81c4..ad2d874 100644 --- a/src/declarative/qml/qmllist.h +++ b/src/declarative/qml/qmllist.h @@ -119,72 +119,6 @@ class Qml_ProxyList_ ##ListName : public QmlList<ListType> \ friend class Qml_ProxyList_ ##ListName ; \ Qml_ProxyList_##ListName ListName; -template<typename T> -struct QmlListProperty { - typedef void (*AppendFunction)(QmlListProperty<T> *, T*); - typedef int (*CountFunction)(QmlListProperty<T> *); - typedef T *(*AtFunction)(QmlListProperty<T> *, int); - typedef void (*ClearFunction)(QmlListProperty<T> *); - typedef void (*InsertFunction)(QmlListProperty<T> *, int, T *); - typedef void (*RemoveAtFunction)(QmlListProperty<T> *, int); - - QmlListProperty() - : version(1), object(0), data(0), append(0), count(0), at(0), clear(0), insert(0), removeAt(0) {} - QmlListProperty(QObject *o, QList<T *> &list) - : version(1), object(o), data(&list), append(qlist_append), count(qlist_count), at(qlist_at), - clear(qlist_clear), insert(qlist_insert), removeAt(qlist_removeAt) {} - QmlListProperty(QObject *o, void *d, AppendFunction a, CountFunction c = 0, AtFunction t = 0, - ClearFunction l = 0, InsertFunction i = 0, RemoveAtFunction r = 0) - : version(1), object(o), data(d), append(a), count(c), at(t), clear(l), insert(i), removeAt(r) {} - - bool operator==(const QmlListProperty &o) const { - return version == o.version && - object == o.object && - data == o.data && - append == o.append && - count == o.count && - at == o.at && - clear == o.clear && - insert == o.insert && - removeAt == o.removeAt; - } - - int version; - - QObject *object; - void *data; - - AppendFunction append; - - CountFunction count; - AtFunction at; - - ClearFunction clear; - - InsertFunction insert; - RemoveAtFunction removeAt; - -private: - static void qlist_append(QmlListProperty *p, T *v) { - ((QList<T *> *)p->data)->append(v); - } - static int qlist_count(QmlListProperty *p) { - return ((QList<T *> *)p->data)->count(); - } - static T *qlist_at(QmlListProperty *p, int idx) { - return ((QList<T *> *)p->data)->at(idx); - } - static void qlist_clear(QmlListProperty *p) { - return ((QList<T *> *)p->data)->clear(); - } - static void qlist_insert(QmlListProperty *p, int idx, T *v) { - return ((QList<T *> *)p->data)->insert(idx, v); - } - static void qlist_removeAt(QmlListProperty *p, int idx) { - return ((QList<T *> *)p->data)->removeAt(idx); - } -}; - QT_END_NAMESPACE QT_END_HEADER diff --git a/src/declarative/qml/qmllistscriptclass.cpp b/src/declarative/qml/qmllistscriptclass.cpp index caa4e4e..d4cdc6e 100644 --- a/src/declarative/qml/qmllistscriptclass.cpp +++ b/src/declarative/qml/qmllistscriptclass.cpp @@ -111,31 +111,27 @@ QmlListScriptClass::ScriptValue QmlListScriptClass::property(Object *obj, const if (!data->object) return Value(); - if (data->type == ListProperty) { - QmlListProperty<QObject> list; - void *args[] = { &list, 0 }; + void *list = 0; + void *args[] = { &list, 0 }; + QMetaObject::metacall(data->object, QMetaObject::ReadProperty, + data->propertyIdx, args); - QMetaObject::metacall(data->object, QMetaObject::ReadProperty, - data->propertyIdx, args); + if (!list) + return Value(); + + if (data->type == QListPtr) { + const QList<QObject *> &qlist = *((QList<QObject *>*)list); - quint32 count = list.count(&list); + quint32 count = qlist.count(); if (name == m_lengthId.identifier) return Value(scriptEngine, count); else if (lastIndex < count) - return Value(scriptEngine, enginePriv->objectClass->newQObject(list.at(&list, lastIndex))); + return Value(scriptEngine, enginePriv->objectClass->newQObject(qlist.at(lastIndex))); else return Value(); } else { - void *list = 0; - void *args[] = { &list, 0 }; - QMetaObject::metacall(data->object, QMetaObject::ReadProperty, - data->propertyIdx, args); - - if (!list) - return Value(); - Q_ASSERT(data->type == QmlListPtr); const QmlList<QObject *> &qmllist = *((QmlList<QObject *>*)list); @@ -159,29 +155,18 @@ QVariant QmlListScriptClass::toVariant(Object *obj, bool *ok) return QVariant(); } - if (data->type == QmlListScriptClass::QmlListPtr) { - void *list = 0; - void *args[] = { &list, 0 }; - QMetaObject::metacall(data->object, QMetaObject::ReadProperty, - data->propertyIdx, args); - - if (!list) { - if (ok) *ok = false; - return QVariant(); - } + void *list = 0; + void *args[] = { &list, 0 }; + QMetaObject::metacall(data->object, QMetaObject::ReadProperty, + data->propertyIdx, args); - if (ok) *ok = true; - return QVariant(data->propertyType, &list); - } else { - QmlListProperty<QObject> list; - void *args[] = { &list, 0 }; - - QMetaObject::metacall(data->object, QMetaObject::ReadProperty, - data->propertyIdx, args); - - if (ok) *ok = true; - return QVariant(data->propertyType, &list); + if (!list) { + if (ok) *ok = false; + return QVariant(); } + + if (ok) *ok = true; + return QVariant(data->propertyType, &list); } QT_END_NAMESPACE diff --git a/src/declarative/qml/qmllistscriptclass_p.h b/src/declarative/qml/qmllistscriptclass_p.h index 464f91e..e484b34 100644 --- a/src/declarative/qml/qmllistscriptclass_p.h +++ b/src/declarative/qml/qmllistscriptclass_p.h @@ -64,7 +64,7 @@ public: QmlListScriptClass(QmlEngine *); ~QmlListScriptClass(); - enum ListCategory { ListProperty, QmlListPtr }; + enum ListCategory { QListPtr, QmlListPtr }; QScriptValue newList(QObject *, int, ListCategory, int); protected: diff --git a/src/declarative/qml/qmlmetaproperty.cpp b/src/declarative/qml/qmlmetaproperty.cpp index fc11bd6..70f9ad3 100644 --- a/src/declarative/qml/qmlmetaproperty.cpp +++ b/src/declarative/qml/qmlmetaproperty.cpp @@ -889,8 +889,7 @@ bool QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data QVariant listVar = prop.read(object); QmlMetaType::clear(listVar); for (int ii = 0; ii < list.count(); ++ii) { - QObject *o = list.at(ii); - QVariant v = QVariant(listType, &o); + QVariant v = QmlMetaType::qmlType(listType)->fromObject(list.at(ii)); QmlMetaType::append(listVar, v); } diff --git a/src/declarative/qml/qmlmetatype.cpp b/src/declarative/qml/qmlmetatype.cpp index e613b7c..7dfc48d 100644 --- a/src/declarative/qml/qmlmetatype.cpp +++ b/src/declarative/qml/qmlmetatype.cpp @@ -125,7 +125,7 @@ public: int m_version_maj; int m_version_min; int m_typeId; int m_listId; int m_qmlListId; - QObject *(*m_newFunc)(); + QmlPrivate::Func m_opFunc; const QMetaObject *m_baseMetaObject; QmlAttachedPropertiesFunc m_attachedPropertiesFunc; const QMetaObject *m_attachedPropertiesType; @@ -142,14 +142,15 @@ public: QmlTypePrivate::QmlTypePrivate() : m_isInterface(false), m_iid(0), m_typeId(0), m_listId(0), m_qmlListId(0), - m_newFunc(0), m_baseMetaObject(0), m_attachedPropertiesFunc(0), m_attachedPropertiesType(0), + m_opFunc(0), m_baseMetaObject(0), m_attachedPropertiesFunc(0), m_attachedPropertiesType(0), m_parserStatusCast(-1), m_propertyValueSourceCast(-1), m_propertyValueInterceptorCast(-1), m_extFunc(0), m_extMetaObject(0), m_index(-1), m_customParser(0), m_isSetup(false) { } -QmlType::QmlType(int type, int listType, int qmlListType, const char *iid, int index) +QmlType::QmlType(int type, int listType, int qmlListType, + QmlPrivate::Func opFunc, const char *iid, int index) : d(new QmlTypePrivate) { d->m_isInterface = true; @@ -157,7 +158,7 @@ QmlType::QmlType(int type, int listType, int qmlListType, const char *iid, int i d->m_typeId = type; d->m_listId = listType; d->m_qmlListId = qmlListType; - d->m_newFunc = 0; + d->m_opFunc = opFunc; d->m_index = index; d->m_isSetup = true; d->m_version_maj = 0; @@ -165,7 +166,7 @@ QmlType::QmlType(int type, int listType, int qmlListType, const char *iid, int i } QmlType::QmlType(int type, int listType, int qmlListType, - QObject *(*newFunc)(), const char *qmlName, + QmlPrivate::Func opFunc, const char *qmlName, int version_maj, int version_min, const QMetaObject *metaObject, QmlAttachedPropertiesFunc attachedPropertiesFunc, @@ -182,7 +183,7 @@ QmlType::QmlType(int type, int listType, int qmlListType, d->m_typeId = type; d->m_listId = listType; d->m_qmlListId = qmlListType; - d->m_newFunc = newFunc; + d->m_opFunc = opFunc; d->m_baseMetaObject = metaObject; d->m_attachedPropertiesFunc = attachedPropertiesFunc; d->m_attachedPropertiesType = attachedType; @@ -282,7 +283,10 @@ QObject *QmlType::create() const { d->init(); - QObject *rv = d->m_newFunc(); + QVariant v; + QObject *rv = 0; + d->m_opFunc(QmlPrivate::Create, 0, v, v, (void **)&rv); + if (rv && !d->m_metaObjects.isEmpty()) (void *)new QmlProxyMetaObject(rv, &d->m_metaObjects); @@ -317,35 +321,29 @@ int QmlType::qmlListTypeId() const void QmlType::listClear(const QVariant &list) { Q_ASSERT(list.userType() == qListTypeId()); - QmlListProperty<void> *l = (QmlListProperty<void> *)list.data(); - if (l->clear) l->clear(l); + QVariant arg; + d->m_opFunc(QmlPrivate::Clear, 0, list, arg, 0); } void QmlType::listAppend(const QVariant &list, const QVariant &item) { Q_ASSERT(list.userType() == qListTypeId()); - QmlListProperty<void> *l = (QmlListProperty<void> *)list.data(); - if (l->append) l->append(l, *(void **)item.data()); + d->m_opFunc(QmlPrivate::Append, 0, list, item, 0); } QVariant QmlType::listAt(const QVariant &list, int idx) { Q_ASSERT(list.userType() == qListTypeId()); - QmlListProperty<void> *l = (QmlListProperty<void> *)list.data(); - if (l->at) { - void *v = l->at(l, idx); - return QVariant(typeId(), &v); - } else { - return QVariant(); - } + QVariant rv; + void *ptr = (void *)&rv; + d->m_opFunc(QmlPrivate::Value, idx, list, QVariant(), &ptr); + return rv; } int QmlType::listCount(const QVariant &list) { Q_ASSERT(list.userType() == qListTypeId()); - QmlListProperty<void> *l = (QmlListProperty<void> *)list.data(); - if (l->count) return l->count(l); - return 0; + return d->m_opFunc(QmlPrivate::Length, 0, list, QVariant(), 0); } const QMetaObject *QmlType::metaObject() const @@ -389,6 +387,15 @@ int QmlType::propertyValueInterceptorCast() const return d->m_propertyValueInterceptorCast; } +QVariant QmlType::fromObject(QObject *obj) const +{ + QVariant rv; + QVariant *v_ptr = &rv; + QVariant vobj = QVariant::fromValue(obj); + d->m_opFunc(QmlPrivate::FromObject, 0, QVariant(), vobj, (void **)&v_ptr); + return rv; +} + const char *QmlType::interfaceIId() const { return d->m_iid; @@ -400,6 +407,7 @@ int QmlType::index() const } int QmlMetaType::registerInterface(const QmlPrivate::MetaTypeIds &id, + QmlPrivate::Func listFunction, const char *iid) { QWriteLocker lock(metaTypeDataLock()); @@ -408,7 +416,7 @@ int QmlMetaType::registerInterface(const QmlPrivate::MetaTypeIds &id, int index = data->types.count(); QmlType *type = new QmlType(id.typeId, id.listId, id.qmlListId, - iid, index); + listFunction, iid, index); data->types.append(type); data->idToType.insert(type->typeId(), type); @@ -431,7 +439,7 @@ int QmlMetaType::registerInterface(const QmlPrivate::MetaTypeIds &id, return index; } -int QmlMetaType::registerType(const QmlPrivate::MetaTypeIds &id, QObject *(*func)(), +int QmlMetaType::registerType(const QmlPrivate::MetaTypeIds &id, QmlPrivate::Func func, const char *uri, int version_maj, int version_min, const char *cname, const QMetaObject *mo, QmlAttachedPropertiesFunc attach, const QMetaObject *attachMo, int pStatus, int object, int valueSource, int valueInterceptor, QmlPrivate::CreateFunc extFunc, const QMetaObject *extmo, QmlCustomParser *parser) diff --git a/src/declarative/qml/qmlmetatype.h b/src/declarative/qml/qmlmetatype.h index 1d9c096..45ec11d 100644 --- a/src/declarative/qml/qmlmetatype.h +++ b/src/declarative/qml/qmlmetatype.h @@ -46,7 +46,6 @@ #include "qmlparserstatus.h" #include "qmlpropertyvaluesource.h" #include "qmlpropertyvalueinterceptor.h" -#include "qmllist.h" #include <QtCore/qglobal.h> #include <QtCore/qvariant.h> @@ -63,8 +62,8 @@ class QmlCustomParser; class Q_DECLARATIVE_EXPORT QmlMetaType { public: - static int registerType(const QmlPrivate::MetaTypeIds &, QObject *(*)(), const char *, int vmaj, int vmin, const char *qmlName, const QMetaObject *, QmlAttachedPropertiesFunc, const QMetaObject *, int pStatus, int object, int valueSource, int valueInterceptor, QmlPrivate::CreateFunc extFunc, const QMetaObject *extmo, QmlCustomParser *); - static int registerInterface(const QmlPrivate::MetaTypeIds &, const char *); + static int registerType(const QmlPrivate::MetaTypeIds &, QmlPrivate::Func, const char *, int vmaj, int vmin, const char *qmlName, const QMetaObject *, QmlAttachedPropertiesFunc, const QMetaObject *, int pStatus, int object, int valueSource, int valueInterceptor, QmlPrivate::CreateFunc extFunc, const QMetaObject *extmo, QmlCustomParser *); + static int registerInterface(const QmlPrivate::MetaTypeIds &, QmlPrivate::Func, const char *); static bool copy(int type, void *data, const void *copy = 0); @@ -148,8 +147,8 @@ private: friend class QmlMetaType; friend class QmlTypePrivate; friend struct QmlMetaTypeData; - QmlType(int, int, int, const char *, int); - QmlType(int, int, int, QObject *(*)(), const char *, int, int, const QMetaObject *, QmlAttachedPropertiesFunc, const QMetaObject *, int, int, int, QmlPrivate::CreateFunc, const QMetaObject *, int, QmlCustomParser *); + QmlType(int, int, int, QmlPrivate::Func, const char *, int); + QmlType(int, int, int, QmlPrivate::Func, const char *, int, int, const QMetaObject *, QmlAttachedPropertiesFunc, const QMetaObject *, int, int, int, QmlPrivate::CreateFunc, const QMetaObject *, int, QmlCustomParser *); ~QmlType(); QmlTypePrivate *d; @@ -161,11 +160,11 @@ int qmlRegisterType(const char *typeName) QByteArray name(typeName); QmlPrivate::MetaTypeIds ids = { qRegisterMetaType<T *>(QByteArray(name + '*').constData()), - qRegisterMetaType<QmlListProperty<T> >(QByteArray("QmlListProperty<" + name + ">").constData()), - qRegisterMetaType<QmlList<T *>*>(QByteArray("QmlList<" + name + "*>*").constData()) + qRegisterMetaType<T *>(QByteArray("QList<" + name + "*>*").constData()), + qRegisterMetaType<T *>(QByteArray("QmlList<" + name + "*>*").constData()) }; - return QmlMetaType::registerType(ids, 0, 0, 0, 0, 0, + return QmlMetaType::registerType(ids, QmlPrivate::list_nocreate_op<T>, 0, 0, 0, 0, &T::staticMetaObject, QmlPrivate::attachedPropertiesFunc<T>(), QmlPrivate::attachedPropertiesMetaObject<T>(), @@ -182,11 +181,11 @@ int qmlRegisterType(const char *uri, int version_maj, int version_min, const cha QByteArray name(typeName); QmlPrivate::MetaTypeIds ids = { qRegisterMetaType<T *>(QByteArray(name + '*').constData()), - qRegisterMetaType<QmlListProperty<T> >(QByteArray("QmlListProperty<" + name + ">").constData()), - qRegisterMetaType<QmlList<T *>*>(QByteArray("QmlList<" + name + "*>*").constData()) + qRegisterMetaType<T *>(QByteArray("QList<" + name + "*>*").constData()), + qRegisterMetaType<T *>(QByteArray("QmlList<" + name + "*>*").constData()) }; - return QmlMetaType::registerType(ids, QmlPrivate::create<T>, + return QmlMetaType::registerType(ids, QmlPrivate::list_op<T>, uri, version_maj, version_min, qmlName, &T::staticMetaObject, QmlPrivate::attachedPropertiesFunc<T>(), @@ -204,8 +203,8 @@ int qmlRegisterExtendedType(const char *typeName) QByteArray name(typeName); QmlPrivate::MetaTypeIds ids = { qRegisterMetaType<T *>(QByteArray(name + '*').constData()), - qRegisterMetaType<QmlListProperty<T> >(QByteArray("QmlListProperty<" + name + ">").constData()), - qRegisterMetaType<QmlList<T *>*>(QByteArray("QmlList<" + name + "*>*").constData()) + qRegisterMetaType<T *>(QByteArray("QList<" + name + "*>*").constData()), + qRegisterMetaType<T *>(QByteArray("QmlList<" + name + "*>*").constData()) }; QmlAttachedPropertiesFunc attached = @@ -217,7 +216,7 @@ int qmlRegisterExtendedType(const char *typeName) attachedMo = QmlPrivate::attachedPropertiesMetaObject<T>(); } - return QmlMetaType::registerType(ids, 0, 0, 0, 0, 0, + return QmlMetaType::registerType(ids, QmlPrivate::list_nocreate_op<T>, 0, 0, 0, 0, &T::staticMetaObject, attached, attachedMo, QmlPrivate::StaticCastSelector<T,QmlParserStatus>::cast(), QmlPrivate::StaticCastSelector<T,QObject>::cast(), @@ -232,8 +231,8 @@ int qmlRegisterExtendedType(const char *uri, int version_maj, int version_min, c QByteArray name(typeName); QmlPrivate::MetaTypeIds ids = { qRegisterMetaType<T *>(QByteArray(name + '*').constData()), - qRegisterMetaType<QmlListProperty<T> >(QByteArray("QmlListProperty<" + name + ">").constData()), - qRegisterMetaType<QmlList<T *>*>(QByteArray("QmlList<" + name + "*>*").constData()) + qRegisterMetaType<T *>(QByteArray("QList<" + name + "*>*").constData()), + qRegisterMetaType<T *>(QByteArray("QmlList<" + name + "*>*").constData()) }; QmlAttachedPropertiesFunc attached = @@ -245,7 +244,7 @@ int qmlRegisterExtendedType(const char *uri, int version_maj, int version_min, c attachedMo = QmlPrivate::attachedPropertiesMetaObject<T>(); } - return QmlMetaType::registerType(ids, QmlPrivate::create<T>, + return QmlMetaType::registerType(ids, QmlPrivate::list_op<T>, uri, version_maj, version_min, qmlName, &T::staticMetaObject, attached, attachedMo, @@ -263,11 +262,13 @@ int qmlRegisterInterface(const char *typeName) QByteArray name(typeName); QmlPrivate::MetaTypeIds ids = { qRegisterMetaType<T *>(QByteArray(name + '*').constData()), - qRegisterMetaType<QmlListProperty<T> >(QByteArray("QmlListProperty<" + name + ">").constData()), - qRegisterMetaType<QmlList<T *>*>(QByteArray("QmlList<" + name + "*>*").constData()) + qRegisterMetaType<T *>(QByteArray("QList<" + name + "*>*").constData()), + qRegisterMetaType<T *>(QByteArray("QmlList<" + name + "*>*").constData()) }; - return QmlMetaType::registerInterface(ids, qobject_interface_iid<T *>()); + return QmlMetaType::registerInterface(ids, + QmlPrivate::list_interface_op<T>, + qobject_interface_iid<T *>()); } template<typename T> @@ -276,11 +277,11 @@ int qmlRegisterCustomType(const char *uri, int version_maj, int version_min, con QByteArray name(typeName); QmlPrivate::MetaTypeIds ids = { qRegisterMetaType<T *>(QByteArray(name + '*').constData()), - qRegisterMetaType<QmlListProperty<T> >(QByteArray("QmlListProperty<" + name + ">").constData()), - qRegisterMetaType<QmlList<T *>*>(QByteArray("QmlList<" + name + "*>*").constData()) + qRegisterMetaType<T *>(QByteArray("QList<" + name + "*>*").constData()), + qRegisterMetaType<T *>(QByteArray("QmlList<" + name + "*>*").constData()) }; - return QmlMetaType::registerType(ids, QmlPrivate::create<T>, + return QmlMetaType::registerType(ids, QmlPrivate::list_op<T>, uri, version_maj, version_min, qmlName, &T::staticMetaObject, QmlPrivate::attachedPropertiesFunc<T>(), diff --git a/src/declarative/qml/qmlobjectscriptclass.cpp b/src/declarative/qml/qmlobjectscriptclass.cpp index 75b5c08..1c41d46 100644 --- a/src/declarative/qml/qmlobjectscriptclass.cpp +++ b/src/declarative/qml/qmlobjectscriptclass.cpp @@ -239,7 +239,7 @@ QmlObjectScriptClass::property(QObject *obj, const Identifier &name) } if (lastData->flags & QmlPropertyCache::Data::IsQList) { - return Value(scriptEngine, enginePriv->listClass->newList(obj, lastData->coreIndex, QmlListScriptClass::ListProperty, lastData->propType)); + return Value(scriptEngine, enginePriv->listClass->newList(obj, lastData->coreIndex, QmlListScriptClass::QListPtr, lastData->propType)); } else if (lastData->flags & QmlPropertyCache::Data::IsQmlList) { return Value(scriptEngine, enginePriv->listClass->newList(obj, lastData->coreIndex, QmlListScriptClass::QmlListPtr, lastData->propType)); } else if (lastData->flags & QmlPropertyCache::Data::IsQObjectDerived) { diff --git a/src/declarative/qml/qmlprivate.h b/src/declarative/qml/qmlprivate.h index c367497..dd98110 100644 --- a/src/declarative/qml/qmlprivate.h +++ b/src/declarative/qml/qmlprivate.h @@ -85,8 +85,26 @@ namespace QmlPrivate virtual void clear() = 0; }; + enum ListOp { Append, Set, Insert, Prepend, Length, FromObject, + Object, Create, Value, Clear }; + + template<typename T> + int list_op(ListOp op, int val, + const QVariant &vlist, + const QVariant &value, + void **out); + template<typename T> - QObject *create() { return new T; } + int list_nocreate_op(ListOp op, int val, + const QVariant &vlist, + const QVariant &value, + void **out); + + template<typename T> + int list_interface_op(ListOp op, int val, + const QVariant &vlist, + const QVariant &value, + void **out); template<class From, class To, int N> struct StaticCastSelectorClass @@ -185,6 +203,7 @@ namespace QmlPrivate int listId; int qmlListId; }; + typedef int (*Func)(QmlPrivate::ListOp, int, const QVariant &, const QVariant &, void **); typedef QObject *(*CreateFunc)(QObject *); template<typename T> @@ -218,6 +237,148 @@ namespace QmlPrivate }; } +template<typename T> +int QmlPrivate::list_op(QmlPrivate::ListOp op, int val, + const QVariant &vlist, + const QVariant &value, + void **out) +{ + if (op == QmlPrivate::Create) { + QObject *obj = static_cast<QObject *>(new T); + *((QObject **)out) = obj; + return 0; + } + QList<T *> *list = vlist.value<QList<T *> *>(); + switch(op) { + case QmlPrivate::Append: + list->append(value.value<T *>()); + break; + case QmlPrivate::Set: + (*list)[val] = value.value<T *>(); + break; + case QmlPrivate::Insert: + list->insert(val, value.value<T *>()); + break; + case QmlPrivate::Prepend: + list->prepend(value.value<T *>()); + break; + case QmlPrivate::Length: + return list->count(); + break; + case QmlPrivate::Clear: + list->clear(); + return 0; + break; + case QmlPrivate::Create: + break; + case QmlPrivate::Object: + *out = static_cast<QObject *>(value.value<T *>()); + break; + case QmlPrivate::FromObject: + { + QObject *fromObj = value.value<QObject *>(); + T *me = qobject_cast<T *>(fromObj); + if (me) { + *((QVariant *)*out) = QVariant::fromValue(me); + } + } + break; + case QmlPrivate::Value: + if (list->count() <= val) *((QVariant *)*out) = QVariant(); + else *((QVariant *)*out) = QVariant::fromValue(list->at(val)); + break; + } + return 0; +} + +template<typename T> +int QmlPrivate::list_nocreate_op(QmlPrivate::ListOp op, int val, + const QVariant &vlist, + const QVariant &value, + void **out) +{ + QList<T *> *list = vlist.value<QList<T *> *>(); + switch(op) { + case QmlPrivate::Append: + list->append(value.value<T *>()); + break; + case QmlPrivate::Set: + (*list)[val] = value.value<T *>(); + break; + case QmlPrivate::Insert: + list->insert(val, value.value<T *>()); + break; + case QmlPrivate::Prepend: + list->prepend(value.value<T *>()); + break; + case QmlPrivate::Length: + return list->count(); + break; + case QmlPrivate::Clear: + list->clear(); + return 0; + break; + case QmlPrivate::Create: + break; + case QmlPrivate::Object: + *out = static_cast<QObject *>(value.value<T *>()); + break; + case QmlPrivate::FromObject: + { + QObject *fromObj = value.value<QObject *>(); + T *me = qobject_cast<T *>(fromObj); + if (me) { + *((QVariant *)*out) = QVariant::fromValue(me); + } + } + break; + case QmlPrivate::Value: + *((QVariant *)*out) = QVariant::fromValue(list->at(val)); + break; + } + return 0; +} + +template<typename T> +int QmlPrivate::list_interface_op(QmlPrivate::ListOp op, int val, + const QVariant &vlist, + const QVariant &value, + void **out) +{ + QList<T *> *list = vlist.value<QList<T *> *>(); + switch(op) { + case QmlPrivate::Append: + list->append(value.value<T *>()); + break; + case QmlPrivate::Set: + (*list)[val] = value.value<T *>(); + break; + case QmlPrivate::Insert: + list->insert(val, value.value<T *>()); + break; + case QmlPrivate::Prepend: + list->prepend(value.value<T *>()); + break; + case QmlPrivate::Length: + return list->count(); + break; + case QmlPrivate::Clear: + list->clear(); + return 0; + break; + case QmlPrivate::Create: + break; + case QmlPrivate::Object: + break; + case QmlPrivate::FromObject: + break; + case QmlPrivate::Value: + *((QVariant *)*out) = QVariant::fromValue(list->at(val)); + break; + } + return 0; +} + QT_END_NAMESPACE QT_END_HEADER diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp index 4ab205e..e9a0449 100644 --- a/src/declarative/qml/qmlvme.cpp +++ b/src/declarative/qml/qmlvme.cpp @@ -91,15 +91,14 @@ QmlVME::QmlVME() struct ListInstance { - ListInstance() - : type(0), qmlListInterface(0) {} - ListInstance(int t) - : type(t), qmlListInterface(0) {} + ListInstance() {} + ListInstance(QList<void *> *q, int t) + : type(t), qListInterface(q), qmlListInterface(0) {} ListInstance(QmlPrivate::ListInterface *q, int t) - : type(t), qmlListInterface(q) {} + : type(t), qListInterface(0), qmlListInterface(q) {} int type; - QmlListProperty<void> qListProperty; + QList<void *> *qListInterface; QmlPrivate::ListInterface *qmlListInterface; }; @@ -670,7 +669,7 @@ QObject *QmlVME::run(QmlVMEStack<QObject *> &stack, QmlContext *ctxt, QObject *assign = stack.pop(); const ListInstance &list = qliststack.top(); - list.qListProperty.append((QmlListProperty<void>*)&list.qListProperty, assign); + list.qListInterface->append((void *)assign); } break; @@ -695,7 +694,7 @@ QObject *QmlVME::run(QmlVMEStack<QObject *> &stack, QmlContext *ctxt, void *d = (void *)&ptr; list.qmlListInterface->append(d); } else { - list.qListProperty.append((QmlListProperty<void>*)&list.qListProperty, ptr); + list.qListInterface->append(ptr); } } break; @@ -773,12 +772,17 @@ QObject *QmlVME::run(QmlVMEStack<QObject *> &stack, QmlContext *ctxt, { QObject *target = stack.top(); - qliststack.push(ListInstance(instr.fetchQmlList.type)); - void *a[1]; - a[0] = (void *)&(qliststack.top().qListProperty); + // We know that QList<T *>* can be converted to + // QList<void *>* + QList<void *> *list = 0; + a[0] = &list; QMetaObject::metacall(target, QMetaObject::ReadProperty, instr.fetchQmlList.property, a); + if (!list) + VME_EXCEPTION(QCoreApplication::translate("QmlVME","Cannot assign to null list")); + + qliststack.push(ListInstance(list, instr.fetchQmlList.type)); } break; |