summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/declarative/qml/qmlmetatype.cpp45
-rw-r--r--src/declarative/qml/qmlmetatype.h3
-rw-r--r--src/declarative/qml/qmlprivate.h3
-rw-r--r--tests/auto/declarative/qmlmetatype/tst_qmlmetatype.cpp225
4 files changed, 231 insertions, 45 deletions
diff --git a/src/declarative/qml/qmlmetatype.cpp b/src/declarative/qml/qmlmetatype.cpp
index 6ecaa9f..5fb2f50 100644
--- a/src/declarative/qml/qmlmetatype.cpp
+++ b/src/declarative/qml/qmlmetatype.cpp
@@ -134,7 +134,6 @@ public:
QmlCustomParser *m_customParser;
mutable volatile bool m_isSetup:1;
mutable QList<QmlProxyMetaObject::ProxyData> m_metaObjects;
- mutable QByteArray m_hash;
};
QmlTypePrivate::QmlTypePrivate()
@@ -259,27 +258,6 @@ void QmlTypePrivate::init() const
m_metaObjects.at(ii).metaObject->methodOffset();
}
- // Calculate hash
- QByteArray hashData;
-
- const QMetaObject *myMetaObject = m_metaObjects.isEmpty()?m_baseMetaObject:m_metaObjects.first().metaObject;
-
- for (int ii = 0; ii < myMetaObject->propertyCount(); ++ii) {
- QMetaProperty prop = myMetaObject->property(ii);
- hashData.append(prop.type());
- hashData.append("|");
- hashData.append(prop.name());
- hashData.append("|");
- }
-
- for (int ii = 0; ii < myMetaObject->methodCount(); ++ii) {
- QMetaMethod method = myMetaObject->method(ii);
- hashData.append(method.signature());
- hashData.append("|");
- }
-
- m_hash = QCryptographicHash::hash(hashData, QCryptographicHash::Md5);
-
m_isSetup = true;
lock.unlock();
}
@@ -297,13 +275,6 @@ QByteArray QmlType::qmlTypeName() const
return d->m_name;
}
-QByteArray QmlType::hash() const
-{
- d->init();
-
- return d->m_hash;
-}
-
QObject *QmlType::create() const
{
d->init();
@@ -804,17 +775,6 @@ const char *QmlMetaType::interfaceIId(int userType)
return 0;
}
-bool QmlMetaType::isObject(const QMetaObject *mo)
-{
- // ### Huh?
- while(mo) {
- if (mo == &QObject::staticMetaObject)
- return true;
- mo = mo->superClass();
- }
- return false;
-}
-
bool QmlMetaType::isQmlList(int userType)
{
QReadLocker lock(metaTypeDataLock());
@@ -851,6 +811,9 @@ int QmlMetaType::listCount(const QVariant &v)
QVariant QmlMetaType::listAt(const QVariant &v, int idx)
{
+ if (idx < 0)
+ return QVariant();
+
int userType = v.userType();
QReadLocker lock(metaTypeDataLock());
@@ -861,7 +824,7 @@ QVariant QmlMetaType::listAt(const QVariant &v, int idx)
if (type && type->qListTypeId() == userType)
return type->listAt(v, idx);
else
- return 0;
+ return QVariant();
}
/*!
diff --git a/src/declarative/qml/qmlmetatype.h b/src/declarative/qml/qmlmetatype.h
index e90c367..1f493f8 100644
--- a/src/declarative/qml/qmlmetatype.h
+++ b/src/declarative/qml/qmlmetatype.h
@@ -97,7 +97,6 @@ public:
static bool isInterface(int);
static const char *interfaceIId(int);
static bool isObject(int);
- static bool isObject(const QMetaObject *);
static bool isList(int);
static bool isList(const QVariant &);
static bool isQmlList(int);
@@ -121,8 +120,6 @@ public:
int minorVersion() const;
bool availableInVersion(int vmajor, int vminor) const;
- QByteArray hash() const;
-
QObject *create() const;
QmlCustomParser *customParser() const;
diff --git a/src/declarative/qml/qmlprivate.h b/src/declarative/qml/qmlprivate.h
index e5b1060..0eec43c 100644
--- a/src/declarative/qml/qmlprivate.h
+++ b/src/declarative/qml/qmlprivate.h
@@ -283,7 +283,8 @@ int QmlPrivate::list_op(QmlPrivate::ListOp op, int val,
}
break;
case QmlPrivate::Value:
- *((QVariant *)*out) = QVariant::fromValue(list->at(val));
+ if (list->count() <= val) *((QVariant *)*out) = QVariant();
+ else *((QVariant *)*out) = QVariant::fromValue(list->at(val));
break;
}
return 0;
diff --git a/tests/auto/declarative/qmlmetatype/tst_qmlmetatype.cpp b/tests/auto/declarative/qmlmetatype/tst_qmlmetatype.cpp
index ed102a5..b481ce4 100644
--- a/tests/auto/declarative/qmlmetatype/tst_qmlmetatype.cpp
+++ b/tests/auto/declarative/qmlmetatype/tst_qmlmetatype.cpp
@@ -51,6 +51,7 @@
#include <QVector3D>
#include <QVector4D>
#include <QQuaternion>
+#include <qml.h>
class tst_qmlmetatype : public QObject
{
@@ -60,8 +61,62 @@ public:
private slots:
void copy();
+
+ void qmlParserStatusCast();
+ void qmlPropertyValueSourceCast();
+ void qmlPropertyValueInterceptorCast();
+
+ void isList();
+ void isQmlList();
+
+ void listCount();
+ void listAt();
+
+ void defaultObject();
};
+class TestType : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int foo READ foo);
+
+ Q_CLASSINFO("DefaultProperty", "foo");
+public:
+ int foo() { return 0; }
+};
+QML_DECLARE_TYPE(TestType);
+QML_DEFINE_TYPE(Test, 1, 0, TestType, TestType);
+
+class ParserStatusTestType : public QObject, public QmlParserStatus
+{
+ Q_OBJECT
+ Q_CLASSINFO("DefaultProperty", "foo"); // Missing default property
+};
+QML_DECLARE_TYPE(ParserStatusTestType);
+QML_DEFINE_TYPE(Test, 1, 0, ParserStatusTestType, ParserStatusTestType);
+
+class ValueSourceTestType : public QObject, public QmlPropertyValueSource
+{
+ Q_OBJECT
+ Q_INTERFACES(QmlPropertyValueSource)
+public:
+ virtual void setTarget(const QmlMetaProperty &) {}
+};
+QML_DECLARE_TYPE(ValueSourceTestType);
+QML_DEFINE_TYPE(Test, 1, 0, ValueSourceTestType, ValueSourceTestType);
+
+class ValueInterceptorTestType : public QObject, public QmlPropertyValueInterceptor
+{
+ Q_OBJECT
+ Q_INTERFACES(QmlPropertyValueInterceptor)
+public:
+ virtual void setTarget(const QmlMetaProperty &) {}
+ virtual void write(const QVariant &) {}
+};
+QML_DECLARE_TYPE(ValueInterceptorTestType);
+QML_DEFINE_TYPE(Test, 1, 0, ValueInterceptorTestType, ValueInterceptorTestType);
+
+
#define COPY_TEST(cpptype, metatype, value, defaultvalue) \
{ \
cpptype v = (value); cpptype v2 = (value); \
@@ -181,6 +236,7 @@ void tst_qmlmetatype::copy()
QT_COPY_TEST(QKeySequence, QKeySequence("Ctrl+O"));
QT_COPY_TEST(QPen, QPen(Qt::red));
QT_COPY_TEST(QTextLength, QTextLength(QTextLength::FixedLength, 10.2));
+ QT_COPY_TEST(QTextFormat, QTextFormat(QTextFormat::ListFormat));
QT_COPY_TEST(QMatrix, QMatrix().translate(10, 10));
QT_COPY_TEST(QTransform, QTransform().translate(10, 10));
QT_COPY_TEST(QMatrix4x4, QMatrix4x4().translate(10, 10));
@@ -204,6 +260,175 @@ void tst_qmlmetatype::copy()
COPY_TEST(QObject *, QObjectStar, &objectValue, 0);
COPY_TEST(QWidget *, QWidgetStar, &widgetValue, 0);
COPY_TEST(qreal, QReal, 10.2, 0);
+
+ {
+ QVariant tv = QVariant::fromValue(QVariant(10));
+ QVariant v(tv); QVariant v2(tv);
+ QVERIFY(QmlMetaType::copy(qMetaTypeId<QVariant>(), &v, 0));
+ QVERIFY(v == QVariant());
+ QVERIFY(QmlMetaType::copy(qMetaTypeId<QVariant>(), &v, &v2));
+ QVERIFY(v == tv);
+ }
+
+ {
+ TestType t; QVariant tv = QVariant::fromValue(&t);
+
+ QVariant v(tv); QVariant v2(tv);
+ QVERIFY(QmlMetaType::copy(qMetaTypeId<TestType *>(), &v, 0));
+ QVERIFY(v == QVariant::fromValue((TestType *)0));
+ QVERIFY(QmlMetaType::copy(qMetaTypeId<TestType *>(), &v, &v2));
+ QVERIFY(v == tv);
+ }
+}
+
+void tst_qmlmetatype::qmlParserStatusCast()
+{
+ QCOMPARE(QmlMetaType::qmlParserStatusCast(QVariant::Int), -1);
+ QCOMPARE(QmlMetaType::qmlParserStatusCast(qMetaTypeId<TestType *>()), -1);
+ QCOMPARE(QmlMetaType::qmlParserStatusCast(qMetaTypeId<ValueSourceTestType *>()), -1);
+
+ int cast = QmlMetaType::qmlParserStatusCast(qMetaTypeId<ParserStatusTestType *>());
+ QVERIFY(cast != -1);
+ QVERIFY(cast != 0);
+
+ ParserStatusTestType t;
+ QVERIFY(reinterpret_cast<char *>((QObject *)&t) != reinterpret_cast<char *>((QmlParserStatus *)&t));
+
+ QmlParserStatus *status = reinterpret_cast<QmlParserStatus *>(reinterpret_cast<char *>((QObject *)&t) + cast);
+ QCOMPARE(status, &t);
+}
+
+void tst_qmlmetatype::qmlPropertyValueSourceCast()
+{
+ QCOMPARE(QmlMetaType::qmlPropertyValueSourceCast(QVariant::Int), -1);
+ QCOMPARE(QmlMetaType::qmlPropertyValueSourceCast(qMetaTypeId<TestType *>()), -1);
+ QCOMPARE(QmlMetaType::qmlPropertyValueSourceCast(qMetaTypeId<ParserStatusTestType *>()), -1);
+
+ int cast = QmlMetaType::qmlPropertyValueSourceCast(qMetaTypeId<ValueSourceTestType *>());
+ QVERIFY(cast != -1);
+ QVERIFY(cast != 0);
+
+ ValueSourceTestType t;
+ QVERIFY(reinterpret_cast<char *>((QObject *)&t) != reinterpret_cast<char *>((QmlPropertyValueSource *)&t));
+
+ QmlPropertyValueSource *source = reinterpret_cast<QmlPropertyValueSource *>(reinterpret_cast<char *>((QObject *)&t) + cast);
+ QCOMPARE(source, &t);
+}
+
+void tst_qmlmetatype::qmlPropertyValueInterceptorCast()
+{
+ QCOMPARE(QmlMetaType::qmlPropertyValueInterceptorCast(QVariant::Int), -1);
+ QCOMPARE(QmlMetaType::qmlPropertyValueInterceptorCast(qMetaTypeId<TestType *>()), -1);
+ QCOMPARE(QmlMetaType::qmlPropertyValueInterceptorCast(qMetaTypeId<ParserStatusTestType *>()), -1);
+
+ int cast = QmlMetaType::qmlPropertyValueInterceptorCast(qMetaTypeId<ValueInterceptorTestType *>());
+ QVERIFY(cast != -1);
+ QVERIFY(cast != 0);
+
+ ValueInterceptorTestType t;
+ QVERIFY(reinterpret_cast<char *>((QObject *)&t) != reinterpret_cast<char *>((QmlPropertyValueInterceptor *)&t));
+
+ QmlPropertyValueInterceptor *interceptor = reinterpret_cast<QmlPropertyValueInterceptor *>(reinterpret_cast<char *>((QObject *)&t) + cast);
+ QCOMPARE(interceptor, &t);
+}
+
+void tst_qmlmetatype::isList()
+{
+ QCOMPARE(QmlMetaType::isList(QVariant()), false);
+ QCOMPARE(QmlMetaType::isList(QVariant::Invalid), false);
+ QCOMPARE(QmlMetaType::isList(QVariant::Int), false);
+ QCOMPARE(QmlMetaType::isList(QVariant(10)), false);
+
+ QList<TestType *> list;
+ QmlConcreteList<TestType *> qmllist;
+
+ QCOMPARE(QmlMetaType::isList(qMetaTypeId<QList<TestType *>*>()), true);
+ QCOMPARE(QmlMetaType::isList(QVariant::fromValue(&list)), true);
+ QCOMPARE(QmlMetaType::isList(qMetaTypeId<QmlList<TestType *>*>()), false);
+ QCOMPARE(QmlMetaType::isList(QVariant::fromValue((QmlList<TestType *>*)&qmllist)), false);
+}
+
+void tst_qmlmetatype::isQmlList()
+{
+ QCOMPARE(QmlMetaType::isQmlList(QVariant::Invalid), false);
+ QCOMPARE(QmlMetaType::isQmlList(QVariant::Int), false);
+
+ QCOMPARE(QmlMetaType::isQmlList(qMetaTypeId<QList<TestType *>*>()), false);
+ QCOMPARE(QmlMetaType::isQmlList(qMetaTypeId<QmlList<TestType *>*>()), true);
+}
+
+void tst_qmlmetatype::listCount()
+{
+ QCOMPARE(QmlMetaType::listCount(QVariant()), 0);
+ QCOMPARE(QmlMetaType::listCount(QVariant(10)), 0);
+
+ QList<TestType *> list;
+ QVariant listVar = QVariant::fromValue(&list);
+ QmlConcreteList<TestType *> qmllist;
+ QVariant qmllistVar = QVariant::fromValue((QmlList<TestType *>*)&qmllist);
+
+ QCOMPARE(QmlMetaType::listCount(listVar), 0);
+ QCOMPARE(QmlMetaType::listCount(qmllistVar), 0);
+
+ list.append(0); list.append(0); list.append(0);
+ qmllist.append(0); qmllist.append(0); qmllist.append(0);
+
+ QCOMPARE(QmlMetaType::listCount(listVar), 3);
+ QCOMPARE(QmlMetaType::listCount(qmllistVar), 0);
+}
+
+void tst_qmlmetatype::listAt()
+{
+ QCOMPARE(QmlMetaType::listAt(QVariant(), 0), QVariant());
+ QCOMPARE(QmlMetaType::listAt(QVariant(10), 0), QVariant());
+ QCOMPARE(QmlMetaType::listAt(QVariant(), 10), QVariant());
+ QCOMPARE(QmlMetaType::listAt(QVariant(10), 10), QVariant());
+ QCOMPARE(QmlMetaType::listAt(QVariant(), -10), QVariant());
+ QCOMPARE(QmlMetaType::listAt(QVariant(10), -10), QVariant());
+
+ QList<TestType *> list;
+ QVariant listVar = QVariant::fromValue(&list);
+ QmlConcreteList<TestType *> qmllist;
+ QVariant qmllistVar = QVariant::fromValue((QmlList<TestType *>*)&qmllist);
+
+ QCOMPARE(QmlMetaType::listAt(listVar, 0), QVariant());
+ QCOMPARE(QmlMetaType::listAt(listVar, 2), QVariant());
+ QCOMPARE(QmlMetaType::listAt(listVar, -1), QVariant());
+
+ QCOMPARE(QmlMetaType::listAt(qmllistVar, 0), QVariant());
+ QCOMPARE(QmlMetaType::listAt(qmllistVar, 2), QVariant());
+ QCOMPARE(QmlMetaType::listAt(qmllistVar, -1), QVariant());
+
+ TestType ttype;
+ QVariant ttypeVar = QVariant::fromValue(&ttype);
+ QVariant nullttypeVar = QVariant::fromValue((TestType *)0);
+
+ list.append(0); list.append(&ttype); list.append(0);
+ qmllist.append(0); qmllist.append(&ttype); qmllist.append(0);
+
+ QCOMPARE(QmlMetaType::listAt(listVar, 0), nullttypeVar);
+ QCOMPARE(QmlMetaType::listAt(listVar, 1), ttypeVar);
+ QCOMPARE(QmlMetaType::listAt(listVar, -1), QVariant());
+
+ QCOMPARE(QmlMetaType::listAt(qmllistVar, 0), QVariant());
+ QCOMPARE(QmlMetaType::listAt(qmllistVar, 2), QVariant());
+ QCOMPARE(QmlMetaType::listAt(qmllistVar, -1), QVariant());
+}
+
+void tst_qmlmetatype::defaultObject()
+{
+ QVERIFY(QmlMetaType::defaultProperty(&QObject::staticMetaObject).name() == 0);
+ QVERIFY(QmlMetaType::defaultProperty(&ParserStatusTestType::staticMetaObject).name() == 0);
+ QCOMPARE(QString(QmlMetaType::defaultProperty(&TestType::staticMetaObject).name()), QString("foo"));
+
+ QObject o;
+ TestType t;
+ ParserStatusTestType p;
+
+ QVERIFY(QmlMetaType::defaultProperty((QObject *)0).name() == 0);
+ QVERIFY(QmlMetaType::defaultProperty(&o).name() == 0);
+ QVERIFY(QmlMetaType::defaultProperty(&p).name() == 0);
+ QCOMPARE(QString(QmlMetaType::defaultProperty(&t).name()), QString("foo"));
}
QTEST_MAIN(tst_qmlmetatype)