From 0b4d84e3980e415df3078e97d44ee5216fbbff07 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Fri, 5 Mar 2010 14:19:15 +1000 Subject: Doc fix. --- src/declarative/util/qdeclarativestateoperations.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/declarative/util/qdeclarativestateoperations.cpp b/src/declarative/util/qdeclarativestateoperations.cpp index cd06380..f13c691 100644 --- a/src/declarative/util/qdeclarativestateoperations.cpp +++ b/src/declarative/util/qdeclarativestateoperations.cpp @@ -562,7 +562,11 @@ QString QDeclarativeStateChangeScript::typeName() const \brief The AnchorChanges element allows you to change the anchors of an item in a state. In the following example we change the top and bottom anchors of an item: - \snippet examples/declarative/anchors/anchor-changes.qml 0 + \qml + AnchorChanges { + target: content; top: window.top; bottom: window.bottom + } + \endqml AnchorChanges will 'inject' \c x, \c y, \c width, and \c height changes into the transition, so you can animate them as you would normally changes to these properties: -- cgit v0.12 From f7a684d72652814960601692f4bc9f7240ce2186 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 9 Mar 2010 12:01:02 +1000 Subject: When flicking with snap, bias towards moving at least one item. Task-number: QTBUG-8839 --- src/declarative/graphicsitems/qdeclarativegridview.cpp | 16 +++++++++------- src/declarative/graphicsitems/qdeclarativelistview.cpp | 17 ++++++++++------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index 60ffbe2..f35b903 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -755,14 +755,15 @@ void QDeclarativeGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m vTime = timeline.time(); } } else if (snapMode != QDeclarativeGridView::NoSnap) { - qreal pos = qMax(qMin(snapPosAt(position()) - highlightRangeStart, -maxExtent), -minExtent); - qreal dist = qAbs(data.move + pos); + qreal pos = -snapPosAt(-(data.move.value() - highlightRangeStart)) + highlightRangeStart; + pos = qMin(qMax(pos, maxExtent), minExtent); + qreal dist = qAbs(data.move.value() - pos); if (dist > 0) { timeline.reset(data.move); if (fixupDuration) - timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2); + timeline.move(data.move, pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2); else - data.move.setValue(-pos); + data.move.setValue(pos); vTime = timeline.time(); } } else { @@ -788,7 +789,7 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m if (FxGridItem *item = firstVisibleItem()) maxDistance = qAbs(item->rowPos() + data.move.value()); } else if (data.move.value() < minExtent) { - maxDistance = qAbs(minExtent - data.move.value() + (overShoot?overShootDistance(velocity, vSize):0)); + maxDistance = qAbs(minExtent - data.move.value()); } if (snapMode != QDeclarativeGridView::SnapToRow && highlightRange != QDeclarativeGridView::StrictlyEnforceRange) data.flickTarget = minExtent; @@ -797,7 +798,7 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m qreal pos = snapPosAt(-data.move.value()) + rowSize(); maxDistance = qAbs(pos + data.move.value()); } else if (data.move.value() > maxExtent) { - maxDistance = qAbs(maxExtent - data.move.value()) + (overShoot?overShootDistance(velocity, vSize):0); + maxDistance = qAbs(maxExtent - data.move.value()); } if (snapMode != QDeclarativeGridView::SnapToRow && highlightRange != QDeclarativeGridView::StrictlyEnforceRange) data.flickTarget = maxExtent; @@ -816,7 +817,8 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m qreal maxAccel = v2 / (2.0f * maxDistance); qreal overshootDist = 0.0; if (maxAccel < accel) { - qreal dist = v2 / (accel * 2.0); + // + rowSize()/4 to encourage moving at least one item in the flick direction + qreal dist = v2 / (accel * 2.0) + rowSize()/4; if (v > 0) dist = -dist; data.flickTarget = -snapPosAt(-(data.move.value() - highlightRangeStart) + dist) + highlightRangeStart; diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index d54bb70..73fe1e4 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -1124,7 +1124,7 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m if (FxListItem *item = firstVisibleItem()) maxDistance = qAbs(item->position() + data.move.value()); } else if (data.move.value() < minExtent) { - maxDistance = qAbs(minExtent - data.move.value() + (overShoot?overShootDistance(velocity, vSize):0)); + maxDistance = qAbs(minExtent - data.move.value()); } if (snapMode != QDeclarativeListView::SnapToItem && highlightRange != QDeclarativeListView::StrictlyEnforceRange) data.flickTarget = minExtent; @@ -1133,7 +1133,7 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m if (FxListItem *item = nextVisibleItem()) maxDistance = qAbs(item->position() + data.move.value()); } else if (data.move.value() > maxExtent) { - maxDistance = qAbs(maxExtent - data.move.value()) + (overShoot?overShootDistance(velocity, vSize):0); + maxDistance = qAbs(maxExtent - data.move.value()); } if (snapMode != QDeclarativeListView::SnapToItem && highlightRange != QDeclarativeListView::StrictlyEnforceRange) data.flickTarget = maxExtent; @@ -1156,7 +1156,8 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m qreal v2 = v * v; qreal maxAccel = v2 / (2.0f * maxDistance); if (maxAccel < accel) { - qreal dist = v2 / (accel * 2.0); + // + averageSize/4 to encourage moving at least one item in the flick direction + qreal dist = v2 / (accel * 2.0) + averageSize/4; if (v > 0) dist = -dist; data.flickTarget = -snapPosAt(-(data.move.value() - highlightRangeStart) + dist) + highlightRangeStart; @@ -1166,6 +1167,7 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m } else { data.flickTarget = velocity > 0 ? minExtent : maxExtent; overshootDist = overShoot ? overShootDistance(v, vSize) : 0; + qDebug() << "boundary" << overshootDist; } timeline.reset(data.move); timeline.accel(data.move, v, accel, maxDistance + overshootDist); @@ -1956,10 +1958,11 @@ void QDeclarativeListView::viewportMoved() if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange && d->highlight) { // reposition highlight qreal pos = d->highlight->position(); - if (pos > d->position() + d->highlightRangeEnd - 1 - d->highlight->size()) - pos = d->position() + d->highlightRangeEnd - 1 - d->highlight->size(); - if (pos < d->position() + d->highlightRangeStart) - pos = d->position() + d->highlightRangeStart; + qreal viewPos = qRound(d->position()); + if (pos > viewPos + d->highlightRangeEnd - 1 - d->highlight->size()) + pos = viewPos + d->highlightRangeEnd - 1 - d->highlight->size(); + if (pos < viewPos + d->highlightRangeStart) + pos = viewPos + d->highlightRangeStart; d->highlight->setPosition(pos); // update current index -- cgit v0.12 From fe4c978f90986e52a64a28a42f3445c620a1f5ef Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Tue, 9 Mar 2010 12:41:04 +1000 Subject: Fix warnings and change geometry-related functions to use reals. --- src/declarative/graphicsitems/qdeclarativeitem.cpp | 16 ++++++++-------- src/declarative/graphicsitems/qdeclarativeitem.h | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp index 9d6b2a0..9cf509f 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp @@ -2214,7 +2214,7 @@ void QDeclarativeItem::setKeepMouseGrab(bool keep) } /*! - \qmlmethod object Item::mapFromItem(Item item, int x, int y) + \qmlmethod object Item::mapFromItem(Item item, real x, real y) Maps the point (\a x, \a y), which is in \a item's coordinate system, to this item's coordinate system, and returns an object with \c x and \c y @@ -2223,7 +2223,7 @@ void QDeclarativeItem::setKeepMouseGrab(bool keep) If \a item is a \c null value, this maps the point from the coordinate system of the root QML view. */ -QScriptValue QDeclarativeItem::mapFromItem(const QScriptValue &item, int x, int y) const +QScriptValue QDeclarativeItem::mapFromItem(const QScriptValue &item, qreal x, qreal y) const { QScriptValue sv = QDeclarativeEnginePrivate::getScriptEngine(qmlEngine(this))->newObject(); QDeclarativeItem *itemObj = qobject_cast(item.toQObject()); @@ -2234,13 +2234,13 @@ QScriptValue QDeclarativeItem::mapFromItem(const QScriptValue &item, int x, int // If QGraphicsItem::mapFromItem() is called with 0, behaves the same as mapFromScene() QPointF p = qobject_cast(this)->mapFromItem(itemObj, x, y); - sv.setProperty("x", p.x()); - sv.setProperty("y", p.y()); + sv.setProperty(QLatin1String("x"), p.x()); + sv.setProperty(QLatin1String("y"), p.y()); return sv; } /*! - \qmlmethod object Item::mapToItem(Item item, int x, int y) + \qmlmethod object Item::mapToItem(Item item, real x, real y) Maps the point (\a x, \a y), which is in this item's coordinate system, to \a item's coordinate system, and returns an object with \c x and \c y @@ -2249,7 +2249,7 @@ QScriptValue QDeclarativeItem::mapFromItem(const QScriptValue &item, int x, int If \a item is a \c null value, this maps \a x and \a y to the coordinate system of the root QML view. */ -QScriptValue QDeclarativeItem::mapToItem(const QScriptValue &item, int x, int y) const +QScriptValue QDeclarativeItem::mapToItem(const QScriptValue &item, qreal x, qreal y) const { QScriptValue sv = QDeclarativeEnginePrivate::getScriptEngine(qmlEngine(this))->newObject(); QDeclarativeItem *itemObj = qobject_cast(item.toQObject()); @@ -2260,8 +2260,8 @@ QScriptValue QDeclarativeItem::mapToItem(const QScriptValue &item, int x, int y) // If QGraphicsItem::mapToItem() is called with 0, behaves the same as mapToScene() QPointF p = qobject_cast(this)->mapToItem(itemObj, x, y); - sv.setProperty("x", p.x()); - sv.setProperty("y", p.y()); + sv.setProperty(QLatin1String("x"), p.x()); + sv.setProperty(QLatin1String("y"), p.y()); return sv; } diff --git a/src/declarative/graphicsitems/qdeclarativeitem.h b/src/declarative/graphicsitems/qdeclarativeitem.h index 2053eba..f9e0c7e 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.h +++ b/src/declarative/graphicsitems/qdeclarativeitem.h @@ -161,8 +161,8 @@ public: bool keepMouseGrab() const; void setKeepMouseGrab(bool); - Q_INVOKABLE QScriptValue mapFromItem(const QScriptValue &item, int x, int y) const; - Q_INVOKABLE QScriptValue mapToItem(const QScriptValue &item, int x, int y) const; + Q_INVOKABLE QScriptValue mapFromItem(const QScriptValue &item, qreal x, qreal y) const; + Q_INVOKABLE QScriptValue mapToItem(const QScriptValue &item, qreal x, qreal y) const; QDeclarativeAnchorLine left() const; QDeclarativeAnchorLine right() const; -- cgit v0.12 From db5628ee1f9643ed9a9aada4d3f8fffbdf1f6c81 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Tue, 9 Mar 2010 13:06:05 +1000 Subject: Fix warning. --- src/declarative/graphicsitems/qdeclarativeitem.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp index 9cf509f..1ac26b4 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp @@ -2577,6 +2577,8 @@ bool QDeclarativeItem::sceneEvent(QEvent *event) keyPressEvent(static_cast(event)); if (!event->isAccepted()) return QGraphicsItem::sceneEvent(event); + else + return true; } else { return QGraphicsItem::sceneEvent(event); } -- cgit v0.12 From 0bfeef9649bb130c9932fef0543c71bbaee45867 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Tue, 9 Mar 2010 13:22:48 +1000 Subject: Remove unused data member. --- src/declarative/graphicsitems/qdeclarativemousearea.cpp | 1 - src/declarative/graphicsitems/qdeclarativemousearea_p_p.h | 1 - 2 files changed, 2 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativemousearea.cpp b/src/declarative/graphicsitems/qdeclarativemousearea.cpp index ec7aa62..13195af 100644 --- a/src/declarative/graphicsitems/qdeclarativemousearea.cpp +++ b/src/declarative/graphicsitems/qdeclarativemousearea.cpp @@ -383,7 +383,6 @@ void QDeclarativeMouseArea::mousePressEvent(QGraphicsSceneMouseEvent *event) } d->dragged = false; setHovered(true); - d->start = event->pos(); d->startScene = event->scenePos(); // we should only start timer if pressAndHold is connected to. if (d->isConnected("pressAndHold(QDeclarativeMouseEvent*)")) diff --git a/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h b/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h index d4871f2..88206cd 100644 --- a/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h @@ -101,7 +101,6 @@ public: bool dragY : 1; bool dragged : 1; QDeclarativeDrag *drag; - QPointF start; QPointF startScene; qreal startX; qreal startY; -- cgit v0.12 From 6a5891e7bfd182a52fd71f1b5fdf4d73def63603 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Tue, 9 Mar 2010 14:22:07 +1000 Subject: Integrate QML's object ownership with the JS collector QML now behaves in a way similar to QtScript when it comes to QObject ownership. QT-2803 --- src/corelib/kernel/qobject.cpp | 2 + src/corelib/kernel/qobject_p.h | 1 + src/declarative/qml/qdeclarativecomponent.cpp | 20 +++++-- .../qml/qdeclarativedeclarativedata_p.h | 17 ++++-- src/declarative/qml/qdeclarativeengine.cpp | 62 ++++++++++++++++++++- src/declarative/qml/qdeclarativeengine.h | 4 ++ .../qml/qdeclarativeobjectscriptclass.cpp | 65 +++++++++++++++++----- .../qml/qdeclarativeobjectscriptclass_p.h | 3 + src/declarative/qml/qdeclarativevme.cpp | 2 + src/script/bridge/qscriptdeclarativeclass.cpp | 5 ++ src/script/bridge/qscriptdeclarativeclass_p.h | 1 + src/script/bridge/qscriptdeclarativeobject.cpp | 17 ++++++ src/script/bridge/qscriptdeclarativeobject_p.h | 2 + .../tst_qdeclarativeecmascript.cpp | 52 +++++++++++++++++ 14 files changed, 230 insertions(+), 23 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 389e6e7..68f34ca 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -2033,6 +2033,8 @@ void QObjectPrivate::setParent_helper(QObject *o) } } } + if (!wasDeleted && declarativeData) + declarativeData->parentChanged(q, o); } /*! diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index cc5bf97..20e3da1 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -90,6 +90,7 @@ class Q_CORE_EXPORT QDeclarativeData public: virtual ~QDeclarativeData(); virtual void destroyed(QObject *) = 0; + virtual void parentChanged(QObject *, QObject *) = 0; }; class Q_CORE_EXPORT QObjectPrivate : public QObjectData diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp index d6bb216..d3608c4 100644 --- a/src/declarative/qml/qdeclarativecomponent.cpp +++ b/src/declarative/qml/qdeclarativecomponent.cpp @@ -512,7 +512,6 @@ QDeclarativeComponent::QDeclarativeComponent(QDeclarativeComponentPrivate &dd, Q { } - /*! \internal A version of create which returns a scriptObject, for use in script @@ -526,7 +525,9 @@ QScriptValue QDeclarativeComponent::createObject() return QScriptValue(); } QObject* ret = create(ctxt); - return QDeclarativeEnginePrivate::qmlScriptObject(ret, d->engine); + QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(d->engine); + QDeclarativeDeclarativeData::get(ret, true)->setImplicitDestructible(); + return priv->objectClass->newQObject(ret, QMetaType::QObjectStar); } /*! @@ -541,7 +542,12 @@ QObject *QDeclarativeComponent::create(QDeclarativeContext *context) { Q_D(QDeclarativeComponent); - return d->create(context, QBitField()); + if (!context) + context = d->engine->rootContext(); + + QObject *rv = beginCreate(context); + completeCreate(); + return rv; } QObject *QDeclarativeComponentPrivate::create(QDeclarativeContext *context, @@ -586,7 +592,13 @@ QObject *QDeclarativeComponentPrivate::create(QDeclarativeContext *context, QObject *QDeclarativeComponent::beginCreate(QDeclarativeContext *context) { Q_D(QDeclarativeComponent); - return d->beginCreate(context, QBitField()); + QObject *rv = d->beginCreate(context, QBitField()); + if (rv) { + QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(rv); + Q_ASSERT(ddata); + ddata->indestructible = true; + } + return rv; } QObject * diff --git a/src/declarative/qml/qdeclarativedeclarativedata_p.h b/src/declarative/qml/qdeclarativedeclarativedata_p.h index ae40130..ffce9c9 100644 --- a/src/declarative/qml/qdeclarativedeclarativedata_p.h +++ b/src/declarative/qml/qdeclarativedeclarativedata_p.h @@ -67,12 +67,21 @@ class Q_AUTOTEST_EXPORT QDeclarativeDeclarativeData : public QDeclarativeData { public: QDeclarativeDeclarativeData(QDeclarativeContext *ctxt = 0) - : context(ctxt), bindings(0), nextContextObject(0), prevContextObject(0), - bindingBitsSize(0), bindingBits(0), outerContext(0), lineNumber(0), - columnNumber(0), deferredComponent(0), deferredIdx(0), attachedProperties(0), - propertyCache(0), guards(0) {} + : indestructible(true), explicitIndestructibleSet(false), context(ctxt), + bindings(0), nextContextObject(0), prevContextObject(0), bindingBitsSize(0), bindingBits(0), + outerContext(0), lineNumber(0), columnNumber(0), deferredComponent(0), deferredIdx(0), + attachedProperties(0), propertyCache(0), guards(0) {} virtual void destroyed(QObject *); + virtual void parentChanged(QObject *, QObject *); + + void setImplicitDestructible() { + if (!explicitIndestructibleSet) indestructible = false; + } + + quint32 indestructible:1; + quint32 explicitIndestructibleSet:1; + quint32 dummy:29; QDeclarativeContext *context; QDeclarativeAbstractBinding *bindings; diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 41d55d7..791df9f 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -668,6 +668,59 @@ void QDeclarativeEngine::setContextForObject(QObject *object, QDeclarativeContex context->d_func()->contextObjects = data; } +/*! +\enum QDeclarativeEngine::ObjectOwnership + +Ownership controls whether or not QML automatically destroys the QObject when the object +is garbage collected by the JavaScript engine. The two ownership options are: + +\o CppOwnership The object is owned by C++ code, and will never be deleted by QML. The +JavaScript destroy() method cannot be used on objects with CppOwnership. This option +is similar to QScriptEngine::QtOwnership. + +\o JavaScriptOwnership The object is owned by JavaScript. When the object is returned to QML +as the return value of a method call or property access, QML will delete the object if there +are no remaining JavaScript references to it and it has no QObject::parent(). This option +is similar to QScriptEngine::ScriptOwnership. + +Generally an application doesn't need to set an object's ownership explicitly. QML uses +a heuristic to set the default object ownership. By default, an object that is created by +QML has JavaScriptOwnership. The exception to this are the root objects created by calling +QDeclarativeCompnent::create() or QDeclarativeComponent::beginCreate() which have +CppOwnership by default. The ownership of these root-level objects is considered to have +been transfered to the C++ caller. + +Objects not-created by QML have CppOwnership by default. The exception to this is objects +returned from a C++ method call. The ownership of these objects is passed to JavaScript. + +Calling setObjectOwnership() overrides the default ownership heuristic used by QML. +*/ + +/*! +Sets the \a ownership of \a object. +*/ +void QDeclarativeEngine::setObjectOwnership(QObject *object, ObjectOwnership ownership) +{ + QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(object, true); + if (!ddata) + return; + + ddata->indestructible = (ownership == CppOwnership)?true:false; + ddata->explicitIndestructibleSet = true; +} + +/*! +Returns the ownership of \a object. +*/ +QDeclarativeEngine::ObjectOwnership QDeclarativeEngine::objectOwnership(QObject *object) +{ + QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(object, false); + if (!ddata) + return CppOwnership; + else + return ddata->indestructible?CppOwnership:JavaScriptOwnership; +} + void qmlExecuteDeferred(QObject *object) { QDeclarativeDeclarativeData *data = QDeclarativeDeclarativeData::get(object); @@ -778,6 +831,11 @@ void QDeclarativeDeclarativeData::destroyed(QObject *object) delete this; } +void QDeclarativeDeclarativeData::parentChanged(QObject *, QObject *parent) +{ + if (!parent && scriptValue.isValid()) scriptValue = QScriptValue(); +} + bool QDeclarativeDeclarativeData::hasBindingBit(int bit) const { if (bindingBitsSize > bit) @@ -858,6 +916,7 @@ QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt, QUrl url = QUrl(context->resolvedUrl(QUrl(arg))); QDeclarativeComponent *c = new QDeclarativeComponent(activeEngine, url, activeEngine); c->setCreationContext(context); + QDeclarativeDeclarativeData::get(c, true)->setImplicitDestructible(); return activeEnginePriv->objectClass->newQObject(c, qMetaTypeId()); } } @@ -928,7 +987,8 @@ QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QS if(gobj && gparent) gobj->setParentItem(gparent); - return qmlScriptObject(obj, activeEngine); + QDeclarativeDeclarativeData::get(obj, true)->setImplicitDestructible(); + return activeEnginePriv->objectClass->newQObject(obj, QMetaType::QObjectStar); } QScriptValue QDeclarativeEnginePrivate::vector(QScriptContext *ctxt, QScriptEngine *engine) diff --git a/src/declarative/qml/qdeclarativeengine.h b/src/declarative/qml/qdeclarativeengine.h index fd66358..19e81b6 100644 --- a/src/declarative/qml/qdeclarativeengine.h +++ b/src/declarative/qml/qdeclarativeengine.h @@ -98,6 +98,10 @@ public: static QDeclarativeContext *contextForObject(const QObject *); static void setContextForObject(QObject *, QDeclarativeContext *); + enum ObjectOwnership { CppOwnership, JavaScriptOwnership }; + static void setObjectOwnership(QObject *, ObjectOwnership); + static ObjectOwnership objectOwnership(QObject *); + Q_SIGNALS: void quit (); diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp index e6f6e5f..3ca03b4 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp @@ -59,6 +59,15 @@ QT_BEGIN_NAMESPACE struct ObjectData : public QScriptDeclarativeClass::Object { ObjectData(QObject *o, int t) : object(o), type(t) {} + + virtual ~ObjectData() { + if (object && !object->parent()) { + QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(object, false); + if (ddata && !ddata->indestructible) + object->deleteLater(); + } + } + QDeclarativeGuard object; int type; }; @@ -87,7 +96,7 @@ QDeclarativeObjectScriptClass::~QDeclarativeObjectScriptClass() { } -QScriptValue QDeclarativeObjectScriptClass::newQObject(QObject *object, int type) +QScriptValue QDeclarativeObjectScriptClass::newQObject(QObject *object, int type) { QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); @@ -96,7 +105,11 @@ QScriptValue QDeclarativeObjectScriptClass::newQObject(QObject *object, int type QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(object, true); - if (!ddata->scriptValue.isValid()) { + if (!ddata) { + return scriptEngine->undefinedValue(); + } else if (!ddata->indestructible && !object->parent()) { + return newObject(scriptEngine, this, new ObjectData(object, type)); + } else if (!ddata->scriptValue.isValid()) { ddata->scriptValue = newObject(scriptEngine, this, new ObjectData(object, type)); return ddata->scriptValue; } else if (ddata->scriptValue.engine() == QDeclarativeEnginePrivate::getScriptEngine(engine)) { @@ -392,17 +405,30 @@ QScriptValue QDeclarativeObjectScriptClass::tostring(QScriptContext *context, QS QScriptValue QDeclarativeObjectScriptClass::destroy(QScriptContext *context, QScriptEngine *engine) { - QObject* obj = context->thisObject().toQObject(); - if(obj){ - int delay = 0; - if(context->argumentCount() > 0) - delay = context->argument(0).toInt32(); - if (delay > 0) - QTimer::singleShot(delay, obj, SLOT(deleteLater())); - else - obj->deleteLater(); - } - return engine->nullValue(); + QDeclarativeEnginePrivate *p = QDeclarativeEnginePrivate::get(engine); + QScriptValue that = context->thisObject(); + + if (scriptClass(that) != p->objectClass) + return engine->undefinedValue(); + + ObjectData *data = (ObjectData *)p->objectClass->object(that); + if (!data->object) + return engine->undefinedValue(); + + QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(data->object, false); + if (!ddata || ddata->indestructible) + return engine->currentContext()->throwError(QLatin1String("Invalid attempt to destroy() an indestructible object")); + + QObject *obj = data->object; + int delay = 0; + if (context->argumentCount() > 0) + delay = context->argument(0).toInt32(); + if (delay > 0) + QTimer::singleShot(delay, obj, SLOT(deleteLater())); + else + obj->deleteLater(); + + return engine->undefinedValue(); } QStringList QDeclarativeObjectScriptClass::propertyNames(Object *object) @@ -428,6 +454,14 @@ QStringList QDeclarativeObjectScriptClass::propertyNames(Object *object) return cache->propertyNames(); } +bool QDeclarativeObjectScriptClass::compare(Object *o1, Object *o2) +{ + ObjectData *d1 = (ObjectData *)o1; + ObjectData *d2 = (ObjectData *)o2; + + return d1 == d2 || d1->object == d2->object; +} + #if (QT_VERSION > QT_VERSION_CHECK(4, 6, 2)) || defined(QT_HAVE_QSCRIPTDECLARATIVECLASS_VALUE) struct MethodData : public QScriptDeclarativeClass::Object { @@ -685,7 +719,10 @@ QScriptDeclarativeClass::Value MetaCallArgument::toValue(QDeclarativeEngine *e) } else if (type == QMetaType::QString) { return QScriptDeclarativeClass::Value(engine, *((QString *)data)); } else if (type == QMetaType::QObjectStar) { - return QScriptDeclarativeClass::Value(engine, QDeclarativeEnginePrivate::get(e)->objectClass->newQObject(*((QObject **)data))); + QObject *object = *((QObject **)data); + QDeclarativeDeclarativeData::get(object, true)->setImplicitDestructible(); + QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(e); + return QScriptDeclarativeClass::Value(engine, priv->objectClass->newQObject(object)); } else if (type == -1 || type == qMetaTypeId()) { return QScriptDeclarativeClass::Value(engine, QDeclarativeEnginePrivate::get(e)->scriptValueFromVariant(*((QVariant *)data))); } else { diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass_p.h b/src/declarative/qml/qdeclarativeobjectscriptclass_p.h index 04e760f..1f7d1c9 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass_p.h +++ b/src/declarative/qml/qdeclarativeobjectscriptclass_p.h @@ -57,6 +57,7 @@ #include "qdeclarativetypenamecache_p.h" #include +#include QT_BEGIN_NAMESPACE @@ -99,6 +100,7 @@ public: ~QDeclarativeObjectScriptClass(); QScriptValue newQObject(QObject *, int type = QMetaType::QObjectStar); + QObject *toQObject(const QScriptValue &) const; int objectType(const QScriptValue &) const; @@ -118,6 +120,7 @@ public: void setProperty(QObject *, const Identifier &name, const QScriptValue &, QDeclarativeContext *evalContext = 0); virtual QStringList propertyNames(Object *); + virtual bool compare(Object *, Object *); protected: virtual QScriptClass::QueryFlags queryProperty(Object *, const Identifier &, diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp index 6a08674..d916900 100644 --- a/src/declarative/qml/qdeclarativevme.cpp +++ b/src/declarative/qml/qdeclarativevme.cpp @@ -197,6 +197,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, QDeclarati QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(o); Q_ASSERT(ddata); + ddata->setImplicitDestructible(); ddata->outerContext = ctxt; ddata->lineNumber = instr.line; ddata->columnNumber = instr.create.column; @@ -247,6 +248,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, QDeclarati QDeclarativeEngine::setContextForObject(qcomp, ctxt); QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(qcomp); Q_ASSERT(ddata); + ddata->setImplicitDestructible(); ddata->outerContext = ctxt; ddata->lineNumber = instr.line; ddata->columnNumber = instr.create.column; diff --git a/src/script/bridge/qscriptdeclarativeclass.cpp b/src/script/bridge/qscriptdeclarativeclass.cpp index 1d11ede..46c68ed 100644 --- a/src/script/bridge/qscriptdeclarativeclass.cpp +++ b/src/script/bridge/qscriptdeclarativeclass.cpp @@ -493,6 +493,11 @@ QScriptDeclarativeClass::Value QScriptDeclarativeClass::call(Object *object, return Value(); } +bool QScriptDeclarativeClass::compare(Object *o, Object *o2) +{ + return o == o2; +} + QStringList QScriptDeclarativeClass::propertyNames(Object *object) { Q_UNUSED(object); diff --git a/src/script/bridge/qscriptdeclarativeclass_p.h b/src/script/bridge/qscriptdeclarativeclass_p.h index a0fd6d5..7037e22 100644 --- a/src/script/bridge/qscriptdeclarativeclass_p.h +++ b/src/script/bridge/qscriptdeclarativeclass_p.h @@ -129,6 +129,7 @@ public: virtual void setProperty(Object *, const Identifier &name, const QScriptValue &); virtual QScriptValue::PropertyFlags propertyFlags(Object *, const Identifier &); virtual Value call(Object *, QScriptContext *); + virtual bool compare(Object *, Object *); virtual QStringList propertyNames(Object *); diff --git a/src/script/bridge/qscriptdeclarativeobject.cpp b/src/script/bridge/qscriptdeclarativeobject.cpp index c6ab6a7..70bb1bb 100644 --- a/src/script/bridge/qscriptdeclarativeobject.cpp +++ b/src/script/bridge/qscriptdeclarativeobject.cpp @@ -198,6 +198,23 @@ bool DeclarativeObjectDelegate::hasInstance(QScriptObject* object, JSC::ExecStat return QScriptObjectDelegate::hasInstance(object, exec, value, proto); } +bool DeclarativeObjectDelegate::compareToObject(QScriptObject *o, JSC::ExecState *exec, JSC::JSObject *o2) +{ + if (!o2->inherits(&QScriptObject::info)) + return false; + + QScriptObject *scriptObject = static_cast(o2); + QScriptObjectDelegate *delegate = scriptObject->delegate(); + if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject)) + return false; + + DeclarativeObjectDelegate *other = static_cast(delegate); + if (m_class != other->m_class) + return false; + else + return m_class->compare(m_object, other->m_object); +} + } // namespace QScript QT_END_NAMESPACE diff --git a/src/script/bridge/qscriptdeclarativeobject_p.h b/src/script/bridge/qscriptdeclarativeobject_p.h index ec8a43e..878af24 100644 --- a/src/script/bridge/qscriptdeclarativeobject_p.h +++ b/src/script/bridge/qscriptdeclarativeobject_p.h @@ -99,6 +99,8 @@ public: virtual bool hasInstance(QScriptObject*, JSC::ExecState*, JSC::JSValue value, JSC::JSValue proto); + bool compareToObject(QScriptObject *, JSC::ExecState *, JSC::JSObject *); + private: QScriptDeclarativeClass *m_class; QScriptDeclarativeClass::Object *m_object; diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index 4838288..d134750 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -126,6 +126,7 @@ private slots: void attachedPropertyScope(); void scriptConnect(); void scriptDisconnect(); + void ownership(); void bug1(); @@ -889,6 +890,7 @@ void tst_qdeclarativeecmascript::dynamicDestruction() } QVERIFY(!createdQmlObject); + QDeclarativeEngine::setObjectOwnership(object, QDeclarativeEngine::QMLOwnership); QMetaObject::invokeMethod(object, "killMe"); QVERIFY(object); QTest::qWait(0); @@ -1890,7 +1892,57 @@ void tst_qdeclarativeecmascript::scriptDisconnect() delete object; } +} + +class OwnershipObject : public QObject +{ + Q_OBJECT +public: + OwnershipObject() { object = new QObject; } + + QPointer object; + +public slots: + QObject *getObject() { return object; } +}; + +void tst_qdeclarativeecmascript::ownership() +{ + OwnershipObject own; + QDeclarativeContext *context = new QDeclarativeContext(engine.rootContext()); + context->addDefaultObject(&own); + + { + QDeclarativeComponent component(&engine, TEST_FILE("ownership.qml")); + + QVERIFY(own.object != 0); + + QObject *object = component.create(context); + QDeclarativeEnginePrivate::getScriptEngine(&engine)->collectGarbage(); + QCoreApplication::processEvents(QEventLoop::DeferredDeletion); + + QVERIFY(own.object == 0); + + delete object; + } + + own.object = new QObject(&own); + + { + QDeclarativeComponent component(&engine, TEST_FILE("ownership.qml")); + + QVERIFY(own.object != 0); + + QObject *object = component.create(context); + QDeclarativeEnginePrivate::getScriptEngine(&engine)->collectGarbage(); + + QCoreApplication::processEvents(QEventLoop::DeferredDeletion); + + QVERIFY(own.object != 0); + + delete object; + } } QTEST_MAIN(tst_qdeclarativeecmascript) -- cgit v0.12 From 4367951cbb4a0ddb739724878dc9a1cabad5a773 Mon Sep 17 00:00:00 2001 From: Joona Petrell Date: Mon, 8 Mar 2010 15:26:30 +1000 Subject: Make QDeclarativeItem NOTIFY signals canonical Task-number: QTBUG-7193 Reviewed-by: akennedy --- .../qdeclarativegraphicsobjectcontainer.cpp | 8 +- src/declarative/graphicsitems/qdeclarativeitem.cpp | 40 ++++------ src/declarative/graphicsitems/qdeclarativeitem.h | 23 +++--- src/declarative/graphicsitems/qdeclarativeitem_p.h | 6 +- .../graphicsitems/qdeclarativelistview.cpp | 4 +- .../graphicsitems/qdeclarativepainteditem.cpp | 4 +- .../graphicsitems/qdeclarativetextedit.cpp | 14 +--- .../graphicsitems/qdeclarativetextedit_p.h | 2 - .../graphicsitems/qdeclarativetextedit_p_p.h | 1 + .../graphicsitems/qdeclarativetextinput.cpp | 10 +-- .../graphicsitems/qdeclarativetextinput_p.h | 2 - .../graphicsitems/qdeclarativetextinput_p_p.h | 1 + src/declarative/util/qdeclarativeview.cpp | 4 +- src/imports/webkit/qdeclarativewebview.cpp | 8 +- src/imports/webkit/qdeclarativewebview_p.h | 1 - .../qdeclarativeitem/data/propertychanges.qml | 10 +++ .../qdeclarativeitem/tst_qdeclarativeitem.cpp | 92 +++++++++++++++++++++- .../tst_qdeclarativerepeater.cpp | 2 +- 18 files changed, 158 insertions(+), 74 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativeitem/data/propertychanges.qml diff --git a/src/declarative/graphicsitems/qdeclarativegraphicsobjectcontainer.cpp b/src/declarative/graphicsitems/qdeclarativegraphicsobjectcontainer.cpp index 1977817..eb5b6ce 100644 --- a/src/declarative/graphicsitems/qdeclarativegraphicsobjectcontainer.cpp +++ b/src/declarative/graphicsitems/qdeclarativegraphicsobjectcontainer.cpp @@ -65,12 +65,12 @@ public: if (graphicsObject && graphicsObject->isWidget()) { if (!on) { graphicsObject->removeEventFilter(q); - QObject::disconnect(q, SIGNAL(widthChanged()), q, SLOT(_q_updateSize())); - QObject::disconnect(q, SIGNAL(heightChanged()), q, SLOT(_q_updateSize())); + QObject::disconnect(q, SIGNAL(widthChanged(qreal)), q, SLOT(_q_updateSize())); + QObject::disconnect(q, SIGNAL(heightChanged(qreal)), q, SLOT(_q_updateSize())); } else { graphicsObject->installEventFilter(q); - QObject::connect(q, SIGNAL(widthChanged()), q, SLOT(_q_updateSize())); - QObject::connect(q, SIGNAL(heightChanged()), q, SLOT(_q_updateSize())); + QObject::connect(q, SIGNAL(widthChanged(qreal)), q, SLOT(_q_updateSize())); + QObject::connect(q, SIGNAL(heightChanged(qreal)), q, SLOT(_q_updateSize())); } } } diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp index 1ac26b4..7c6c46b 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp @@ -273,7 +273,7 @@ void QDeclarativeContents::calcHeight() m_height = qMax(bottom - top, qreal(0.0)); if (m_height != oldheight || m_y != oldy) - emit rectChanged(); + emit rectChanged(rectF()); } //TODO: optimization: only check sender(), if there is one @@ -301,7 +301,7 @@ void QDeclarativeContents::calcWidth() m_width = qMax(right - left, qreal(0.0)); if (m_width != oldwidth || m_x != oldx) - emit rectChanged(); + emit rectChanged(rectF()); } void QDeclarativeContents::setItem(QDeclarativeItem *item) @@ -313,11 +313,11 @@ void QDeclarativeContents::setItem(QDeclarativeItem *item) QDeclarativeItem *child = qobject_cast(children.at(i)); if(!child)//### Should this be ignoring non-QDeclarativeItem graphicsobjects? continue; - connect(child, SIGNAL(heightChanged()), this, SLOT(calcHeight())); + connect(child, SIGNAL(heightChanged(qreal)), this, SLOT(calcHeight())); connect(child, SIGNAL(yChanged()), this, SLOT(calcHeight())); - connect(child, SIGNAL(widthChanged()), this, SLOT(calcWidth())); + connect(child, SIGNAL(widthChanged(qreal)), this, SLOT(calcWidth())); connect(child, SIGNAL(xChanged()), this, SLOT(calcWidth())); - connect(this, SIGNAL(rectChanged()), m_item, SIGNAL(childrenRectChanged())); + connect(this, SIGNAL(rectChanged(QRectF)), m_item, SIGNAL(childrenRectChanged(QRectF))); } calcHeight(); @@ -1652,7 +1652,7 @@ void QDeclarativeItem::setClip(bool c) if (clip() == c) return; setFlag(ItemClipsChildrenToShape, c); - emit clipChanged(); + emit clipChanged(c); } /*! @@ -1792,11 +1792,11 @@ void QDeclarativeItem::geometryChanged(const QRectF &newGeometry, if (newGeometry.x() != oldGeometry.x()) emit xChanged(); if (newGeometry.width() != oldGeometry.width()) - emit widthChanged(); + emit widthChanged(newGeometry.width()); if (newGeometry.y() != oldGeometry.y()) emit yChanged(); if (newGeometry.height() != oldGeometry.height()) - emit heightChanged(); + emit heightChanged(newGeometry.height()); for(int ii = 0; ii < d->changeListeners.count(); ++ii) { const QDeclarativeItemPrivate::ChangeListener &change = d->changeListeners.at(ii); @@ -2058,7 +2058,6 @@ void QDeclarativeItem::setBaselineOffset(qreal offset) return; d->_baselineOffset = offset; - emit baselineOffsetChanged(); for(int ii = 0; ii < d->changeListeners.count(); ++ii) { const QDeclarativeItemPrivate::ChangeListener &change = d->changeListeners.at(ii); @@ -2068,6 +2067,7 @@ void QDeclarativeItem::setBaselineOffset(qreal offset) anchor->updateVerticalAnchors(); } } + emit baselineOffsetChanged(offset); } /*! @@ -2265,18 +2265,10 @@ QScriptValue QDeclarativeItem::mapToItem(const QScriptValue &item, qreal x, qrea return sv; } -/*! - \internal - - This function emits the \e focusChanged signal. - - Subclasses overriding this function should call up - to their base class. -*/ -void QDeclarativeItem::focusChanged(bool flag) +void QDeclarativeItemPrivate::focusChanged(bool flag) { - Q_UNUSED(flag); - emit focusChanged(); + Q_Q(QDeclarativeItem); + emit q->focusChanged(flag); } /*! \internal */ @@ -2569,9 +2561,9 @@ QPointF QDeclarativeItemPrivate::computeTransformOrigin() const /*! \internal */ bool QDeclarativeItem::sceneEvent(QEvent *event) { + Q_D(QDeclarativeItem); if (event->type() == QEvent::KeyPress) { QKeyEvent *k = static_cast(event); - if ((k->key() == Qt::Key_Tab || k->key() == Qt::Key_Backtab) && !(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { keyPressEvent(static_cast(event)); @@ -2587,7 +2579,7 @@ bool QDeclarativeItem::sceneEvent(QEvent *event) if (event->type() == QEvent::FocusIn || event->type() == QEvent::FocusOut) { - focusChanged(hasFocus()); + d->focusChanged(hasFocus()); } return rv; } @@ -2600,7 +2592,7 @@ QVariant QDeclarativeItem::itemChange(GraphicsItemChange change, Q_D(const QDeclarativeItem); switch (change) { case ItemParentHasChanged: - emit parentChanged(); + emit parentChanged(parentItem()); break; case ItemChildAddedChange: case ItemChildRemovedChange: @@ -2713,7 +2705,7 @@ void QDeclarativeItem::setSmooth(bool smooth) if (d->smooth == smooth) return; d->smooth = smooth; - emit smoothChanged(); + emit smoothChanged(smooth); update(); } diff --git a/src/declarative/graphicsitems/qdeclarativeitem.h b/src/declarative/graphicsitems/qdeclarativeitem.h index f9e0c7e..9b85ba3 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.h +++ b/src/declarative/graphicsitems/qdeclarativeitem.h @@ -42,8 +42,8 @@ #ifndef QDECLARATIVEITEM_H #define QDECLARATIVEITEM_H -#include -#include +#include +#include #include #include @@ -173,18 +173,18 @@ public: QDeclarativeAnchorLine baseline() const; Q_SIGNALS: - void widthChanged(); - void heightChanged(); + void widthChanged(qreal); + void heightChanged(qreal); void childrenChanged(); - void childrenRectChanged(); - void baselineOffsetChanged(); + void childrenRectChanged(const QRectF &); + void baselineOffsetChanged(qreal); void stateChanged(const QString &); - void focusChanged(); - void wantsFocusChanged(); - void parentChanged(); + void focusChanged(bool); + void wantsFocusChanged(bool); + void parentChanged(QDeclarativeItem *); void transformOriginChanged(TransformOrigin); - void smoothChanged(); - void clipChanged(); + void smoothChanged(bool); + void clipChanged(bool); protected: bool isComponentComplete() const; @@ -199,7 +199,6 @@ protected: virtual void classBegin(); virtual void componentComplete(); - virtual void focusChanged(bool); virtual void keyPressEvent(QKeyEvent *event); virtual void keyReleaseEvent(QKeyEvent *event); virtual void inputMethodEvent(QInputMethodEvent *); diff --git a/src/declarative/graphicsitems/qdeclarativeitem_p.h b/src/declarative/graphicsitems/qdeclarativeitem_p.h index e424970..76ebcb4 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem_p.h +++ b/src/declarative/graphicsitems/qdeclarativeitem_p.h @@ -91,7 +91,7 @@ public Q_SLOTS: void calcWidth(); Q_SIGNALS: - void rectChanged(); + void rectChanged(QRectF); private: QDeclarativeItem *m_item; @@ -240,7 +240,7 @@ public: // Reimplemented from QGraphicsItemPrivate virtual void subFocusItemChange() { - emit q_func()->wantsFocusChanged(); + emit q_func()->wantsFocusChanged(subFocusItem != 0); } // Reimplemented from QGraphicsItemPrivate @@ -255,6 +255,8 @@ public: } } + virtual void focusChanged(bool); + static int consistentTime; static QTime currentTime(); static void Q_DECLARATIVE_EXPORT setConsistentTime(int t); diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 73fe1e4..6385ddd 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -557,7 +557,7 @@ void QDeclarativeListViewPrivate::releaseItem(FxListItem *item) return; if (trackedItem == item) { const char *notifier1 = orient == QDeclarativeListView::Vertical ? SIGNAL(yChanged()) : SIGNAL(xChanged()); - const char *notifier2 = orient == QDeclarativeListView::Vertical ? SIGNAL(heightChanged()) : SIGNAL(widthChanged()); + const char *notifier2 = orient == QDeclarativeListView::Vertical ? SIGNAL(heightChanged(qreal)) : SIGNAL(widthChanged(qreal)); QObject::disconnect(trackedItem->item, notifier1, q, SLOT(trackedPositionChanged())); QObject::disconnect(trackedItem->item, notifier2, q, SLOT(trackedPositionChanged())); trackedItem = 0; @@ -748,7 +748,7 @@ void QDeclarativeListViewPrivate::updateTrackedItem() FxListItem *oldTracked = trackedItem; const char *notifier1 = orient == QDeclarativeListView::Vertical ? SIGNAL(yChanged()) : SIGNAL(xChanged()); - const char *notifier2 = orient == QDeclarativeListView::Vertical ? SIGNAL(heightChanged()) : SIGNAL(widthChanged()); + const char *notifier2 = orient == QDeclarativeListView::Vertical ? SIGNAL(heightChanged(qreal)) : SIGNAL(widthChanged(qreal)); if (trackedItem && item != trackedItem) { QObject::disconnect(trackedItem->item, notifier1, q, SLOT(trackedPositionChanged())); diff --git a/src/declarative/graphicsitems/qdeclarativepainteditem.cpp b/src/declarative/graphicsitems/qdeclarativepainteditem.cpp index ab6007a..28a93d2 100644 --- a/src/declarative/graphicsitems/qdeclarativepainteditem.cpp +++ b/src/declarative/graphicsitems/qdeclarativepainteditem.cpp @@ -211,8 +211,8 @@ QDeclarativePaintedItem::~QDeclarativePaintedItem() */ void QDeclarativePaintedItem::init() { - connect(this,SIGNAL(widthChanged()),this,SLOT(clearCache())); - connect(this,SIGNAL(heightChanged()),this,SLOT(clearCache())); + connect(this,SIGNAL(widthChanged(qreal)),this,SLOT(clearCache())); + connect(this,SIGNAL(heightChanged(qreal)),this,SLOT(clearCache())); connect(this,SIGNAL(visibleChanged()),this,SLOT(clearCache())); } diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp index be73b39..dbae47d 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp @@ -760,17 +760,11 @@ void QDeclarativeTextEdit::keyReleaseEvent(QKeyEvent *event) QDeclarativePaintedItem::keyReleaseEvent(event); } -/*! - \overload - Handles changing of the focus property. Focus is applied to the control - even if the edit does not have active focus. This is because things - like KeyProxy can give the behavior of focus even when hasFocus() isn't - true. -*/ -void QDeclarativeTextEdit::focusChanged(bool hasFocus) +void QDeclarativeTextEditPrivate::focusChanged(bool hasFocus) { - setCursorVisible(hasFocus); - QDeclarativeItem::focusChanged(hasFocus); + Q_Q(QDeclarativeTextEdit); + q->setCursorVisible(hasFocus); + QDeclarativeItemPrivate::focusChanged(hasFocus); } /*! diff --git a/src/declarative/graphicsitems/qdeclarativetextedit_p.h b/src/declarative/graphicsitems/qdeclarativetextedit_p.h index 6183b1d..b1682c4 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextedit_p.h @@ -215,8 +215,6 @@ protected: void keyPressEvent(QKeyEvent *); void keyReleaseEvent(QKeyEvent *); - void focusChanged(bool); - // mouse filter? void mousePressEvent(QGraphicsSceneMouseEvent *event); void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); diff --git a/src/declarative/graphicsitems/qdeclarativetextedit_p_p.h b/src/declarative/graphicsitems/qdeclarativetextedit_p_p.h index 002fac4..dd2a29d 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextedit_p_p.h @@ -80,6 +80,7 @@ public: void updateDefaultTextOption(); void relayoutDocument(); void updateSelection(); + void focusChanged(bool); QString text; QFont font; diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp index 3382628..6df3533 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp @@ -636,12 +636,12 @@ int QDeclarativeTextInput::xToPos(int x) return d->control->xToPos(x - d->hscroll); } -void QDeclarativeTextInput::focusChanged(bool hasFocus) +void QDeclarativeTextInputPrivate::focusChanged(bool hasFocus) { - Q_D(QDeclarativeTextInput); - d->focused = hasFocus; - setCursorVisible(hasFocus); - QDeclarativeItem::focusChanged(hasFocus); + Q_Q(QDeclarativeTextInput); + focused = hasFocus; + q->setCursorVisible(hasFocus); + QDeclarativeItemPrivate::focusChanged(hasFocus); } void QDeclarativeTextInput::keyPressEvent(QKeyEvent* ev) diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p.h index f690ae2..6a61c2d 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextinput_p.h @@ -199,8 +199,6 @@ protected: void keyPressEvent(QKeyEvent* ev); bool event(QEvent *e); - void focusChanged(bool hasFocus); - public Q_SLOTS: void selectAll(); diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h index 3d28f40..5d17a55 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h @@ -83,6 +83,7 @@ public: void init(); void startCreatingCursor(); + void focusChanged(bool hasFocus); QLineControl* control; diff --git a/src/declarative/util/qdeclarativeview.cpp b/src/declarative/util/qdeclarativeview.cpp index cd67aeb..218b587 100644 --- a/src/declarative/util/qdeclarativeview.cpp +++ b/src/declarative/util/qdeclarativeview.cpp @@ -447,8 +447,8 @@ void QDeclarativeView::setRootObject(QObject *obj) QPerformanceLog::clear(); d->root = item; d->qmlRoot = item; - connect(item, SIGNAL(widthChanged()), this, SLOT(sizeChanged())); - connect(item, SIGNAL(heightChanged()), this, SLOT(sizeChanged())); + connect(item, SIGNAL(widthChanged(qreal)), this, SLOT(sizeChanged())); + connect(item, SIGNAL(heightChanged(qreal)), this, SLOT(sizeChanged())); if (d->initialSize.height() <= 0 && d->qmlRoot->width() > 0) d->initialSize.setWidth(d->qmlRoot->width()); if (d->initialSize.height() <= 0 && d->qmlRoot->height() > 0) diff --git a/src/imports/webkit/qdeclarativewebview.cpp b/src/imports/webkit/qdeclarativewebview.cpp index d78ba28..f8b2b88 100644 --- a/src/imports/webkit/qdeclarativewebview.cpp +++ b/src/imports/webkit/qdeclarativewebview.cpp @@ -80,6 +80,7 @@ public: rendering(true) { } + void focusChanged(bool); QUrl url; // page url might be different if it has not loaded yet QWebPage *page; @@ -378,11 +379,12 @@ QVariant QDeclarativeWebView::evaluateJavaScript(const QString &scriptSource) return this->page()->mainFrame()->evaluateJavaScript(scriptSource); } -void QDeclarativeWebView::focusChanged(bool hasFocus) +void QDeclarativeWebViewPrivate::focusChanged(bool hasFocus) { + Q_Q(QDeclarativeWebView); QFocusEvent e(hasFocus ? QEvent::FocusIn : QEvent::FocusOut); - page()->event(&e); - QDeclarativeItem::focusChanged(hasFocus); + q->page()->event(&e); + QDeclarativeItemPrivate::focusChanged(hasFocus); } void QDeclarativeWebView::initialLayout() diff --git a/src/imports/webkit/qdeclarativewebview_p.h b/src/imports/webkit/qdeclarativewebview_p.h index 145e74b..95f51d1 100644 --- a/src/imports/webkit/qdeclarativewebview_p.h +++ b/src/imports/webkit/qdeclarativewebview_p.h @@ -239,7 +239,6 @@ protected: void keyReleaseEvent(QKeyEvent* event); virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); - virtual void focusChanged(bool); virtual bool sceneEvent(QEvent *event); QDeclarativeWebView *createWindow(QWebPage::WebWindowType type); diff --git a/tests/auto/declarative/qdeclarativeitem/data/propertychanges.qml b/tests/auto/declarative/qdeclarativeitem/data/propertychanges.qml new file mode 100644 index 0000000..bf4dd85 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeitem/data/propertychanges.qml @@ -0,0 +1,10 @@ +import Qt 4.6 + +Item { + Item { + objectName: "item" + } + Item { + objectName: "parentItem" + } +} \ No newline at end of file diff --git a/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp b/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp index bbcc86e..45d670f 100644 --- a/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp +++ b/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp @@ -60,6 +60,7 @@ private slots: void clip(); void mapCoordinates(); void mapCoordinates_data(); + void propertyChanges(); private: template @@ -289,7 +290,7 @@ void tst_QDeclarativeItem::smooth() QDeclarativeComponent component(&engine); component.setData("import Qt 4.6; Item { smooth: false; }", QUrl::fromLocalFile("")); QDeclarativeItem *item = qobject_cast(component.create()); - QSignalSpy spy(item, SIGNAL(smoothChanged())); + QSignalSpy spy(item, SIGNAL(smoothChanged(bool))); QVERIFY(item); QVERIFY(!item->smooth()); @@ -297,6 +298,10 @@ void tst_QDeclarativeItem::smooth() item->setSmooth(true); QVERIFY(item->smooth()); QCOMPARE(spy.count(),1); + QList arguments = spy.first(); + QVERIFY(arguments.count() == 1); + QVERIFY(arguments.at(0).toBool() == true); + item->setSmooth(true); QCOMPARE(spy.count(),1); @@ -314,13 +319,18 @@ void tst_QDeclarativeItem::clip() QDeclarativeComponent component(&engine); component.setData("import Qt 4.6\nItem { clip: false\n }", QUrl::fromLocalFile("")); QDeclarativeItem *item = qobject_cast(component.create()); - QSignalSpy spy(item, SIGNAL(clipChanged())); + QSignalSpy spy(item, SIGNAL(clipChanged(bool))); QVERIFY(item); QVERIFY(!item->clip()); item->setClip(true); QVERIFY(item->clip()); + + QList arguments = spy.first(); + QVERIFY(arguments.count() == 1); + QVERIFY(arguments.at(0).toBool() == true); + QCOMPARE(spy.count(),1); item->setClip(true); QCOMPARE(spy.count(),1); @@ -392,6 +402,84 @@ void tst_QDeclarativeItem::mapCoordinates_data() QTest::newRow(QTest::toString(i)) << i << i; } +void tst_QDeclarativeItem::propertyChanges() +{ + QDeclarativeView *canvas = new QDeclarativeView(0); + canvas->setFixedSize(240,320); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml")); + canvas->show(); + + QEvent wa(QEvent::WindowActivate); + QApplication::sendEvent(canvas, &wa); + QFocusEvent fe(QEvent::FocusIn); + QApplication::sendEvent(canvas, &fe); + + QDeclarativeItem *item = findItem(canvas->rootObject(), "item"); + QDeclarativeItem *parentItem = findItem(canvas->rootObject(), "parentItem"); + + QVERIFY(item); + QVERIFY(parentItem); + + QSignalSpy parentSpy(item, SIGNAL(parentChanged(QDeclarativeItem *))); + QSignalSpy widthSpy(item, SIGNAL(widthChanged(qreal))); + QSignalSpy heightSpy(item, SIGNAL(heightChanged(qreal))); + QSignalSpy baselineOffsetSpy(item, SIGNAL(baselineOffsetChanged(qreal))); + QSignalSpy childrenRectSpy(parentItem, SIGNAL(childrenRectChanged(QRectF))); + QSignalSpy focusSpy(item, SIGNAL(focusChanged(bool))); + QSignalSpy wantsFocusSpy(parentItem, SIGNAL(wantsFocusChanged(bool))); + + item->setParentItem(parentItem); + item->setWidth(100.0); + item->setHeight(200.0); + item->setFocus(true); + item->setBaselineOffset(10.0); + + QCOMPARE(item->parentItem(), parentItem); + QCOMPARE(parentSpy.count(),1); + QList parentArguments = parentSpy.first(); + QVERIFY(parentArguments.count() == 1); + QCOMPARE(item->parentItem(), qvariant_cast(parentArguments.at(0))); + + QCOMPARE(item->width(), 100.0); + QCOMPARE(widthSpy.count(),1); + QList widthArguments = widthSpy.first(); + QVERIFY(widthArguments.count() == 1); + QCOMPARE(item->width(), widthArguments.at(0).toReal()); + + QCOMPARE(item->height(), 200.0); + QCOMPARE(heightSpy.count(),1); + QList heightArguments = heightSpy.first(); + QVERIFY(heightArguments.count() == 1); + QCOMPARE(item->height(), heightArguments.at(0).toReal()); + + QCOMPARE(item->baselineOffset(), 10.0); + QCOMPARE(baselineOffsetSpy.count(),1); + QList baselineOffsetArguments = baselineOffsetSpy.first(); + QVERIFY(baselineOffsetArguments.count() == 1); + QCOMPARE(item->baselineOffset(), baselineOffsetArguments.at(0).toReal()); + + QCOMPARE(parentItem->childrenRect(), QRectF(0.0,0.0,100.0,200.0)); + QCOMPARE(childrenRectSpy.count(),2); + QList childrenRectArguments = childrenRectSpy.at(1); + QVERIFY(childrenRectArguments.count() == 1); + QCOMPARE(parentItem->childrenRect(), childrenRectArguments.at(0).toRectF()); + + QCOMPARE(item->hasFocus(), true); + QCOMPARE(focusSpy.count(),1); + QList focusArguments = focusSpy.first(); + QVERIFY(focusArguments.count() == 1); + QCOMPARE(focusArguments.at(0).toBool(), true); + + QCOMPARE(parentItem->hasFocus(), false); + QCOMPARE(parentItem->wantsFocus(), true); + QCOMPARE(wantsFocusSpy.count(),1); + QList wantsFocusArguments = wantsFocusSpy.first(); + QVERIFY(wantsFocusArguments.count() == 1); + QCOMPARE(wantsFocusArguments.at(0).toBool(), true); + + delete canvas; +} + template T *tst_QDeclarativeItem::findItem(QGraphicsObject *parent, const QString &objectName) { diff --git a/tests/auto/declarative/qdeclarativerepeater/tst_qdeclarativerepeater.cpp b/tests/auto/declarative/qdeclarativerepeater/tst_qdeclarativerepeater.cpp index 7a97e60..7da9454 100644 --- a/tests/auto/declarative/qdeclarativerepeater/tst_qdeclarativerepeater.cpp +++ b/tests/auto/declarative/qdeclarativerepeater/tst_qdeclarativerepeater.cpp @@ -109,7 +109,7 @@ public: setRoleNames(roles); } - int rowCount(const QModelIndex &parent=QModelIndex()) const { return list.count(); } + int rowCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return list.count(); } QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const { QVariant rv; if (role == Name) -- cgit v0.12 From 9abf138562c583617205c60e05d5ed2c2874d4be Mon Sep 17 00:00:00 2001 From: Joona Petrell Date: Tue, 9 Mar 2010 15:50:55 +1000 Subject: Update configure.exe to include declarative module by default --- configure.exe | Bin 1008128 -> 1224192 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/configure.exe b/configure.exe index 9974236..326fcdf 100755 Binary files a/configure.exe and b/configure.exe differ -- cgit v0.12 From 782422352f5e2280345054eacd6a001cca164570 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Tue, 9 Mar 2010 16:06:17 +1000 Subject: Compile --- .../declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index d134750..16086cd 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -890,7 +890,7 @@ void tst_qdeclarativeecmascript::dynamicDestruction() } QVERIFY(!createdQmlObject); - QDeclarativeEngine::setObjectOwnership(object, QDeclarativeEngine::QMLOwnership); + QDeclarativeEngine::setObjectOwnership(object, QDeclarativeEngine::JavaScriptOwnership); QMetaObject::invokeMethod(object, "killMe"); QVERIFY(object); QTest::qWait(0); -- cgit v0.12 From fba8a431a9af215c54b04b5ab23c684621615a94 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Tue, 9 Mar 2010 16:20:45 +1000 Subject: Add QML support for methods returning QList --- .../qml/qdeclarativeobjectscriptclass.cpp | 90 +++++++++++++--------- .../qdeclarativeecmascript/data/ownership.qml | 5 ++ .../data/qlistqobjectMethods.qml | 6 ++ .../tst_qdeclarativeecmascript.cpp | 38 +++++++++ 4 files changed, 104 insertions(+), 35 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/ownership.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/qlistqobjectMethods.qml diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp index 3ca03b4..dc4a676 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp @@ -475,6 +475,8 @@ QDeclarativeObjectMethodScriptClass::QDeclarativeObjectMethodScriptClass(QDeclar : QScriptDeclarativeClass(QDeclarativeEnginePrivate::getScriptEngine(bindEngine)), engine(bindEngine) { + qRegisterMetaType >("QList"); + setSupportsCall(true); QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); @@ -585,7 +587,7 @@ private: inline void cleanup(); - char *data[16]; + char data[2 * sizeof(void *)]; int type; }; } @@ -603,11 +605,13 @@ MetaCallArgument::~MetaCallArgument() void MetaCallArgument::cleanup() { if (type == QMetaType::QString) { - ((QString *)data)->~QString(); + ((QString *)&data)->~QString(); } else if (type == -1 || type == qMetaTypeId()) { - ((QVariant *)data)->~QVariant(); + ((QVariant *)&data)->~QVariant(); } else if (type == qMetaTypeId()) { - ((QScriptValue *)data)->~QScriptValue(); + ((QScriptValue *)&data)->~QScriptValue(); + } else if (type == qMetaTypeId >()) { + ((QList *)&data)->~QList(); } } @@ -616,7 +620,7 @@ void *MetaCallArgument::dataPtr() if (type == -1) return ((QVariant *)data)->data(); else - return (void *)data; + return (void *)&data; } void MetaCallArgument::initAsType(int callType, QDeclarativeEngine *e) @@ -627,7 +631,7 @@ void MetaCallArgument::initAsType(int callType, QDeclarativeEngine *e) QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(e); if (callType == qMetaTypeId()) { - new (data) QScriptValue(engine->undefinedValue()); + new (&data) QScriptValue(engine->undefinedValue()); type = callType; } else if (callType == QMetaType::Int || callType == QMetaType::UInt || @@ -636,17 +640,20 @@ void MetaCallArgument::initAsType(int callType, QDeclarativeEngine *e) callType == QMetaType::Float) { type = callType; } else if (callType == QMetaType::QObjectStar) { - *((QObject **)data) = 0; + *((QObject **)&data) = 0; type = callType; } else if (callType == QMetaType::QString) { - new (data) QString(); + new (&data) QString(); type = callType; } else if (callType == qMetaTypeId()) { - type = qMetaTypeId(); - new (data) QVariant(); + type = callType; + new (&data) QVariant(); + } else if (callType == qMetaTypeId >()) { + type = callType; + new (&data) QList(); } else { type = -1; - new (data) QVariant(callType, (void *)0); + new (&data) QVariant(callType, (void *)0); } } @@ -655,47 +662,50 @@ void MetaCallArgument::fromScriptValue(int callType, QDeclarativeEngine *engine, if (type != 0) { cleanup(); type = 0; } if (callType == qMetaTypeId()) { - new (data) QScriptValue(value); + new (&data) QScriptValue(value); type = qMetaTypeId(); } else if (callType == QMetaType::Int) { - *((int *)data) = int(value.toInt32()); + *((int *)&data) = int(value.toInt32()); type = callType; } else if (callType == QMetaType::UInt) { - *((uint *)data) = uint(value.toUInt32()); + *((uint *)&data) = uint(value.toUInt32()); type = callType; } else if (callType == QMetaType::Bool) { - *((bool *)data) = value.toBool(); + *((bool *)&data) = value.toBool(); type = callType; } else if (callType == QMetaType::Double) { - *((double *)data) = double(value.toNumber()); + *((double *)&data) = double(value.toNumber()); type = callType; } else if (callType == QMetaType::Float) { - *((float *)data) = float(value.toNumber()); + *((float *)&data) = float(value.toNumber()); type = callType; } else if (callType == QMetaType::QString) { if (value.isNull() || value.isUndefined()) - new (data) QString(); + new (&data) QString(); else - new (data) QString(value.toString()); + new (&data) QString(value.toString()); type = callType; } else if (callType == QMetaType::QObjectStar) { - *((QObject **)data) = value.toQObject(); + *((QObject **)&data) = value.toQObject(); type = callType; } else if (callType == qMetaTypeId()) { - new (data) QVariant(QDeclarativeScriptClass::toVariant(engine, value)); + new (&data) QVariant(QDeclarativeScriptClass::toVariant(engine, value)); + type = callType; + } else if (callType == qMetaTypeId >()) { + new (&data) QList(); // We don't support passing in QList type = callType; } else { - new (data) QVariant(); + new (&data) QVariant(); type = -1; QVariant v = QDeclarativeScriptClass::toVariant(engine, value); if (v.userType() == callType) { - *((QVariant *)data) = v; + *((QVariant *)&data) = v; } else if (v.canConvert((QVariant::Type)callType)) { - *((QVariant *)data) = v; - ((QVariant *)data)->convert((QVariant::Type)callType); + *((QVariant *)&data) = v; + ((QVariant *)&data)->convert((QVariant::Type)callType); } else { - *((QVariant *)data) = QVariant(callType, (void *)0); + *((QVariant *)&data) = QVariant(callType, (void *)0); } } } @@ -705,26 +715,36 @@ QScriptDeclarativeClass::Value MetaCallArgument::toValue(QDeclarativeEngine *e) QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(e); if (type == qMetaTypeId()) { - return QScriptDeclarativeClass::Value(engine, *((QScriptValue *)data)); + return QScriptDeclarativeClass::Value(engine, *((QScriptValue *)&data)); } else if (type == QMetaType::Int) { - return QScriptDeclarativeClass::Value(engine, *((int *)data)); + return QScriptDeclarativeClass::Value(engine, *((int *)&data)); } else if (type == QMetaType::UInt) { - return QScriptDeclarativeClass::Value(engine, *((uint *)data)); + return QScriptDeclarativeClass::Value(engine, *((uint *)&data)); } else if (type == QMetaType::Bool) { - return QScriptDeclarativeClass::Value(engine, *((bool *)data)); + return QScriptDeclarativeClass::Value(engine, *((bool *)&data)); } else if (type == QMetaType::Double) { - return QScriptDeclarativeClass::Value(engine, *((double *)data)); + return QScriptDeclarativeClass::Value(engine, *((double *)&data)); } else if (type == QMetaType::Float) { - return QScriptDeclarativeClass::Value(engine, *((float *)data)); + return QScriptDeclarativeClass::Value(engine, *((float *)&data)); } else if (type == QMetaType::QString) { - return QScriptDeclarativeClass::Value(engine, *((QString *)data)); + return QScriptDeclarativeClass::Value(engine, *((QString *)&data)); } else if (type == QMetaType::QObjectStar) { - QObject *object = *((QObject **)data); + QObject *object = *((QObject **)&data); QDeclarativeDeclarativeData::get(object, true)->setImplicitDestructible(); QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(e); return QScriptDeclarativeClass::Value(engine, priv->objectClass->newQObject(object)); + } else if (type == qMetaTypeId >()) { + QList &list = *(QList*)&data; + QScriptValue rv = engine->newArray(list.count()); + QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(e); + for (int ii = 0; ii < list.count(); ++ii) { + QObject *object = list.at(ii); + QDeclarativeDeclarativeData::get(object, true)->setImplicitDestructible(); + rv.setProperty(ii, priv->objectClass->newQObject(object)); + } + return QScriptDeclarativeClass::Value(engine, rv); } else if (type == -1 || type == qMetaTypeId()) { - return QScriptDeclarativeClass::Value(engine, QDeclarativeEnginePrivate::get(e)->scriptValueFromVariant(*((QVariant *)data))); + return QScriptDeclarativeClass::Value(engine, QDeclarativeEnginePrivate::get(e)->scriptValueFromVariant(*((QVariant *)&data))); } else { return QScriptDeclarativeClass::Value(); } diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/ownership.qml b/tests/auto/declarative/qdeclarativeecmascript/data/ownership.qml new file mode 100644 index 0000000..72edf6e --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/ownership.qml @@ -0,0 +1,5 @@ +import Qt 4.6 + +QtObject { + Component.onCompleted: { var a = getObject(); a = null; } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/qlistqobjectMethods.qml b/tests/auto/declarative/qdeclarativeecmascript/data/qlistqobjectMethods.qml new file mode 100644 index 0000000..5897e2a --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/qlistqobjectMethods.qml @@ -0,0 +1,6 @@ +import Qt 4.6 + +QtObject { + property int test: getObjects().length + property bool test2: getObjects()[0].trueProperty +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index 16086cd..bdd2c93 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -127,6 +127,7 @@ private slots: void scriptConnect(); void scriptDisconnect(); void ownership(); + void qlistqobjectMethods(); void bug1(); @@ -1945,6 +1946,43 @@ void tst_qdeclarativeecmascript::ownership() } } +class QListQObjectMethodsObject : public QObject +{ + Q_OBJECT +public: + QListQObjectMethodsObject() { + m_objects.append(new MyQmlObject()); + m_objects.append(new MyQmlObject()); + } + + ~QListQObjectMethodsObject() { + qDeleteAll(m_objects); + } + +public slots: + QList getObjects() { return m_objects; } + +private: + QList m_objects; +}; + +// Tests that returning a QList from a method works +void tst_qdeclarativeecmascript::qlistqobjectMethods() +{ + QListQObjectMethodsObject obj; + QDeclarativeContext *context = new QDeclarativeContext(engine.rootContext()); + context->addDefaultObject(&obj); + + QDeclarativeComponent component(&engine, TEST_FILE("qlistqobjectMethods.qml")); + + QObject *object = component.create(context); + + QCOMPARE(object->property("test").toInt(), 2); + QCOMPARE(object->property("test2").toBool(), true); + + delete object; +} + QTEST_MAIN(tst_qdeclarativeecmascript) #include "tst_qdeclarativeecmascript.moc" -- cgit v0.12 From 262c7eb1e93e8cafe8de8e49b53c218deb23639e Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 9 Mar 2010 16:37:59 +1000 Subject: Handle itemsInserted/Removed/Moved() correctly for repeater. Also make positioners react correctly to item moves. Task-number: QT-745 --- .../graphicsitems/qdeclarativepositioners.cpp | 7 ++- .../graphicsitems/qdeclarativerepeater.cpp | 56 +++++++++++++++++++--- 2 files changed, 55 insertions(+), 8 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativepositioners.cpp b/src/declarative/graphicsitems/qdeclarativepositioners.cpp index 1212e89..0f59a70 100644 --- a/src/declarative/graphicsitems/qdeclarativepositioners.cpp +++ b/src/declarative/graphicsitems/qdeclarativepositioners.cpp @@ -212,19 +212,22 @@ void QDeclarativeBasePositioner::prePositioning() QList children = d->QGraphicsItemPrivate::children; qSort(children.begin(), children.end(), d->insertionOrder); + QPODVector oldItems; + positionedItems.copyAndClear(oldItems); for (int ii = 0; ii < children.count(); ++ii) { QDeclarativeItem *child = qobject_cast(children.at(ii)); if (!child) continue; PositionedItem *item = 0; PositionedItem posItem(child); - int wIdx = positionedItems.find(posItem); + int wIdx = oldItems.find(posItem); if (wIdx < 0) { d->watchChanges(child); positionedItems.append(posItem); item = &positionedItems[positionedItems.count()-1]; } else { - item = &positionedItems[wIdx]; + item = &oldItems[wIdx]; + positionedItems.append(*item); } if (child->opacity() <= 0.0 || !child->isVisible()) { item->isVisible = false; diff --git a/src/declarative/graphicsitems/qdeclarativerepeater.cpp b/src/declarative/graphicsitems/qdeclarativerepeater.cpp index e4cd499..b9696c8 100644 --- a/src/declarative/graphicsitems/qdeclarativerepeater.cpp +++ b/src/declarative/graphicsitems/qdeclarativerepeater.cpp @@ -296,6 +296,8 @@ void QDeclarativeRepeater::clear() void QDeclarativeRepeater::regenerate() { Q_D(QDeclarativeRepeater); + if (!isComponentComplete()) + return; clear(); @@ -312,23 +314,65 @@ void QDeclarativeRepeater::regenerate() } } -void QDeclarativeRepeater::itemsInserted(int, int) +void QDeclarativeRepeater::itemsInserted(int index, int count) { - regenerate(); + Q_D(QDeclarativeRepeater); + if (!isComponentComplete()) + return; + for (int i = 0; i < count; ++i) { + int modelIndex = index + i; + QDeclarativeItem *item = d->model->item(modelIndex); + if (item) { + item->setParent(parentItem()); + if (modelIndex < d->deletables.count()) + item->stackBefore(d->deletables.at(modelIndex)); + else + item->stackBefore(this); + d->deletables.insert(modelIndex, item); + } + } } -void QDeclarativeRepeater::itemsRemoved(int, int) +void QDeclarativeRepeater::itemsRemoved(int index, int count) { - regenerate(); + Q_D(QDeclarativeRepeater); + if (!isComponentComplete()) + return; + while (count--) { + QDeclarativeItem *item = d->deletables.takeAt(index); + if (item) { + item->setParentItem(this); + d->model->release(item); + } + } } -void QDeclarativeRepeater::itemsMoved(int,int,int) +void QDeclarativeRepeater::itemsMoved(int from, int to, int count) { - regenerate(); + Q_D(QDeclarativeRepeater); + if (!isComponentComplete()) + return; + QList removed; + int removedCount = count; + while (removedCount--) + removed << d->deletables.takeAt(from); + for (int i = 0; i < count; ++i) + d->deletables.insert(to + i, removed.at(i)); + for (int i = 0; i < d->model->count(); ++i) { + if (i < from && i < to) + continue; + QDeclarativeItem *item = d->deletables.at(i); + if (i < d->deletables.count()-1) + item->stackBefore(d->deletables.at(i+1)); + else + item->stackBefore(this); + } } void QDeclarativeRepeater::modelReset() { + if (!isComponentComplete()) + return; regenerate(); } -- cgit v0.12 From 55c38d6dc34c0f4248cf115a739163cd20c3b2d7 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 9 Mar 2010 17:08:08 +1000 Subject: Initialize member variable in QDeclarativeGridViewAttached Task-number: QT-3062 --- src/declarative/graphicsitems/qdeclarativegridview_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarative/graphicsitems/qdeclarativegridview_p.h b/src/declarative/graphicsitems/qdeclarativegridview_p.h index 787c04c..183bb05 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview_p.h +++ b/src/declarative/graphicsitems/qdeclarativegridview_p.h @@ -192,7 +192,7 @@ class QDeclarativeGridViewAttached : public QObject Q_OBJECT public: QDeclarativeGridViewAttached(QObject *parent) - : QObject(parent), m_isCurrent(false), m_delayRemove(false) {} + : QObject(parent), m_view(0), m_isCurrent(false), m_delayRemove(false) {} ~QDeclarativeGridViewAttached() {} Q_PROPERTY(QDeclarativeGridView *view READ view CONSTANT) -- cgit v0.12 From 42233381569dccd6fd23f2a112b9eac758093afa Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Tue, 9 Mar 2010 17:13:52 +1000 Subject: Fix qdeclarativevaluetype::font() autotest --- .../qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp b/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp index 51f9a07..eba83ce 100644 --- a/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp +++ b/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp @@ -314,8 +314,17 @@ void tst_qdeclarativevaluetypes::font() font.setLetterSpacing(QFont::AbsoluteSpacing, 9.7); font.setWordSpacing(11.2); - QEXPECT_FAIL("", "QT-2920", Continue); - QCOMPARE(object->font(), font); + QFont f = object->font(); + QCOMPARE(f.family(), font.family()); + QCOMPARE(f.bold(), font.bold()); + QCOMPARE(f.weight(), font.weight()); + QCOMPARE(f.italic(), font.italic()); + QCOMPARE(f.underline(), font.underline()); + QCOMPARE(f.strikeOut(), font.strikeOut()); + QCOMPARE(f.pointSize(), font.pointSize()); + QCOMPARE(f.capitalization(), font.capitalization()); + QCOMPARE(f.letterSpacing(), font.letterSpacing()); + QCOMPARE(f.wordSpacing(), font.wordSpacing()); delete object; } -- cgit v0.12 From 9cf0e75b2b73a59a65edb640b62a6838f31a8a1f Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Tue, 9 Mar 2010 12:15:53 +0100 Subject: Probably fix compile should fix the current failure when building on windows. --- src/declarative/graphicsitems/qdeclarativeitem_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarative/graphicsitems/qdeclarativeitem_p.h b/src/declarative/graphicsitems/qdeclarativeitem_p.h index 76ebcb4..dab0fb6 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem_p.h +++ b/src/declarative/graphicsitems/qdeclarativeitem_p.h @@ -101,7 +101,7 @@ private: qreal m_height; }; -class QDeclarativeItemPrivate : public QGraphicsItemPrivate +class Q_DECLARATIVE_EXPORT QDeclarativeItemPrivate : public QGraphicsItemPrivate { Q_DECLARE_PUBLIC(QDeclarativeItem) -- cgit v0.12 From fb77eadad25d55d1b1d08776f7f74e6cb5c1b39e Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Tue, 9 Mar 2010 13:07:45 +0100 Subject: Fix typo in docs QStringList::appenf is private API, and shouldn't show up in docs. --- doc/src/declarative/qdeclarativemodels.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/declarative/qdeclarativemodels.qdoc b/doc/src/declarative/qdeclarativemodels.qdoc index c0e028e..f7d1a73 100644 --- a/doc/src/declarative/qdeclarativemodels.qdoc +++ b/doc/src/declarative/qdeclarativemodels.qdoc @@ -208,7 +208,7 @@ QStringList provides the contents of the list via the \e modelData role: QStringList dataList; dataList.append("Fred"); dataList.append("Ginger"); -dataList.appenf("Skipper"); +dataList.append("Skipper"); QDeclarativeContext *ctxt = view.rootContext(); ctxt->setContextProperty("myModel", QVariant::fromValue(&dataList)); -- cgit v0.12 From cd7f6dae4c886b8b1bfb2ddc56eb986fad545220 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Tue, 9 Mar 2010 13:17:09 +0100 Subject: Probably fix compile on windows --- src/declarative/graphicsitems/qdeclarativeitem_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarative/graphicsitems/qdeclarativeitem_p.h b/src/declarative/graphicsitems/qdeclarativeitem_p.h index dab0fb6..55df063 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem_p.h +++ b/src/declarative/graphicsitems/qdeclarativeitem_p.h @@ -259,7 +259,7 @@ public: static int consistentTime; static QTime currentTime(); - static void Q_DECLARATIVE_EXPORT setConsistentTime(int t); + static void setConsistentTime(int t); static void start(QTime &); static int elapsed(QTime &); static int restart(QTime &); -- cgit v0.12 From 83b057467054004fe0c1f14638f455cbf447d2b0 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Tue, 9 Mar 2010 13:32:25 +0100 Subject: Update Autotests Unless given an id, animations in behaviours aren't created until needed. As they are never actually needed in these tests, ids are needed --- tests/auto/declarative/qdeclarativebehaviors/data/dontStart.qml | 2 +- .../declarative/qdeclarativebehaviors/data/reassignedAnimation.qml | 4 ++-- tests/auto/declarative/qdeclarativebehaviors/data/simple.qml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/dontStart.qml b/tests/auto/declarative/qdeclarativebehaviors/data/dontStart.qml index 12b1b7b..5e1891a 100644 --- a/tests/auto/declarative/qdeclarativebehaviors/data/dontStart.qml +++ b/tests/auto/declarative/qdeclarativebehaviors/data/dontStart.qml @@ -10,7 +10,7 @@ Rectangle { width: 100; height: 100 color: Qt.rgba(1,0,0) Behavior on x { - NumberAnimation { objectName: "MyAnim"; running: true } + NumberAnimation {id: myAnim; objectName: "MyAnim"; running: true } } } diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/reassignedAnimation.qml b/tests/auto/declarative/qdeclarativebehaviors/data/reassignedAnimation.qml index 6419a6b..11b2d3a 100644 --- a/tests/auto/declarative/qdeclarativebehaviors/data/reassignedAnimation.qml +++ b/tests/auto/declarative/qdeclarativebehaviors/data/reassignedAnimation.qml @@ -8,8 +8,8 @@ Rectangle { width: 100; height: 100; color: "green" Behavior on x { objectName: "MyBehavior" - NumberAnimation { duration: 200 } - NumberAnimation { duration: 1000 } + NumberAnimation {id: na1; duration: 200 } + NumberAnimation {id: na2; duration: 1000 } } } MouseArea { diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/simple.qml b/tests/auto/declarative/qdeclarativebehaviors/data/simple.qml index c28fa9a..5e72bca 100644 --- a/tests/auto/declarative/qdeclarativebehaviors/data/simple.qml +++ b/tests/auto/declarative/qdeclarativebehaviors/data/simple.qml @@ -8,7 +8,7 @@ Rectangle { width: 100; height: 100; color: "green" Behavior on x { objectName: "MyBehavior"; - NumberAnimation { duration: 500; } + NumberAnimation {id: na; duration: 500; } } } MouseArea { -- cgit v0.12 From 4029da6fae201512b15f1e088bf720b0c37e1437 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Tue, 9 Mar 2010 14:58:00 +0100 Subject: update Browser.qml to run again --- tools/qml/content/Browser.qml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/qml/content/Browser.qml b/tools/qml/content/Browser.qml index 35120bc..62996ef 100644 --- a/tools/qml/content/Browser.qml +++ b/tools/qml/content/Browser.qml @@ -137,12 +137,12 @@ Rectangle { Transition { to: "current" SequentialAnimation { - NumberAnimation { matchProperties: "x"; duration: 250 } + NumberAnimation { properties: "x"; duration: 250 } } }, Transition { - NumberAnimation { matchProperties: "x"; duration: 250 } - NumberAnimation { matchProperties: "x"; duration: 250 } + NumberAnimation { properties: "x"; duration: 250 } + NumberAnimation { properties: "x"; duration: 250 } } ] Keys.onPressed: { root.keyPressed = true; } @@ -177,11 +177,11 @@ Rectangle { Transition { to: "current" SequentialAnimation { - NumberAnimation { matchProperties: "x"; duration: 250 } + NumberAnimation { properties: "x"; duration: 250 } } }, Transition { - NumberAnimation { matchProperties: "x"; duration: 250 } + NumberAnimation { properties: "x"; duration: 250 } } ] Keys.onPressed: { root.keyPressed = true; } -- cgit v0.12 From 7f2836aba3334dc4c9da5cc5f57889c11a2bd85c Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 10 Mar 2010 09:12:12 +1000 Subject: Remove unused struct --- src/declarative/graphicsitems/qdeclarativepathview_p_p.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativepathview_p_p.h b/src/declarative/graphicsitems/qdeclarativepathview_p_p.h index 4083ab5..62f7d95 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativepathview_p_p.h @@ -66,11 +66,6 @@ QT_BEGIN_NAMESPACE -typedef struct PathViewItem{ - int index; - QDeclarativeItem* item; -}PathViewItem; - class QDeclarativeOpenMetaObjectType; class QDeclarativePathViewAttached; class QDeclarativePathViewPrivate : public QDeclarativeItemPrivate -- cgit v0.12