diff options
-rw-r--r-- | src/declarative/qml/qmlmetatype.cpp | 45 | ||||
-rw-r--r-- | src/declarative/qml/qmlmetatype.h | 3 | ||||
-rw-r--r-- | src/declarative/qml/qmlprivate.h | 3 | ||||
-rw-r--r-- | tests/auto/declarative/qmlmetatype/tst_qmlmetatype.cpp | 225 |
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) |