From 774cb9eca9ea243436dbf61cdb7081fc270cdec9 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Tue, 15 Mar 2011 10:25:54 +1000 Subject: Remove bindings before assigning constants in VME Change-Id: I4c246cbcf8d0168cb4af028d6d04088fe20cdbba Task-number: QTBUG-17276 --- src/declarative/qml/qdeclarativevme.cpp | 63 ++++++++++++++++++++++ .../data/InlineAssignmentsOverrideBindingsType.qml | 7 +++ .../InlineAssignmentsOverrideBindingsType2.qml | 5 ++ .../data/inlineAssignmentsOverrideBindings.qml | 6 +++ .../tst_qdeclarativelanguage.cpp | 12 ++++- 5 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 tests/auto/declarative/qdeclarativelanguage/data/InlineAssignmentsOverrideBindingsType.qml create mode 100644 tests/auto/declarative/qdeclarativelanguage/data/InlineAssignmentsOverrideBindingsType2.qml create mode 100644 tests/auto/declarative/qdeclarativelanguage/data/inlineAssignmentsOverrideBindings.qml diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp index 2d551f2..781e1b8 100644 --- a/src/declarative/qml/qdeclarativevme.cpp +++ b/src/declarative/qml/qdeclarativevme.cpp @@ -127,6 +127,22 @@ void QDeclarativeVME::runDeferred(QObject *object) run(stack, ctxt, comp, start, count, QBitField()); } +inline bool fastHasBinding(QObject *o, int index) +{ + QDeclarativeData *ddata = static_cast(QObjectPrivate::get(o)->declarativeData); + + return ddata && (ddata->bindingBitsSize > index) && + (ddata->bindingBits[index / 32] & (1 << (index % 32))); +} + +static void removeBindingOnProperty(QObject *o, int index) +{ + QDeclarativeAbstractBinding *binding = QDeclarativePropertyPrivate::setBinding(o, index, -1, 0); + if (binding) binding->destroy(); +} + +#define CLEAN_PROPERTY(o, index) if (fastHasBinding(o, index)) removeBindingOnProperty(o, index) + QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, QDeclarativeContextData *ctxt, QDeclarativeCompiledData *comp, @@ -336,6 +352,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, case QDeclarativeInstruction::StoreVariant: { QObject *target = stack.top(); + CLEAN_PROPERTY(target, instr.storeString.propertyIndex); + // XXX - can be more efficient QVariant v = QDeclarativeStringConverters::variantFromString(primitives.at(instr.storeString.value)); void *a[] = { &v, 0, &status, &flags }; @@ -347,6 +365,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, case QDeclarativeInstruction::StoreVariantInteger: { QObject *target = stack.top(); + CLEAN_PROPERTY(target, instr.storeString.propertyIndex); + QVariant v(instr.storeInteger.value); void *a[] = { &v, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, @@ -357,6 +377,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, case QDeclarativeInstruction::StoreVariantDouble: { QObject *target = stack.top(); + CLEAN_PROPERTY(target, instr.storeString.propertyIndex); + QVariant v(instr.storeDouble.value); void *a[] = { &v, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, @@ -367,6 +389,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, case QDeclarativeInstruction::StoreVariantBool: { QObject *target = stack.top(); + CLEAN_PROPERTY(target, instr.storeString.propertyIndex); + QVariant v(instr.storeBool.value); void *a[] = { &v, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, @@ -377,6 +401,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, case QDeclarativeInstruction::StoreString: { QObject *target = stack.top(); + CLEAN_PROPERTY(target, instr.storeString.propertyIndex); + void *a[] = { (void *)&primitives.at(instr.storeString.value), 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.storeString.propertyIndex, a); @@ -386,6 +412,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, case QDeclarativeInstruction::StoreUrl: { QObject *target = stack.top(); + CLEAN_PROPERTY(target, instr.storeUrl.propertyIndex); + void *a[] = { (void *)&urls.at(instr.storeUrl.value), 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.storeUrl.propertyIndex, a); @@ -395,6 +423,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, case QDeclarativeInstruction::StoreFloat: { QObject *target = stack.top(); + CLEAN_PROPERTY(target, instr.storeFloat.propertyIndex); + float f = instr.storeFloat.value; void *a[] = { &f, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, @@ -405,6 +435,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, case QDeclarativeInstruction::StoreDouble: { QObject *target = stack.top(); + CLEAN_PROPERTY(target, instr.storeDouble.propertyIndex); + double d = instr.storeDouble.value; void *a[] = { &d, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, @@ -415,6 +447,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, case QDeclarativeInstruction::StoreBool: { QObject *target = stack.top(); + CLEAN_PROPERTY(target, instr.storeBool.propertyIndex); + void *a[] = { (void *)&instr.storeBool.value, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.storeBool.propertyIndex, a); @@ -424,6 +458,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, case QDeclarativeInstruction::StoreInteger: { QObject *target = stack.top(); + CLEAN_PROPERTY(target, instr.storeInteger.propertyIndex); + void *a[] = { (void *)&instr.storeInteger.value, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, instr.storeInteger.propertyIndex, a); @@ -433,6 +469,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, case QDeclarativeInstruction::StoreColor: { QObject *target = stack.top(); + CLEAN_PROPERTY(target, instr.storeColor.propertyIndex); + QColor c = QColor::fromRgba(instr.storeColor.value); void *a[] = { &c, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, @@ -443,6 +481,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, case QDeclarativeInstruction::StoreDate: { QObject *target = stack.top(); + CLEAN_PROPERTY(target, instr.storeDate.propertyIndex); + QDate d = QDate::fromJulianDay(instr.storeDate.value); void *a[] = { &d, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, @@ -453,6 +493,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, case QDeclarativeInstruction::StoreTime: { QObject *target = stack.top(); + CLEAN_PROPERTY(target, instr.storeTime.propertyIndex); + QTime t; t.setHMS(intData.at(instr.storeTime.valueIndex), intData.at(instr.storeTime.valueIndex+1), @@ -467,6 +509,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, case QDeclarativeInstruction::StoreDateTime: { QObject *target = stack.top(); + CLEAN_PROPERTY(target, instr.storeDateTime.propertyIndex); + QTime t; t.setHMS(intData.at(instr.storeDateTime.valueIndex+1), intData.at(instr.storeDateTime.valueIndex+2), @@ -482,6 +526,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, case QDeclarativeInstruction::StorePoint: { QObject *target = stack.top(); + CLEAN_PROPERTY(target, instr.storeRealPair.propertyIndex); + QPoint p = QPointF(floatData.at(instr.storeRealPair.valueIndex), floatData.at(instr.storeRealPair.valueIndex+1)).toPoint(); void *a[] = { &p, 0, &status, &flags }; @@ -493,6 +539,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, case QDeclarativeInstruction::StorePointF: { QObject *target = stack.top(); + CLEAN_PROPERTY(target, instr.storeRealPair.propertyIndex); + QPointF p(floatData.at(instr.storeRealPair.valueIndex), floatData.at(instr.storeRealPair.valueIndex+1)); void *a[] = { &p, 0, &status, &flags }; @@ -504,6 +552,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, case QDeclarativeInstruction::StoreSize: { QObject *target = stack.top(); + CLEAN_PROPERTY(target, instr.storeRealPair.propertyIndex); + QSize p = QSizeF(floatData.at(instr.storeRealPair.valueIndex), floatData.at(instr.storeRealPair.valueIndex+1)).toSize(); void *a[] = { &p, 0, &status, &flags }; @@ -515,6 +565,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, case QDeclarativeInstruction::StoreSizeF: { QObject *target = stack.top(); + CLEAN_PROPERTY(target, instr.storeRealPair.propertyIndex); + QSizeF s(floatData.at(instr.storeRealPair.valueIndex), floatData.at(instr.storeRealPair.valueIndex+1)); void *a[] = { &s, 0, &status, &flags }; @@ -526,6 +578,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, case QDeclarativeInstruction::StoreRect: { QObject *target = stack.top(); + CLEAN_PROPERTY(target, instr.storeRect.propertyIndex); + QRect r = QRectF(floatData.at(instr.storeRect.valueIndex), floatData.at(instr.storeRect.valueIndex+1), floatData.at(instr.storeRect.valueIndex+2), @@ -539,6 +593,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, case QDeclarativeInstruction::StoreRectF: { QObject *target = stack.top(); + CLEAN_PROPERTY(target, instr.storeRect.propertyIndex); + QRectF r(floatData.at(instr.storeRect.valueIndex), floatData.at(instr.storeRect.valueIndex+1), floatData.at(instr.storeRect.valueIndex+2), @@ -552,6 +608,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, case QDeclarativeInstruction::StoreVector3D: { QObject *target = stack.top(); + CLEAN_PROPERTY(target, instr.storeVector3D.propertyIndex); + QVector3D p(floatData.at(instr.storeVector3D.valueIndex), floatData.at(instr.storeVector3D.valueIndex+1), floatData.at(instr.storeVector3D.valueIndex+2)); @@ -565,6 +623,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, { QObject *assignObj = stack.pop(); QObject *target = stack.top(); + CLEAN_PROPERTY(target, instr.storeObject.propertyIndex); void *a[] = { (void *)&assignObj, 0, &status, &flags }; QMetaObject::metacall(target, QMetaObject::WriteProperty, @@ -576,6 +635,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, case QDeclarativeInstruction::AssignCustomType: { QObject *target = stack.top(); + CLEAN_PROPERTY(target, instr.assignCustomType.propertyIndex); + QDeclarativeCompiledData::CustomTypeData data = customTypeData.at(instr.assignCustomType.valueIndex); const QString &primitive = primitives.at(data.index); QDeclarativeMetaType::StringConverter converter = @@ -780,6 +841,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, { QObject *assign = stack.pop(); QObject *target = stack.top(); + CLEAN_PROPERTY(target, instr.storeObject.propertyIndex); QVariant v = QVariant::fromValue(assign); void *a[] = { &v, 0, &status, &flags }; @@ -792,6 +854,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, { QObject *assign = stack.pop(); QObject *target = stack.top(); + CLEAN_PROPERTY(target, instr.storeObject.propertyIndex); int coreIdx = instr.storeObject.propertyIndex; QMetaProperty prop = target->metaObject()->property(coreIdx); diff --git a/tests/auto/declarative/qdeclarativelanguage/data/InlineAssignmentsOverrideBindingsType.qml b/tests/auto/declarative/qdeclarativelanguage/data/InlineAssignmentsOverrideBindingsType.qml new file mode 100644 index 0000000..4526cf0 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/InlineAssignmentsOverrideBindingsType.qml @@ -0,0 +1,7 @@ +import QtQuick 1.0 + +QtObject { + property InlineAssignmentsOverrideBindingsType2 nested: InlineAssignmentsOverrideBindingsType2 { + value: 19 * 33 + } +} diff --git a/tests/auto/declarative/qdeclarativelanguage/data/InlineAssignmentsOverrideBindingsType2.qml b/tests/auto/declarative/qdeclarativelanguage/data/InlineAssignmentsOverrideBindingsType2.qml new file mode 100644 index 0000000..4127ca4 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/InlineAssignmentsOverrideBindingsType2.qml @@ -0,0 +1,5 @@ +import QtQuick 1.0 + +QtObject { + property int value +} diff --git a/tests/auto/declarative/qdeclarativelanguage/data/inlineAssignmentsOverrideBindings.qml b/tests/auto/declarative/qdeclarativelanguage/data/inlineAssignmentsOverrideBindings.qml new file mode 100644 index 0000000..8f3c5ce --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/inlineAssignmentsOverrideBindings.qml @@ -0,0 +1,6 @@ +import QtQuick 1.0 + +InlineAssignmentsOverrideBindingsType { + property int test: nested.value + nested.value: 11 +} diff --git a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp index f3f41a9..5a2591f 100644 --- a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp +++ b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp @@ -134,6 +134,7 @@ private slots: void dontDoubleCallClassBegin(); void reservedWords_data(); void reservedWords(); + void inlineAssignmentsOverrideBindings(); void basicRemote_data(); void basicRemote(); @@ -1413,9 +1414,18 @@ void tst_qdeclarativelanguage::testType(const QString& qml, const QString& type, } } +// QTBUG-17276 +void tst_qdeclarativelanguage::inlineAssignmentsOverrideBindings() +{ + QDeclarativeComponent component(&engine, TEST_FILE("inlineAssignmentsOverrideBindings.qml")); -// Import tests (QT-558) + QObject *o = component.create(); + QVERIFY(o != 0); + QCOMPARE(o->property("test").toInt(), 11); + delete o; +} +// Import tests (QT-558) void tst_qdeclarativelanguage::importsBuiltin_data() { // QT-610 -- cgit v0.12 From ce38c6e3a9b7eb336cbd9cd1e9520a5000c8f8ac Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 15 Mar 2011 13:53:34 +1000 Subject: Regression: currentIndex was not set correctly after model cleared. Change b3080d78f2ff2d98410249e09d5d7d6e20fd155c stopped the currentIndex from being updated when a new item is added to an empty view. Change-Id: I77a0789fcf3693034a2d7aca173fec669b913b18 Task-number: QTBUG-18123 Reviewed-by: Bea Lam --- .../graphicsitems/qdeclarativegridview.cpp | 6 ++-- .../graphicsitems/qdeclarativelistview.cpp | 6 ++-- .../tst_qdeclarativegridview.cpp | 39 ++++++++++++++++++++++ .../tst_qdeclarativelistview.cpp | 7 ++++ 4 files changed, 53 insertions(+), 5 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index 5c2f781..c0cbed0 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -2834,11 +2834,9 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count) if (d->currentItem) { d->currentItem->index = d->currentIndex; d->currentItem->setPosition(d->colPosAt(d->currentIndex), d->rowPosAt(d->currentIndex)); - } else if (!d->currentIndex || (d->currentIndex < 0 && !d->currentIndexCleared)) { - d->updateCurrent(0); } emit currentIndexChanged(); - } else if (d->itemCount == 0 && d->currentIndex == -1) { + } else if (d->itemCount == 0 && (!d->currentIndex || (d->currentIndex < 0 && !d->currentIndexCleared))) { setCurrentIndex(0); } @@ -2906,6 +2904,8 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count) d->currentIndex = -1; if (d->itemCount) d->updateCurrent(qMin(modelIndex, d->itemCount-1)); + else + emit currentIndexChanged(); } // update visibleIndex diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 2c23a1b..6ae1ddc 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -3272,10 +3272,10 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count) if (d->currentItem) { d->currentItem->index = d->currentIndex; d->currentItem->setPosition(d->currentItem->position() + diff); - } else if (!d->currentIndex || (d->currentIndex < 0 && !d->currentIndexCleared)) { - d->updateCurrent(0); } emit currentIndexChanged(); + } else if (!d->itemCount && (!d->currentIndex || (d->currentIndex < 0 && !d->currentIndexCleared))) { + d->updateCurrent(0); } // Update the indexes of the following visible items. for (; index < d->visibleItems.count(); ++index) { @@ -3356,6 +3356,8 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count) d->currentIndex = -1; if (d->itemCount) d->updateCurrent(qMin(modelIndex, d->itemCount-1)); + else + emit currentIndexChanged(); } // update visibleIndex diff --git a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp index 5ced02b..c183934 100644 --- a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp +++ b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp @@ -69,6 +69,7 @@ private slots: void changed(); void inserted(); void removed(); + void clear(); void moved(); void changeFlow(); void currentIndex(); @@ -501,6 +502,44 @@ void tst_QDeclarativeGridView::removed() delete canvas; } +void tst_QDeclarativeGridView::clear() +{ + QDeclarativeView *canvas = createView(); + + TestModel model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("testRightToLeft", QVariant(false)); + ctxt->setContextProperty("testTopToBottom", QVariant(false)); + + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml")); + qApp->processEvents(); + + QDeclarativeGridView *gridview = findItem(canvas->rootObject(), "grid"); + QVERIFY(gridview != 0); + + QDeclarativeItem *contentItem = gridview->contentItem(); + QVERIFY(contentItem != 0); + + model.clear(); + + QVERIFY(gridview->count() == 0); + QVERIFY(gridview->currentItem() == 0); + QVERIFY(gridview->contentY() == 0); + QVERIFY(gridview->currentIndex() == -1); + + // confirm sanity when adding an item to cleared list + model.addItem("New", "1"); + QVERIFY(gridview->count() == 1); + QVERIFY(gridview->currentItem() != 0); + QVERIFY(gridview->currentIndex() == 0); + + delete canvas; +} + void tst_QDeclarativeGridView::moved() { QDeclarativeView *canvas = createView(); diff --git a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp index c87318e..2267a89 100644 --- a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp +++ b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp @@ -741,6 +741,13 @@ void tst_QDeclarativeListView::clear() QTRY_VERIFY(listview->count() == 0); QTRY_VERIFY(listview->currentItem() == 0); QTRY_VERIFY(listview->contentY() == 0); + QVERIFY(listview->currentIndex() == -1); + + // confirm sanity when adding an item to cleared list + model.addItem("New", "1"); + QTRY_VERIFY(listview->count() == 1); + QVERIFY(listview->currentItem() != 0); + QVERIFY(listview->currentIndex() == 0); delete canvas; } -- cgit v0.12 From 77342ad3e7beecb75c136ee26c0c77cd1a41b415 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 15 Mar 2011 14:26:20 +1000 Subject: Border still drawn on Rectangle elements when border.width == 0 The _valid flag did not consider both color alpha and line width in both setters. Change-Id: Iba544d65a0a40e36f1e09091e007418c9eefa0cd Task-number: QTBUG-18102 Reviewed-by: Alan Alpert --- src/declarative/graphicsitems/qdeclarativerectangle.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativerectangle.cpp b/src/declarative/graphicsitems/qdeclarativerectangle.cpp index d962919..8f59073 100644 --- a/src/declarative/graphicsitems/qdeclarativerectangle.cpp +++ b/src/declarative/graphicsitems/qdeclarativerectangle.cpp @@ -70,7 +70,7 @@ QT_BEGIN_NAMESPACE void QDeclarativePen::setColor(const QColor &c) { _color = c; - _valid = _color.alpha() ? true : false; + _valid = (_color.alpha() && _width >= 1) ? true : false; emit penChanged(); } @@ -80,7 +80,7 @@ void QDeclarativePen::setWidth(int w) return; _width = w; - _valid = (_width < 1) ? false : true; + _valid = (_color.alpha() && _width >= 1) ? true : false; emit penChanged(); } -- cgit v0.12