diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2010-09-03 09:53:43 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2010-09-03 09:53:43 (GMT) |
commit | d4a2b1694a2cd315cebfb3592c0da3ce3288ef9b (patch) | |
tree | 7a7b00f3b084086efabf8d2d6bb88f244812789a | |
parent | 9c726c2f2791f82de52f54ffc1f580630d10c61d (diff) | |
parent | 1dc5853f7dc40fd18cc5674d89ebc327514449f4 (diff) | |
download | Qt-d4a2b1694a2cd315cebfb3592c0da3ce3288ef9b.zip Qt-d4a2b1694a2cd315cebfb3592c0da3ce3288ef9b.tar.gz Qt-d4a2b1694a2cd315cebfb3592c0da3ce3288ef9b.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-qml into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/qt-qml:
Cleanup visible item checking in positioners
Missing file
Fix the same bug that was in the demo samegame, in the tutorial version
qreal == float fixes
Don't modify the signal order on the second dynamic meta object pass
Doc
Support passing QObject derived types to QML methods
14 files changed, 138 insertions, 37 deletions
diff --git a/doc/src/declarative/extending.qdoc b/doc/src/declarative/extending.qdoc index 6388764..0cc989d 100644 --- a/doc/src/declarative/extending.qdoc +++ b/doc/src/declarative/extending.qdoc @@ -674,6 +674,16 @@ declaring a new property, and the corresponding C++ type. \row \o variant \o QVariant \endtable +From QML you can also declare object and list properties using any element name +like this: + +\code + property QtObject objectProperty + property Item itemProperty + property MyCustomType customProperty + property list<Item> listOfItemsProperty +\endcode + QML supports two methods for adding a new property to a type: a new property definition, and a property alias. diff --git a/examples/declarative/tutorials/samegame/samegame4/content/samegame.js b/examples/declarative/tutorials/samegame/samegame4/content/samegame.js index b1f427c..79ff0c1 100755 --- a/examples/declarative/tutorials/samegame/samegame4/content/samegame.js +++ b/examples/declarative/tutorials/samegame/samegame4/content/samegame.js @@ -127,7 +127,7 @@ function shuffleDown() { } else { if (fallDist > 0) { var obj = board[index(column, row)]; - obj.y += fallDist * gameCanvas.blockSize; + obj.y = (row + fallDist) * gameCanvas.blockSize; board[index(column, row + fallDist)] = obj; board[index(column, row)] = null; } @@ -145,7 +145,7 @@ function shuffleDown() { obj = board[index(column, row)]; if (obj == null) continue; - obj.x -= fallDist * gameCanvas.blockSize; + obj.x = (fallDist - column) * gameCanvas.blockSize; board[index(column - fallDist, row)] = obj; board[index(column, row)] = null; } diff --git a/src/declarative/graphicsitems/qdeclarativepositioners.cpp b/src/declarative/graphicsitems/qdeclarativepositioners.cpp index b776b8e..77b26b9 100644 --- a/src/declarative/graphicsitems/qdeclarativepositioners.cpp +++ b/src/declarative/graphicsitems/qdeclarativepositioners.cpp @@ -247,13 +247,13 @@ void QDeclarativeBasePositioner::prePositioning() positionedItems.append(posItem); item = &positionedItems[positionedItems.count()-1]; item->isNew = true; - if (child->opacity() <= 0.0 || childPrivate->explicitlyHidden) + if (child->opacity() <= 0.0 || childPrivate->explicitlyHidden || !childPrivate->width() || !childPrivate->height()) item->isVisible = false; } else { item = &oldItems[wIdx]; // Items are only omitted from positioning if they are explicitly hidden // i.e. their positioning is not affected if an ancestor is hidden. - if (child->opacity() <= 0.0 || childPrivate->explicitlyHidden) { + if (child->opacity() <= 0.0 || childPrivate->explicitlyHidden || !childPrivate->width() || !childPrivate->height()) { item->isVisible = false; } else if (!item->isVisible) { item->isVisible = true; @@ -321,12 +321,6 @@ void QDeclarativeBasePositioner::finishApplyTransitions() d->moveActions.clear(); } -static inline bool isInvisible(QGraphicsObject *child) -{ - QGraphicsItemPrivate *childPrivate = static_cast<QGraphicsItemPrivate*>(QGraphicsItemPrivate::get(child)); - return child->opacity() == 0.0 || childPrivate->explicitlyHidden || !childPrivate->width() || !childPrivate->height(); -} - /*! \qmlclass Column QDeclarativeColumn \ingroup qml-positioning-elements @@ -449,7 +443,7 @@ void QDeclarativeColumn::doPositioning(QSizeF *contentSize) for (int ii = 0; ii < positionedItems.count(); ++ii) { const PositionedItem &child = positionedItems.at(ii); - if (!child.item || isInvisible(child.item)) + if (!child.item || !child.isVisible) continue; if(child.item->y() != voffset) @@ -584,7 +578,7 @@ void QDeclarativeRow::doPositioning(QSizeF *contentSize) for (int ii = 0; ii < positionedItems.count(); ++ii) { const PositionedItem &child = positionedItems.at(ii); - if (!child.item || isInvisible(child.item)) + if (!child.item || !child.isVisible) continue; if(child.item->x() != hoffset) @@ -793,9 +787,17 @@ void QDeclarativeGrid::setFlow(Flow flow) void QDeclarativeGrid::doPositioning(QSizeF *contentSize) { + int c = m_columns; int r = m_rows; - int numVisible = positionedItems.count(); + //Is allocating the extra QPODVector too much overhead? + QPODVector<PositionedItem, 8> visibleItems;//we aren't concerned with invisible items + visibleItems.reserve(positionedItems.count()); + for(int i=0; i<positionedItems.count(); i++) + if(positionedItems[i].item && positionedItems[i].isVisible) + visibleItems.append(positionedItems[i]); + + int numVisible = visibleItems.count(); if (m_columns <= 0 && m_rows <= 0){ c = 4; r = (numVisible+3)/4; @@ -816,11 +818,10 @@ void QDeclarativeGrid::doPositioning(QSizeF *contentSize) if (i==0) maxColWidth << 0; - if (childIndex == positionedItems.count()) - continue; - const PositionedItem &child = positionedItems.at(childIndex++); - if (!child.item || isInvisible(child.item)) - continue; + if (childIndex == visibleItems.count()) + break; + + const PositionedItem &child = visibleItems.at(childIndex++); QGraphicsItemPrivate *childPrivate = QGraphicsItemPrivate::get(child.item); if (childPrivate->width() > maxColWidth[j]) maxColWidth[j] = childPrivate->width(); @@ -837,10 +838,9 @@ void QDeclarativeGrid::doPositioning(QSizeF *contentSize) maxColWidth << 0; if (childIndex == positionedItems.count()) - continue; - const PositionedItem &child = positionedItems.at(childIndex++); - if (!child.item || isInvisible(child.item)) - continue; + break; + + const PositionedItem &child = visibleItems.at(childIndex++); QGraphicsItemPrivate *childPrivate = QGraphicsItemPrivate::get(child.item); if (childPrivate->width() > maxColWidth[j]) maxColWidth[j] = childPrivate->width(); @@ -854,10 +854,8 @@ void QDeclarativeGrid::doPositioning(QSizeF *contentSize) int yoffset=0; int curRow =0; int curCol =0; - for (int i = 0; i < positionedItems.count(); ++i) { - const PositionedItem &child = positionedItems.at(i); - if (!child.item || isInvisible(child.item)) - continue; + for (int i = 0; i < visibleItems.count(); ++i) { + const PositionedItem &child = visibleItems.at(i); if((child.item->x()!=xoffset)||(child.item->y()!=yoffset)){ positionX(xoffset, child); positionY(yoffset, child); @@ -1033,7 +1031,7 @@ void QDeclarativeFlow::doPositioning(QSizeF *contentSize) for (int i = 0; i < positionedItems.count(); ++i) { const PositionedItem &child = positionedItems.at(i); - if (!child.item || isInvisible(child.item)) + if (!child.item || !child.isVisible) continue; QGraphicsItemPrivate *childPrivate = QGraphicsItemPrivate::get(child.item); diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index 7847303..61ea9c8 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -2416,13 +2416,17 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn propBuilder.setWritable(!readonly); } - if (mode == ResolveAliases) { - for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) { - const Object::DynamicProperty &p = obj->dynamicProperties.at(ii); + for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) { + const Object::DynamicProperty &p = obj->dynamicProperties.at(ii); - if (p.type == Object::DynamicProperty::Alias) { + if (p.type == Object::DynamicProperty::Alias) { + if (mode == ResolveAliases) { ((QDeclarativeVMEMetaData *)dynamicData.data())->aliasCount++; compileAlias(builder, dynamicData, obj, p); + } else { + // Need a fake signal so that the metaobject remains consistent across + // the resolve and non-resolve alias runs + builder.addSignal(p.name + "Changed()"); } } } diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 8461368..e77a53e 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -2113,7 +2113,7 @@ bool QDeclarativeEnginePrivate::isQObject(int t) QObject *QDeclarativeEnginePrivate::toQObject(const QVariant &v, bool *ok) const { int t = v.userType(); - if (m_compositeTypes.contains(t)) { + if (t == QMetaType::QObjectStar || m_compositeTypes.contains(t)) { if (ok) *ok = true; return *(QObject **)(v.constData()); } else { diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp index f439151..9d74238 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp @@ -625,11 +625,12 @@ private: char data[4 * sizeof(void *)]; int type; + bool isObjectType; }; } MetaCallArgument::MetaCallArgument() -: type(QVariant::Invalid) +: type(QVariant::Invalid), isObjectType(false) { } @@ -744,12 +745,23 @@ void MetaCallArgument::fromScriptValue(int callType, QDeclarativeEngine *engine, new (&data) QVariant(); type = -1; - QVariant v = QDeclarativeEnginePrivate::get(engine)->scriptValueToVariant(value); + QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(engine); + QVariant v = priv->scriptValueToVariant(value); if (v.userType() == callType) { *((QVariant *)&data) = v; } else if (v.canConvert((QVariant::Type)callType)) { *((QVariant *)&data) = v; ((QVariant *)&data)->convert((QVariant::Type)callType); + } else if (const QMetaObject *mo = priv->rawMetaObjectForType(callType)) { + QObject *obj = priv->toQObject(v); + + if (obj) { + const QMetaObject *objMo = obj->metaObject(); + while (objMo && objMo != mo) objMo = objMo->superClass(); + if (!objMo) obj = 0; + } + + *((QVariant *)&data) = QVariant(callType, &obj); } else { *((QVariant *)&data) = QVariant(callType, (void *)0); } diff --git a/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp b/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp index f06d6ae..60f2cb3 100644 --- a/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp +++ b/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp @@ -168,7 +168,7 @@ void QDeclarativeValueTypeScriptClass::setProperty(Object *obj, const Identifier ref->type->read(ref->object, ref->property); QMetaProperty p = ref->type->metaObject()->property(m_lastIndex); - if (p.isEnumType() && (QMetaType::Type)v.type() == QMetaType::QReal) + if (p.isEnumType() && (QMetaType::Type)v.type() == QMetaType::Double) v = v.toInt(); p.write(ref->type, v); ref->type->write(ref->object, ref->property, 0); diff --git a/tests/auto/declarative/qdeclarativedom/tst_qdeclarativedom.cpp b/tests/auto/declarative/qdeclarativedom/tst_qdeclarativedom.cpp index 5028ba1..dca5205 100644 --- a/tests/auto/declarative/qdeclarativedom/tst_qdeclarativedom.cpp +++ b/tests/auto/declarative/qdeclarativedom/tst_qdeclarativedom.cpp @@ -480,7 +480,7 @@ void tst_qdeclarativedom::loadDynamicProperty() DP_TEST(0, a, QVariant::Int, 25, 14, "int"); DP_TEST(1, b, QVariant::Bool, 44, 15, "bool"); - DP_TEST(2, c, QVariant::Double, 64, 17, "double"); + DP_TEST(2, c, QMetaType::QReal, 64, 17, "double"); DP_TEST(3, d, QMetaType::QReal, 86, 15, "real"); DP_TEST(4, e, QVariant::String, 106, 17, "string"); DP_TEST(5, f, QVariant::Url, 128, 14, "url"); diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/invokableObjectArg.qml b/tests/auto/declarative/qdeclarativeecmascript/data/invokableObjectArg.qml new file mode 100644 index 0000000..d5d3329 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/invokableObjectArg.qml @@ -0,0 +1,9 @@ +import Qt.test 1.0 +import Qt 4.7 + +MyQmlObject { + id: root + Component.onCompleted: { + root.myinvokable(root); + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/invokableObjectRet.qml b/tests/auto/declarative/qdeclarativeecmascript/data/invokableObjectRet.qml new file mode 100644 index 0000000..29d7d01 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/invokableObjectRet.qml @@ -0,0 +1,11 @@ +import Qt.test 1.0 +import Qt 4.7 + +MyQmlObject { + id: root + property bool test: false + Component.onCompleted: { + test = (root.returnme() == root) + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h index 7d7e3d9..220318d 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h +++ b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h @@ -95,7 +95,7 @@ class MyQmlObject : public QObject Q_PROPERTY(int nonscriptable READ nonscriptable WRITE setNonscriptable SCRIPTABLE false); public: - MyQmlObject(): m_methodCalled(false), m_methodIntCalled(false), m_object(0), m_value(0), m_resetProperty(13) {} + MyQmlObject(): myinvokableObject(0), m_methodCalled(false), m_methodIntCalled(false), m_object(0), m_value(0), m_resetProperty(13) {} enum MyEnum { EnumValue1 = 0, EnumValue2 = 1 }; enum MyEnum2 { EnumValue3 = 2, EnumValue4 = 3 }; @@ -149,6 +149,9 @@ public: int nonscriptable() const { return 0; } void setNonscriptable(int) {} + MyQmlObject *myinvokableObject; + Q_INVOKABLE MyQmlObject *returnme() { return this; } + signals: void basicSignal(); void argumentSignal(int a, QString b, qreal c); @@ -162,6 +165,7 @@ public slots: void methodNoArgs() { m_methodCalled = true; } void method(int a) { if(a == 163) m_methodIntCalled = true; } void setString(const QString &s) { m_string = s; } + void myinvokable(MyQmlObject *o) { myinvokableObject = o; } private: friend class tst_qdeclarativeecmascript; diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index 76ca964..33bf7ea 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -164,6 +164,8 @@ private slots: void include(); void callQtInvokables(); + void invokableObjectArg(); + void invokableObjectRet(); private: QDeclarativeEngine engine; }; @@ -1733,6 +1735,31 @@ void tst_qdeclarativeecmascript::callQtInvokables() QCOMPARE(o.actuals().at(0), QVariant(9)); } +// QTBUG-13047 (check that you can pass registered object types as args) +void tst_qdeclarativeecmascript::invokableObjectArg() +{ + QDeclarativeComponent component(&engine, TEST_FILE("invokableObjectArg.qml")); + + QObject *o = component.create(); + QVERIFY(o); + MyQmlObject *qmlobject = qobject_cast<MyQmlObject *>(o); + QVERIFY(qmlobject); + QCOMPARE(qmlobject->myinvokableObject, qmlobject); + + delete o; +} + +// QTBUG-13047 (check that you can return registered object types from methods) +void tst_qdeclarativeecmascript::invokableObjectRet() +{ + QDeclarativeComponent component(&engine, TEST_FILE("invokableObjectRet.qml")); + + QObject *o = component.create(); + QVERIFY(o); + QCOMPARE(o->property("test").toBool(), true); + delete o; +} + // QTBUG-5675 void tst_qdeclarativeecmascript::listToVariant() { diff --git a/tests/auto/declarative/qdeclarativelanguage/data/aliasPropertiesAndSignals.qml b/tests/auto/declarative/qdeclarativelanguage/data/aliasPropertiesAndSignals.qml new file mode 100644 index 0000000..59afe58 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/aliasPropertiesAndSignals.qml @@ -0,0 +1,14 @@ +import Qt 4.7 + +QtObject { + id: root + + property bool test: false + property alias myalias: root.objectName + signal go + onGo: test = true + + Component.onCompleted: { + root.go(); + } +} diff --git a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp index dc00e16..1825991 100644 --- a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp +++ b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp @@ -118,6 +118,7 @@ private slots: void valueTypes(); void cppnamespace(); void aliasProperties(); + void aliasPropertiesAndSignals(); void componentCompositeType(); void i18n(); void i18n_data(); @@ -1051,6 +1052,17 @@ void tst_qdeclarativelanguage::aliasProperties() } } +// QTBUG-13374 Test that alias properties and signals can coexist +void tst_qdeclarativelanguage::aliasPropertiesAndSignals() +{ + QDeclarativeComponent component(&engine, TEST_FILE("aliasPropertiesAndSignals.qml")); + VERIFY_ERRORS(0); + QObject *o = component.create(); + QVERIFY(o); + QCOMPARE(o->property("test").toBool(), true); + delete o; +} + // Test that the root element in a composite type can be a Component void tst_qdeclarativelanguage::componentCompositeType() { |