summaryrefslogtreecommitdiffstats
path: root/src/declarative/qml
diff options
context:
space:
mode:
authorRoberto Raggi <roberto.raggi@nokia.com>2010-02-22 11:26:08 (GMT)
committerRoberto Raggi <roberto.raggi@nokia.com>2010-02-22 11:26:08 (GMT)
commit97930918c8f5d20c6a27c22a1f0670ac7576c17a (patch)
tree688f93eacf376df07679f06203834e44143103fa /src/declarative/qml
parent80fc5bf17e5f049a395d6a5612843c69c5b0fde1 (diff)
parent66818ea9bc50af50bb26515cf667fe1c0c62a12d (diff)
downloadQt-97930918c8f5d20c6a27c22a1f0670ac7576c17a.zip
Qt-97930918c8f5d20c6a27c22a1f0670ac7576c17a.tar.gz
Qt-97930918c8f5d20c6a27c22a1f0670ac7576c17a.tar.bz2
Merge remote branch 'origin/master' into qtruntime
Conflicts: src/declarative/qml/qml.pri src/declarative/qml/qmlengine.cpp src/declarative/util/qmlview.h
Diffstat (limited to 'src/declarative/qml')
-rw-r--r--src/declarative/qml/qml.h6
-rw-r--r--src/declarative/qml/qml.pri4
-rw-r--r--src/declarative/qml/qmlbinding.cpp2
-rw-r--r--src/declarative/qml/qmlcompiler.cpp103
-rw-r--r--src/declarative/qml/qmlcontext.cpp25
-rw-r--r--src/declarative/qml/qmlcontext.h4
-rw-r--r--src/declarative/qml/qmlcontext_p.h3
-rw-r--r--src/declarative/qml/qmlcontextscriptclass.cpp9
-rw-r--r--src/declarative/qml/qmldom.cpp1
-rw-r--r--src/declarative/qml/qmlengine.cpp38
-rw-r--r--src/declarative/qml/qmlengine_p.h6
-rw-r--r--src/declarative/qml/qmlenginedebug.cpp10
-rw-r--r--src/declarative/qml/qmlexpression.cpp2
-rw-r--r--src/declarative/qml/qmlinstruction.cpp6
-rw-r--r--src/declarative/qml/qmlinstruction_p.h2
-rw-r--r--src/declarative/qml/qmllist.cpp312
-rw-r--r--src/declarative/qml/qmllist.h140
-rw-r--r--src/declarative/qml/qmllist_p.h85
-rw-r--r--src/declarative/qml/qmllistscriptclass.cpp72
-rw-r--r--src/declarative/qml/qmllistscriptclass_p.h5
-rw-r--r--src/declarative/qml/qmlmetaproperty.cpp92
-rw-r--r--src/declarative/qml/qmlmetaproperty.h1
-rw-r--r--src/declarative/qml/qmlmetatype.cpp181
-rw-r--r--src/declarative/qml/qmlmetatype.h56
-rw-r--r--src/declarative/qml/qmlobjectscriptclass.cpp4
-rw-r--r--src/declarative/qml/qmlprivate.h177
-rw-r--r--src/declarative/qml/qmlpropertycache.cpp2
-rw-r--r--src/declarative/qml/qmlpropertycache_p.h1
-rw-r--r--src/declarative/qml/qmlscript.cpp2
-rw-r--r--src/declarative/qml/qmlvme.cpp60
-rw-r--r--src/declarative/qml/qmlvmemetaobject.cpp36
-rw-r--r--src/declarative/qml/qmlvmemetaobject_p.h31
32 files changed, 731 insertions, 747 deletions
diff --git a/src/declarative/qml/qml.h b/src/declarative/qml/qml.h
index e5e7c59..7972305 100644
--- a/src/declarative/qml/qml.h
+++ b/src/declarative/qml/qml.h
@@ -59,12 +59,10 @@ QT_MODULE(Declarative)
#define QML_DECLARE_TYPE(TYPE) \
Q_DECLARE_METATYPE(TYPE *) \
- Q_DECLARE_METATYPE(QList<TYPE *> *) \
- Q_DECLARE_METATYPE(QmlList<TYPE *> *)
+ Q_DECLARE_METATYPE(QmlListProperty<TYPE>)
#define QML_DECLARE_TYPE_HASMETATYPE(TYPE) \
- Q_DECLARE_METATYPE(QList<TYPE *> *) \
- Q_DECLARE_METATYPE(QmlList<TYPE *> *)
+ Q_DECLARE_METATYPE(QmlListProperty<TYPE>)
#define QML_DECLARE_INTERFACE(INTERFACE) \
QML_DECLARE_TYPE(INTERFACE)
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index 6c74863..daee431 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -53,7 +53,8 @@ SOURCES += \
$$PWD/qmlimageprovider.cpp \
$$PWD/qmlnetworkaccessmanagerfactory.cpp \
$$PWD/qmldirparser.cpp \
- $$PWD/qmlextensionplugin.cpp
+ $$PWD/qmlextensionplugin.cpp \
+ $$PWD/qmllist.cpp
HEADERS += \
$$PWD/qmlparser_p.h \
@@ -94,6 +95,7 @@ HEADERS += \
$$PWD/qmlcompositetypedata_p.h \
$$PWD/qmlcompositetypemanager_p.h \
$$PWD/qmllist.h \
+ $$PWD/qmllist_p.h \
$$PWD/qmldeclarativedata_p.h \
$$PWD/qmlerror.h \
$$PWD/qmlscriptparser_p.h \
diff --git a/src/declarative/qml/qmlbinding.cpp b/src/declarative/qml/qmlbinding.cpp
index 0dbe63b..feadd0f 100644
--- a/src/declarative/qml/qmlbinding.cpp
+++ b/src/declarative/qml/qmlbinding.cpp
@@ -54,8 +54,6 @@
#include <QVariant>
#include <QtCore/qdebug.h>
-Q_DECLARE_METATYPE(QList<QObject *>);
-
QT_BEGIN_NAMESPACE
QML_DEFINE_NOCREATE_TYPE(QmlBinding);
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index 2b1081e..bbae201 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -1495,8 +1495,7 @@ bool QmlCompiler::buildProperty(QmlParser::Property *prop,
COMPILE_CHECK(buildGroupedProperty(prop, obj, ctxt));
- } else if (QmlEnginePrivate::get(engine)->isQmlList(prop->type) ||
- QmlMetaType::isList(prop->type)) {
+ } else if (QmlEnginePrivate::get(engine)->isList(prop->type)) {
COMPILE_CHECK(buildListProperty(prop, obj, ctxt));
@@ -1552,8 +1551,7 @@ QmlCompiler::buildPropertyInNamespace(QmlEnginePrivate::ImportedNamespace *ns,
void QmlCompiler::genValueProperty(QmlParser::Property *prop,
QmlParser::Object *obj)
{
- if (QmlEnginePrivate::get(engine)->isQmlList(prop->type) ||
- QmlMetaType::isList(prop->type)) {
+ if (QmlEnginePrivate::get(engine)->isList(prop->type)) {
genListProperty(prop, obj);
} else {
genPropertyAssignment(prop, obj);
@@ -1563,22 +1561,10 @@ void QmlCompiler::genValueProperty(QmlParser::Property *prop,
void QmlCompiler::genListProperty(QmlParser::Property *prop,
QmlParser::Object *obj)
{
- QmlInstruction::Type fetchType;
- QmlInstruction::Type storeType;
- int listType;
-
- if (QmlEnginePrivate::get(engine)->isQmlList(prop->type)) {
- fetchType = QmlInstruction::FetchQmlList;
- storeType = QmlInstruction::StoreObjectQmlList;
- listType = QmlEnginePrivate::get(engine)->qmlListType(prop->type);
- } else {
- fetchType = QmlInstruction::FetchQList;
- storeType = QmlInstruction::StoreObjectQList;
- listType = QmlMetaType::listType(prop->type);
- }
+ int listType = QmlEnginePrivate::get(engine)->listType(prop->type);
QmlInstruction fetch;
- fetch.type = fetchType;
+ fetch.type = QmlInstruction::FetchQList;
fetch.line = prop->location.start.line;
fetch.fetchQmlList.property = prop->index;
bool listTypeIsInterface = QmlMetaType::isInterface(listType);
@@ -1598,7 +1584,7 @@ void QmlCompiler::genListProperty(QmlParser::Property *prop,
output->bytecode << assign;
} else {
QmlInstruction store;
- store.type = storeType;
+ store.type = QmlInstruction::StoreObjectQList;
store.line = prop->location.start.line;
output->bytecode << store;
}
@@ -1895,67 +1881,40 @@ bool QmlCompiler::buildListProperty(QmlParser::Property *prop,
QmlParser::Object *obj,
const BindingContext &ctxt)
{
- Q_ASSERT(QmlMetaType::isList(prop->type) ||
- QmlEnginePrivate::get(engine)->isQmlList(prop->type));
+ Q_ASSERT(QmlEnginePrivate::get(engine)->isList(prop->type));
int t = prop->type;
obj->addValueProperty(prop);
- if (QmlEnginePrivate::get(engine)->isQmlList(t)) {
- int listType = QmlEnginePrivate::get(engine)->qmlListType(t);
- bool listTypeIsInterface = QmlMetaType::isInterface(listType);
-
- for (int ii = 0; ii < prop->values.count(); ++ii) {
- Value *v = prop->values.at(ii);
- if (v->object) {
- v->type = Value::CreatedObject;
- COMPILE_CHECK(buildObject(v->object, ctxt));
-
- // We check object coercian here. We check interface assignment
- // at runtime.
- if (!listTypeIsInterface) {
- if (!canCoerce(listType, v->object)) {
- COMPILE_EXCEPTION(v, QCoreApplication::translate("QmlCompiler","Cannot assign object to list"));
- }
- }
+ int listType = QmlEnginePrivate::get(engine)->listType(t);
+ bool listTypeIsInterface = QmlMetaType::isInterface(listType);
- } else {
- COMPILE_EXCEPTION(v, QCoreApplication::translate("QmlCompiler","Cannot assign primitives to lists"));
- }
- }
+ bool assignedBinding = false;
+ for (int ii = 0; ii < prop->values.count(); ++ii) {
+ Value *v = prop->values.at(ii);
+ if (v->object) {
+ v->type = Value::CreatedObject;
+ COMPILE_CHECK(buildObject(v->object, ctxt));
- } else {
- int listType = QmlMetaType::listType(t);
- bool listTypeIsInterface = QmlMetaType::isInterface(listType);
-
- bool assignedBinding = false;
- for (int ii = 0; ii < prop->values.count(); ++ii) {
- Value *v = prop->values.at(ii);
- if (v->object) {
- v->type = Value::CreatedObject;
- COMPILE_CHECK(buildObject(v->object, ctxt));
-
- // We check object coercian here. We check interface assignment
- // at runtime.
- if (!listTypeIsInterface) {
- if (!canCoerce(listType, v->object)) {
- COMPILE_EXCEPTION(v, QCoreApplication::translate("QmlCompiler","Cannot assign object to list"));
- }
+ // We check object coercian here. We check interface assignment
+ // at runtime.
+ if (!listTypeIsInterface) {
+ if (!canCoerce(listType, v->object)) {
+ COMPILE_EXCEPTION(v, QCoreApplication::translate("QmlCompiler","Cannot assign object to list"));
}
+ }
- } else if (v->value.isScript()) {
- if (assignedBinding)
- COMPILE_EXCEPTION(v, QCoreApplication::translate("QmlCompiler","Can only assign one binding to lists"));
+ } else if (v->value.isScript()) {
+ if (assignedBinding)
+ COMPILE_EXCEPTION(v, QCoreApplication::translate("QmlCompiler","Can only assign one binding to lists"));
- assignedBinding = true;
- COMPILE_CHECK(buildBinding(v, prop, ctxt));
- v->type = Value::PropertyBinding;
- } else {
- COMPILE_EXCEPTION(v, QCoreApplication::translate("QmlCompiler","Cannot assign primitives to lists"));
- }
+ assignedBinding = true;
+ COMPILE_CHECK(buildBinding(v, prop, ctxt));
+ v->type = Value::PropertyBinding;
+ } else {
+ COMPILE_EXCEPTION(v, QCoreApplication::translate("QmlCompiler","Cannot assign primitives to lists"));
}
-
}
return true;
@@ -2335,10 +2294,10 @@ bool QmlCompiler::buildDynamicMeta(QmlParser::Object *obj, DynamicMetaMode mode)
propertyType = QMetaType::QObjectStar;
} else {
readonly = true;
- type = "QmlList<";
+ type = "QmlListProperty<";
type.append(customTypeName);
- type.append("*>*");
- propertyType = qMetaTypeId<QmlList<QObject*>* >();
+ type.append(">");
+ propertyType = qMetaTypeId<QmlListProperty<QObject> >();
}
}
break;
diff --git a/src/declarative/qml/qmlcontext.cpp b/src/declarative/qml/qmlcontext.cpp
index 303af42..56038cf 100644
--- a/src/declarative/qml/qmlcontext.cpp
+++ b/src/declarative/qml/qmlcontext.cpp
@@ -544,5 +544,30 @@ QUrl QmlContext::baseUrl() const
return QUrl();
}
+int QmlContextPrivate::context_count(QmlListProperty<QObject> *prop)
+{
+ QmlContext *context = static_cast<QmlContext*>(prop->object);
+ QmlContextPrivate *d = QmlContextPrivate::get(context);
+ int contextProperty = (int)(intptr_t)prop->data;
+
+ if (d->propertyValues.at(contextProperty).userType() != qMetaTypeId<QList<QObject*> >()) {
+ return 0;
+ } else {
+ return ((const QList<QObject> *)d->propertyValues.at(contextProperty).constData())->count();
+ }
+}
+
+QObject *QmlContextPrivate::context_at(QmlListProperty<QObject> *prop, int index)
+{
+ QmlContext *context = static_cast<QmlContext*>(prop->object);
+ QmlContextPrivate *d = QmlContextPrivate::get(context);
+ int contextProperty = (int)(intptr_t)prop->data;
+
+ if (d->propertyValues.at(contextProperty).userType() != qMetaTypeId<QList<QObject*> >()) {
+ return 0;
+ } else {
+ return ((const QList<QObject*> *)d->propertyValues.at(contextProperty).constData())->at(index);
+ }
+}
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlcontext.h b/src/declarative/qml/qmlcontext.h
index 21b1a1e..e96ed84 100644
--- a/src/declarative/qml/qmlcontext.h
+++ b/src/declarative/qml/qmlcontext.h
@@ -45,6 +45,7 @@
#include <QtCore/qurl.h>
#include <QtCore/qobject.h>
#include <QtScript/qscriptvalue.h>
+#include <QtCore/qmetatype.h>
QT_BEGIN_HEADER
@@ -97,9 +98,10 @@ private:
QmlContext(QmlContext *parent, QObject *objParent, bool);
QmlContext(QmlEngine *, bool);
};
-
QT_END_NAMESPACE
+Q_DECLARE_METATYPE(QList<QObject*>);
+
QT_END_HEADER
#endif // QMLCONTEXT_H
diff --git a/src/declarative/qml/qmlcontext_p.h b/src/declarative/qml/qmlcontext_p.h
index bd4f5d5..965eeed 100644
--- a/src/declarative/qml/qmlcontext_p.h
+++ b/src/declarative/qml/qmlcontext_p.h
@@ -152,6 +152,9 @@ public:
// Only used for debugging
QList<QPointer<QObject> > instances;
+
+ static int context_count(QmlListProperty<QObject> *);
+ static QObject *context_at(QmlListProperty<QObject> *, int);
};
QmlContextPrivate::IdNotifier::IdNotifier()
diff --git a/src/declarative/qml/qmlcontextscriptclass.cpp b/src/declarative/qml/qmlcontextscriptclass.cpp
index be3bbc3..4c71903 100644
--- a/src/declarative/qml/qmlcontextscriptclass.cpp
+++ b/src/declarative/qml/qmlcontextscriptclass.cpp
@@ -44,6 +44,7 @@
#include "qmlengine_p.h"
#include "qmlcontext_p.h"
#include "qmltypenamescriptclass_p.h"
+#include "qmllistscriptclass_p.h"
#include "qmlguard_p.h"
QT_BEGIN_NAMESPACE
@@ -227,8 +228,12 @@ QmlContextScriptClass::property(Object *object, const Identifier &name)
if (lastPropertyIndex < cp->idValueCount) {
rv = ep->objectClass->newQObject(cp->idValues[lastPropertyIndex].data());
} else {
- QVariant value = cp->propertyValues.at(lastPropertyIndex);
- rv = ep->scriptValueFromVariant(value);
+ const QVariant &value = cp->propertyValues.at(lastPropertyIndex);
+ if (value.userType() == qMetaTypeId<QList<QObject*> >()) {
+ rv = ep->listClass->newList(QmlListProperty<QObject>(bindContext, (void*)lastPropertyIndex, 0, QmlContextPrivate::context_count, QmlContextPrivate::context_at), qMetaTypeId<QmlListProperty<QObject> >());
+ } else {
+ rv = ep->scriptValueFromVariant(value);
+ }
}
ep->capturedProperties <<
diff --git a/src/declarative/qml/qmldom.cpp b/src/declarative/qml/qmldom.cpp
index 01061ee..c75a299 100644
--- a/src/declarative/qml/qmldom.cpp
+++ b/src/declarative/qml/qmldom.cpp
@@ -1346,7 +1346,6 @@ QmlDomValue::Type QmlDomValue::type() const
{
if (d->property)
if (QmlMetaType::isList(d->property->type) ||
- QmlMetaType::isQmlList(d->property->type) ||
(d->property && d->property->values.count() > 1))
return List;
diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp
index 1f5caa5..ce2a693 100644
--- a/src/declarative/qml/qmlengine.cpp
+++ b/src/declarative/qml/qmlengine.cpp
@@ -68,6 +68,8 @@
#include "qmlimageprovider.h"
#include "qmldirparser_p.h"
#include "qmlextensioninterface.h"
+#include "qmllist_p.h"
+
#include <qfxperf_p_p.h>
#include <QtCore/qmetaobject.h>
@@ -109,7 +111,6 @@
#endif
Q_DECLARE_METATYPE(QmlMetaProperty)
-Q_DECLARE_METATYPE(QList<QObject *>);
QT_BEGIN_NAMESPACE
@@ -1172,6 +1173,15 @@ QScriptValue QmlEnginePrivate::tint(QScriptContext *ctxt, QScriptEngine *engine)
QScriptValue QmlEnginePrivate::scriptValueFromVariant(const QVariant &val)
{
+ if (val.userType() == qMetaTypeId<QmlListReference>()) {
+ QmlListReferencePrivate *p = QmlListReferencePrivate::get((QmlListReference*)val.constData());
+ if (p->object) {
+ return listClass->newList(p->property, p->propertyType);
+ } else {
+ return scriptEngine.nullValue();
+ }
+ }
+
bool objOk;
QObject *obj = QmlMetaType::toQObject(val, &objOk);
if (objOk) {
@@ -1673,7 +1683,7 @@ void QmlEnginePrivate::registerCompositeType(QmlCompiledData *data)
QByteArray name = data->root->className();
QByteArray ptr = name + '*';
- QByteArray lst = "QmlList<" + ptr + ">*";
+ QByteArray lst = "QmlListProperty<" + name + ">";
int ptr_type = QMetaType::registerType(ptr.constData(), voidptr_destructor,
voidptr_constructor);
@@ -1685,9 +1695,18 @@ void QmlEnginePrivate::registerCompositeType(QmlCompiledData *data)
data->addref();
}
-bool QmlEnginePrivate::isQmlList(int t) const
+bool QmlEnginePrivate::isList(int t) const
{
- return m_qmlLists.contains(t) || QmlMetaType::isQmlList(t);
+ return m_qmlLists.contains(t) || QmlMetaType::isList(t);
+}
+
+int QmlEnginePrivate::listType(int t) const
+{
+ QHash<int, int>::ConstIterator iter = m_qmlLists.find(t);
+ if (iter != m_qmlLists.end())
+ return *iter;
+ else
+ return QmlMetaType::listType(t);
}
bool QmlEnginePrivate::isQObject(int t)
@@ -1706,21 +1725,12 @@ QObject *QmlEnginePrivate::toQObject(const QVariant &v, bool *ok) const
}
}
-int QmlEnginePrivate::qmlListType(int t) const
-{
- QHash<int, int>::ConstIterator iter = m_qmlLists.find(t);
- if (iter != m_qmlLists.end())
- return *iter;
- else
- return QmlMetaType::qmlListType(t);
-}
-
QmlMetaType::TypeCategory QmlEnginePrivate::typeCategory(int t) const
{
if (m_compositeTypes.contains(t))
return QmlMetaType::Object;
else if (m_qmlLists.contains(t))
- return QmlMetaType::QmlList;
+ return QmlMetaType::List;
else
return QmlMetaType::typeCategory(t);
}
diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h
index 7ec6dd6..3fe7991 100644
--- a/src/declarative/qml/qmlengine_p.h
+++ b/src/declarative/qml/qmlengine_p.h
@@ -274,11 +274,12 @@ public:
void registerCompositeType(QmlCompiledData *);
- bool isQmlList(int) const;
+
bool isQObject(int);
QObject *toQObject(const QVariant &, bool *ok = 0) const;
- int qmlListType(int) const;
QmlMetaType::TypeCategory typeCategory(int) const;
+ bool isList(int) const;
+ int listType(int) const;
const QMetaObject *rawMetaObjectForType(int) const;
const QMetaObject *metaObjectForType(int) const;
QHash<int, int> m_qmlLists;
@@ -322,7 +323,6 @@ public:
QmlContext *getContext(QScriptContext *);
};
-
QT_END_NAMESPACE
#endif // QMLENGINE_P_H
diff --git a/src/declarative/qml/qmlenginedebug.cpp b/src/declarative/qml/qmlenginedebug.cpp
index d3caa95..654157c 100644
--- a/src/declarative/qml/qmlenginedebug.cpp
+++ b/src/declarative/qml/qmlenginedebug.cpp
@@ -119,8 +119,7 @@ QmlEngineDebugServer::propertyData(QObject *obj, int propIdx)
rv.type = QmlObjectProperty::Basic;
} else if (QmlMetaType::isQObject(prop.userType())) {
rv.type = QmlObjectProperty::Object;
- } else if (QmlMetaType::isList(prop.userType()) ||
- QmlMetaType::isQmlList(prop.userType())) {
+ } else if (QmlMetaType::isList(prop.userType())) {
rv.type = QmlObjectProperty::List;
}
@@ -133,14 +132,15 @@ QVariant QmlEngineDebugServer::valueContents(const QVariant &value) const
if (QVariant::Type(userType) < QVariant::UserType)
return value;
-
- if (QmlMetaType::isList(userType) || QmlMetaType::isQmlList(userType)) {
+ /*
+ if (QmlMetaType::isList(userType)) {
int count = QmlMetaType::listCount(value);
QVariantList contents;
for (int i=0; i<count; i++)
contents << valueContents(QmlMetaType::listAt(value, i));
return contents;
- } else if (QmlMetaType::isQObject(userType)) {
+ } else */
+ if (QmlMetaType::isQObject(userType)) {
QObject *o = QmlMetaType::toQObject(value);
if (o) {
QString name = o->objectName();
diff --git a/src/declarative/qml/qmlexpression.cpp b/src/declarative/qml/qmlexpression.cpp
index d428377..8f0c945 100644
--- a/src/declarative/qml/qmlexpression.cpp
+++ b/src/declarative/qml/qmlexpression.cpp
@@ -52,8 +52,6 @@
#include <private/qscriptdeclarativeclass_p.h>
-Q_DECLARE_METATYPE(QList<QObject *>);
-
QT_BEGIN_NAMESPACE
bool QmlDelayedError::addError(QmlEnginePrivate *e)
diff --git a/src/declarative/qml/qmlinstruction.cpp b/src/declarative/qml/qmlinstruction.cpp
index de01bfe..e37ade7 100644
--- a/src/declarative/qml/qmlinstruction.cpp
+++ b/src/declarative/qml/qmlinstruction.cpp
@@ -171,9 +171,6 @@ void QmlCompiledData::dump(QmlInstruction *instr, int idx)
case QmlInstruction::BeginObject:
qWarning().nospace() << idx << "\t\t" << line << "\t" << "BEGIN\t\t\t" << instr->begin.castValue;
break;
- case QmlInstruction::StoreObjectQmlList:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_OBJECT_QMLLIST";
- break;
case QmlInstruction::StoreObjectQList:
qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_OBJECT_QLIST";
break;
@@ -183,9 +180,6 @@ void QmlCompiledData::dump(QmlInstruction *instr, int idx)
case QmlInstruction::FetchAttached:
qWarning().nospace() << idx << "\t\t" << line << "\t" << "FETCH_ATTACHED\t\t" << instr->fetchAttached.id;
break;
- case QmlInstruction::FetchQmlList:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "FETCH_QMLLIST\t\t" << instr->fetchQmlList.property << "\t" << instr->fetchQmlList.type;
- break;
case QmlInstruction::FetchQList:
qWarning().nospace() << idx << "\t\t" << line << "\t" << "FETCH_QLIST\t\t" << instr->fetch.property;
break;
diff --git a/src/declarative/qml/qmlinstruction_p.h b/src/declarative/qml/qmlinstruction_p.h
index 5613888..ea785b6 100644
--- a/src/declarative/qml/qmlinstruction_p.h
+++ b/src/declarative/qml/qmlinstruction_p.h
@@ -134,12 +134,10 @@ public:
BeginObject, /* begin */
- StoreObjectQmlList, /* NA */
StoreObjectQList, /* NA */
AssignObjectList, /* NA */
FetchAttached, /* fetchAttached */
- FetchQmlList, /* fetchQmlList */
FetchQList, /* fetch */
FetchObject, /* fetch */
FetchValueType, /* fetchValue */
diff --git a/src/declarative/qml/qmllist.cpp b/src/declarative/qml/qmllist.cpp
new file mode 100644
index 0000000..4cd2120
--- /dev/null
+++ b/src/declarative/qml/qmllist.cpp
@@ -0,0 +1,312 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmllist.h"
+#include "qmllist_p.h"
+#include "qmlengine_p.h"
+#include "qmlmetaproperty_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QmlListReferencePrivate::QmlListReferencePrivate()
+: propertyType(-1), refCount(1)
+{
+}
+
+QmlListReference QmlListReferencePrivate::init(const QmlListProperty<QObject> &prop, int propType, QmlEngine *engine)
+{
+ QmlListReference rv;
+
+ if (!prop.object) return rv;
+
+ QmlEnginePrivate *p = engine?QmlEnginePrivate::get(engine):0;
+
+ int listType = p?p->listType(propType):QmlMetaType::listType(propType);
+ if (listType == -1) return rv;
+
+ rv.d = new QmlListReferencePrivate;
+ rv.d->object = prop.object;
+ rv.d->elementType = p?p->rawMetaObjectForType(listType):QmlMetaType::qmlType(listType)->baseMetaObject();
+ rv.d->property = prop;
+ rv.d->propertyType = propType;
+
+ return rv;
+}
+
+void QmlListReferencePrivate::addref()
+{
+ Q_ASSERT(refCount > 0);
+ ++refCount;
+}
+
+void QmlListReferencePrivate::release()
+{
+ Q_ASSERT(refCount > 0);
+ --refCount;
+ if (!refCount)
+ delete this;
+}
+
+QmlListReference::QmlListReference()
+: d(0)
+{
+}
+
+QmlListReference::QmlListReference(QObject *o, const char *property, QmlEngine *engine)
+: d(0)
+{
+ if (!o || !property) return;
+
+ QmlPropertyCache::Data local;
+ QmlPropertyCache::Data *data = QmlPropertyCache::property(engine, o, QLatin1String(property), local);
+
+ if (!data || !(data->flags & QmlPropertyCache::Data::IsQList)) return;
+
+ QmlEnginePrivate *p = engine?QmlEnginePrivate::get(engine):0;
+
+ int listType = p?p->listType(data->propType):QmlMetaType::listType(data->propType);
+ if (listType == -1) return;
+
+ d = new QmlListReferencePrivate;
+ d->object = o;
+ d->elementType = p?p->rawMetaObjectForType(listType):QmlMetaType::qmlType(listType)->baseMetaObject();
+ d->propertyType = data->propType;
+
+ void *args[] = { &d->property, 0 };
+ QMetaObject::metacall(o, QMetaObject::ReadProperty, data->coreIndex, args);
+}
+
+QmlListReference::QmlListReference(const QmlListReference &o)
+: d(o.d)
+{
+ if (d) d->addref();
+}
+
+QmlListReference &QmlListReference::operator=(const QmlListReference &o)
+{
+ if (o.d) o.d->addref();
+ if (d) d->release();
+ d = o.d;
+ return *this;
+}
+
+QmlListReference::~QmlListReference()
+{
+ if (d) d->release();
+}
+
+bool QmlListReference::isValid() const
+{
+ return d && d->object;
+}
+
+QObject *QmlListReference::object() const
+{
+ if (isValid()) return d->object;
+ else return 0;
+}
+
+const QMetaObject *QmlListReference::listElementType() const
+{
+ if (isValid()) return d->elementType;
+ else return 0;
+}
+
+bool QmlListReference::canAppend() const
+{
+ return (isValid() && d->property.append);
+}
+
+bool QmlListReference::canAt() const
+{
+ return (isValid() && d->property.at);
+}
+
+bool QmlListReference::canClear() const
+{
+ return (isValid() && d->property.clear);
+}
+
+bool QmlListReference::canCount() const
+{
+ return (isValid() && d->property.count);
+}
+
+bool QmlListReference::append(QObject *o) const
+{
+ if (!canAppend()) return false;
+
+ if (o && !QmlMetaPropertyPrivate::canConvert(o->metaObject(), d->elementType))
+ return false;
+
+ d->property.append(&d->property, o);
+
+ return true;
+}
+
+QObject *QmlListReference::at(int index) const
+{
+ if (!canAt()) return 0;
+
+ return d->property.at(&d->property, index);
+}
+
+bool QmlListReference::clear() const
+{
+ if (!canClear()) return false;
+
+ d->property.clear(&d->property);
+
+ return true;
+}
+
+int QmlListReference::count() const
+{
+ if (!canCount()) return 0;
+
+ return d->property.count(&d->property);
+}
+
+/*!
+\class QmlListProperty
+\brief The QmlListProperty class allows applications to explose list-like
+properties to QML.
+
+QML has many list properties, where more than one object value can be assigned.
+The use of a list property from QML looks like this:
+
+\code
+FruitBasket {
+ fruit: [
+ Apple {},
+ Orange{},
+ Banana {}
+ ]
+}
+\endcode
+
+The QmlListProperty encapsulates a group of function pointers that represet the
+set of actions QML can perform on the list - adding items, retrieving items and
+clearing the list. In the future, additional operations may be supported. All
+list properties must implement the append operation, but the rest are optional.
+
+To provide a list property, a C++ class must implement the operation callbacks,
+and then return an appropriate QmlListProperty value from the property getter.
+List properties should have no setter. In the example above, the Q_PROPERTY()
+declarative will look like this:
+
+\code
+Q_PROPERTY(QmlListProperty<Fruit> fruit READ fruit);
+\endcode
+
+QML list properties are typesafe - in this case \c {Fruit} is a QObject type that
+\c {Apple}, \c {Orange} and \c {Banana} all derive from.
+*/
+
+/*!
+\fn QmlListProperty::QmlListProperty()
+\internal
+*/
+
+/*!
+\fn QmlListProperty::QmlListProperty(QObject *object, QList<T *> &list)
+
+Convenience constructor for making a QmlListProperty value from an existing
+QList \a list. The \a list reference must remain valid for as long as \a object
+exists. \a object must be provided.
+
+Generally this constructor should not be used in production code, as a
+writable QList violates QML's memory management rules. However, this constructor
+can very useful while prototyping.
+*/
+
+/*!
+\fn QmlListProperty::QmlListProperty(QObject *object, void *data, AppendFunction append,
+ CountFunction count = 0, AtFunction at = 0,
+ ClearFunction clear = 0)
+
+Construct a QmlListProperty from a set of operation functions. An opaque \a data handle
+may be passed which can be accessed from within the operation functions. The list property
+remains valid while \a object exists.
+
+The \a append operation is compulsory and must be provided, while the \a count, \a at and
+\a clear methods are optional.
+*/
+
+/*!
+\typedef QmlListProperty::AppendFunction
+
+Synonym for \c {void (*)(QmlListProperty<T> *property, T *value)}.
+
+Append the \a value to the list \a property.
+*/
+
+/*!
+\typedef QmlListProperty::CountFunction
+
+Synonym for \c {int (*)(QmlListProperty<T> *property)}.
+
+Return the number of elements in the list \a property.
+*/
+
+/*!
+\fn bool QmlListProperty::operator==(const QmlListProperty &other) const
+
+Returns true if this QmlListProperty is equal to \a other, otherwise false.
+*/
+
+/*!
+\typedef QmlListProperty::AtFunction
+
+Synonym for \c {T *(*)(QmlListProperty<T> *property, int index)}.
+
+Return the element at position \a index in the list \a property.
+*/
+
+/*!
+\typedef QmlListProperty::ClearFunction
+
+Synonym for \c {void (*)(QmlListProperty<T> *property)}.
+
+Clear the list \a property.
+*/
+
+QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmllist.h b/src/declarative/qml/qmllist.h
index 261145d..cedc35b 100644
--- a/src/declarative/qml/qmllist.h
+++ b/src/declarative/qml/qmllist.h
@@ -51,73 +51,89 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
template<typename T>
-class QmlList : private QmlPrivate::ListInterface
-{
-public:
- virtual void append(T) = 0;
- virtual void insert(int, T) = 0;
- virtual void removeAt(int) = 0;
- virtual T at(int) const = 0;
- virtual int count() const = 0;
- virtual void clear() = 0;
- QmlList<T> &operator<<(T t) { append(t); return *this; }
-
-protected:
- virtual int type() const { return qMetaTypeId<T>(); }
- virtual void append(void *d) { const T &v = *(T *)d; append(v); }
- virtual void insert(int i, void *d) { const T &v = *(T *)d; insert(i, v); }
- virtual void at(int i, void *p) const { const T &v = at(i); *((T*)p) = v; }
+struct QmlListProperty {
+ typedef void (*AppendFunction)(QmlListProperty<T> *, T*);
+ typedef int (*CountFunction)(QmlListProperty<T> *);
+ typedef T *(*AtFunction)(QmlListProperty<T> *, int);
+ typedef void (*ClearFunction)(QmlListProperty<T> *);
+
+ QmlListProperty()
+ : object(0), data(0), append(0), count(0), at(0), clear(0), dummy1(0), dummy2(0) {}
+ QmlListProperty(QObject *o, QList<T *> &list)
+ : object(o), data(&list), append(qlist_append), count(qlist_count), at(qlist_at),
+ clear(qlist_clear), dummy1(0), dummy2(0) {}
+ QmlListProperty(QObject *o, void *d, AppendFunction a, CountFunction c = 0, AtFunction t = 0,
+ ClearFunction r = 0)
+ : object(o), data(d), append(a), count(c), at(t), clear(r), dummy1(0), dummy2(0) {}
+
+ bool operator==(const QmlListProperty &o) const {
+ return object == o.object &&
+ data == o.data &&
+ append == o.append &&
+ count == o.count &&
+ at == o.at &&
+ clear == o.clear;
+ }
+
+ QObject *object;
+ void *data;
+
+ AppendFunction append;
+
+ CountFunction count;
+ AtFunction at;
+
+ ClearFunction clear;
+
+ void *dummy1;
+ void *dummy2;
+
+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();
+ }
};
-template<typename T>
-class QmlConcreteList : public QList<T>, public QmlList<T>
+class QmlEngine;
+class QmlListReferencePrivate;
+class Q_DECLARATIVE_EXPORT QmlListReference
{
public:
- virtual void append(T v) { QList<T>::append(v); }
- virtual void insert(int i, T v) { QList<T>::insert(i, v); }
- virtual void clear() { QList<T>::clear(); }
- virtual T at(int i) const { return QList<T>::at(i); }
- virtual void removeAt(int i) { QList<T>::removeAt(i); }
- virtual int count() const { return QList<T>::count(); }
-};
+ QmlListReference();
+ QmlListReference(QObject *, const char *property, QmlEngine * = 0);
+ QmlListReference(const QmlListReference &);
+ QmlListReference &operator=(const QmlListReference &);
+ ~QmlListReference();
+
+ bool isValid() const;
-#define QML_DECLARE_LIST_PROXY(ClassName, ListType, ListName) \
-class Qml_ProxyList_ ##ListName : public QmlList<ListType> \
-{ \
- public: \
- virtual void removeAt(int idx) \
- { \
- ClassName *p = (ClassName *)((char *)this + ((char *)(ClassName *)(0x10000000) - (char *)&((ClassName *)(0x10000000))->ListName)); \
- p->ListName ## _removeAt(idx); \
- } \
- virtual int count() const \
- { \
- ClassName *p = (ClassName *)((char *)this + ((char *)(ClassName *)(0x10000000) - (char *)&((ClassName *)(0x10000000))->ListName)); \
- return p->ListName ## _count(); \
- } \
- virtual void append(ListType v) \
- { \
- ClassName *p = (ClassName *)((char *)this + ((char *)(ClassName *)(0x10000000) - (char *)&((ClassName *)(0x10000000))->ListName)); \
- p->ListName ## _append(v); \
- } \
- virtual void insert(int idx, ListType v) \
- { \
- ClassName *p = (ClassName *)((char *)this + ((char *)(ClassName *)(0x10000000) - (char *)&((ClassName *)(0x10000000))->ListName)); \
- p->ListName ## _insert(idx, v); \
- } \
- virtual ListType at(int idx) const \
- { \
- ClassName *p = (ClassName *)((char *)this + ((char *)(ClassName *)(0x10000000) - (char *)&((ClassName *)(0x10000000))->ListName)); \
- return p->ListName ## _at(idx); \
- } \
- virtual void clear() \
- { \
- ClassName *p = (ClassName *)((char *)this + ((char *)(ClassName *)(0x10000000) - (char *)&((ClassName *)(0x10000000))->ListName)); \
- p->ListName ## _clear(); \
- } \
-}; \
-friend class Qml_ProxyList_ ##ListName ; \
-Qml_ProxyList_##ListName ListName;
+ QObject *object() const;
+ const QMetaObject *listElementType() const;
+
+ bool canAppend() const;
+ bool canAt() const;
+ bool canClear() const;
+ bool canCount() const;
+
+ bool append(QObject *) const;
+ QObject *at(int) const;
+ bool clear() const;
+ int count() const;
+
+private:
+ friend class QmlListReferencePrivate;
+ QmlListReferencePrivate* d;
+};
+Q_DECLARE_METATYPE(QmlListReference);
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmllist_p.h b/src/declarative/qml/qmllist_p.h
new file mode 100644
index 0000000..4660e47
--- /dev/null
+++ b/src/declarative/qml/qmllist_p.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLLIST_P_H
+#define QMLLIST_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qmllist.h"
+#include "qmlguard_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QmlListReferencePrivate
+{
+public:
+ QmlListReferencePrivate();
+
+ static QmlListReference init(const QmlListProperty<QObject> &, int, QmlEngine *);
+
+ QmlGuard<QObject> object;
+ const QMetaObject *elementType;
+ QmlListProperty<QObject> property;
+ int propertyType;
+
+ void addref();
+ void release();
+ int refCount;
+
+ static inline QmlListReferencePrivate *get(QmlListReference *ref) {
+ return ref->d;
+ }
+};
+
+
+QT_END_NAMESPACE
+
+#endif // QMLLIST_P_H
diff --git a/src/declarative/qml/qmllistscriptclass.cpp b/src/declarative/qml/qmllistscriptclass.cpp
index d74a9b0..bb29763 100644
--- a/src/declarative/qml/qmllistscriptclass.cpp
+++ b/src/declarative/qml/qmllistscriptclass.cpp
@@ -43,13 +43,13 @@
#include "qmlengine_p.h"
#include "qmlguard_p.h"
+#include "qmllist_p.h"
QT_BEGIN_NAMESPACE
struct ListData : public QScriptDeclarativeClass::Object {
QmlGuard<QObject> object;
- int propertyIdx;
- QmlListScriptClass::ListCategory type;
+ QmlListProperty<QObject> property;
int propertyType;
};
@@ -66,7 +66,7 @@ QmlListScriptClass::~QmlListScriptClass()
{
}
-QScriptValue QmlListScriptClass::newList(QObject *object, int propId, ListCategory type, int propType)
+QScriptValue QmlListScriptClass::newList(QObject *object, int propId, int propType)
{
QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine);
@@ -75,8 +75,20 @@ QScriptValue QmlListScriptClass::newList(QObject *object, int propId, ListCatego
ListData *data = new ListData;
data->object = object;
- data->propertyIdx = propId;
- data->type = type;
+ data->propertyType = propType;
+ void *args[] = { &data->property, 0 };
+ QMetaObject::metacall(object, QMetaObject::ReadProperty, propId, args);
+
+ return newObject(scriptEngine, this, data);
+}
+
+QScriptValue QmlListScriptClass::newList(const QmlListProperty<QObject> &prop, int propType)
+{
+ QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine);
+
+ ListData *data = new ListData;
+ data->object = prop.object;
+ data->property = prop;
data->propertyType = propType;
return newObject(scriptEngine, this, data);
@@ -111,39 +123,14 @@ QmlListScriptClass::ScriptValue QmlListScriptClass::property(Object *obj, const
if (!data->object)
return Value();
- void *list = 0;
- void *args[] = { &list, 0 };
- QMetaObject::metacall(data->object, QMetaObject::ReadProperty,
- data->propertyIdx, args);
+ quint32 count = data->property.count?data->property.count(&data->property):0;
- if (!list)
+ if (name == m_lengthId.identifier)
+ return Value(scriptEngine, count);
+ else if (lastIndex < count && data->property.at)
+ return Value(scriptEngine, enginePriv->objectClass->newQObject(data->property.at(&data->property, lastIndex)));
+ else
return Value();
-
- if (data->type == QListPtr) {
- const QList<QObject *> &qlist = *((QList<QObject *>*)list);
-
- quint32 count = qlist.count();
-
- if (name == m_lengthId.identifier)
- return Value(scriptEngine, count);
- else if (lastIndex < count)
- return Value(scriptEngine, enginePriv->objectClass->newQObject(qlist.at(lastIndex)));
- else
- return Value();
-
- } else {
- Q_ASSERT(data->type == QmlListPtr);
- const QmlList<QObject *> &qmllist = *((QmlList<QObject *>*)list);
-
- quint32 count = qmllist.count();
-
- if (name == m_lengthId.identifier)
- return Value(scriptEngine, count);
- else if (lastIndex < count)
- return Value(scriptEngine, enginePriv->objectClass->newQObject(qmllist.at(lastIndex)));
- else
- return Value();
- }
}
QVariant QmlListScriptClass::toVariant(Object *obj, bool *ok)
@@ -155,18 +142,7 @@ QVariant QmlListScriptClass::toVariant(Object *obj, bool *ok)
return QVariant();
}
- void *list = 0;
- void *args[] = { &list, 0 };
- QMetaObject::metacall(data->object, QMetaObject::ReadProperty,
- data->propertyIdx, args);
-
- if (!list) {
- if (ok) *ok = false;
- return QVariant();
- }
-
- if (ok) *ok = true;
- return QVariant(data->propertyType, &list);
+ return QVariant::fromValue(QmlListReferencePrivate::init(data->property, data->propertyType, engine));
}
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmllistscriptclass_p.h b/src/declarative/qml/qmllistscriptclass_p.h
index 92cf17f..07b09c3 100644
--- a/src/declarative/qml/qmllistscriptclass_p.h
+++ b/src/declarative/qml/qmllistscriptclass_p.h
@@ -54,6 +54,7 @@
//
#include <private/qmlscriptclass_p.h>
+#include "qmllist.h"
QT_BEGIN_NAMESPACE
@@ -64,8 +65,8 @@ public:
QmlListScriptClass(QmlEngine *);
~QmlListScriptClass();
- enum ListCategory { QListPtr, QmlListPtr };
- QScriptValue newList(QObject *, int, ListCategory, int);
+ QScriptValue newList(QObject *, int, int);
+ QScriptValue newList(const QmlListProperty<QObject> &, int);
protected:
virtual QScriptClass::QueryFlags queryProperty(Object *, const Identifier &,
diff --git a/src/declarative/qml/qmlmetaproperty.cpp b/src/declarative/qml/qmlmetaproperty.cpp
index d7d4a07..7c273dc 100644
--- a/src/declarative/qml/qmlmetaproperty.cpp
+++ b/src/declarative/qml/qmlmetaproperty.cpp
@@ -52,16 +52,13 @@
#include "qmlengine_p.h"
#include "qmldeclarativedata_p.h"
#include "qmlstringconverters_p.h"
-
-#include <qfxperf_p_p.h>
+#include "qmllist_p.h"
#include <QStringList>
#include <QtCore/qdebug.h>
#include <math.h>
-Q_DECLARE_METATYPE(QList<QObject *>);
-
QT_BEGIN_NAMESPACE
/*!
@@ -213,7 +210,6 @@ QmlMetaProperty::QmlMetaProperty(const QmlMetaProperty &other)
\value InvalidProperty The property is invalid.
\value Bindable The property is a QmlBinding.
\value List The property is a QList pointer
- \value QmlList The property is a QmlList pointer
\value Object The property is a QObject derived type pointer
\value Normal The property is none of the above.
*/
@@ -257,8 +253,6 @@ QmlMetaPropertyPrivate::propertyCategory() const
return QmlMetaProperty::Bindable;
else if (core.flags & QmlPropertyCache::Data::IsQObjectDerived)
return QmlMetaProperty::Object;
- else if (core.flags & QmlPropertyCache::Data::IsQmlList)
- return QmlMetaProperty::QmlList;
else if (core.flags & QmlPropertyCache::Data::IsQList)
return QmlMetaProperty::List;
else
@@ -401,7 +395,7 @@ bool QmlMetaProperty::isWritable() const
if (!d->object)
return false;
- if (category == List || category == QmlList)
+ if (category == List)
return true;
else if (type() & SignalProperty)
return false;
@@ -703,6 +697,13 @@ QVariant QmlMetaPropertyPrivate::readValueProperty()
if (!ep) delete valueType;
return rv;
+ } else if(core.flags & QmlPropertyCache::Data::IsQList) {
+
+ QmlListProperty<QObject> prop;
+ void *args[] = { &prop, 0 };
+ QMetaObject::metacall(object, QMetaObject::ReadProperty, core.coreIndex, args);
+ return QVariant::fromValue(QmlListReferencePrivate::init(prop, core.propType, context?context->engine():0));
+
} else {
return object->metaObject()->property(core.coreIndex).read(object.data());
@@ -813,9 +814,7 @@ bool QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data
int t = property.propType;
int vt = value.userType();
- QmlEnginePrivate *enginePriv = 0;
- if (context && context->engine())
- enginePriv = QmlEnginePrivate::get(context->engine());
+ QmlEnginePrivate *enginePriv = QmlEnginePrivate::get(context);
if (t == QVariant::Url) {
@@ -880,55 +879,40 @@ bool QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data
} else if (property.flags & QmlPropertyCache::Data::IsQList) {
- int listType = QmlMetaType::listType(t);
- QMetaProperty prop = object->metaObject()->property(property.coreIndex);
-
- if (value.userType() == qMetaTypeId<QList<QObject *> >()) {
- const QList<QObject *> &list =
- qvariant_cast<QList<QObject *> >(value);
- QVariant listVar = prop.read(object);
- QmlMetaType::clear(listVar);
- for (int ii = 0; ii < list.count(); ++ii) {
- QVariant v = QmlMetaType::qmlType(listType)->fromObject(list.at(ii));
- QmlMetaType::append(listVar, v);
- }
-
- } else if (vt == listType ||
- value.userType() == listType) {
- QVariant listVar = prop.read(object);
- QmlMetaType::append(listVar, value);
+ const QMetaObject *listType = 0;
+ if (enginePriv) {
+ listType = enginePriv->rawMetaObjectForType(enginePriv->listType(property.propType));
+ } else {
+ QmlType *type = QmlMetaType::qmlType(QmlMetaType::listType(property.propType));
+ if (!type) return false;
+ listType = type->baseMetaObject();
}
+ if (!listType) return false;
- } else if (property.flags & QmlPropertyCache::Data::IsQmlList) {
+ QmlListProperty<void> prop;
+ void *args[] = { &prop, 0 };
+ QMetaObject::metacall(object, QMetaObject::ReadProperty, coreIdx, args);
- // XXX - optimize!
- QMetaProperty prop = object->metaObject()->property(property.coreIndex);
- QVariant list = prop.read(object);
- QmlPrivate::ListInterface *li =
- *(QmlPrivate::ListInterface **)list.constData();
-
- int type = li->type();
-
- if (QObject *obj = QmlMetaType::toQObject(value)) {
- const QMetaObject *mo = rawMetaObjectForType(enginePriv, type);
-
- const QMetaObject *objMo = obj->metaObject();
- bool found = false;
- while(!found && objMo) {
- if (equal(objMo, mo))
- found = true;
- else
- objMo = objMo->superClass();
- }
+ if (!prop.clear) return false;
- if (!found)
- return false;
+ prop.clear(&prop);
+
+ if (value.userType() == qMetaTypeId<QList<QObject *> >()) {
+ const QList<QObject *> &list = qvariant_cast<QList<QObject *> >(value);
- // NOTE: This assumes a cast to QObject does not alter
- // the object pointer
- void *d = (void *)&obj;
- li->append(d);
+ for (int ii = 0; ii < list.count(); ++ii) {
+ QObject *o = list.at(ii);
+ if (!canConvert(o->metaObject(), listType))
+ o = 0;
+ prop.append(&prop, (void *)o);
+ }
+ } else {
+ QObject *o = enginePriv?enginePriv->toQObject(value):QmlMetaType::toQObject(value);
+ if (!canConvert(o->metaObject(), listType))
+ o = 0;
+ prop.append(&prop, (void *)o);
}
+
} else {
Q_ASSERT(vt != t);
diff --git a/src/declarative/qml/qmlmetaproperty.h b/src/declarative/qml/qmlmetaproperty.h
index 723fc50..82266c8 100644
--- a/src/declarative/qml/qmlmetaproperty.h
+++ b/src/declarative/qml/qmlmetaproperty.h
@@ -68,7 +68,6 @@ public:
InvalidProperty,
Bindable,
List,
- QmlList, //XXX
Object,
Normal
};
diff --git a/src/declarative/qml/qmlmetatype.cpp b/src/declarative/qml/qmlmetatype.cpp
index b94a815..6db70d4 100644
--- a/src/declarative/qml/qmlmetatype.cpp
+++ b/src/declarative/qml/qmlmetatype.cpp
@@ -100,7 +100,6 @@ struct QmlMetaTypeData
QBitArray objects;
QBitArray interfaces;
- QBitArray qmllists;
QBitArray lists;
};
Q_GLOBAL_STATIC(QmlMetaTypeData, metaTypeData)
@@ -124,8 +123,8 @@ public:
QByteArray m_name;
int m_version_maj;
int m_version_min;
- int m_typeId; int m_listId; int m_qmlListId;
- QmlPrivate::Func m_opFunc;
+ int m_typeId; int m_listId;
+ QObject *(*m_newFunc)();
const QMetaObject *m_baseMetaObject;
QmlAttachedPropertiesFunc m_attachedPropertiesFunc;
const QMetaObject *m_attachedPropertiesType;
@@ -141,32 +140,30 @@ 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_attachedPropertiesType(0),
+: m_isInterface(false), m_iid(0), m_typeId(0), m_listId(0),
+ m_newFunc(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,
- QmlPrivate::Func opFunc, const char *iid, int index)
+QmlType::QmlType(int type, int listType, const char *iid, int index)
: d(new QmlTypePrivate)
{
d->m_isInterface = true;
d->m_iid = iid;
d->m_typeId = type;
d->m_listId = listType;
- d->m_qmlListId = qmlListType;
- d->m_opFunc = opFunc;
+ d->m_newFunc = 0;
d->m_index = index;
d->m_isSetup = true;
d->m_version_maj = 0;
d->m_version_min = 0;
}
-QmlType::QmlType(int type, int listType, int qmlListType,
- QmlPrivate::Func opFunc, const char *qmlName,
+QmlType::QmlType(int type, int listType,
+ QObject *(*newFunc)(), const char *qmlName,
int version_maj, int version_min,
const QMetaObject *metaObject,
QmlAttachedPropertiesFunc attachedPropertiesFunc,
@@ -182,8 +179,7 @@ QmlType::QmlType(int type, int listType, int qmlListType,
d->m_version_min = version_min;
d->m_typeId = type;
d->m_listId = listType;
- d->m_qmlListId = qmlListType;
- d->m_opFunc = opFunc;
+ d->m_newFunc = newFunc;
d->m_baseMetaObject = metaObject;
d->m_attachedPropertiesFunc = attachedPropertiesFunc;
d->m_attachedPropertiesType = attachedType;
@@ -283,10 +279,7 @@ QObject *QmlType::create() const
{
d->init();
- QVariant v;
- QObject *rv = 0;
- d->m_opFunc(QmlPrivate::Create, 0, v, v, (void **)&rv);
-
+ QObject *rv = d->m_newFunc();
if (rv && !d->m_metaObjects.isEmpty())
(void *)new QmlProxyMetaObject(rv, &d->m_metaObjects);
@@ -313,39 +306,6 @@ int QmlType::qListTypeId() const
return d->m_listId;
}
-int QmlType::qmlListTypeId() const
-{
- return d->m_qmlListId;
-}
-
-void QmlType::listClear(const QVariant &list)
-{
- Q_ASSERT(list.userType() == qListTypeId());
- 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());
- d->m_opFunc(QmlPrivate::Append, 0, list, item, 0);
-}
-
-QVariant QmlType::listAt(const QVariant &list, int idx)
-{
- Q_ASSERT(list.userType() == qListTypeId());
- 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());
- return d->m_opFunc(QmlPrivate::Length, 0, list, QVariant(), 0);
-}
-
const QMetaObject *QmlType::metaObject() const
{
d->init();
@@ -387,15 +347,6 @@ 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;
@@ -407,7 +358,6 @@ int QmlType::index() const
}
int QmlMetaType::registerInterface(const QmlPrivate::MetaTypeIds &id,
- QmlPrivate::Func listFunction,
const char *iid)
{
QWriteLocker lock(metaTypeDataLock());
@@ -415,31 +365,26 @@ int QmlMetaType::registerInterface(const QmlPrivate::MetaTypeIds &id,
int index = data->types.count();
- QmlType *type = new QmlType(id.typeId, id.listId, id.qmlListId,
- listFunction, iid, index);
+ QmlType *type = new QmlType(id.typeId, id.listId, iid, index);
data->types.append(type);
data->idToType.insert(type->typeId(), type);
data->idToType.insert(type->qListTypeId(), type);
- data->idToType.insert(type->qmlListTypeId(), type);
// XXX No insertMulti, so no multi-version interfaces?
if (!type->qmlTypeName().isEmpty())
data->nameToType.insert(type->qmlTypeName(), type);
- if (data->interfaces.size() < id.typeId)
+ if (data->interfaces.size() <= id.typeId)
data->interfaces.resize(id.typeId + 16);
- if (data->qmllists.size() < id.qmlListId)
- data->qmllists.resize(id.qmlListId + 16);
- if (data->lists.size() < id.listId)
+ if (data->lists.size() <= id.listId)
data->lists.resize(id.listId + 16);
data->interfaces.setBit(id.typeId, true);
- data->qmllists.setBit(id.qmlListId, true);
data->lists.setBit(id.listId, true);
return index;
}
-int QmlMetaType::registerType(const QmlPrivate::MetaTypeIds &id, QmlPrivate::Func func,
+int QmlMetaType::registerType(const QmlPrivate::MetaTypeIds &id, QObject *(*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)
@@ -464,14 +409,13 @@ int QmlMetaType::registerType(const QmlPrivate::MetaTypeIds &id, QmlPrivate::Fun
name += '/';
name += cname;
- QmlType *type = new QmlType(id.typeId, id.listId, id.qmlListId,
+ QmlType *type = new QmlType(id.typeId, id.listId,
func, name, version_maj, version_min, mo, attach, attachMo, pStatus,
valueSource, valueInterceptor, extFunc, extmo, index, parser);
data->types.append(type);
data->idToType.insert(type->typeId(), type);
data->idToType.insert(type->qListTypeId(), type);
- data->idToType.insert(type->qmlListTypeId(), type);
if (!type->qmlTypeName().isEmpty())
data->nameToType.insertMulti(type->qmlTypeName(), type);
@@ -480,12 +424,9 @@ int QmlMetaType::registerType(const QmlPrivate::MetaTypeIds &id, QmlPrivate::Fun
if (data->objects.size() <= id.typeId)
data->objects.resize(id.typeId + 16);
- if (data->qmllists.size() <= id.qmlListId)
- data->qmllists.resize(id.qmlListId + 16);
if (data->lists.size() <= id.listId)
data->lists.resize(id.listId + 16);
data->objects.setBit(id.typeId, true);
- data->qmllists.setBit(id.qmlListId, true);
data->lists.setBit(id.listId, true);
return index;
@@ -527,51 +468,6 @@ int QmlMetaType::listType(int id)
return 0;
}
-/*
- Returns the item type for a qml list of type \a id.
- */
-int QmlMetaType::qmlListType(int id)
-{
- QReadLocker lock(metaTypeDataLock());
- QmlMetaTypeData *data = metaTypeData();
- QmlType *type = data->idToType.value(id);
- if (type && type->qmlListTypeId() == id)
- return type->typeId();
- else
- return 0;
-}
-
-bool QmlMetaType::clear(const QVariant &list)
-{
- int userType = list.userType();
- QReadLocker lock(metaTypeDataLock());
- QmlMetaTypeData *data = metaTypeData();
- QmlType *type = data->idToType.value(userType);
- lock.unlock();
- if (type && type->qListTypeId() == userType) {
- type->listClear(list);
- return true;
- } else {
- return false;
- }
-}
-
-bool QmlMetaType::append(const QVariant &list, const QVariant &item)
-{
- int userType = list.userType();
- QReadLocker lock(metaTypeDataLock());
- QmlMetaTypeData *data = metaTypeData();
- QmlType *type = data->idToType.value(userType);
- lock.unlock();
- if (type && type->qListTypeId() == userType &&
- item.userType() == type->typeId()) {
- type->listAppend(list, item);
- return true;
- } else {
- return false;
- }
-}
-
int QmlMetaType::attachedPropertiesFuncId(const QMetaObject *mo)
{
QReadLocker lock(metaTypeDataLock());
@@ -656,8 +552,6 @@ QmlMetaType::TypeCategory QmlMetaType::typeCategory(int userType)
QmlMetaTypeData *data = metaTypeData();
if (userType < data->objects.size() && data->objects.testBit(userType))
return Object;
- else if (userType < data->qmllists.size() && data->qmllists.testBit(userType))
- return QmlList;
else if (userType < data->lists.size() && data->lists.testBit(userType))
return List;
else
@@ -683,13 +577,6 @@ const char *QmlMetaType::interfaceIId(int userType)
return 0;
}
-bool QmlMetaType::isQmlList(int userType)
-{
- QReadLocker lock(metaTypeDataLock());
- QmlMetaTypeData *data = metaTypeData();
- return userType >= 0 && userType < data->qmllists.size() && data->qmllists.testBit(userType);
-}
-
bool QmlMetaType::isList(int userType)
{
QReadLocker lock(metaTypeDataLock());
@@ -697,44 +584,6 @@ bool QmlMetaType::isList(int userType)
return userType >= 0 && userType < data->lists.size() && data->lists.testBit(userType);
}
-bool QmlMetaType::isList(const QVariant &v)
-{
- return (v.type() == QVariant::UserType && isList(v.userType()));
-}
-
-int QmlMetaType::listCount(const QVariant &v)
-{
- int userType = v.userType();
-
- QReadLocker lock(metaTypeDataLock());
- QmlMetaTypeData *data = metaTypeData();
- QmlType *type = data->idToType.value(userType);
- lock.unlock();
-
- if (type && type->qListTypeId() == userType)
- return type->listCount(v);
- else
- return 0;
-}
-
-QVariant QmlMetaType::listAt(const QVariant &v, int idx)
-{
- if (idx < 0)
- return QVariant();
-
- int userType = v.userType();
-
- QReadLocker lock(metaTypeDataLock());
- QmlMetaTypeData *data = metaTypeData();
- QmlType *type = data->idToType.value(userType);
- lock.unlock();
-
- if (type && type->qListTypeId() == userType)
- return type->listAt(v, idx);
- else
- return QVariant();
-}
-
/*!
A custom string convertor allows you to specify a function pointer that
returns a variant of \a type. For example, if you have written your own icon
diff --git a/src/declarative/qml/qmlmetatype.h b/src/declarative/qml/qmlmetatype.h
index 3d082f8..98d04c1 100644
--- a/src/declarative/qml/qmlmetatype.h
+++ b/src/declarative/qml/qmlmetatype.h
@@ -46,6 +46,7 @@
#include "qmlparserstatus.h"
#include "qmlpropertyvaluesource.h"
#include "qmlpropertyvalueinterceptor.h"
+#include "qmllist.h"
#include <QtCore/qglobal.h>
#include <QtCore/qvariant.h>
@@ -62,8 +63,8 @@ class QmlCustomParser;
class Q_DECLARATIVE_EXPORT QmlMetaType
{
public:
- 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 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 bool copy(int type, void *data, const void *copy = 0);
@@ -83,22 +84,15 @@ public:
static QObject *toQObject(const QVariant &, bool *ok = 0);
static int listType(int);
- static bool clear(const QVariant &);
- static bool append(const QVariant &, const QVariant &);
static int attachedPropertiesFuncId(const QMetaObject *);
static QmlAttachedPropertiesFunc attachedPropertiesFuncById(int);
- enum TypeCategory { Unknown, Object, List, QmlList };
+ enum TypeCategory { Unknown, Object, List };
static TypeCategory typeCategory(int);
static bool isInterface(int);
static const char *interfaceIId(int);
static bool isList(int);
- static bool isList(const QVariant &);
- static bool isQmlList(int);
- static int qmlListType(int);
- static int listCount(const QVariant &);
- static QVariant listAt(const QVariant &, int);
typedef QVariant (*StringConverter)(const QString &);
static void registerCustomStringConverter(int, StringConverter);
@@ -123,12 +117,6 @@ public:
bool isInterface() const;
int typeId() const;
int qListTypeId() const;
- int qmlListTypeId() const;
-
- void listClear(const QVariant &);
- void listAppend(const QVariant &, const QVariant &);
- QVariant listAt(const QVariant &, int);
- int listCount(const QVariant &);
const QMetaObject *metaObject() const;
const QMetaObject *baseMetaObject() const;
@@ -147,8 +135,8 @@ private:
friend class QmlMetaType;
friend class QmlTypePrivate;
friend struct QmlMetaTypeData;
- 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(int, int, const char *, int);
+ QmlType(int, int, QObject *(*)(), const char *, int, int, const QMetaObject *, QmlAttachedPropertiesFunc, const QMetaObject *, int, int, int, QmlPrivate::CreateFunc, const QMetaObject *, int, QmlCustomParser *);
~QmlType();
QmlTypePrivate *d;
@@ -160,11 +148,10 @@ int qmlRegisterType(const char *typeName)
QByteArray name(typeName);
QmlPrivate::MetaTypeIds ids = {
qRegisterMetaType<T *>(QByteArray(name + '*').constData()),
- qRegisterMetaType<T *>(QByteArray("QList<" + name + "*>*").constData()),
- qRegisterMetaType<T *>(QByteArray("QmlList<" + name + "*>*").constData())
+ qRegisterMetaType<QmlListProperty<T> >(QByteArray("QmlListProperty<" + name + ">").constData()),
};
- return QmlMetaType::registerType(ids, QmlPrivate::list_nocreate_op<T>, 0, 0, 0, 0,
+ return QmlMetaType::registerType(ids, 0, 0, 0, 0, 0,
&T::staticMetaObject,
QmlPrivate::attachedPropertiesFunc<T>(),
QmlPrivate::attachedPropertiesMetaObject<T>(),
@@ -181,11 +168,10 @@ 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<T *>(QByteArray("QList<" + name + "*>*").constData()),
- qRegisterMetaType<T *>(QByteArray("QmlList<" + name + "*>*").constData())
+ qRegisterMetaType<QmlListProperty<T> >(QByteArray("QmlListProperty<" + name + ">").constData()),
};
- return QmlMetaType::registerType(ids, QmlPrivate::list_op<T>,
+ return QmlMetaType::registerType(ids, QmlPrivate::create<T>,
uri, version_maj, version_min, qmlName,
&T::staticMetaObject,
QmlPrivate::attachedPropertiesFunc<T>(),
@@ -203,8 +189,7 @@ int qmlRegisterExtendedType(const char *typeName)
QByteArray name(typeName);
QmlPrivate::MetaTypeIds ids = {
qRegisterMetaType<T *>(QByteArray(name + '*').constData()),
- qRegisterMetaType<T *>(QByteArray("QList<" + name + "*>*").constData()),
- qRegisterMetaType<T *>(QByteArray("QmlList<" + name + "*>*").constData())
+ qRegisterMetaType<QmlListProperty<T> >(QByteArray("QmlListProperty<" + name + ">").constData()),
};
QmlAttachedPropertiesFunc attached =
@@ -216,7 +201,7 @@ int qmlRegisterExtendedType(const char *typeName)
attachedMo = QmlPrivate::attachedPropertiesMetaObject<T>();
}
- return QmlMetaType::registerType(ids, QmlPrivate::list_nocreate_op<T>, 0, 0, 0, 0,
+ return QmlMetaType::registerType(ids, 0, 0, 0, 0, 0,
&T::staticMetaObject, attached, attachedMo,
QmlPrivate::StaticCastSelector<T,QmlParserStatus>::cast(),
QmlPrivate::StaticCastSelector<T,QObject>::cast(),
@@ -231,8 +216,7 @@ int qmlRegisterExtendedType(const char *uri, int version_maj, int version_min, c
QByteArray name(typeName);
QmlPrivate::MetaTypeIds ids = {
qRegisterMetaType<T *>(QByteArray(name + '*').constData()),
- qRegisterMetaType<T *>(QByteArray("QList<" + name + "*>*").constData()),
- qRegisterMetaType<T *>(QByteArray("QmlList<" + name + "*>*").constData())
+ qRegisterMetaType<QmlListProperty<T> >(QByteArray("QmlListProperty<" + name + ">").constData()),
};
QmlAttachedPropertiesFunc attached =
@@ -244,7 +228,7 @@ int qmlRegisterExtendedType(const char *uri, int version_maj, int version_min, c
attachedMo = QmlPrivate::attachedPropertiesMetaObject<T>();
}
- return QmlMetaType::registerType(ids, QmlPrivate::list_op<T>,
+ return QmlMetaType::registerType(ids, QmlPrivate::create<T>,
uri, version_maj, version_min, qmlName,
&T::staticMetaObject,
attached, attachedMo,
@@ -262,13 +246,10 @@ int qmlRegisterInterface(const char *typeName)
QByteArray name(typeName);
QmlPrivate::MetaTypeIds ids = {
qRegisterMetaType<T *>(QByteArray(name + '*').constData()),
- qRegisterMetaType<T *>(QByteArray("QList<" + name + "*>*").constData()),
- qRegisterMetaType<T *>(QByteArray("QmlList<" + name + "*>*").constData())
+ qRegisterMetaType<QmlListProperty<T> >(QByteArray("QmlListProperty<" + name + ">").constData()),
};
- return QmlMetaType::registerInterface(ids,
- QmlPrivate::list_interface_op<T>,
- qobject_interface_iid<T *>());
+ return QmlMetaType::registerInterface(ids, qobject_interface_iid<T *>());
}
template<typename T>
@@ -277,11 +258,10 @@ int qmlRegisterCustomType(const char *uri, int version_maj, int version_min, con
QByteArray name(typeName);
QmlPrivate::MetaTypeIds ids = {
qRegisterMetaType<T *>(QByteArray(name + '*').constData()),
- qRegisterMetaType<T *>(QByteArray("QList<" + name + "*>*").constData()),
- qRegisterMetaType<T *>(QByteArray("QmlList<" + name + "*>*").constData())
+ qRegisterMetaType<QmlListProperty<T> >(QByteArray("QmlListProperty<" + name + ">").constData()),
};
- return QmlMetaType::registerType(ids, QmlPrivate::list_op<T>,
+ return QmlMetaType::registerType(ids, QmlPrivate::create<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 76d1837..15ece1d 100644
--- a/src/declarative/qml/qmlobjectscriptclass.cpp
+++ b/src/declarative/qml/qmlobjectscriptclass.cpp
@@ -239,9 +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::QListPtr, lastData->propType));
- } else if (lastData->flags & QmlPropertyCache::Data::IsQmlList) {
- return Value(scriptEngine, enginePriv->listClass->newList(obj, lastData->coreIndex, QmlListScriptClass::QmlListPtr, lastData->propType));
+ return Value(scriptEngine, enginePriv->listClass->newList(obj, lastData->coreIndex, lastData->propType));
} else if (lastData->flags & QmlPropertyCache::Data::IsQObjectDerived) {
QObject *rv = 0;
void *args[] = { &rv, 0 };
diff --git a/src/declarative/qml/qmlprivate.h b/src/declarative/qml/qmlprivate.h
index e087788..e5ea07f 100644
--- a/src/declarative/qml/qmlprivate.h
+++ b/src/declarative/qml/qmlprivate.h
@@ -72,39 +72,8 @@ public:
namespace QmlPrivate
{
- class ListInterface
- {
- public:
- virtual ~ListInterface() {}
- virtual int type() const = 0;
- virtual void append(void *) = 0;
- virtual void insert(int, void *) = 0;
- virtual void removeAt(int) = 0;
- virtual void at(int, void *) const = 0;
- virtual int count() const = 0;
- 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>
- 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);
+ QObject *create() { return new T; }
template<class From, class To, int N>
struct StaticCastSelectorClass
@@ -201,9 +170,7 @@ namespace QmlPrivate
struct MetaTypeIds {
int typeId;
int listId;
- int qmlListId;
};
- typedef int (*Func)(QmlPrivate::ListOp, int, const QVariant &, const QVariant &, void **);
typedef QObject *(*CreateFunc)(QObject *);
template<typename T>
@@ -237,148 +204,6 @@ 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/qmlpropertycache.cpp b/src/declarative/qml/qmlpropertycache.cpp
index e567fd2..a3e655b 100644
--- a/src/declarative/qml/qmlpropertycache.cpp
+++ b/src/declarative/qml/qmlpropertycache.cpp
@@ -77,8 +77,6 @@ void QmlPropertyCache::Data::load(const QMetaProperty &p, QmlEngine *engine)
flags |= Data::IsQObjectDerived;
else if (cat == QmlMetaType::List)
flags |= Data::IsQList;
- else if (cat == QmlMetaType::QmlList)
- flags |= Data::IsQmlList;
}
}
diff --git a/src/declarative/qml/qmlpropertycache_p.h b/src/declarative/qml/qmlpropertycache_p.h
index 34b648d..18eea80 100644
--- a/src/declarative/qml/qmlpropertycache_p.h
+++ b/src/declarative/qml/qmlpropertycache_p.h
@@ -86,7 +86,6 @@ public:
IsFunction = 0x00000008,
IsQObjectDerived = 0x00000010,
IsEnumType = 0x00000020,
- IsQmlList = 0x00000040,
IsQList = 0x00000080,
IsQmlBinding = 0x00000100,
IsQScriptValue = 0x00000200,
diff --git a/src/declarative/qml/qmlscript.cpp b/src/declarative/qml/qmlscript.cpp
index c0320cd..ef142a5 100644
--- a/src/declarative/qml/qmlscript.cpp
+++ b/src/declarative/qml/qmlscript.cpp
@@ -58,7 +58,7 @@
console.log(otherinterestingitem.property);
}
}
- MouseRegion { onClicked: debugMyComponent() }
+ MouseArea { onClicked: debugMyComponent() }
\endqml
\note While it is possible to use any JavaScript code within a Script element,
diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp
index 39de062..8655809 100644
--- a/src/declarative/qml/qmlvme.cpp
+++ b/src/declarative/qml/qmlvme.cpp
@@ -91,15 +91,13 @@ QmlVME::QmlVME()
struct ListInstance
{
- ListInstance() {}
- ListInstance(QList<void *> *q, int t)
- : type(t), qListInterface(q), qmlListInterface(0) {}
- ListInstance(QmlPrivate::ListInterface *q, int t)
- : type(t), qListInterface(0), qmlListInterface(q) {}
+ ListInstance()
+ : type(0) {}
+ ListInstance(int t)
+ : type(t) {}
int type;
- QList<void *> *qListInterface;
- QmlPrivate::ListInterface *qmlListInterface;
+ QmlListProperty<void> qListProperty;
};
QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledData *comp,
@@ -654,22 +652,12 @@ QObject *QmlVME::run(QmlVMEStack<QObject *> &stack, QmlContext *ctxt,
}
break;
- case QmlInstruction::StoreObjectQmlList:
- {
- QObject *assign = stack.pop();
- const ListInstance &list = qliststack.top();
-
- void *d = (void *)&assign;
- list.qmlListInterface->append(d);
- }
- break;
-
case QmlInstruction::StoreObjectQList:
{
QObject *assign = stack.pop();
const ListInstance &list = qliststack.top();
- list.qListInterface->append((void *)assign);
+ list.qListProperty.append((QmlListProperty<void>*)&list.qListProperty, assign);
}
break;
@@ -690,12 +678,7 @@ QObject *QmlVME::run(QmlVMEStack<QObject *> &stack, QmlContext *ctxt,
VME_EXCEPTION(QCoreApplication::translate("QmlVME","Cannot assign object to list"));
- if (list.qmlListInterface) {
- void *d = (void *)&ptr;
- list.qmlListInterface->append(d);
- } else {
- list.qListInterface->append(ptr);
- }
+ list.qListProperty.append((QmlListProperty<void>*)&list.qListProperty, ptr);
}
break;
@@ -750,39 +733,16 @@ QObject *QmlVME::run(QmlVMEStack<QObject *> &stack, QmlContext *ctxt,
}
break;
- case QmlInstruction::FetchQmlList:
- {
- QObject *target = stack.top();
-
- void *a[1];
- // We know that QmlList<*> can be converted to
- // QmlPrivate::ListInterface
- QmlPrivate::ListInterface *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;
-
case QmlInstruction::FetchQList:
{
QObject *target = stack.top();
+ qliststack.push(ListInstance(instr.fetchQmlList.type));
+
void *a[1];
- // We know that QList<T *>* can be converted to
- // QList<void *>*
- QList<void *> *list = 0;
- a[0] = &list;
+ a[0] = (void *)&(qliststack.top().qListProperty);
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;
diff --git a/src/declarative/qml/qmlvmemetaobject.cpp b/src/declarative/qml/qmlvmemetaobject.cpp
index 3858138..4886680 100644
--- a/src/declarative/qml/qmlvmemetaobject.cpp
+++ b/src/declarative/qml/qmlvmemetaobject.cpp
@@ -77,13 +77,14 @@ QmlVMEMetaObject::QmlVMEMetaObject(QObject *obj,
data = new QVariant[metaData->propertyCount];
aConnected.resize(metaData->aliasCount);
- int list_type = qMetaTypeId<QmlList<QObject*>* >();
+ int list_type = qMetaTypeId<QmlListProperty<QObject> >();
// ### Optimize
for (int ii = 0; ii < metaData->propertyCount; ++ii) {
int t = (metaData->propertyData() + ii)->propertyType;
if (t == list_type) {
- listProperties.append(new List(this, ii));
- data[ii] = QVariant::fromValue((QmlList<QObject *>*)listProperties.last());
+ listProperties.append(new List(methodOffset + ii));
+ data[ii] = QVariant::fromValue(QmlListProperty<QObject>(obj, listProperties.last(), list_append,
+ list_count, list_at, list_clear));
} else if (t != -1) {
data[ii] = QVariant((QVariant::Type)t);
}
@@ -182,8 +183,9 @@ int QmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
default:
break;
}
- if (t == qMetaTypeId<QmlList<QObject*>* >()) {
- *reinterpret_cast<QmlList<QObject *> **>(a[0]) = data[id].value<QmlList<QObject*>*>();
+ if (t == qMetaTypeId<QmlListProperty<QObject> >()) {
+ *reinterpret_cast<QmlListProperty<QObject> *>(a[0]) =
+ data[id].value<QmlListProperty<QObject> >();
}
} else if (c == QMetaObject::WriteProperty) {
@@ -318,6 +320,30 @@ void QmlVMEMetaObject::listChanged(int id)
activate(object, methodOffset + id, 0);
}
+void QmlVMEMetaObject::list_append(QmlListProperty<QObject> *prop, QObject *o)
+{
+ List *list = static_cast<List *>(prop->data);
+ list->append(o);
+ QMetaObject::activate(prop->object, list->notifyIndex, 0);
+}
+
+int QmlVMEMetaObject::list_count(QmlListProperty<QObject> *prop)
+{
+ return static_cast<List *>(prop->data)->count();
+}
+
+QObject *QmlVMEMetaObject::list_at(QmlListProperty<QObject> *prop, int index)
+{
+ return static_cast<List *>(prop->data)->at(index);
+}
+
+void QmlVMEMetaObject::list_clear(QmlListProperty<QObject> *prop)
+{
+ List *list = static_cast<List *>(prop->data);
+ list->clear();
+ QMetaObject::activate(prop->object, list->notifyIndex, 0);
+}
+
void QmlVMEMetaObject::registerInterceptor(int index, int valueIndex, QmlPropertyValueInterceptor *interceptor)
{
if (aInterceptors.isEmpty())
diff --git a/src/declarative/qml/qmlvmemetaobject_p.h b/src/declarative/qml/qmlvmemetaobject_p.h
index 7fa46fd..3eb776e 100644
--- a/src/declarative/qml/qmlvmemetaobject_p.h
+++ b/src/declarative/qml/qmlvmemetaobject_p.h
@@ -138,33 +138,18 @@ private:
QAbstractDynamicMetaObject *parent;
void listChanged(int);
- class List : public QmlConcreteList<QObject*>
+ class List : public QList<QObject*>
{
public:
- List(QmlVMEMetaObject *p, int propIdx)
- : parent(p), parentProperty(propIdx) { }
-
- virtual void append(QObject *v) {
- QmlConcreteList<QObject*>::append(v);
- parent->listChanged(parentProperty);
- }
- virtual void insert(int i, QObject *v) {
- QmlConcreteList<QObject*>::insert(i, v);
- parent->listChanged(parentProperty);
- }
- virtual void clear() {
- QmlConcreteList<QObject*>::clear();
- parent->listChanged(parentProperty);
- }
- virtual void removeAt(int i) {
- QmlConcreteList<QObject*>::removeAt(i);
- parent->listChanged(parentProperty);
- }
- private:
- QmlVMEMetaObject *parent;
- int parentProperty;
+ List(int lpi) : notifyIndex(lpi) {}
+ int notifyIndex;
};
QList<List *> listProperties;
+
+ static void list_append(QmlListProperty<QObject> *, QObject *);
+ static int list_count(QmlListProperty<QObject> *);
+ static QObject *list_at(QmlListProperty<QObject> *, int);
+ static void list_clear(QmlListProperty<QObject> *);
};
QT_END_NAMESPACE