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 From 2b7de14b26de6f38b73b691c881f1c8f7be1a354 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 10 Mar 2010 10:36:47 +1000 Subject: Link with the correct library for TCommDbConnPref --- tools/qml/qml.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/qml/qml.pro b/tools/qml/qml.pro index 9b68dbc..0579493 100644 --- a/tools/qml/qml.pro +++ b/tools/qml/qml.pro @@ -55,6 +55,6 @@ symbian { include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) TARGET.EPOCHEAPSIZE = 0x20000 0x2000000 HEADERS += $$QT_SOURCE_TREE/examples/network/qftp/sym_iap_util.h - LIBS += -lesock -lconnmon -linsock + LIBS += -lesock -lcommdb -linsock TARGET.CAPABILITY = "All -TCB" } -- cgit v0.12 From 099dc3000e2767bad3c657d7011c8701afa11873 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 10 Mar 2010 10:44:02 +1000 Subject: Doc QTBUG-8448 --- src/declarative/graphicsitems/qdeclarativeloader.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativeloader.cpp b/src/declarative/graphicsitems/qdeclarativeloader.cpp index b0499d7..c9e80ee 100644 --- a/src/declarative/graphicsitems/qdeclarativeloader.cpp +++ b/src/declarative/graphicsitems/qdeclarativeloader.cpp @@ -346,12 +346,13 @@ QDeclarativeLoader::Status QDeclarativeLoader::status() const } /*! - \qmlproperty real Loader::progress +\qmlproperty real Loader::progress - This property holds the progress of QML data loading, from 0.0 (nothing loaded) - to 1.0 (finished). +This property holds the progress of loading QML data from the network, from +0.0 (nothing loaded) to 1.0 (finished). Most QML files are quite small, so +this value will rapidly change from 0 to 1. - \sa status +\sa status */ qreal QDeclarativeLoader::progress() const { -- cgit v0.12 From 07ed7e7d61b9c8bce86cdb7d763c3697eceafda4 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Wed, 10 Mar 2010 13:53:57 +1000 Subject: Implement URL redirection for types and XmlListModel. Task-number: QTBUG-7515 --- .../qml/qdeclarativecompositetypemanager.cpp | 32 +++++++++++++++++++++- .../qml/qdeclarativecompositetypemanager_p.h | 3 ++ src/declarative/util/qdeclarativexmllistmodel.cpp | 21 ++++++++++++-- 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/src/declarative/qml/qdeclarativecompositetypemanager.cpp b/src/declarative/qml/qdeclarativecompositetypemanager.cpp index b90a598..6f41963 100644 --- a/src/declarative/qml/qdeclarativecompositetypemanager.cpp +++ b/src/declarative/qml/qdeclarativecompositetypemanager.cpp @@ -154,7 +154,7 @@ QDeclarativeCompositeTypeData::TypeReference::TypeReference() } QDeclarativeCompositeTypeManager::QDeclarativeCompositeTypeManager(QDeclarativeEngine *e) -: engine(e) +: engine(e), redirectCount(0) { } @@ -172,6 +172,10 @@ QDeclarativeCompositeTypeManager::~QDeclarativeCompositeTypeManager() QDeclarativeCompositeTypeData *QDeclarativeCompositeTypeManager::get(const QUrl &url) { + Redirects::Iterator redir = redirects.find(url); + if (redir != redirects.end()) + return get(*redir); + QDeclarativeCompositeTypeData *unit = components.value(url); if (!unit) { @@ -219,6 +223,8 @@ void QDeclarativeCompositeTypeManager::clearCache() } } +#define TYPEMANAGER_MAXIMUM_REDIRECT_RECURSION 16 + void QDeclarativeCompositeTypeManager::replyFinished() { QNetworkReply *reply = static_cast(sender()); @@ -226,6 +232,26 @@ void QDeclarativeCompositeTypeManager::replyFinished() QDeclarativeCompositeTypeData *unit = components.value(reply->url()); Q_ASSERT(unit); + redirectCount++; + if (redirectCount < TYPEMANAGER_MAXIMUM_REDIRECT_RECURSION) { + QVariant redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute); + if (redirect.isValid()) { + QUrl url = reply->url().resolved(redirect.toUrl()); + redirects.insert(reply->url(),url); + unit->imports.setBaseUrl(url); + components.remove(reply->url()); + components.insert(url, unit); + reply->deleteLater(); + reply = engine->networkAccessManager()->get(QNetworkRequest(url)); + QObject::connect(reply, SIGNAL(finished()), + this, SLOT(replyFinished())); + QObject::connect(reply, SIGNAL(downloadProgress(qint64,qint64)), + this, SLOT(requestProgress(qint64,qint64))); + return; + } + } + redirectCount = 0; + if (reply->error() != QNetworkReply::NoError) { QString errorDescription; // ### - Fill in error @@ -546,6 +572,10 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData continue; } + Redirects::Iterator redir = redirects.find(url); + if (redir != redirects.end()) + url = *redir; + QDeclarativeCompositeTypeData *urlUnit = components.value(url); if (!urlUnit) { diff --git a/src/declarative/qml/qdeclarativecompositetypemanager_p.h b/src/declarative/qml/qdeclarativecompositetypemanager_p.h index 03d16b8..a572e0c 100644 --- a/src/declarative/qml/qdeclarativecompositetypemanager_p.h +++ b/src/declarative/qml/qdeclarativecompositetypemanager_p.h @@ -109,6 +109,9 @@ private: Components components; typedef QHash Resources; Resources resources; + typedef QHash Redirects; + Redirects redirects; + int redirectCount; }; QT_END_NAMESPACE diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp index 49dbb27..249880e 100644 --- a/src/declarative/util/qdeclarativexmllistmodel.cpp +++ b/src/declarative/util/qdeclarativexmllistmodel.cpp @@ -396,7 +396,7 @@ public: QDeclarativeXmlListModelPrivate() : isComponentComplete(true), size(-1), highestRole(Qt::UserRole) , reply(0), status(QDeclarativeXmlListModel::Null), progress(0.0) - , queryId(-1), roleObjects() {} + , queryId(-1), roleObjects(), redirectCount(0) {} bool isComponentComplete; QUrl src; @@ -417,6 +417,7 @@ public: static void removeAt_role(QDeclarativeListProperty *list, int i); static void insert_role(QDeclarativeListProperty *list, int i, QDeclarativeXmlListModelRole *role); QList > data; + int redirectCount; }; @@ -575,8 +576,8 @@ void QDeclarativeXmlListModel::setSource(const QUrl &src) { Q_D(QDeclarativeXmlListModel); if (d->src != src) { - reload(); d->src = src; + reload(); emit sourceChanged(); } } @@ -778,9 +779,25 @@ void QDeclarativeXmlListModel::reload() this, SLOT(requestProgress(qint64,qint64))); } +#define XMLLISTMODEL_MAX_REDIRECT 16 + void QDeclarativeXmlListModel::requestFinished() { Q_D(QDeclarativeXmlListModel); + + d->redirectCount++; + if (d->redirectCount < XMLLISTMODEL_MAX_REDIRECT) { + QVariant redirect = d->reply->attribute(QNetworkRequest::RedirectionTargetAttribute); + if (redirect.isValid()) { + QUrl url = d->reply->url().resolved(redirect.toUrl()); + d->reply->deleteLater(); + d->reply = 0; + setSource(url); + return; + } + } + d->redirectCount = 0; + if (d->reply->error() != QNetworkReply::NoError) { disconnect(d->reply, 0, this, 0); d->reply->deleteLater(); -- cgit v0.12 From 954ff8673c1b9913697ecdeec355f2b0f9e4633a Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Wed, 10 Mar 2010 14:31:58 +1000 Subject: URL redirects for border image. Task-number: QTBUG-7515 --- .../graphicsitems/qdeclarativeborderimage.cpp | 16 +++++++++++++++- .../graphicsitems/qdeclarativeborderimage_p_p.h | 4 +++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp index de16668..a7534b8 100644 --- a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp +++ b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp @@ -191,7 +191,7 @@ void QDeclarativeBorderImage::load() update(); } else { d->status = Loading; - if (d->url.path().endsWith(QLatin1String(".sci"))) { + if (d->url.path().endsWith(QLatin1String("sci"))) { #ifndef QT_NO_LOCALFILE_OPTIMIZED_QML QString lf = toLocalFileOrQrc(d->url); if (!lf.isEmpty()) { @@ -400,9 +400,23 @@ void QDeclarativeBorderImage::requestFinished() update(); } +#define BORDERIMAGE_MAX_REDIRECT 16 + void QDeclarativeBorderImage::sciRequestFinished() { Q_D(QDeclarativeBorderImage); + + d->redirectCount++; + if (d->redirectCount < BORDERIMAGE_MAX_REDIRECT) { + QVariant redirect = d->sciReply->attribute(QNetworkRequest::RedirectionTargetAttribute); + if (redirect.isValid()) { + QUrl url = d->sciReply->url().resolved(redirect.toUrl()); + setSource(url); + return; + } + } + d->redirectCount=0; + if (d->sciReply->error() != QNetworkReply::NoError) { d->status = Error; d->sciReply->deleteLater(); diff --git a/src/declarative/graphicsitems/qdeclarativeborderimage_p_p.h b/src/declarative/graphicsitems/qdeclarativeborderimage_p_p.h index b9cf73a..82b9ebf 100644 --- a/src/declarative/graphicsitems/qdeclarativeborderimage_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativeborderimage_p_p.h @@ -68,7 +68,8 @@ public: : border(0), sciReply(0), sciPendingPixmapCache(false), horizontalTileMode(QDeclarativeBorderImage::Stretch), - verticalTileMode(QDeclarativeBorderImage::Stretch) + verticalTileMode(QDeclarativeBorderImage::Stretch), + redirectCount(0) { } @@ -90,6 +91,7 @@ public: bool sciPendingPixmapCache; QDeclarativeBorderImage::TileMode horizontalTileMode; QDeclarativeBorderImage::TileMode verticalTileMode; + int redirectCount; }; QT_END_NAMESPACE -- cgit v0.12 From 3863b79be5e0d6a86a2313a1015aebb2c84ed1bf Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Wed, 10 Mar 2010 15:00:57 +1000 Subject: URL redirection for components resources. Task-number: QTBUG-7515 --- .../qml/qdeclarativecompositetypemanager.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/declarative/qml/qdeclarativecompositetypemanager.cpp b/src/declarative/qml/qdeclarativecompositetypemanager.cpp index 6f41963..9b3a8b4 100644 --- a/src/declarative/qml/qdeclarativecompositetypemanager.cpp +++ b/src/declarative/qml/qdeclarativecompositetypemanager.cpp @@ -282,6 +282,24 @@ void QDeclarativeCompositeTypeManager::resourceReplyFinished() QDeclarativeCompositeTypeResource *resource = resources.value(reply->url()); Q_ASSERT(resource); + redirectCount++; + if (redirectCount < TYPEMANAGER_MAXIMUM_REDIRECT_RECURSION) { + QVariant redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute); + if (redirect.isValid()) { + QUrl url = reply->url().resolved(redirect.toUrl()); + redirects.insert(reply->url(),url); + resource->url = url.toString(); + resources.remove(reply->url()); + resources.insert(url, resource); + reply->deleteLater(); + reply = engine->networkAccessManager()->get(QNetworkRequest(url)); + QObject::connect(reply, SIGNAL(finished()), + this, SLOT(resourceReplyFinished())); + return; + } + } + redirectCount = 0; + if (reply->error() != QNetworkReply::NoError) { resource->status = QDeclarativeCompositeTypeResource::Error; -- cgit v0.12 From 27efe3efc0859019e465955961ff699c9c54df09 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Wed, 10 Mar 2010 15:01:48 +1000 Subject: URL redirection for normal images. Task-number: QTBUG-7515 --- src/declarative/util/qdeclarativepixmapcache.cpp | 41 ++++++++++++++++++++---- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/src/declarative/util/qdeclarativepixmapcache.cpp b/src/declarative/util/qdeclarativepixmapcache.cpp index cfb25dd..942d5f6 100644 --- a/src/declarative/util/qdeclarativepixmapcache.cpp +++ b/src/declarative/util/qdeclarativepixmapcache.cpp @@ -137,7 +137,7 @@ class QDeclarativeImageRequestHandler : public QObject Q_OBJECT public: QDeclarativeImageRequestHandler(QDeclarativeImageReader *read, QDeclarativeEngine *eng) - : QObject(), accessManager(0), engine(eng), reader(read) + : QObject(), accessManager(0), engine(eng), reader(read), redirectCount(0) { QCoreApplication::postEvent(this, new QEvent(QEvent::User)); } @@ -162,18 +162,24 @@ private: QNetworkAccessManager *accessManager; QDeclarativeEngine *engine; QDeclarativeImageReader *reader; + int redirectCount; + + static int replyDownloadProgress; + static int replyFinished; + static int downloadProgress; + static int thisNetworkRequestDone; }; //=========================================================================== +int QDeclarativeImageRequestHandler::replyDownloadProgress = -1; +int QDeclarativeImageRequestHandler::replyFinished = -1; +int QDeclarativeImageRequestHandler::downloadProgress = -1; +int QDeclarativeImageRequestHandler::thisNetworkRequestDone = -1; + bool QDeclarativeImageRequestHandler::event(QEvent *event) { if (event->type() == QEvent::User) { - static int replyDownloadProgress = -1; - static int replyFinished = -1; - static int downloadProgress = -1; - static int thisNetworkRequestDone = -1; - if (replyDownloadProgress == -1) { replyDownloadProgress = QNetworkReply::staticMetaObject.indexOfSignal("downloadProgress(qint64,qint64)"); replyFinished = QNetworkReply::staticMetaObject.indexOfSignal("finished()"); @@ -264,10 +270,33 @@ bool QDeclarativeImageRequestHandler::event(QEvent *event) return QObject::event(event); } +#define IMAGEREQUESTHANDLER_MAX_REDIRECT_RECURSION 16 + void QDeclarativeImageRequestHandler::networkRequestDone() { QNetworkReply *reply = static_cast(sender()); QDeclarativePixmapReply *job = replies.take(reply); + + redirectCount++; + if (redirectCount < IMAGEREQUESTHANDLER_MAX_REDIRECT_RECURSION) { + QVariant redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute); + if (redirect.isValid()) { + QUrl url = reply->url().resolved(redirect.toUrl()); + QNetworkRequest req(url); + req.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true); + + reply->deleteLater(); + reply = networkAccessManager()->get(req); + + QMetaObject::connect(reply, replyDownloadProgress, job, downloadProgress); + QMetaObject::connect(reply, replyFinished, this, thisNetworkRequestDone); + + replies.insert(reply, job); + return; + } + } + redirectCount=0; + if (job) { QImage image; QDeclarativeImageReaderEvent::ReadError error; -- cgit v0.12 From 53079ad30ba53fc7b3f53fd460d48cb5c5dcf0b8 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Wed, 10 Mar 2010 15:04:07 +1000 Subject: Technically, Location can be relative (never is though...) --- src/declarative/qml/qdeclarativexmlhttprequest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarative/qml/qdeclarativexmlhttprequest.cpp b/src/declarative/qml/qdeclarativexmlhttprequest.cpp index 87cab85..58e67fa 100644 --- a/src/declarative/qml/qdeclarativexmlhttprequest.cpp +++ b/src/declarative/qml/qdeclarativexmlhttprequest.cpp @@ -1245,7 +1245,7 @@ void QDeclarativeXMLHttpRequest::finished() if (m_redirectCount < XMLHTTPREQUEST_MAXIMUM_REDIRECT_RECURSION) { QVariant redirect = m_network->attribute(QNetworkRequest::RedirectionTargetAttribute); if (redirect.isValid()) { - QUrl url = redirect.toUrl(); + QUrl url = m_network->url().resolved(redirect.toUrl()); destroyNetwork(); requestFromUrl(url); return; -- cgit v0.12 From 63ac95323b3fb8884f8d7ede0ebf4e360393f658 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Wed, 10 Mar 2010 15:10:10 +1000 Subject: URL redirection for AnimatedImage Task-number: QTBUG-7515 --- .../graphicsitems/qdeclarativeanimatedimage.cpp | 16 ++++++++++++++++ .../graphicsitems/qdeclarativeanimatedimage_p_p.h | 3 ++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp b/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp index 20b1de3..2c2e034 100644 --- a/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp +++ b/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp @@ -247,9 +247,25 @@ void QDeclarativeAnimatedImage::setSource(const QUrl &url) emit statusChanged(d->status); } +#define ANIMATEDIMAGE_MAXIMUM_REDIRECT_RECURSION 16 + void QDeclarativeAnimatedImage::movieRequestFinished() { Q_D(QDeclarativeAnimatedImage); + + d->redirectCount++; + if (d->redirectCount < ANIMATEDIMAGE_MAXIMUM_REDIRECT_RECURSION) { + QVariant redirect = d->reply->attribute(QNetworkRequest::RedirectionTargetAttribute); + if (redirect.isValid()) { + QUrl url = d->reply->url().resolved(redirect.toUrl()); + d->reply->deleteLater(); + d->reply = 0; + setSource(url); + return; + } + } + d->redirectCount=0; + d->_movie = new QMovie(d->reply); if (!d->_movie->isValid()){ qWarning() << "Error Reading Animated Image File " << d->url; diff --git a/src/declarative/graphicsitems/qdeclarativeanimatedimage_p_p.h b/src/declarative/graphicsitems/qdeclarativeanimatedimage_p_p.h index 39bb3e5..273c1d6 100644 --- a/src/declarative/graphicsitems/qdeclarativeanimatedimage_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativeanimatedimage_p_p.h @@ -66,7 +66,7 @@ class QDeclarativeAnimatedImagePrivate : public QDeclarativeImagePrivate public: QDeclarativeAnimatedImagePrivate() - : playing(true), paused(false), preset_currentframe(0), _movie(0), reply(0) + : playing(true), paused(false), preset_currentframe(0), _movie(0), reply(0), redirectCount(0) { } @@ -75,6 +75,7 @@ public: int preset_currentframe; QMovie *_movie; QNetworkReply *reply; + int redirectCount; }; QT_END_NAMESPACE -- cgit v0.12 From df1e179df5a8607bdf97fff901e2156efcc48623 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Wed, 10 Mar 2010 15:14:06 +1000 Subject: URL redirection for font loader Task-number: QTBUG-7515 --- src/declarative/util/qdeclarativefontloader.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/declarative/util/qdeclarativefontloader.cpp b/src/declarative/util/qdeclarativefontloader.cpp index 8f5f537..0509242 100644 --- a/src/declarative/util/qdeclarativefontloader.cpp +++ b/src/declarative/util/qdeclarativefontloader.cpp @@ -61,7 +61,7 @@ class QDeclarativeFontLoaderPrivate : public QObjectPrivate Q_DECLARE_PUBLIC(QDeclarativeFontLoader) public: - QDeclarativeFontLoaderPrivate() : reply(0), status(QDeclarativeFontLoader::Null) {} + QDeclarativeFontLoaderPrivate() : reply(0), status(QDeclarativeFontLoader::Null), redirectCount(0) {} void addFontToDatabase(const QByteArray &); @@ -69,6 +69,7 @@ public: QString name; QNetworkReply *reply; QDeclarativeFontLoader::Status status; + int redirectCount; }; @@ -206,10 +207,25 @@ QDeclarativeFontLoader::Status QDeclarativeFontLoader::status() const return d->status; } +#define FONTLOADER_MAXIMUM_REDIRECT_RECURSION 16 + void QDeclarativeFontLoader::replyFinished() { Q_D(QDeclarativeFontLoader); if (d->reply) { + d->redirectCount++; + if (d->redirectCount < FONTLOADER_MAXIMUM_REDIRECT_RECURSION) { + QVariant redirect = d->reply->attribute(QNetworkRequest::RedirectionTargetAttribute); + if (redirect.isValid()) { + QUrl url = d->reply->url().resolved(redirect.toUrl()); + d->reply->deleteLater(); + d->reply = 0; + setSource(url); + return; + } + } + d->redirectCount=0; + if (!d->reply->error()) { QByteArray ba = d->reply->readAll(); d->addFontToDatabase(ba); -- cgit v0.12 From 6db08d1cfeb70bff5a114579fb2bfbde81310b64 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Wed, 10 Mar 2010 15:26:57 +1000 Subject: Use no-version-specified to mean any version (used to work, fixed again, was only working with -1.-1 which looks silly) --- demos/declarative/flickr/common/qmldir | 20 ++++++++++---------- demos/declarative/samegame/SamegameCore/qmldir | 6 +++--- src/declarative/qml/qdeclarativedirparser.cpp | 5 ++++- .../qtest/declarative/qmllanguage/qmldir | 6 +++--- .../qtest/declarative/qmllanguage/subdir/qmldir | 2 +- 5 files changed, 21 insertions(+), 18 deletions(-) diff --git a/demos/declarative/flickr/common/qmldir b/demos/declarative/flickr/common/qmldir index 0c94f60..adc2479 100644 --- a/demos/declarative/flickr/common/qmldir +++ b/demos/declarative/flickr/common/qmldir @@ -1,10 +1,10 @@ -ImageDetails 0.0 ImageDetails.qml -LikeOMeter 0.0 LikeOMeter.qml -Loading 0.0 Loading.qml -MediaButton 0.0 MediaButton.qml -MediaLineEdit 0.0 MediaLineEdit.qml -Progress 0.0 Progress.qml -RssModel 0.0 RssModel.qml -ScrollBar 0.0 ScrollBar.qml -Slider 0.0 Slider.qml -Star 0.0 Star.qml +ImageDetails ImageDetails.qml +LikeOMeter LikeOMeter.qml +Loading Loading.qml +MediaButton MediaButton.qml +MediaLineEdit MediaLineEdit.qml +Progress Progress.qml +RssModel RssModel.qml +ScrollBar ScrollBar.qml +Slider Slider.qml +Star Star.qml diff --git a/demos/declarative/samegame/SamegameCore/qmldir b/demos/declarative/samegame/SamegameCore/qmldir index a8f8a98..e17b1f5 100644 --- a/demos/declarative/samegame/SamegameCore/qmldir +++ b/demos/declarative/samegame/SamegameCore/qmldir @@ -1,3 +1,3 @@ -BoomBlock 0.0 BoomBlock.qml -Button 0.0 Button.qml -Dialog 0.0 Dialog.qml +BoomBlock BoomBlock.qml +Button Button.qml +Dialog Dialog.qml diff --git a/src/declarative/qml/qdeclarativedirparser.cpp b/src/declarative/qml/qdeclarativedirparser.cpp index e730b92..b6d2115 100644 --- a/src/declarative/qml/qdeclarativedirparser.cpp +++ b/src/declarative/qml/qdeclarativedirparser.cpp @@ -151,13 +151,16 @@ bool QDeclarativeDirParser::parse() _plugins.append(entry); + } else if (sectionCount == 2) { + // No version specified (should only be used for relative qmldir files) + const Component entry(sections[0], sections[1], -1, -1); + _components.append(entry); } else if (sectionCount == 3) { const QString &version = sections[1]; const int dotIndex = version.indexOf(QLatin1Char('.')); if (dotIndex == -1) { qWarning() << "expected '.'"; // ### use reportError - } else if (version.indexOf(QLatin1Char('.'), dotIndex + 1) != -1) { qWarning() << "unexpected '.'"; // ### use reportError diff --git a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/qmldir b/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/qmldir index b32f82b..303c5c8 100644 --- a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/qmldir +++ b/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/qmldir @@ -1,3 +1,3 @@ -Test 0.0 Test.qml -TestSubDir 0.0 TestSubDir.qml -TestLocal 0.0 TestLocal.qml +Test Test.qml +TestSubDir TestSubDir.qml +TestLocal TestLocal.qml diff --git a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/subdir/qmldir b/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/subdir/qmldir index f7016c7..a54f7df 100644 --- a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/subdir/qmldir +++ b/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/subdir/qmldir @@ -1 +1 @@ -SubTest 0.0 SubTest.qml +SubTest SubTest.qml -- cgit v0.12 From 5f10fa564830cbfb79061c6108098c7e133b79aa Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 10 Mar 2010 16:02:56 +1000 Subject: Schedule view relayout after itemsInserted/Removed() So that they handle model changes involving multiple insertion and deletion without entering the event loop. --- .../graphicsitems/qdeclarativeflickable.cpp | 3 + .../graphicsitems/qdeclarativegridview.cpp | 94 ++++++++++++++-------- .../graphicsitems/qdeclarativegridview_p.h | 2 +- .../graphicsitems/qdeclarativelistview.cpp | 81 ++++++++++++------- .../graphicsitems/qdeclarativelistview_p.h | 1 + .../tst_qdeclarativelistview.cpp | 3 + 6 files changed, 121 insertions(+), 63 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp index 67068a0..9ccb3b6 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp @@ -264,6 +264,7 @@ void QDeclarativeFlickablePrivate::fixupY() void QDeclarativeFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent) { + Q_Q(QDeclarativeFlickable); if (data.move.value() > minExtent || maxExtent > minExtent) { timeline.reset(data.move); if (data.move.value() != minExtent) { @@ -273,6 +274,7 @@ void QDeclarativeFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal timeline.move(data.move, minExtent, QEasingCurve(QEasingCurve::OutQuint), 3*fixupDuration/4); } else { data.move.setValue(minExtent); + q->viewportMoved(); } } //emit flickingChanged(); @@ -284,6 +286,7 @@ void QDeclarativeFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal timeline.move(data.move, maxExtent, QEasingCurve(QEasingCurve::OutQuint), 3*fixupDuration/4); } else { data.move.setValue(maxExtent); + q->viewportMoved(); } //emit flickingChanged(); } else { diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index f35b903..af22e08 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -97,7 +97,7 @@ class QDeclarativeGridViewPrivate : public QDeclarativeFlickablePrivate public: QDeclarativeGridViewPrivate() : currentItem(0), flow(QDeclarativeGridView::LeftToRight) - , visiblePos(0), visibleIndex(0) , currentIndex(-1) + , visibleIndex(0) , currentIndex(-1) , cellWidth(100), cellHeight(100), columns(1), requestedIndex(-1) , highlightRangeStart(0), highlightRangeEnd(0), highlightRange(QDeclarativeGridView::NoHighlightRange) , highlightComponent(0), highlight(0), trackedItem(0) @@ -305,7 +305,6 @@ public: QHash unrequestedItems; FxGridItem *currentItem; QDeclarativeGridView::Flow flow; - int visiblePos; int visibleIndex; int currentIndex; int cellWidth; @@ -350,7 +349,6 @@ void QDeclarativeGridViewPrivate::clear() for (int i = 0; i < visibleItems.count(); ++i) releaseItem(visibleItems.at(i)); visibleItems.clear(); - visiblePos = 0; visibleIndex = 0; releaseItem(currentItem); currentItem = 0; @@ -536,7 +534,7 @@ void QDeclarativeGridViewPrivate::scheduleLayout() Q_Q(QDeclarativeGridView); if (!layoutScheduled) { layoutScheduled = true; - QMetaObject::invokeMethod(q, "layout", Qt::QueuedConnection); + QCoreApplication::postEvent(q, new QEvent(QEvent::User), Qt::HighEventPriority); } } @@ -748,10 +746,12 @@ void QDeclarativeGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m if (currentItem && currentItem->rowPos() - position() != highlightRangeStart) { qreal pos = currentItem->rowPos() - highlightRangeStart; timeline.reset(data.move); - if (fixupDuration) + if (fixupDuration) { timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2); - else + } else { data.move.setValue(-pos); + q->viewportMoved(); + } vTime = timeline.time(); } } else if (snapMode != QDeclarativeGridView::NoSnap) { @@ -760,10 +760,12 @@ void QDeclarativeGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m qreal dist = qAbs(data.move.value() - pos); if (dist > 0) { timeline.reset(data.move); - if (fixupDuration) + if (fixupDuration) { timeline.move(data.move, pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2); - else + } else { data.move.setValue(pos); + q->viewportMoved(); + } vTime = timeline.time(); } } else { @@ -1423,6 +1425,17 @@ void QDeclarativeGridView::setSnapMode(SnapMode mode) } } +bool QDeclarativeGridView::event(QEvent *event) +{ + Q_D(QDeclarativeGridView); + if (event->type() == QEvent::User) { + d->layout(); + return true; + } + + return QDeclarativeFlickable::event(event); +} + void QDeclarativeGridView::viewportMoved() { Q_D(QDeclarativeGridView); @@ -1765,7 +1778,7 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count) { Q_D(QDeclarativeGridView); if (!d->visibleItems.count() || d->model->count() <= 1) { - refill(); + d->scheduleLayout(); d->updateCurrent(qMax(0, qMin(d->currentIndex, d->model->count()-1))); emit countChanged(); return; @@ -1795,7 +1808,7 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count) if (d->currentItem) d->currentItem->index = d->currentIndex; } - d->layout(); + d->scheduleLayout(); emit countChanged(); return; } @@ -1825,9 +1838,21 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count) } } + // Update the indexes of the following visible items. + for (int i = 0; i < d->visibleItems.count(); ++i) { + FxGridItem *listItem = d->visibleItems.at(i); + if (listItem->index != -1 && listItem->index >= modelIndex) + listItem->index += count; + } + + bool addedVisible = false; QList added; int i = 0; while (i < insertCount && rowPos <= to + d->rowSize()*(d->columns - (colPos/d->colSize()))/qreal(d->columns)) { + if (!addedVisible) { + d->scheduleLayout(); + addedVisible = true; + } FxGridItem *item = d->createItem(modelIndex + i); d->visibleItems.insert(index, item); item->setPosition(colPos, rowPos); @@ -1848,6 +1873,15 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count) } } + // update visibleIndex + d->visibleIndex = 0; + for (QList::Iterator it = d->visibleItems.begin(); it != d->visibleItems.end(); ++it) { + if ((*it)->index != -1) { + d->visibleIndex = (*it)->index; + break; + } + } + if (d->currentIndex >= modelIndex) { // adjust current item index d->currentIndex += count; @@ -1856,17 +1890,11 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count) d->currentItem->setPosition(d->colPosAt(d->currentIndex), d->rowPosAt(d->currentIndex)); } } - // Update the indexes of the following visible items. - for (; index < d->visibleItems.count(); ++index) { - FxGridItem *listItem = d->visibleItems.at(index); - if (listItem->index != -1) - listItem->index += count; - } // everything is in order now - emit add() signal for (int j = 0; j < added.count(); ++j) added.at(j)->attached->emitAdd(); - d->layout(); + emit countChanged(); } @@ -1882,8 +1910,10 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count) FxGridItem *item = *it; if (item->index == -1 || item->index < modelIndex) { // already removed, or before removed items - if (item->index < modelIndex) + if (item->index < modelIndex && !removedVisible) { + d->scheduleLayout(); removedVisible = true; + } ++it; } else if (item->index >= modelIndex + count) { // after removed items @@ -1891,7 +1921,10 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count) ++it; } else { // removed item - removedVisible = true; + if (!removedVisible) { + d->scheduleLayout(); + removedVisible = true; + } item->attached->emitRemove(); if (item->attached->delayRemove()) { item->index = -1; @@ -1909,6 +1942,7 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count) d->currentIndex -= count; if (d->currentItem) d->currentItem->index -= count; + emit currentIndexChanged(); } else if (currentRemoved) { // current item has been removed. d->releaseItem(d->currentItem); @@ -1918,6 +1952,7 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count) } // update visibleIndex + d->visibleIndex = 0; for (it = d->visibleItems.begin(); it != d->visibleItems.end(); ++it) { if ((*it)->index != -1) { d->visibleIndex = (*it)->index; @@ -1925,27 +1960,16 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count) } } - if (removedVisible) { - if (d->visibleItems.isEmpty()) { - d->visibleIndex = 0; - d->setPosition(0); - refill(); - } else { - // Correct the positioning of the items - d->scheduleLayout(); - } + if (removedVisible && d->visibleItems.isEmpty()) { + d->timeline.clear(); + d->setPosition(0); + if (d->model->count() == 0) + update(); } emit countChanged(); } -void QDeclarativeGridView::layout() -{ - Q_D(QDeclarativeGridView); - if (d->layoutScheduled) - d->layout(); -} - void QDeclarativeGridView::destroyRemoved() { Q_D(QDeclarativeGridView); diff --git a/src/declarative/graphicsitems/qdeclarativegridview_p.h b/src/declarative/graphicsitems/qdeclarativegridview_p.h index 183bb05..8e253e5 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview_p.h +++ b/src/declarative/graphicsitems/qdeclarativegridview_p.h @@ -164,6 +164,7 @@ Q_SIGNALS: void snapModeChanged(); protected: + virtual bool event(QEvent *event); virtual void viewportMoved(); virtual qreal minYExtent() const; virtual qreal maxYExtent() const; @@ -181,7 +182,6 @@ private Q_SLOTS: void destroyRemoved(); void createdItem(int index, QDeclarativeItem *item); void destroyingItem(QDeclarativeItem *item); - void layout(); private: void refill(); diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 6385ddd..007b31b 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -158,7 +158,7 @@ public: , bufferMode(NoBuffer) , ownModel(false), wrap(false), autoHighlight(true), haveHighlightRange(false) , correctFlick(true), inFlickCorrection(false), lazyRelease(false) - , deferredRelease(false), minExtentDirty(true), maxExtentDirty(true) + , deferredRelease(false), layoutScheduled(false), minExtentDirty(true), maxExtentDirty(true) {} void init(); @@ -414,6 +414,7 @@ public: } void refill(qreal from, qreal to, bool doBuffer = false); + void scheduleLayout(); void layout(); void updateUnrequestedIndexes(); void updateUnrequestedPositions(); @@ -480,6 +481,7 @@ public: bool inFlickCorrection : 1; bool lazyRelease : 1; bool deferredRelease : 1; + bool layoutScheduled : 1; mutable bool minExtentDirty : 1; mutable bool maxExtentDirty : 1; }; @@ -680,9 +682,19 @@ void QDeclarativeListViewPrivate::refill(qreal from, qreal to, bool doBuffer) lazyRelease = false; } +void QDeclarativeListViewPrivate::scheduleLayout() +{ + Q_Q(QDeclarativeListView); + if (!layoutScheduled) { + layoutScheduled = true; + QCoreApplication::postEvent(q, new QEvent(QEvent::User), Qt::HighEventPriority); + } +} + void QDeclarativeListViewPrivate::layout() { Q_Q(QDeclarativeListView); + layoutScheduled = false; updateSections(); if (!visibleItems.isEmpty()) { int oldEnd = visibleItems.last()->endPosition(); @@ -1082,10 +1094,12 @@ void QDeclarativeListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m if (currentItem && currentItem->position() - position() != highlightRangeStart) { qreal pos = currentItem->position() - highlightRangeStart; timeline.reset(data.move); - if (fixupDuration) + if (fixupDuration) { timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2); - else + } else { data.move.setValue(-pos); + q->viewportMoved(); + } vTime = timeline.time(); } } else if (snapMode != QDeclarativeListView::NoSnap) { @@ -1094,10 +1108,12 @@ void QDeclarativeListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m qreal dist = qAbs(data.move + pos); if (dist > 0) { timeline.reset(data.move); - if (fixupDuration) + if (fixupDuration) { timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2); - else + } else { data.move.setValue(-pos); + q->viewportMoved(); + } vTime = timeline.time(); } } @@ -1167,7 +1183,6 @@ 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); @@ -1946,6 +1961,17 @@ void QDeclarativeListView::setHeader(QDeclarativeComponent *header) } } +bool QDeclarativeListView::event(QEvent *event) +{ + Q_D(QDeclarativeListView); + if (event->type() == QEvent::User) { + d->layout(); + return true; + } + + return QDeclarativeFlickable::event(event); +} + void QDeclarativeListView::viewportMoved() { Q_D(QDeclarativeListView); @@ -2276,7 +2302,7 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count) d->updateUnrequestedIndexes(); d->moveReason = QDeclarativeListViewPrivate::Other; if (!d->visibleItems.count() || d->model->count() <= 1) { - d->layout(); + d->scheduleLayout(); d->updateCurrent(qMax(0, qMin(d->currentIndex, d->model->count()-1))); emit countChanged(); return; @@ -2307,7 +2333,7 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count) if (d->currentItem) d->currentItem->index = d->currentIndex; } - d->layout(); + d->scheduleLayout(); emit countChanged(); return; } @@ -2330,7 +2356,10 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count) int i = 0; int from = d->position() - d->buffer; for (i = count-1; i >= 0 && pos > from; --i) { - addedVisible = true; + if (!addedVisible) { + d->scheduleLayout(); + addedVisible = true; + } FxListItem *item = d->createItem(modelIndex + i); d->visibleItems.insert(insertionIdx, item); pos -= item->size() + d->spacing; @@ -2357,7 +2386,10 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count) int i = 0; int to = d->buffer+d->position()+d->size()-1; for (i = 0; i < count && pos <= to; ++i) { - addedVisible = true; + if (!addedVisible) { + d->scheduleLayout(); + addedVisible = true; + } FxListItem *item = d->createItem(modelIndex + i); d->visibleItems.insert(index, item); item->setPosition(pos); @@ -2393,8 +2425,6 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count) for (int j = 0; j < added.count(); ++j) added.at(j)->attached->emitAdd(); - if (addedVisible) - d->layout(); emit countChanged(); } @@ -2420,7 +2450,10 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count) ++it; } else { // removed item - removedVisible = true; + if (!removedVisible) { + d->scheduleLayout(); + removedVisible = true; + } item->attached->emitRemove(); if (item->attached->delayRemove()) { item->index = -1; @@ -2445,6 +2478,7 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count) d->currentIndex -= count; if (d->currentItem) d->currentItem->index -= count; + emit currentIndexChanged(); } else if (d->currentIndex >= modelIndex && d->currentIndex < modelIndex + count) { // current item has been removed. d->currentItem->attached->setIsCurrentItem(false); @@ -2462,20 +2496,13 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count) } } - if (removedVisible) { - if (d->visibleItems.isEmpty()) { - d->visibleIndex = 0; - d->visiblePos = d->header ? d->header->size() : 0; - d->timeline.clear(); - d->setPosition(0); - if (d->model->count() == 0) - update(); - else - refill(); - } else { - // Correct the positioning of the items - d->layout(); - } + if (removedVisible && d->visibleItems.isEmpty()) { + d->visibleIndex = 0; + d->visiblePos = d->header ? d->header->size() : 0; + d->timeline.clear(); + d->setPosition(0); + if (d->model->count() == 0) + update(); } emit countChanged(); diff --git a/src/declarative/graphicsitems/qdeclarativelistview_p.h b/src/declarative/graphicsitems/qdeclarativelistview_p.h index d66ac2b..1bf9652 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview_p.h +++ b/src/declarative/graphicsitems/qdeclarativelistview_p.h @@ -219,6 +219,7 @@ Q_SIGNALS: void footerChanged(); protected: + virtual bool event(QEvent *event); virtual void viewportMoved(); virtual qreal minYExtent() const; virtual qreal maxYExtent() const; diff --git a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp index 75fbbf8..17257ae 100644 --- a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp +++ b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp @@ -925,6 +925,7 @@ void tst_QDeclarativeListView::sections() // Remove section boundary model.removeItem(5); + QTest::qWait(100); // New section header created QDeclarativeItem *item = findItem(viewport, "wrapper", 5); @@ -932,6 +933,7 @@ void tst_QDeclarativeListView::sections() QCOMPARE(item->height(), 40.0); model.insertItem(3, "New Item", "0"); + QTest::qWait(100); // Section header moved item = findItem(viewport, "wrapper", 5); @@ -944,6 +946,7 @@ void tst_QDeclarativeListView::sections() // insert item which will become a section header model.insertItem(6, "Replace header", "1"); + QTest::qWait(100); item = findItem(viewport, "wrapper", 6); QVERIFY(item); -- cgit v0.12 From 46dfe1e6dad1f3a74cb15bfd538e9fe28ffac5b3 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 10 Mar 2010 15:56:38 +1000 Subject: Unify binding optimizer and QtScript binding signal management logic --- .../qml/qdeclarativecompiledbindings.cpp | 97 +------- src/declarative/qml/qdeclarativecontext.cpp | 7 +- src/declarative/qml/qdeclarativecontext_p.h | 5 +- src/declarative/qml/qdeclarativeexpression.cpp | 153 ++++-------- src/declarative/qml/qdeclarativeexpression_p.h | 19 +- src/declarative/qml/qdeclarativenotifier.cpp | 109 +++++++++ src/declarative/qml/qdeclarativenotifier_p.h | 272 +++++++++++++++++++++ src/declarative/qml/qdeclarativepropertycache.cpp | 4 + src/declarative/qml/qdeclarativepropertycache_p.h | 19 +- src/declarative/qml/qml.pri | 2 + .../tst_qdeclarativeanchors.cpp | 1 - 11 files changed, 458 insertions(+), 230 deletions(-) create mode 100644 src/declarative/qml/qdeclarativenotifier.cpp create mode 100644 src/declarative/qml/qdeclarativenotifier_p.h diff --git a/src/declarative/qml/qdeclarativecompiledbindings.cpp b/src/declarative/qml/qdeclarativecompiledbindings.cpp index 17937fd..b35b5b5 100644 --- a/src/declarative/qml/qdeclarativecompiledbindings.cpp +++ b/src/declarative/qml/qdeclarativecompiledbindings.cpp @@ -124,24 +124,7 @@ public: QDeclarativeCompiledBindingsPrivate *parent; }; - struct Subscription { - struct Signal { - QDeclarativeGuard source; - int notifyIndex; - }; - - enum { InvalidType, SignalType, IdType } type; - inline Subscription(); - inline ~Subscription(); - bool isSignal() const { return type == SignalType; } - bool isId() const { return type == IdType; } - inline Signal *signal(); - inline QDeclarativeContextPrivate::IdNotifier *id(); - union { - char signalData[sizeof(Signal)]; - char idData[sizeof(QDeclarativeContextPrivate::IdNotifier)]; - }; - }; + typedef QDeclarativeNotifierEndpoint Subscription; Subscription *subscriptions; QScriptDeclarativeClass::PersistentIdentifier *identifiers; @@ -190,18 +173,6 @@ QDeclarativeCompiledBindingsPrivate::~QDeclarativeCompiledBindingsPrivate() delete [] identifiers; identifiers = 0; } -QDeclarativeCompiledBindingsPrivate::Subscription::Subscription() -: type(InvalidType) -{ -} - -QDeclarativeCompiledBindingsPrivate::Subscription::~Subscription() -{ - if (type == SignalType) ((Signal *)signalData)->~Signal(); - else if (type == IdType) ((QDeclarativeContextPrivate::IdNotifier *)idData)->~IdNotifier(); -} - - int QDeclarativeCompiledBindingsPrivate::methodCount = -1; QDeclarativeCompiledBindings::QDeclarativeCompiledBindings(const char *program, QDeclarativeContext *context) @@ -330,22 +301,6 @@ void QDeclarativeCompiledBindingsPrivate::run(Binding *binding) } } -QDeclarativeCompiledBindingsPrivate::Subscription::Signal *QDeclarativeCompiledBindingsPrivate::Subscription::signal() -{ - if (type == IdType) ((QDeclarativeContextPrivate::IdNotifier *)idData)->~IdNotifier(); - if (type != SignalType) new (signalData) Signal; - type = SignalType; - return (Signal *)signalData; -} - -QDeclarativeContextPrivate::IdNotifier *QDeclarativeCompiledBindingsPrivate::Subscription::id() -{ - if (type == SignalType) ((Signal *)signalData)->~Signal(); - if (type != IdType) new (idData) QDeclarativeContextPrivate::IdNotifier; - type = IdType; - return (QDeclarativeContextPrivate::IdNotifier *)idData; -} - namespace { // This structure is exactly 8-bytes in size struct Instr { @@ -656,20 +611,7 @@ void QDeclarativeCompiledBindingsPrivate::unsubscribe(int subIndex) Q_Q(QDeclarativeCompiledBindings); QDeclarativeCompiledBindingsPrivate::Subscription *sub = (subscriptions + subIndex); - if (sub->isSignal()) { - QDeclarativeCompiledBindingsPrivate::Subscription::Signal *s = sub->signal(); - if (s->source) -#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 2)) - QMetaObject::disconnectOne(s->source, s->notifyIndex, - q, methodCount + subIndex); -#else - // QTBUG-6781 - QMetaObject::disconnect(s->source, s->notifyIndex, - q, methodCount + subIndex); -#endif - } else if (sub->isId()) { - sub->id()->clear(); - } + sub->disconnect(); } void QDeclarativeCompiledBindingsPrivate::subscribeId(QDeclarativeContextPrivate *p, int idIndex, int subIndex) @@ -680,15 +622,8 @@ void QDeclarativeCompiledBindingsPrivate::subscribeId(QDeclarativeContextPrivate if (p->idValues[idIndex]) { QDeclarativeCompiledBindingsPrivate::Subscription *sub = (subscriptions + subIndex); - QDeclarativeContextPrivate::IdNotifier *i = sub->id(); - - i->next = p->idValues[idIndex].bindings; - i->prev = &p->idValues[idIndex].bindings; - p->idValues[idIndex].bindings = i; - if (i->next) i->next->prev = &i->next; - - i->target = q; - i->methodIndex = methodCount + subIndex; + sub->target = q; + sub->targetMethod = methodCount + subIndex; } } @@ -697,27 +632,9 @@ void QDeclarativeCompiledBindingsPrivate::subscribe(QObject *o, int notifyIndex, Q_Q(QDeclarativeCompiledBindings); QDeclarativeCompiledBindingsPrivate::Subscription *sub = (subscriptions + subIndex); - - if (sub->isId()) - unsubscribe(subIndex); - - QDeclarativeCompiledBindingsPrivate::Subscription::Signal *s = sub->signal(); - if (o != s->source || notifyIndex != s->notifyIndex) { - if (s->source) -#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 2)) - QMetaObject::disconnectOne(s->source, s->notifyIndex, - q, methodCount + subIndex); -#else - // QTBUG-6781 - QMetaObject::disconnect(s->source, s->notifyIndex, - q, methodCount + subIndex); -#endif - s->source = o; - s->notifyIndex = notifyIndex; - if (s->source && s->notifyIndex != -1) - QMetaObject::connect(s->source, s->notifyIndex, q, - methodCount + subIndex, Qt::DirectConnection); - } + sub->target = q; + sub->targetMethod = methodCount + subIndex; + sub->connect(o, notifyIndex); } // Conversion functions - these MUST match the QtScript expression path diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp index f70e143..356a4ab 100644 --- a/src/declarative/qml/qdeclarativecontext.cpp +++ b/src/declarative/qml/qdeclarativecontext.cpp @@ -109,12 +109,7 @@ void QDeclarativeContextPrivate::destroyed(ContextGuard *guard) if (parent && QObjectPrivate::get(parent)->wasDeleted) return; - while(guard->bindings) { - QObject *o = guard->bindings->target; - int mi = guard->bindings->methodIndex; - guard->bindings->clear(); - if (o) o->qt_metacall(QMetaObject::InvokeMetaMethod, mi, 0); - } + guard->bindings.notify(); for (int ii = 0; ii < idValueCount; ++ii) { if (&idValues[ii] == guard) { diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h index 8297280..5b597fa 100644 --- a/src/declarative/qml/qdeclarativecontext_p.h +++ b/src/declarative/qml/qdeclarativecontext_p.h @@ -59,6 +59,7 @@ #include "qdeclarativeengine_p.h" #include "qdeclarativeintegercache_p.h" #include "qdeclarativetypenamecache_p.h" +#include "qdeclarativenotifier_p.h" #include #include @@ -133,7 +134,7 @@ public: inline virtual void objectDestroyed(QObject *); QDeclarativeContextPrivate *priv; - IdNotifier *bindings; + QDeclarativeNotifier bindings; }; ContextGuard *idValues; int idValueCount; @@ -176,7 +177,7 @@ void QDeclarativeContextPrivate::IdNotifier::clear() } QDeclarativeContextPrivate::ContextGuard::ContextGuard() -: priv(0), bindings(0) +: priv(0) { } diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp index e528e9e..207ded6 100644 --- a/src/declarative/qml/qdeclarativeexpression.cpp +++ b/src/declarative/qml/qdeclarativeexpression.cpp @@ -621,137 +621,74 @@ void QDeclarativeExpression::__q_notify() void QDeclarativeExpressionPrivate::clearGuards() { - Q_Q(QDeclarativeExpression); - - static int notifyIdx = -1; - if (notifyIdx == -1) - notifyIdx = - QDeclarativeExpression::staticMetaObject.indexOfMethod("__q_notify()"); - - for (int ii = 0; ii < data->guardListLength; ++ii) { - if (data->guardList[ii].data()) { -#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 2)) - QMetaObject::disconnectOne(data->guardList[ii].data(), - data->guardList[ii].notifyIndex, - q, notifyIdx); -#else - // QTBUG-6781 - QMetaObject::disconnect(data->guardList[ii].data(), - data->guardList[ii].notifyIndex, - q, notifyIdx); -#endif - } - } - - delete [] data->guardList; data->guardList = 0; + delete [] data->guardList; + data->guardList = 0; data->guardListLength = 0; } void QDeclarativeExpressionPrivate::updateGuards(const QPODVector &properties) { - //clearGuards(); Q_Q(QDeclarativeExpression); static int notifyIdx = -1; if (notifyIdx == -1) - notifyIdx = - QDeclarativeExpression::staticMetaObject.indexOfMethod("__q_notify()"); + notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("__q_notify()"); - QDeclarativeExpressionData::SignalGuard *newGuardList = 0; - - if (properties.count() != data->guardListLength) - newGuardList = new QDeclarativeExpressionData::SignalGuard[properties.count()]; + if (properties.count() != data->guardListLength) { + QDeclarativeNotifierEndpoint *newGuardList = + new QDeclarativeNotifierEndpoint[properties.count()]; + + for (int ii = 0; ii < qMin(data->guardListLength, properties.count()); ++ii) + data->guardList[ii].copyAndClear(newGuardList[ii]); + + delete [] data->guardList; + data->guardList = newGuardList; + data->guardListLength = properties.count(); + } bool outputWarningHeader = false; - int hit = 0; + bool noChanges = true; for (int ii = 0; ii < properties.count(); ++ii) { + QDeclarativeNotifierEndpoint &guard = data->guardList[ii]; const QDeclarativeEnginePrivate::CapturedProperty &property = properties.at(ii); - bool needGuard = true; - if (ii >= data->guardListLength) { - // New guard - } else if(data->guardList[ii].data() == property.object && - data->guardList[ii].notifyIndex == property.notifyIndex) { - // Cache hit - if (!data->guardList[ii].isDuplicate || - (data->guardList[ii].isDuplicate && hit == ii)) { - needGuard = false; - ++hit; - } - } else if(data->guardList[ii].data() && !data->guardList[ii].isDuplicate) { - // Cache miss -#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 2)) - QMetaObject::disconnectOne(data->guardList[ii].data(), - data->guardList[ii].notifyIndex, - q, notifyIdx); -#else - // QTBUG-6781 - QMetaObject::disconnect(data->guardList[ii].data(), - data->guardList[ii].notifyIndex, - q, notifyIdx); -#endif - } - /* else { - // Cache miss, but nothing to do - } */ - - if (needGuard) { - if (!newGuardList) { - newGuardList = new QDeclarativeExpressionData::SignalGuard[properties.count()]; - for (int jj = 0; jj < ii; ++jj) - newGuardList[jj] = data->guardList[jj]; - } + guard.target = q; + guard.targetMethod = notifyIdx; + + if (property.notifyIndex != -1) { + + if (!noChanges && guard.isConnected(property.object, property.notifyIndex)) { + // Nothing to do + + } else { + noChanges = false; - if (property.notifyIndex != -1) { bool existing = false; for (int jj = 0; !existing && jj < ii; ++jj) - existing = newGuardList[jj].data() == property.object && - newGuardList[jj].notifyIndex == property.notifyIndex; - - newGuardList[ii] = property.object; - newGuardList[ii].notifyIndex = property.notifyIndex; - if (existing) - newGuardList[ii].isDuplicate = true; - else - QMetaObject::connect(property.object, property.notifyIndex, - q, notifyIdx); - } else { - if (!outputWarningHeader) { - outputWarningHeader = true; - qWarning() << "QDeclarativeExpression: Expression" << q->expression() - << "depends on non-NOTIFYable properties:"; + if (data->guardList[jj].isConnected(property.object, property.notifyIndex)) + existing = true; + + if (existing) { + // duplicate + guard.disconnect(); + } else { + guard.connect(property.object, property.notifyIndex); } + } - const QMetaObject *metaObj = property.object->metaObject(); - QMetaProperty metaProp = metaObj->property(property.coreIndex); - - qWarning().nospace() << " " << metaObj->className() - << "::" << metaProp.name(); + } else { + if (!outputWarningHeader) { + outputWarningHeader = true; + qWarning() << "QDeclarativeExpression: Expression" << q->expression() + << "depends on non-NOTIFYable properties:"; } - } else if (newGuardList) { - newGuardList[ii] = data->guardList[ii]; - } - } - for (int ii = properties.count(); ii < data->guardListLength; ++ii) { - if (data->guardList[ii].data() && !data->guardList[ii].isDuplicate) { -#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 2)) - QMetaObject::disconnectOne(data->guardList[ii].data(), - data->guardList[ii].notifyIndex, - q, notifyIdx); -#else - // QTBUG-6781 - QMetaObject::disconnect(data->guardList[ii].data(), - data->guardList[ii].notifyIndex, - q, notifyIdx); -#endif - } - } + const QMetaObject *metaObj = property.object->metaObject(); + QMetaProperty metaProp = metaObj->property(property.coreIndex); - if (newGuardList) { - if (data->guardList) delete [] data->guardList; - data->guardList = newGuardList; - data->guardListLength = properties.count(); + qWarning().nospace() << " " << metaObj->className() + << "::" << metaProp.name(); + } } } diff --git a/src/declarative/qml/qdeclarativeexpression_p.h b/src/declarative/qml/qdeclarativeexpression_p.h index cd1729d..d170559 100644 --- a/src/declarative/qml/qdeclarativeexpression_p.h +++ b/src/declarative/qml/qdeclarativeexpression_p.h @@ -129,24 +129,7 @@ public: QString url; // This is a QString for a reason. QUrls are slooooooow... int line; - struct SignalGuard : public QDeclarativeGuard { - SignalGuard() : isDuplicate(false), notifyIndex(-1) {} - - SignalGuard &operator=(QObject *obj) { - QDeclarativeGuard::operator=(obj); - return *this; - } - SignalGuard &operator=(const SignalGuard &o) { - QDeclarativeGuard::operator=(o); - isDuplicate = o.isDuplicate; - notifyIndex = o.notifyIndex; - return *this; - } - - bool isDuplicate:1; - int notifyIndex:31; - }; - SignalGuard *guardList; + QDeclarativeNotifierEndpoint *guardList; int guardListLength; }; diff --git a/src/declarative/qml/qdeclarativenotifier.cpp b/src/declarative/qml/qdeclarativenotifier.cpp new file mode 100644 index 0000000..0a8783a --- /dev/null +++ b/src/declarative/qml/qdeclarativenotifier.cpp @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdeclarativenotifier_p.h" + +QT_BEGIN_NAMESPACE + +void QDeclarativeNotifier::emitNotify(QDeclarativeNotifierEndpoint *endpoint) +{ + QDeclarativeNotifierEndpoint::Notifier *n = endpoint->asNotifier(); + + QDeclarativeNotifierEndpoint::Notifier **oldDisconnected = n->disconnected; + n->disconnected = &n; + + if (n->next) + emitNotify(n->next); + + if (n) { + void *args[] = { 0 }; + + QMetaObject::metacall(endpoint->target, QMetaObject::InvokeMetaMethod, + endpoint->targetMethod, args); + + n->disconnected = oldDisconnected; + } + + if (oldDisconnected) *oldDisconnected = n; +} + +void QDeclarativeNotifierEndpoint::copyAndClear(QDeclarativeNotifierEndpoint &other) +{ + other.disconnect(); + + other.target = target; + other.targetMethod = targetMethod; + + if (!isConnected()) + return; + + if (SignalType == type) { + Signal *other_s = other.toSignal(); + Signal *s = asSignal(); + + other_s->source = s->source; + other_s->sourceSignal = s->sourceSignal; + s->source = 0; + } else if(NotifierType == type) { + Notifier *other_n = other.toNotifier(); + Notifier *n = asNotifier(); + + other_n->notifier = n->notifier; + other_n->disconnected = n->disconnected; + if (other_n->disconnected) *other_n->disconnected = other_n; + + if (n->next) { + other_n->next = n->next; + n->next->asNotifier()->prev = &other_n->next; + } + other_n->prev = n->prev; + *other_n->prev = &other; + + n->prev = 0; + n->next = 0; + n->disconnected = 0; + n->notifier = 0; + } +} + + +QT_END_NAMESPACE + diff --git a/src/declarative/qml/qdeclarativenotifier_p.h b/src/declarative/qml/qdeclarativenotifier_p.h new file mode 100644 index 0000000..a0e6b43 --- /dev/null +++ b/src/declarative/qml/qdeclarativenotifier_p.h @@ -0,0 +1,272 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDECLARATIVENOTIFIER_P_H +#define QDECLARATIVENOTIFIER_P_H + +#include "qdeclarativeguard_p.h" + +QT_BEGIN_NAMESPACE + +class QDeclarativeNotifierEndpoint; +class QDeclarativeNotifier +{ +public: + inline QDeclarativeNotifier(); + inline ~QDeclarativeNotifier(); + inline void notify(); + +private: + friend class QDeclarativeNotifierEndpoint; + + static void emitNotify(QDeclarativeNotifierEndpoint *); + QDeclarativeNotifierEndpoint *endpoints; +}; + +class QDeclarativeNotifierEndpoint +{ +public: + inline QDeclarativeNotifierEndpoint(); + inline QDeclarativeNotifierEndpoint(QObject *t, int m); + inline ~QDeclarativeNotifierEndpoint(); + + QObject *target; + int targetMethod; + + inline bool isConnected(); + inline bool isConnected(QObject *source, int sourceSignal); + inline bool isConnected(QDeclarativeNotifier *); + + inline void connect(QObject *source, int sourceSignal); + inline void connect(QDeclarativeNotifier *); + inline void disconnect(); + + void copyAndClear(QDeclarativeNotifierEndpoint &other); + +private: + friend class QDeclarativeNotifier; + + struct Signal { + QDeclarativeGuard source; + int sourceSignal; + }; + + struct Notifier { + QDeclarativeNotifier *notifier; + Notifier **disconnected; + + QDeclarativeNotifierEndpoint *next; + QDeclarativeNotifierEndpoint **prev; + }; + + enum { InvalidType, SignalType, NotifierType } type; + union { + char signalData[sizeof(Signal)]; + char notifierData[sizeof(Notifier)]; + }; + + inline Notifier *toNotifier(); + inline Notifier *asNotifier(); + inline Signal *toSignal(); + inline Signal *asSignal(); +}; + +QDeclarativeNotifier::QDeclarativeNotifier() +: endpoints(0) +{ + QDeclarativeNotifierEndpoint *endpoint = endpoints; + while (endpoint) { + QDeclarativeNotifierEndpoint *next = endpoint->asNotifier()->next; + endpoint->asNotifier()->next = 0; + endpoint->asNotifier()->prev = 0; + endpoint->asNotifier()->notifier = 0; + endpoint = next; + } +} + +QDeclarativeNotifier::~QDeclarativeNotifier() +{ +} + +void QDeclarativeNotifier::notify() +{ + if (endpoints) emitNotify(endpoints); +} + +QDeclarativeNotifierEndpoint::QDeclarativeNotifierEndpoint() +: target(0), targetMethod(0), type(InvalidType) +{ +} + +QDeclarativeNotifierEndpoint::QDeclarativeNotifierEndpoint(QObject *t, int m) +: target(t), targetMethod(m), type(InvalidType) +{ +} + +QDeclarativeNotifierEndpoint::~QDeclarativeNotifierEndpoint() +{ + disconnect(); + if (SignalType == type) { + Signal *s = asSignal(); + s->~Signal(); + } +} + +bool QDeclarativeNotifierEndpoint::isConnected() +{ + if (SignalType == type) { + return asSignal()->source; + } else if (NotifierType == type) { + return asNotifier()->notifier; + } else { + return false; + } +} + +bool QDeclarativeNotifierEndpoint::isConnected(QObject *source, int sourceSignal) +{ + return SignalType == type && asSignal()->source == source && asSignal()->sourceSignal == sourceSignal; +} + +bool QDeclarativeNotifierEndpoint::isConnected(QDeclarativeNotifier *notifier) +{ + return NotifierType == type && asNotifier()->notifier == notifier; +} + +void QDeclarativeNotifierEndpoint::connect(QObject *source, int sourceSignal) +{ + Signal *s = toSignal(); + + if (s->source == source && s->sourceSignal == sourceSignal) + return; + + disconnect(); + + QMetaObject::connect(source, sourceSignal, target, targetMethod); + + s->source = source; + s->sourceSignal = sourceSignal; +} + +void QDeclarativeNotifierEndpoint::connect(QDeclarativeNotifier *notifier) +{ + Notifier *n = toNotifier(); + + if (n->notifier == notifier) + return; + + disconnect(); + + n->next = notifier->endpoints; + if (n->next) { n->next->asNotifier()->prev = &n->next; } + notifier->endpoints = this; + n->prev = ¬ifier->endpoints; + n->notifier = notifier; +} + +void QDeclarativeNotifierEndpoint::disconnect() +{ + if (type == SignalType) { + Signal *s = (Signal *)&signalData; + if (s->source) { + QMetaObject::disconnectOne(s->source, s->sourceSignal, target, targetMethod); + s->source = 0; + } + } else if (type == NotifierType) { + Notifier *n = asNotifier(); + + if (n->next) n->next->asNotifier()->prev = n->prev; + if (n->prev) *n->prev = n->next; + if (n->disconnected) *n->disconnected = 0; + n->next = 0; + n->prev = 0; + n->disconnected = 0; + n->notifier = 0; + } +} + +QDeclarativeNotifierEndpoint::Notifier *QDeclarativeNotifierEndpoint::toNotifier() +{ + if (NotifierType == type) + return asNotifier(); + + if (SignalType == type) { + disconnect(); + Signal *s = asSignal(); + s->~Signal(); + } + + Notifier *n = asNotifier(); + n->next = 0; + n->prev = 0; + n->disconnected = 0; + n->notifier = 0; + type = NotifierType; + return n; +} + +QDeclarativeNotifierEndpoint::Notifier *QDeclarativeNotifierEndpoint::asNotifier() +{ + return (Notifier *)(¬ifierData); +} + +QDeclarativeNotifierEndpoint::Signal *QDeclarativeNotifierEndpoint::toSignal() +{ + if (SignalType == type) + return asSignal(); + + disconnect(); + Signal *s = asSignal(); + new (s) Signal; + type = SignalType; + + return s; +} + +QDeclarativeNotifierEndpoint::Signal *QDeclarativeNotifierEndpoint::asSignal() +{ + return (Signal *)(&signalData); +} + +QT_END_NAMESPACE + +#endif // QDECLARATIVENOTIFIER_P_H + diff --git a/src/declarative/qml/qdeclarativepropertycache.cpp b/src/declarative/qml/qdeclarativepropertycache.cpp index fea59e5..cbb67e1 100644 --- a/src/declarative/qml/qdeclarativepropertycache.cpp +++ b/src/declarative/qml/qdeclarativepropertycache.cpp @@ -420,4 +420,8 @@ QDeclarativePropertyCache::Data *QDeclarativePropertyCache::property(QDeclarativ return rv; } +QDeclarativePropertyCache::Data QDeclarativePropertyCache::property(const QMetaObject *, const char *) +{ +} + QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativepropertycache_p.h b/src/declarative/qml/qdeclarativepropertycache_p.h index 68e6e6b..ea2f01a 100644 --- a/src/declarative/qml/qdeclarativepropertycache_p.h +++ b/src/declarative/qml/qdeclarativepropertycache_p.h @@ -55,15 +55,16 @@ #include "qdeclarativerefcount_p.h" #include "qdeclarativecleanup_p.h" +#include "qdeclarativenotifier_p.h" #include #include - QT_BEGIN_NAMESPACE class QDeclarativeEngine; class QMetaProperty; + class QDeclarativePropertyCache : public QDeclarativeRefCount, public QDeclarativeCleanup { public: @@ -81,11 +82,12 @@ public: IsConstant = 0x00000001, IsWritable = 0x00000002, IsResettable = 0x00000004, + HasNotify = 0x00000008, // These are mutualy exclusive - IsFunction = 0x00000008, - IsQObjectDerived = 0x00000010, - IsEnumType = 0x00000020, + IsFunction = 0x00000010, + IsQObjectDerived = 0x00000020, + IsEnumType = 0x00000040, IsQList = 0x00000080, IsQmlBinding = 0x00000100, IsQScriptValue = 0x00000200, @@ -97,11 +99,17 @@ public: }; Q_DECLARE_FLAGS(Flags, Flag) + enum Call { ReadProperty, WriteProperty, ConnectNotify, DisconnectNotify }; + typedef void (*MetaCall)(QObject *, Call, void *); + bool isValid() const { return coreIndex != -1; } Flags flags; int propType; - int coreIndex; + union { + MetaCall call; + int coreIndex; + }; int notifyIndex; static Flags flagsForProperty(const QMetaProperty &, QDeclarativeEngine *engine = 0); @@ -136,6 +144,7 @@ public: inline QDeclarativeEngine *qmlEngine() const; static Data *property(QDeclarativeEngine *, QObject *, const QScriptDeclarativeClass::Identifier &, Data &); static Data *property(QDeclarativeEngine *, QObject *, const QString &, Data &); + static Data property(const QMetaObject *, const char *); protected: virtual void clear(); diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri index aa1a34b..49888c3 100644 --- a/src/declarative/qml/qml.pri +++ b/src/declarative/qml/qml.pri @@ -38,6 +38,7 @@ SOURCES += \ $$PWD/qdeclarativescript.cpp \ $$PWD/qdeclarativecleanup.cpp \ $$PWD/qdeclarativepropertycache.cpp \ + $$PWD/qdeclarativenotifier.cpp \ $$PWD/qdeclarativeintegercache.cpp \ $$PWD/qdeclarativetypenamecache.cpp \ $$PWD/qdeclarativescriptstring.cpp \ @@ -108,6 +109,7 @@ HEADERS += \ $$PWD/qdeclarativewatcher_p.h \ $$PWD/qdeclarativecleanup_p.h \ $$PWD/qdeclarativepropertycache_p.h \ + $$PWD/qdeclarativenotifier_p.h \ $$PWD/qdeclarativeintegercache_p.h \ $$PWD/qdeclarativetypenamecache_p.h \ $$PWD/qdeclarativescriptstring.h \ diff --git a/tests/auto/declarative/qdeclarativeanchors/tst_qdeclarativeanchors.cpp b/tests/auto/declarative/qdeclarativeanchors/tst_qdeclarativeanchors.cpp index 9d8ba6c..6b7d57f 100644 --- a/tests/auto/declarative/qdeclarativeanchors/tst_qdeclarativeanchors.cpp +++ b/tests/auto/declarative/qdeclarativeanchors/tst_qdeclarativeanchors.cpp @@ -373,7 +373,6 @@ void tst_qdeclarativeanchors::crash1() QString expect = "QML Text (" + source.toString() + ":4:5" + ") Possible anchor loop detected on fill."; QTest::ignoreMessage(QtWarningMsg, expect.toLatin1()); - QTest::ignoreMessage(QtWarningMsg, expect.toLatin1()); // XXX ideally, should be one message QDeclarativeView *view = new QDeclarativeView(source); qApp->processEvents(); -- cgit v0.12 From 7b29dc7daa035a351ba10dcfb879bc3f70434f63 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 10 Mar 2010 16:34:58 +1000 Subject: Ensure currentIndex NOTIFY is emitted when currentIndex changes due to model change. --- src/declarative/graphicsitems/qdeclarativegridview.cpp | 2 ++ src/declarative/graphicsitems/qdeclarativelistview.cpp | 2 ++ .../declarative/qdeclarativegridview/data/gridview-initCurrent.qml | 1 + .../declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp | 5 +++++ .../declarative/qdeclarativelistview/data/listview-initCurrent.qml | 1 + .../declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp | 5 +++++ 6 files changed, 16 insertions(+) diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index af22e08..e66bcf6 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -1807,6 +1807,7 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count) d->currentIndex += count; if (d->currentItem) d->currentItem->index = d->currentIndex; + emit currentIndexChanged(); } d->scheduleLayout(); emit countChanged(); @@ -1889,6 +1890,7 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count) d->currentItem->index = d->currentIndex; d->currentItem->setPosition(d->colPosAt(d->currentIndex), d->rowPosAt(d->currentIndex)); } + emit currentIndexChanged(); } // everything is in order now - emit add() signal diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 007b31b..b988e6e 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -2332,6 +2332,7 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count) d->currentIndex += count; if (d->currentItem) d->currentItem->index = d->currentIndex; + emit currentIndexChanged(); } d->scheduleLayout(); emit countChanged(); @@ -2412,6 +2413,7 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count) d->currentItem->index = d->currentIndex; d->currentItem->setPosition(d->currentItem->position() + diff); } + emit currentIndexChanged(); } // Update the indexes of the following visible items. for (; index < d->visibleItems.count(); ++index) { diff --git a/tests/auto/declarative/qdeclarativegridview/data/gridview-initCurrent.qml b/tests/auto/declarative/qdeclarativegridview/data/gridview-initCurrent.qml index 32833d2..cc3e549 100644 --- a/tests/auto/declarative/qdeclarativegridview/data/gridview-initCurrent.qml +++ b/tests/auto/declarative/qdeclarativegridview/data/gridview-initCurrent.qml @@ -1,6 +1,7 @@ import Qt 4.6 Rectangle { + property int current: grid.currentIndex width: 240 height: 320 color: "#ffffff" diff --git a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp index a1edc53..aaf8291 100644 --- a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp +++ b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp @@ -703,6 +703,11 @@ void tst_QDeclarativeGridView::currentIndex() QCOMPARE(gridview->highlightItem()->x(), hlPosX); QCOMPARE(gridview->highlightItem()->y(), hlPosY); + // insert item before currentIndex + gridview->setCurrentIndex(28); + model.insertItem(0, "Foo", "1111"); + QCOMPARE(canvas->rootObject()->property("current").toInt(), 29); + delete canvas; } diff --git a/tests/auto/declarative/qdeclarativelistview/data/listview-initCurrent.qml b/tests/auto/declarative/qdeclarativelistview/data/listview-initCurrent.qml index 74f5ef4..a6d7610 100644 --- a/tests/auto/declarative/qdeclarativelistview/data/listview-initCurrent.qml +++ b/tests/auto/declarative/qdeclarativelistview/data/listview-initCurrent.qml @@ -1,6 +1,7 @@ import Qt 4.6 Rectangle { + property int current: list.currentIndex width: 240 height: 320 color: "#ffffff" diff --git a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp index 17257ae..e5542c2 100644 --- a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp +++ b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp @@ -1059,6 +1059,11 @@ void tst_QDeclarativeListView::currentIndex() QTest::qWait(500); QCOMPARE(listview->highlightItem()->y(), hlPos); + // insert item before currentIndex + listview->setCurrentIndex(28); + model.insertItem(0, "Foo", "1111"); + QCOMPARE(canvas->rootObject()->property("current").toInt(), 29); + delete canvas; } -- cgit v0.12 From f5693b93949758905dac770a0c21eb34c4e1686b Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 10 Mar 2010 16:53:27 +1000 Subject: Remove accidentally submitted code --- src/declarative/qml/qdeclarativepropertycache_p.h | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/declarative/qml/qdeclarativepropertycache_p.h b/src/declarative/qml/qdeclarativepropertycache_p.h index ea2f01a..db93de3 100644 --- a/src/declarative/qml/qdeclarativepropertycache_p.h +++ b/src/declarative/qml/qdeclarativepropertycache_p.h @@ -82,7 +82,6 @@ public: IsConstant = 0x00000001, IsWritable = 0x00000002, IsResettable = 0x00000004, - HasNotify = 0x00000008, // These are mutualy exclusive IsFunction = 0x00000010, @@ -98,18 +97,12 @@ public: }; Q_DECLARE_FLAGS(Flags, Flag) - - enum Call { ReadProperty, WriteProperty, ConnectNotify, DisconnectNotify }; - typedef void (*MetaCall)(QObject *, Call, void *); bool isValid() const { return coreIndex != -1; } Flags flags; int propType; - union { - MetaCall call; - int coreIndex; - }; + int coreIndex; int notifyIndex; static Flags flagsForProperty(const QMetaProperty &, QDeclarativeEngine *engine = 0); -- cgit v0.12 From 5c4e609c4505fc0fb1564d8daea06e68df5d8f13 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 10 Mar 2010 17:13:32 +1000 Subject: Doc --- src/declarative/qml/qdeclarativepropertycache_p.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/declarative/qml/qdeclarativepropertycache_p.h b/src/declarative/qml/qdeclarativepropertycache_p.h index db93de3..79ddf8d 100644 --- a/src/declarative/qml/qdeclarativepropertycache_p.h +++ b/src/declarative/qml/qdeclarativepropertycache_p.h @@ -115,9 +115,9 @@ public: struct ValueTypeData { inline ValueTypeData(); inline bool operator==(const ValueTypeData &); - Data::Flags flags; // flags on the value type wrapper - int valueTypeCoreIdx; // The prop index of the access property on the value type wrapper - int valueTypePropType; // The QVariant::Type of access property on the value type wrapper + Data::Flags flags; // flags of the access property on the value type proxy object + int valueTypeCoreIdx; // The prop index of the access property on the value type proxy object + int valueTypePropType; // The QVariant::Type of access property on the value type proxy object }; void update(QDeclarativeEngine *, const QMetaObject *); -- cgit v0.12 From 878c2a984b78cdfc88e4474f6719f07662c7ac68 Mon Sep 17 00:00:00 2001 From: mae Date: Wed, 10 Mar 2010 10:45:07 +0100 Subject: Oooops --- revert wrong commit --- examples/declarative/imageprovider/imageprovider.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/declarative/imageprovider/imageprovider.qml b/examples/declarative/imageprovider/imageprovider.qml index f899b1e..a1f2794 100644 --- a/examples/declarative/imageprovider/imageprovider.qml +++ b/examples/declarative/imageprovider/imageprovider.qml @@ -1,5 +1,5 @@ import Qt 4.6 -import "ImageProviderCore" +import ImageProviderCore 1.0 //![0] ListView { width: 100 -- cgit v0.12 From dd8deba7147230c398b31e6fd180a47f4f3037d2 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Wed, 10 Mar 2010 12:56:57 +0100 Subject: Fix location in which webkit import is stored in builddir --- src/imports/webkit/webkit.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/imports/webkit/webkit.pro b/src/imports/webkit/webkit.pro index fdc12cc..9ad9c68 100644 --- a/src/imports/webkit/webkit.pro +++ b/src/imports/webkit/webkit.pro @@ -10,7 +10,7 @@ HEADERS += qdeclarativewebview_p.h \ qdeclarativewebview_p_p.h \ webkitqmlplugin_export.h -QTDIR_build:DESTDIR = $$TARGETPATH +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/$$TARGETPATH target.path = $$TARGETPATH qmldir.files += $$QT_BUILD_TREE/imports/org/webkit/qmldir -- cgit v0.12 From 017571d4f84f6929da315f3afe3e4a8907946bac Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Wed, 10 Mar 2010 12:57:26 +0100 Subject: Use TARGETPATH instead of hardcoding locations --- src/imports/multimedia/multimedia.pro | 2 +- src/imports/widgets/widgets.pro | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/imports/multimedia/multimedia.pro b/src/imports/multimedia/multimedia.pro index f7a1d1b..f348fef 100644 --- a/src/imports/multimedia/multimedia.pro +++ b/src/imports/multimedia/multimedia.pro @@ -17,7 +17,7 @@ SOURCES += \ qdeclarativevideo.cpp \ qmetadatacontrolmetaobject.cpp -QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/Qt/multimedia +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/$$TARGETPATH target.path = $$TARGETPATH qmldir.files += $$QT_BUILD_TREE/imports/Qt/multimedia/qmldir diff --git a/src/imports/widgets/widgets.pro b/src/imports/widgets/widgets.pro index 02223d7..de22403 100644 --- a/src/imports/widgets/widgets.pro +++ b/src/imports/widgets/widgets.pro @@ -12,7 +12,7 @@ HEADERS += \ graphicswidgets_p.h \ graphicslayouts_p.h -QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/Qt/widgets +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/$$TARGETPATH target.path = $$TARGETPATH # install qmldir file -- cgit v0.12 From 49c975754c2b297eb2845a076b047ba206c9f93b Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 10 Mar 2010 13:41:37 +0100 Subject: fix inclusion of qt_targets.pri in qimportbase.pri Reviewed-by: Roberto Raggi --- src/imports/qimportbase.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/imports/qimportbase.pri b/src/imports/qimportbase.pri index 5433059..ea12356 100644 --- a/src/imports/qimportbase.pri +++ b/src/imports/qimportbase.pri @@ -22,7 +22,7 @@ QMAKE_EXTRA_COMPILERS += copy2build TARGET = $$qtLibraryTarget($$TARGET) contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols -include(../../qt_targets.pri) +include(../qt_targets.pri) wince*:LIBS += $$QMAKE_LIBS_GUI -- cgit v0.12 From b8f9d43dc87054f4f0322a2d124beeb7aaf8bb8f Mon Sep 17 00:00:00 2001 From: mae Date: Wed, 10 Mar 2010 14:20:28 +0100 Subject: when loading debug import plugins on Mac, try with _debug.dylib suffix --- src/declarative/qml/qdeclarativeengine.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 6325466..62fe5b5 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1844,6 +1844,9 @@ QString QDeclarativeEnginePrivate::resolvePlugin(const QDir &dir, const QString return resolvePlugin(dir, baseName, QStringList() +# ifdef QT_DEBUG + << QLatin1String("_debug.dylib") // try a qmake-style debug build first +# endif << QLatin1String(".dylib") << QLatin1String(".so") << QLatin1String(".bundle"), -- cgit v0.12 From e5922ab126f3532483b18720ce893d6be826d50e Mon Sep 17 00:00:00 2001 From: mae Date: Wed, 10 Mar 2010 18:29:44 +0100 Subject: Document - and use - the qmlRegisterXXX template functions This commit removes the obsolete QML_REGISTER_TYPE macros. --- demos/declarative/minehunt/minehunt.cpp | 5 +- doc/src/declarative/declarativeui.qdoc | 4 +- doc/src/declarative/extending.qdoc | 62 +++++----- doc/src/declarative/qtdeclarative.qdoc | 48 ++++++++ examples/declarative/extending/adding/main.cpp | 2 +- examples/declarative/extending/attached/main.cpp | 12 +- examples/declarative/extending/binding/main.cpp | 15 ++- examples/declarative/extending/coercion/main.cpp | 8 +- examples/declarative/extending/default/main.cpp | 8 +- examples/declarative/extending/extended/main.cpp | 2 +- examples/declarative/extending/grouped/main.cpp | 10 +- examples/declarative/extending/properties/main.cpp | 4 +- examples/declarative/extending/signal/main.cpp | 12 +- .../declarative/extending/valuesource/main.cpp | 14 +-- .../graphicsitems/qdeclarativeitemsmodule.cpp | 134 ++++++++++----------- src/declarative/qml/qdeclarative.h | 3 + src/declarative/qml/qdeclarativecustomparser_p.h | 3 +- src/declarative/qml/qdeclarativeengine.cpp | 10 +- src/declarative/util/qdeclarativeutilmodule.cpp | 75 ++++++------ src/imports/webkit/plugin.cpp | 2 +- src/imports/widgets/widgets.cpp | 6 +- tools/qml/qdeclarativefolderlistmodel.cpp | 2 +- tools/qml/qfxtester.cpp | 8 +- tools/qml/qmlruntime.cpp | 2 +- 24 files changed, 254 insertions(+), 197 deletions(-) diff --git a/demos/declarative/minehunt/minehunt.cpp b/demos/declarative/minehunt/minehunt.cpp index 89845ef..2e1b5b3 100644 --- a/demos/declarative/minehunt/minehunt.cpp +++ b/demos/declarative/minehunt/minehunt.cpp @@ -292,9 +292,8 @@ class MinehuntExtensionPlugin : public QDeclarativeExtensionPlugin public: void registerTypes(const char *uri) { - Q_UNUSED(uri); - QML_REGISTER_TYPE(SameGameCore, 0, 1, Tile, Tile); - QML_REGISTER_TYPE(SameGameCore, 0, 1, Game, MinehuntGame); + qmlRegisterType(uri, 0, 1, "Tile"); + qmlRegisterType(uri, 0, 1, "Game"); } void initializeEngine(QDeclarativeEngine *engine, const char *uri) { diff --git a/doc/src/declarative/declarativeui.qdoc b/doc/src/declarative/declarativeui.qdoc index 4b61bd9..ed63367 100644 --- a/doc/src/declarative/declarativeui.qdoc +++ b/doc/src/declarative/declarativeui.qdoc @@ -68,7 +68,7 @@ internet-enabled applications like a \l {http://www.flickr.com}{Flickr} photo br Qt Declarative builds on \l {QML for Qt programmers}{Qt's existing strengths}. QML can be be used to incrementally extend an existing application or to build -completely new applications. QML is fully \l {Extending QML}{extensible from C++}. +completely new applications. QML is fully \l {Extending QML in C++}{extensible from C++}. \section1 Getting Started: \list @@ -100,7 +100,7 @@ completely new applications. QML is fully \l {Extending QML}{extensible from C+ \list \o \l {QML Elements} \o \l {QML Global Object} -\o \l {Extending QML} +\o \l {Extending QML in C++} \o \l {QML Internationalization} \o \l {QtDeclarative Module} \o \l {Debugging QML} diff --git a/doc/src/declarative/extending.qdoc b/doc/src/declarative/extending.qdoc index 5aaa7bd..0ae4f7d 100644 --- a/doc/src/declarative/extending.qdoc +++ b/doc/src/declarative/extending.qdoc @@ -41,7 +41,7 @@ /*! \page qml-extending.html -\title Extending QML +\title Extending QML in C++ The QML syntax declaratively describes how to construct an in memory object tree. In Qt, QML is mainly used to describe a visual scene graph, but it is @@ -67,21 +67,23 @@ that derive from QObject. The QML engine has no intrinsic knowledge of any class types. Instead the programmer must define the C++ types, and their corresponding QML name. -Custom C++ types are made available to QML using these two macros: +Custom C++ types are declared QML types using a macro and a template function: \quotation + \code #define QML_DECLARE_TYPE(T) -#define QML_REGISTER_TYPE(URI,VMAJ,VMIN,QDeclarativeName,T) +template +int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName) \endcode -Register the C++ type \a T with the QML system, and make it available in QML -under the name \a QDeclarativeName in library URI version VMAJ.VMIN. -\a T and \a QDeclarativeName may be the same. +Calling qmlRegisterType() registers the C++ type \a T with the QML system, and makes it available in QML +under the name \a qmlName in library \a uri version \a versionMajor.versionMinor. +The \a qmlName can be the same as the C++ type name. Generally the QML_DECLARE_TYPE() macro should be included immediately following -the type declaration (usually in its header file), and the QML_REGISTER_TYPE() -macro called by the implementation. +the type declaration (usually in its header file), and the template function qmlRegisterType() +called by the implementation. Type \a T must be a concrete type that inherits QObject and has a default constructor. @@ -147,19 +149,20 @@ property can be assigned. QML also supports assigning Qt interfaces. To assign to a property whose type is a Qt interface pointer, the interface must also be registered with QML. As they cannot be instantiated directly, registering a Qt interface is different -from registering a new QML type. The following macros are used instead: +from registering a new QML type. The following macro and function are used instead: \quotation \code - #define QML_DECLARE_INTERFACE(T) - #define QML_REGISTER_INTERFACE(T) +#define QML_DECLARE_INTERFACE(T) +template +int qmlRegisterInterface(const char *typeName) \endcode -Register the C++ interface \a T with the QML system. +Registers the C++ interface \a T with the QML system as \a typeName. Generally the QML_DECLARE_INTERFACE() macro should be included immediately following the interface declaration (usually in its header file), and the -QML_REGISTER_INTERFACE() macro called by the implementation. +qmlRegisterInterface() template function called by the implementation. Following registration, QML can coerce objects that implement this interface for assignment to appropriately typed properties. @@ -174,7 +177,7 @@ The guest property declaration looks like this: \snippet examples/declarative/extending/properties/birthdayparty.h 2 -\l {Extending QML - Object and List Property Types Example} shows the complete +\l {Extending QML in C++ - Object and List Property Types Example} shows the complete code used to create the \c BirthdayParty type. \section1 Inheritance and Coercion @@ -192,25 +195,26 @@ type used in the previous section, but the assignment is valid as both the Boy and Girl objects inherit from Person. To assign to a property, the property's type must have been registered with QML. -Both the QML_REGISTER_TYPE() and QML_REGISTER_INTERFACE() macros already shown can -be used to register a type with QML. Additionally, if a type that acts purely +Both the qmlRegisterType() and qmlRegisterInterface() template functions already +shown can be used to register a type with QML. Additionally, if a type that acts purely as a base class that cannot be instantiated from QML needs to be -registered these macros can be used: +registered these macro and function can be used: \quotation \code #define QML_DECLARE_TYPE(T) - #define QML_REGISTER_NOCREATE_TYPE(T) + template + int qmlRegisterType() \endcode -Register the C++ type \a T with the QML system. QML_REGISTER_NOCREATE_TYPE() -differs from QML_REGISTER_TYPE() in that it does not define a mapping between the +Registers the C++ type \a T with the QML system. The parameterless call to the template +function qmlRegisterType() does not define a mapping between the C++ class and a QML element name, so the type is not instantiable from QML, but it is available for type coercion. Generally the QML_DECLARE_TYPE() macro should be included immediately following the type declaration (usually in its header file), and the -QML_REGISTER_NOCREATE_TYPE() macro called from the implementation. +qmlRegisterType() template function called from the implementation. Type \a T must inherit QObject, but there are no restrictions on whether it is concrete or the signature of its constructor. @@ -220,7 +224,7 @@ QML will automatically coerce C++ types when assigning to either an object property, or to a list property. Only if coercion fails does an assignment error occur. -\l {Extending QML - Inheritance and Coercion Example} shows the complete +\l {Extending QML in C++ - Inheritance and Coercion Example} shows the complete code used to create the \c Boy and \c Girl types. \section1 Default Property @@ -252,7 +256,7 @@ refer to a property declared in the class itself, or a property inherited from a base class. \endquotation -\l {Extending QML - Default Property Example} shows the complete code used to +\l {Extending QML in C++ - Default Property Example} shows the complete code used to specify a default property. \section1 Grouped Properties @@ -277,7 +281,7 @@ property block - in this case the size, color, brand and price properties. Grouped property blocks may declared and accessed be recusively. -\l {Extending QML - Grouped Properties Example} shows the complete code used to +\l {Extending QML in C++ - Grouped Properties Example} shows the complete code used to implement the \c shoe property grouping. \section1 Attached Properties @@ -369,7 +373,7 @@ creating it if it does not already exist. If \a create is false, the attachment object will only be returned if it has previously been created. \endquotation -\l {Extending QML - Attached Properties Example} shows the complete code used to +\l {Extending QML in C++ - Attached Properties Example} shows the complete code used to implement the rsvp attached property. \section1 Memory Management and QVariant types @@ -431,7 +435,7 @@ listed in \l {Adding Types}, as well registered object types are permitted as signal parameter types. Using other types is not an error, but the parameter value will not be accessible from script. -\l {Extending QML - Signal Support Example} shows the complete code used to +\l {Extending QML in C++ - Signal Support Example} shows the complete code used to implement the onPartyStarted signal property. \section1 Property Value Sources @@ -478,7 +482,7 @@ to assign it normally, as though it were a regular QML type. Only if this assignment fails does the engine call the setTarget() method. This allows the type to also be used in contexts other than just as a value source. -\l {Extending QML - Property Value Source Example} shows the complete code used +\l {Extending QML in C++ - Property Value Source Example} shows the complete code used implement the HappyBirthday property value source. \section1 Property Binding @@ -550,7 +554,7 @@ The CONSTANT attribute should only be used for properties whose value is set, and finalized, only in the class constructor. All other properties that want to be used in bindings should have a NOTIFY signal instead. -\l {Extending QML - Binding Example} shows the BirthdayParty example updated to +\l {Extending QML in C++ - Binding Example} shows the BirthdayParty example updated to include NOTIFY signals for use in binding. \section1 Extension Objects @@ -623,7 +627,7 @@ public: \title Extending types from QML Many of the elements available for use in QML are implemented in -\l {Extending QML}{C++}. These types are know as "core types". QML +\l {Extending QML in C++}{C++}. These types are know as "core types". QML allows programmers to build new, fully functional elements without using C++. Existing core types can be extended, and new types defined entirely in the QML language. diff --git a/doc/src/declarative/qtdeclarative.qdoc b/doc/src/declarative/qtdeclarative.qdoc index 41d6338..b43d0ec 100644 --- a/doc/src/declarative/qtdeclarative.qdoc +++ b/doc/src/declarative/qtdeclarative.qdoc @@ -65,3 +65,51 @@ For more information on the Qt Declarative module, see the \l{declarativeui.html}{Declarative UI} documentation. */ + + +/*! + \macro QML_DECLARE_TYPE(T) + \relates QDeclarativeEngine + + yada yada yada + +*/ + + +/*! + \fn int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName) + \relates QDeclarativeEngine + + This template function registers the C++ type \a T with the QML system, and make it available in + QML under the name \a qmlName in the import library \a uri version \a versionMajor.versionMajor. + + Returns the QML type id. + + Example: Register the C++ class \c MinehuntGame as QML type \c Game version 0.1 in the import + library \c MinehuntCore: + + \code + qmlRegisterType("MinehuntCore", 0, 1, "Game"); + \endcode + +*/ + +/*! + \fn int qmlRegisterType() + \relates QDeclarativeEngine + \overload + + This template function registers the C++ type \a T with the QML system. Instances of this type cannot + be created from the QML system. + + Returns the QML type id. +*/ + +/*! \fn int qmlRegisterInterface(const char *typeName) + \relates QDeclarativeEngine + + This template function registers the C++ type \a T as interface with the QML system, under the name + \a typeName. + + Returns the QML type id. + */ diff --git a/examples/declarative/extending/adding/main.cpp b/examples/declarative/extending/adding/main.cpp index 76e0736..b9e5aa3 100644 --- a/examples/declarative/extending/adding/main.cpp +++ b/examples/declarative/extending/adding/main.cpp @@ -48,7 +48,7 @@ int main(int argc, char ** argv) { QCoreApplication app(argc, argv); - QML_REGISTER_TYPE(People, 1,0, Person, Person); + qmlRegisterType("People", 1,0, "Person"); QDeclarativeEngine engine; QDeclarativeComponent component(&engine, ":example.qml"); diff --git a/examples/declarative/extending/attached/main.cpp b/examples/declarative/extending/attached/main.cpp index 684d8d3..fd2d525 100644 --- a/examples/declarative/extending/attached/main.cpp +++ b/examples/declarative/extending/attached/main.cpp @@ -49,12 +49,12 @@ int main(int argc, char ** argv) { QCoreApplication app(argc, argv); - QML_REGISTER_NOCREATE_TYPE(BirthdayPartyAttached); - QML_REGISTER_TYPE(People, 1,0, BirthdayParty, BirthdayParty); - QML_REGISTER_NOCREATE_TYPE(ShoeDescription); - QML_REGISTER_NOCREATE_TYPE(Person); - QML_REGISTER_TYPE(People, 1,0, Boy, Boy); - QML_REGISTER_TYPE(People, 1,0, Girl, Girl); + qmlRegisterType(); + qmlRegisterType("People", 1,0, "BirthdayParty"); + qmlRegisterType(); + qmlRegisterType(); + qmlRegisterType("People", 1,0, "Boy"); + qmlRegisterType("People", 1,0, "Girl"); QDeclarativeEngine engine; QDeclarativeComponent component(&engine, ":example.qml"); diff --git a/examples/declarative/extending/binding/main.cpp b/examples/declarative/extending/binding/main.cpp index 873f8c9..ce6c50d 100644 --- a/examples/declarative/extending/binding/main.cpp +++ b/examples/declarative/extending/binding/main.cpp @@ -49,14 +49,13 @@ int main(int argc, char ** argv) { QCoreApplication app(argc, argv); - - QML_REGISTER_NOCREATE_TYPE(BirthdayPartyAttached); - QML_REGISTER_TYPE(People, 1,0, BirthdayParty, BirthdayParty); - QML_REGISTER_TYPE(People, 1,0, HappyBirthday, HappyBirthday); - QML_REGISTER_NOCREATE_TYPE(ShoeDescription); - QML_REGISTER_NOCREATE_TYPE(Person); - QML_REGISTER_TYPE(People, 1,0, Boy, Boy); - QML_REGISTER_TYPE(People, 1,0, Girl, Girl); + qmlRegisterType(); + qmlRegisterType("People", 1,0, "BirthdayParty"); + qmlRegisterType("People", 1,0, "HappyBirthday"); + qmlRegisterType(); + qmlRegisterType(); + qmlRegisterType("People", 1,0, "Boy"); + qmlRegisterType("People", 1,0, "Girl"); QDeclarativeEngine engine; QDeclarativeComponent component(&engine, ":example.qml"); diff --git a/examples/declarative/extending/coercion/main.cpp b/examples/declarative/extending/coercion/main.cpp index 1e2209f..312aff9 100644 --- a/examples/declarative/extending/coercion/main.cpp +++ b/examples/declarative/extending/coercion/main.cpp @@ -49,12 +49,12 @@ int main(int argc, char ** argv) { QCoreApplication app(argc, argv); - QML_REGISTER_TYPE(People, 1,0, BirthdayParty, BirthdayParty); + qmlRegisterType("People", 1,0, "BirthdayParty"); // ![0] - QML_REGISTER_NOCREATE_TYPE(Person); + qmlRegisterType(); // ![0] - QML_REGISTER_TYPE(People, 1,0, Boy, Boy); - QML_REGISTER_TYPE(People, 1,0, Girl, Girl); + qmlRegisterType("People", 1,0, "Boy"); + qmlRegisterType("People", 1,0, "Girl"); QDeclarativeEngine engine; QDeclarativeComponent component(&engine, ":example.qml"); diff --git a/examples/declarative/extending/default/main.cpp b/examples/declarative/extending/default/main.cpp index 7d7f8a1..06282ad 100644 --- a/examples/declarative/extending/default/main.cpp +++ b/examples/declarative/extending/default/main.cpp @@ -49,10 +49,10 @@ int main(int argc, char ** argv) { QCoreApplication app(argc, argv); - QML_REGISTER_TYPE(People, 1,0, BirthdayParty, BirthdayParty); - QML_REGISTER_NOCREATE_TYPE(Person); - QML_REGISTER_TYPE(People, 1,0, Boy, Boy); - QML_REGISTER_TYPE(People, 1,0, Girl, Girl); + qmlRegisterType("People", 1,0, "BirthdayParty"); + qmlRegisterType(); + qmlRegisterType("People", 1,0, "Boy"); + qmlRegisterType("People", 1,0, "Girl"); QDeclarativeEngine engine; QDeclarativeComponent component(&engine, ":example.qml"); diff --git a/examples/declarative/extending/extended/main.cpp b/examples/declarative/extending/extended/main.cpp index 5cbeea3..ca7242d 100644 --- a/examples/declarative/extending/extended/main.cpp +++ b/examples/declarative/extending/extended/main.cpp @@ -49,7 +49,7 @@ int main(int argc, char ** argv) { QApplication app(argc, argv); - QML_REGISTER_EXTENDED_TYPE(People, 1,0, QLineEdit, QLineEdit, LineEditExtension); + qmlRegisterExtendedType("People", 1,0, "QLineEdit"); QDeclarativeEngine engine; QDeclarativeComponent component(&engine, ":example.qml"); diff --git a/examples/declarative/extending/grouped/main.cpp b/examples/declarative/extending/grouped/main.cpp index 15a0bb5..b383a8b 100644 --- a/examples/declarative/extending/grouped/main.cpp +++ b/examples/declarative/extending/grouped/main.cpp @@ -49,11 +49,11 @@ int main(int argc, char ** argv) { QCoreApplication app(argc, argv); - QML_REGISTER_TYPE(People, 1,0, BirthdayParty, BirthdayParty); - QML_REGISTER_NOCREATE_TYPE(ShoeDescription); - QML_REGISTER_NOCREATE_TYPE(Person); - QML_REGISTER_TYPE(People, 1,0, Boy, Boy); - QML_REGISTER_TYPE(People, 1,0, Girl, Girl); + qmlRegisterType("People", 1,0, "BirthdayParty"); + qmlRegisterType(); + qmlRegisterType(); + qmlRegisterType("People", 1,0, "Boy"); + qmlRegisterType("People", 1,0, "Girl"); QDeclarativeEngine engine; QDeclarativeComponent component(&engine, ":example.qml"); diff --git a/examples/declarative/extending/properties/main.cpp b/examples/declarative/extending/properties/main.cpp index ce69ad2..350f8bd 100644 --- a/examples/declarative/extending/properties/main.cpp +++ b/examples/declarative/extending/properties/main.cpp @@ -49,8 +49,8 @@ int main(int argc, char ** argv) { QCoreApplication app(argc, argv); - QML_REGISTER_TYPE(People, 1,0, BirthdayParty, BirthdayParty); - QML_REGISTER_TYPE(People, 1,0, Person, Person); + qmlRegisterType("People", 1,0, "BirthdayParty"); + qmlRegisterType("People", 1,0, "Person"); QDeclarativeEngine engine; QDeclarativeComponent component(&engine, ":example.qml"); diff --git a/examples/declarative/extending/signal/main.cpp b/examples/declarative/extending/signal/main.cpp index afc1a66..1b23a46 100644 --- a/examples/declarative/extending/signal/main.cpp +++ b/examples/declarative/extending/signal/main.cpp @@ -49,12 +49,12 @@ int main(int argc, char ** argv) { QCoreApplication app(argc, argv); - QML_REGISTER_NOCREATE_TYPE(BirthdayPartyAttached); - QML_REGISTER_TYPE(People, 1,0, BirthdayParty, BirthdayParty); - QML_REGISTER_NOCREATE_TYPE(ShoeDescription); - QML_REGISTER_NOCREATE_TYPE(Person); - QML_REGISTER_TYPE(People, 1,0, Boy, Boy); - QML_REGISTER_TYPE(People, 1,0, Girl, Girl); + qmlRegisterType(); + qmlRegisterType("People", 1,0, "BirthdayParty"); + qmlRegisterType(); + qmlRegisterType(); + qmlRegisterType("People", 1,0, "Boy"); + qmlRegisterType("People", 1,0, "Girl"); QDeclarativeEngine engine; QDeclarativeComponent component(&engine, ":example.qml"); diff --git a/examples/declarative/extending/valuesource/main.cpp b/examples/declarative/extending/valuesource/main.cpp index 873f8c9..2574917 100644 --- a/examples/declarative/extending/valuesource/main.cpp +++ b/examples/declarative/extending/valuesource/main.cpp @@ -50,13 +50,13 @@ int main(int argc, char ** argv) { QCoreApplication app(argc, argv); - QML_REGISTER_NOCREATE_TYPE(BirthdayPartyAttached); - QML_REGISTER_TYPE(People, 1,0, BirthdayParty, BirthdayParty); - QML_REGISTER_TYPE(People, 1,0, HappyBirthday, HappyBirthday); - QML_REGISTER_NOCREATE_TYPE(ShoeDescription); - QML_REGISTER_NOCREATE_TYPE(Person); - QML_REGISTER_TYPE(People, 1,0, Boy, Boy); - QML_REGISTER_TYPE(People, 1,0, Girl, Girl); + qmlRegisterType(); + qmlRegisterType("People", 1,0, "BirthdayParty"); + qmlRegisterType("People", 1,0, "HappyBirthday"); + qmlRegisterType(); + qmlRegisterType(); + qmlRegisterType("People", 1,0, "Boy"); + qmlRegisterType("People", 1,0, "Girl"); QDeclarativeEngine engine; QDeclarativeComponent component(&engine, ":example.qml"); diff --git a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp index 25660f8..2d05c7c 100644 --- a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp @@ -82,76 +82,76 @@ void QDeclarativeItemModule::defineModule() { - QML_REGISTER_TYPE(Qt,4,6,AnimatedImage,QDeclarativeAnimatedImage); - QML_REGISTER_TYPE(Qt,4,6,Blur,QGraphicsBlurEffect); - QML_REGISTER_TYPE(Qt,4,6,BorderImage,QDeclarativeBorderImage); - QML_REGISTER_TYPE(Qt,4,6,Colorize,QGraphicsColorizeEffect); - QML_REGISTER_TYPE(Qt,4,6,Column,QDeclarativeColumn); - QML_REGISTER_TYPE(Qt,4,6,Drag,QDeclarativeDrag); - QML_REGISTER_TYPE(Qt,4,6,DropShadow,QGraphicsDropShadowEffect); - QML_REGISTER_TYPE(Qt,4,6,Flickable,QDeclarativeFlickable); - QML_REGISTER_TYPE(Qt,4,6,Flipable,QDeclarativeFlipable); - QML_REGISTER_TYPE(Qt,4,6,Flow,QDeclarativeFlow); - QML_REGISTER_TYPE(Qt,4,6,FocusPanel,QDeclarativeFocusPanel); - QML_REGISTER_TYPE(Qt,4,6,FocusScope,QDeclarativeFocusScope); - QML_REGISTER_TYPE(Qt,4,6,Gradient,QDeclarativeGradient); - QML_REGISTER_TYPE(Qt,4,6,GradientStop,QDeclarativeGradientStop); - QML_REGISTER_TYPE(Qt,4,6,GraphicsObjectContainer,QDeclarativeGraphicsObjectContainer); - QML_REGISTER_TYPE(Qt,4,6,Grid,QDeclarativeGrid); - QML_REGISTER_TYPE(Qt,4,6,GridView,QDeclarativeGridView); - QML_REGISTER_TYPE(Qt,4,6,Image,QDeclarativeImage); - QML_REGISTER_TYPE(Qt,4,6,Item,QDeclarativeItem); - QML_REGISTER_TYPE(Qt,4,6,KeyNavigation,QDeclarativeKeyNavigationAttached); - QML_REGISTER_TYPE(Qt,4,6,Keys,QDeclarativeKeysAttached); - QML_REGISTER_TYPE(Qt,4,6,LayoutItem,QDeclarativeLayoutItem); - QML_REGISTER_TYPE(Qt,4,6,ListView,QDeclarativeListView); - QML_REGISTER_TYPE(Qt,4,6,Loader,QDeclarativeLoader); - QML_REGISTER_TYPE(Qt,4,6,MouseArea,QDeclarativeMouseArea); - QML_REGISTER_TYPE(Qt,4,6,Opacity,QGraphicsOpacityEffect); - QML_REGISTER_TYPE(Qt,4,6,ParticleMotion,QDeclarativeParticleMotion); - QML_REGISTER_TYPE(Qt,4,6,ParticleMotionGravity,QDeclarativeParticleMotionGravity); - QML_REGISTER_TYPE(Qt,4,6,ParticleMotionLinear,QDeclarativeParticleMotionLinear); - QML_REGISTER_TYPE(Qt,4,6,ParticleMotionWander,QDeclarativeParticleMotionWander); - QML_REGISTER_TYPE(Qt,4,6,Particles,QDeclarativeParticles); - QML_REGISTER_TYPE(Qt,4,6,Path,QDeclarativePath); - QML_REGISTER_TYPE(Qt,4,6,PathAttribute,QDeclarativePathAttribute); - QML_REGISTER_TYPE(Qt,4,6,PathCubic,QDeclarativePathCubic); - QML_REGISTER_TYPE(Qt,4,6,PathLine,QDeclarativePathLine); - QML_REGISTER_TYPE(Qt,4,6,PathPercent,QDeclarativePathPercent); - QML_REGISTER_TYPE(Qt,4,6,PathQuad,QDeclarativePathQuad); - QML_REGISTER_TYPE(Qt,4,6,PathView,QDeclarativePathView); - QML_REGISTER_TYPE(Qt,4,6,Pen,QDeclarativePen); - QML_REGISTER_TYPE(Qt,4,6,QIntValidator,QIntValidator); + qmlRegisterType("Qt",4,6,"AnimatedImage"); + qmlRegisterType("Qt",4,6,"Blur"); + qmlRegisterType("Qt",4,6,"BorderImage"); + qmlRegisterType("Qt",4,6,"Colorize"); + qmlRegisterType("Qt",4,6,"Column"); + qmlRegisterType("Qt",4,6,"Drag"); + qmlRegisterType("Qt",4,6,"DropShadow"); + qmlRegisterType("Qt",4,6,"Flickable"); + qmlRegisterType("Qt",4,6,"Flipable"); + qmlRegisterType("Qt",4,6,"Flow"); + qmlRegisterType("Qt",4,6,"FocusPanel"); + qmlRegisterType("Qt",4,6,"FocusScope"); + qmlRegisterType("Qt",4,6,"Gradient"); + qmlRegisterType("Qt",4,6,"GradientStop"); + qmlRegisterType("Qt",4,6,"GraphicsObjectContainer"); + qmlRegisterType("Qt",4,6,"Grid"); + qmlRegisterType("Qt",4,6,"GridView"); + qmlRegisterType("Qt",4,6,"Image"); + qmlRegisterType("Qt",4,6,"Item"); + qmlRegisterType("Qt",4,6,"KeyNavigation"); + qmlRegisterType("Qt",4,6,"Keys"); + qmlRegisterType("Qt",4,6,"LayoutItem"); + qmlRegisterType("Qt",4,6,"ListView"); + qmlRegisterType("Qt",4,6,"Loader"); + qmlRegisterType("Qt",4,6,"MouseArea"); + qmlRegisterType("Qt",4,6,"Opacity"); + qmlRegisterType("Qt",4,6,"ParticleMotion"); + qmlRegisterType("Qt",4,6,"ParticleMotionGravity"); + qmlRegisterType("Qt",4,6,"ParticleMotionLinear"); + qmlRegisterType("Qt",4,6,"ParticleMotionWander"); + qmlRegisterType("Qt",4,6,"Particles"); + qmlRegisterType("Qt",4,6,"Path"); + qmlRegisterType("Qt",4,6,"PathAttribute"); + qmlRegisterType("Qt",4,6,"PathCubic"); + qmlRegisterType("Qt",4,6,"PathLine"); + qmlRegisterType("Qt",4,6,"PathPercent"); + qmlRegisterType("Qt",4,6,"PathQuad"); + qmlRegisterType("Qt",4,6,"PathView"); + qmlRegisterType("Qt",4,6,"Pen"); + qmlRegisterType("Qt",4,6,"QIntValidator"); #if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) - QML_REGISTER_TYPE(Qt,4,7,QDoubleValidator,QDoubleValidator); - QML_REGISTER_TYPE(Qt,4,7,QRegExpValidator,QRegExpValidator); + qmlRegisterType("Qt",4,7,"QDoubleValidator"); + qmlRegisterType("Qt",4,7,"QRegExpValidator"); #endif - QML_REGISTER_TYPE(Qt,4,6,Rectangle,QDeclarativeRectangle); - QML_REGISTER_TYPE(Qt,4,6,Repeater,QDeclarativeRepeater); - QML_REGISTER_TYPE(Qt,4,6,Rotation,QGraphicsRotation); - QML_REGISTER_TYPE(Qt,4,6,Row,QDeclarativeRow); - QML_REGISTER_TYPE(Qt,4,6,Scale,QGraphicsScale); - QML_REGISTER_TYPE(Qt,4,6,Text,QDeclarativeText); - QML_REGISTER_TYPE(Qt,4,6,TextEdit,QDeclarativeTextEdit); - QML_REGISTER_TYPE(Qt,4,6,TextInput,QDeclarativeTextInput); - QML_REGISTER_TYPE(Qt,4,6,ViewSection,QDeclarativeViewSection); - QML_REGISTER_TYPE(Qt,4,6,VisibleArea,QDeclarativeFlickableVisibleArea); - QML_REGISTER_TYPE(Qt,4,6,VisualDataModel,QDeclarativeVisualDataModel); - QML_REGISTER_TYPE(Qt,4,6,VisualItemModel,QDeclarativeVisualItemModel); + qmlRegisterType("Qt",4,6,"Rectangle"); + qmlRegisterType("Qt",4,6,"Repeater"); + qmlRegisterType("Qt",4,6,"Rotation"); + qmlRegisterType("Qt",4,6,"Row"); + qmlRegisterType("Qt",4,6,"Scale"); + qmlRegisterType("Qt",4,6,"Text"); + qmlRegisterType("Qt",4,6,"TextEdit"); + qmlRegisterType("Qt",4,6,"TextInput"); + qmlRegisterType("Qt",4,6,"ViewSection"); + qmlRegisterType("Qt",4,6,"VisibleArea"); + qmlRegisterType("Qt",4,6,"VisualDataModel"); + qmlRegisterType("Qt",4,6,"VisualItemModel"); - QML_REGISTER_NOCREATE_TYPE(QDeclarativeAnchors); - QML_REGISTER_NOCREATE_TYPE(QGraphicsEffect); - QML_REGISTER_NOCREATE_TYPE(QDeclarativeKeyEvent); - QML_REGISTER_NOCREATE_TYPE(QDeclarativeMouseEvent); - QML_REGISTER_NOCREATE_TYPE(QGraphicsObject); - QML_REGISTER_NOCREATE_TYPE(QGraphicsTransform); - QML_REGISTER_NOCREATE_TYPE(QDeclarativePathElement); - QML_REGISTER_NOCREATE_TYPE(QDeclarativeCurve); - QML_REGISTER_NOCREATE_TYPE(QDeclarativeScaleGrid); - QML_REGISTER_NOCREATE_TYPE(QValidator); - QML_REGISTER_NOCREATE_TYPE(QDeclarativeVisualModel); - QML_REGISTER_NOCREATE_TYPE(QAction); + qmlRegisterType(); + qmlRegisterType(); + qmlRegisterType(); + qmlRegisterType(); + qmlRegisterType(); + qmlRegisterType(); + qmlRegisterType(); + qmlRegisterType(); + qmlRegisterType(); + qmlRegisterType(); + qmlRegisterType(); + qmlRegisterType(); #ifdef QT_WEBKIT_LIB - QML_REGISTER_NOCREATE_TYPE(QDeclarativeWebSettings); + qmlRegisterType(); #endif } diff --git a/src/declarative/qml/qdeclarative.h b/src/declarative/qml/qdeclarative.h index 77b7484..2a7a9cf 100644 --- a/src/declarative/qml/qdeclarative.h +++ b/src/declarative/qml/qdeclarative.h @@ -275,6 +275,7 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor, return QDeclarativePrivate::registerType(type); } +#if 0 #define QML_REGISTER_INTERFACE(INTERFACE) \ qmlRegisterInterface(#INTERFACE) @@ -287,6 +288,8 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor, #define QML_REGISTER_NOCREATE_TYPE(CLASS) \ qmlRegisterType() +#endif + class QDeclarativeContext; class QDeclarativeEngine; Q_DECLARATIVE_EXPORT void qmlExecuteDeferred(QObject *); diff --git a/src/declarative/qml/qdeclarativecustomparser_p.h b/src/declarative/qml/qdeclarativecustomparser_p.h index 99587a8..39bd43c 100644 --- a/src/declarative/qml/qdeclarativecustomparser_p.h +++ b/src/declarative/qml/qdeclarativecustomparser_p.h @@ -128,9 +128,10 @@ private: QList exceptions; }; +#if 0 #define QML_REGISTER_CUSTOM_TYPE(URI, VERSION_MAJ, VERSION_MIN, NAME, TYPE, CUSTOMTYPE) \ qmlRegisterCustomType(#URI, VERSION_MAJ, VERSION_MIN, #NAME, #TYPE, new CUSTOMTYPE) - +#endif QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 62fe5b5..41c0f5c 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -146,12 +146,12 @@ static bool qt_QmlQtModule_registered = false; void QDeclarativeEnginePrivate::defineModule() { - QML_REGISTER_TYPE(Qt,4,6,Component,QDeclarativeComponent); - QML_REGISTER_TYPE(Qt,4,6,QtObject,QObject); - QML_REGISTER_TYPE(Qt,4,6,WorkerScript,QDeclarativeWorkerScript); - QML_REGISTER_TYPE(Qt,4,6,WorkerListModel,QDeclarativeWorkerListModel); + qmlRegisterType("Qt",4,6,"Component"); + qmlRegisterType("Qt",4,6,"QtObject"); + qmlRegisterType("Qt",4,6,"WorkerScript"); + qmlRegisterType("Qt",4,6,"WorkerListModel"); - QML_REGISTER_NOCREATE_TYPE(QDeclarativeBinding); + qmlRegisterType(); } QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e) diff --git a/src/declarative/util/qdeclarativeutilmodule.cpp b/src/declarative/util/qdeclarativeutilmodule.cpp index 65bfdc1..9c3b0aa 100644 --- a/src/declarative/util/qdeclarativeutilmodule.cpp +++ b/src/declarative/util/qdeclarativeutilmodule.cpp @@ -75,44 +75,47 @@ void QDeclarativeUtilModule::defineModule() { - QML_REGISTER_TYPE(Qt,4,6,AnchorChanges,QDeclarativeAnchorChanges); - QML_REGISTER_TYPE(Qt,4,6,Behavior,QDeclarativeBehavior); - QML_REGISTER_TYPE(Qt,4,6,Binding,QDeclarativeBind); - QML_REGISTER_TYPE(Qt,4,6,ColorAnimation,QDeclarativeColorAnimation); - QML_REGISTER_TYPE(Qt,4,6,Connections,QDeclarativeConnections); - QML_REGISTER_TYPE(Qt,4,6,EaseFollow,QDeclarativeEaseFollow);; - QML_REGISTER_TYPE(Qt,4,6,FontLoader,QDeclarativeFontLoader); - QML_REGISTER_TYPE(Qt,4,6,ListElement,QDeclarativeListElement); - QML_REGISTER_TYPE(Qt,4,6,NumberAnimation,QDeclarativeNumberAnimation); - QML_REGISTER_TYPE(Qt,4,6,Package,QDeclarativePackage); - QML_REGISTER_TYPE(Qt,4,6,ParallelAnimation,QDeclarativeParallelAnimation); - QML_REGISTER_TYPE(Qt,4,6,ParentAction,QDeclarativeParentAction); - QML_REGISTER_TYPE(Qt,4,6,ParentAnimation,QDeclarativeParentAnimation); - QML_REGISTER_TYPE(Qt,4,6,ParentChange,QDeclarativeParentChange); - QML_REGISTER_TYPE(Qt,4,6,PauseAnimation,QDeclarativePauseAnimation); - QML_REGISTER_TYPE(Qt,4,6,PropertyAction,QDeclarativePropertyAction); - QML_REGISTER_TYPE(Qt,4,6,PropertyAnimation,QDeclarativePropertyAnimation); - QML_REGISTER_TYPE(Qt,4,6,RotationAnimation,QDeclarativeRotationAnimation); - QML_REGISTER_TYPE(Qt,4,6,ScriptAction,QDeclarativeScriptAction); - QML_REGISTER_TYPE(Qt,4,6,SequentialAnimation,QDeclarativeSequentialAnimation); - QML_REGISTER_TYPE(Qt,4,6,SpringFollow,QDeclarativeSpringFollow); - QML_REGISTER_TYPE(Qt,4,6,StateChangeScript,QDeclarativeStateChangeScript); - QML_REGISTER_TYPE(Qt,4,6,StateGroup,QDeclarativeStateGroup); - QML_REGISTER_TYPE(Qt,4,6,State,QDeclarativeState); - QML_REGISTER_TYPE(Qt,4,6,SystemPalette,QDeclarativeSystemPalette); - QML_REGISTER_TYPE(Qt,4,6,Timer,QDeclarativeTimer); - QML_REGISTER_TYPE(Qt,4,6,Transition,QDeclarativeTransition); - QML_REGISTER_TYPE(Qt,4,6,Vector3dAnimation,QDeclarativeVector3dAnimation); + qmlRegisterType("Qt",4,6,"AnchorChanges"); + qmlRegisterType("Qt",4,6,"Behavior"); + qmlRegisterType("Qt",4,6,"Binding"); + qmlRegisterType("Qt",4,6,"ColorAnimation"); + qmlRegisterType("Qt",4,6,"Connections"); + qmlRegisterType("Qt",4,6,"EaseFollow"); + qmlRegisterType("Qt",4,6,"FontLoader"); + qmlRegisterType("Qt",4,6,"ListElement"); + qmlRegisterType("Qt",4,6,"NumberAnimation"); + qmlRegisterType("Qt",4,6,"Package"); + qmlRegisterType("Qt",4,6,"ParallelAnimation"); + qmlRegisterType("Qt",4,6,"ParentAction"); + qmlRegisterType("Qt",4,6,"ParentAnimation"); + qmlRegisterType("Qt",4,6,"ParentChange"); + qmlRegisterType("Qt",4,6,"PauseAnimation"); + qmlRegisterType("Qt",4,6,"PropertyAction"); + qmlRegisterType("Qt",4,6,"PropertyAnimation"); + qmlRegisterType("Qt",4,6,"RotationAnimation"); + qmlRegisterType("Qt",4,6,"ScriptAction"); + qmlRegisterType("Qt",4,6,"SequentialAnimation"); + qmlRegisterType("Qt",4,6,"SpringFollow"); + qmlRegisterType("Qt",4,6,"StateChangeScript"); + qmlRegisterType("Qt",4,6,"StateGroup"); + qmlRegisterType("Qt",4,6,"State"); + qmlRegisterType("Qt",4,6,"SystemPalette"); + qmlRegisterType("Qt",4,6,"Timer"); + qmlRegisterType("Qt",4,6,"Transition"); + qmlRegisterType("Qt",4,6,"Vector3dAnimation"); #ifndef QT_NO_XMLPATTERNS - QML_REGISTER_TYPE(Qt,4,6,XmlListModel,QDeclarativeXmlListModel); - QML_REGISTER_TYPE(Qt,4,6,XmlRole,QDeclarativeXmlListModelRole); + qmlRegisterType("Qt",4,6,"XmlListModel"); + qmlRegisterType("Qt",4,6,"XmlRole"); #endif - QML_REGISTER_NOCREATE_TYPE(QDeclarativeAnchors); - QML_REGISTER_NOCREATE_TYPE(QDeclarativeAbstractAnimation); - QML_REGISTER_NOCREATE_TYPE(QDeclarativeStateOperation); + qmlRegisterType(); + qmlRegisterType(); + qmlRegisterType(); - QML_REGISTER_CUSTOM_TYPE(Qt, 4,6, ListModel, QDeclarativeListModel, QDeclarativeListModelParser); - QML_REGISTER_CUSTOM_TYPE(Qt, 4,6, PropertyChanges, QDeclarativePropertyChanges, QDeclarativePropertyChangesParser); - QML_REGISTER_CUSTOM_TYPE(Qt, 4,6, Connections, QDeclarativeConnections, QDeclarativeConnectionsParser); + qmlRegisterCustomType("Qt", 4,6, "ListModel", "QDeclarativeListModel", + new QDeclarativeListModelParser); + qmlRegisterCustomType("Qt", 4, 6, "PropertyChanges", "QDeclarativePropertyChanges", + new QDeclarativePropertyChangesParser); + qmlRegisterCustomType("Qt", 4, 6, "Connections", "QDeclarativeConnections", + new QDeclarativeConnectionsParser); } diff --git a/src/imports/webkit/plugin.cpp b/src/imports/webkit/plugin.cpp index 799fe9e..e3d73ec 100644 --- a/src/imports/webkit/plugin.cpp +++ b/src/imports/webkit/plugin.cpp @@ -54,7 +54,7 @@ public: virtual void registerTypes(const char *uri) { Q_ASSERT(QLatin1String(uri) == QLatin1String("org.webkit")); - QML_REGISTER_NOCREATE_TYPE(QDeclarativeWebSettings); + qmlRegisterType(); qmlRegisterType(uri,1,0,"WebView"); } }; diff --git a/src/imports/widgets/widgets.cpp b/src/imports/widgets/widgets.cpp index ec21cc4..bc18e8a 100644 --- a/src/imports/widgets/widgets.cpp +++ b/src/imports/widgets/widgets.cpp @@ -118,15 +118,15 @@ public: { Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.widgets")); - QML_REGISTER_INTERFACE(QGraphicsLayoutItem); - QML_REGISTER_INTERFACE(QGraphicsLayout); + qmlRegisterInterface("QGraphicsLayoutItem"); + qmlRegisterInterface("QGraphicsLayout"); qmlRegisterType(uri,4,6,"QGraphicsLinearLayoutStretchItem"); qmlRegisterType(uri,4,6,"QGraphicsLinearLayout"); qmlRegisterType(uri,4,6,"QGraphicsGridLayout"); qmlRegisterExtendedType(uri,4,6,"QGraphicsView"); qmlRegisterExtendedType(uri,4,6,"QGraphicsScene"); qmlRegisterExtendedType(uri,4,6,"QGraphicsWidget"); - QML_REGISTER_INTERFACE(QGraphicsItem); + qmlRegisterInterface("QGraphicsItem"); } }; diff --git a/tools/qml/qdeclarativefolderlistmodel.cpp b/tools/qml/qdeclarativefolderlistmodel.cpp index 58bf59b..d36033d 100644 --- a/tools/qml/qdeclarativefolderlistmodel.cpp +++ b/tools/qml/qdeclarativefolderlistmodel.cpp @@ -413,7 +413,7 @@ void QDeclarativeFolderListModel::setShowOnlyReadable(bool on) void QDeclarativeFolderListModel::registerTypes() { - QML_REGISTER_TYPE(Qt,4,6,FolderListModel,QDeclarativeFolderListModel); + qmlRegisterType("Qt",4,6,"FolderListModel"); } QT_END_NAMESPACE diff --git a/tools/qml/qfxtester.cpp b/tools/qml/qfxtester.cpp index 638a3c9..28bbf5e 100644 --- a/tools/qml/qfxtester.cpp +++ b/tools/qml/qfxtester.cpp @@ -372,10 +372,10 @@ void QDeclarativeTester::updateCurrentTime(int msec) void QDeclarativeTester::registerTypes() { - QML_REGISTER_TYPE(Qt.VisualTest, 4,6, VisualTest, QDeclarativeVisualTest); - QML_REGISTER_TYPE(Qt.VisualTest, 4,6, Frame, QDeclarativeVisualTestFrame); - QML_REGISTER_TYPE(Qt.VisualTest, 4,6, Mouse, QDeclarativeVisualTestMouse); - QML_REGISTER_TYPE(Qt.VisualTest, 4,6, Key, QDeclarativeVisualTestKey); + qmlRegisterType("Qt.VisualTest", 4,6, "VisualTest"); + qmlRegisterType("Qt.VisualTest", 4,6, "Frame"); + qmlRegisterType("Qt.VisualTest", 4,6, "Mouse"); + qmlRegisterType("Qt.VisualTest", 4,6, "Key"); } QT_END_NAMESPACE diff --git a/tools/qml/qmlruntime.cpp b/tools/qml/qmlruntime.cpp index 7da3f5a..f12ec6f 100644 --- a/tools/qml/qmlruntime.cpp +++ b/tools/qml/qmlruntime.cpp @@ -1460,7 +1460,7 @@ void QDeclarativeViewer::setUseNativeFileBrowser(bool use) void QDeclarativeViewer::registerTypes() { - QML_REGISTER_TYPE(QDeclarativeViewer, 1, 0, Screen, Screen); + qmlRegisterType("QDeclarativeViewer", 1, 0, "Screen"); } QT_END_NAMESPACE -- cgit v0.12 From 1c76ce32af211250935db7af8fa6f6e3e8afd01c Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 11 Mar 2010 09:40:31 +1000 Subject: Comment out unused method. --- src/declarative/qml/qdeclarativepropertycache.cpp | 3 ++- src/declarative/qml/qdeclarativepropertycache_p.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/declarative/qml/qdeclarativepropertycache.cpp b/src/declarative/qml/qdeclarativepropertycache.cpp index cbb67e1..2c39d97 100644 --- a/src/declarative/qml/qdeclarativepropertycache.cpp +++ b/src/declarative/qml/qdeclarativepropertycache.cpp @@ -419,9 +419,10 @@ QDeclarativePropertyCache::Data *QDeclarativePropertyCache::property(QDeclarativ return rv; } - +/* QDeclarativePropertyCache::Data QDeclarativePropertyCache::property(const QMetaObject *, const char *) { } +*/ QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativepropertycache_p.h b/src/declarative/qml/qdeclarativepropertycache_p.h index db93de3..9117658 100644 --- a/src/declarative/qml/qdeclarativepropertycache_p.h +++ b/src/declarative/qml/qdeclarativepropertycache_p.h @@ -137,7 +137,7 @@ public: inline QDeclarativeEngine *qmlEngine() const; static Data *property(QDeclarativeEngine *, QObject *, const QScriptDeclarativeClass::Identifier &, Data &); static Data *property(QDeclarativeEngine *, QObject *, const QString &, Data &); - static Data property(const QMetaObject *, const char *); +// static Data property(const QMetaObject *, const char *); protected: virtual void clear(); -- cgit v0.12 From dd7230279bf22fe34f04aa7d216b6d2fb60db720 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 11 Mar 2010 10:19:53 +1000 Subject: Remove more accidentally submitted code --- src/declarative/qml/qdeclarativepropertycache.cpp | 4 ---- src/declarative/qml/qdeclarativepropertycache_p.h | 1 - 2 files changed, 5 deletions(-) diff --git a/src/declarative/qml/qdeclarativepropertycache.cpp b/src/declarative/qml/qdeclarativepropertycache.cpp index cbb67e1..fea59e5 100644 --- a/src/declarative/qml/qdeclarativepropertycache.cpp +++ b/src/declarative/qml/qdeclarativepropertycache.cpp @@ -420,8 +420,4 @@ QDeclarativePropertyCache::Data *QDeclarativePropertyCache::property(QDeclarativ return rv; } -QDeclarativePropertyCache::Data QDeclarativePropertyCache::property(const QMetaObject *, const char *) -{ -} - QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativepropertycache_p.h b/src/declarative/qml/qdeclarativepropertycache_p.h index 79ddf8d..bfbeff4 100644 --- a/src/declarative/qml/qdeclarativepropertycache_p.h +++ b/src/declarative/qml/qdeclarativepropertycache_p.h @@ -137,7 +137,6 @@ public: inline QDeclarativeEngine *qmlEngine() const; static Data *property(QDeclarativeEngine *, QObject *, const QScriptDeclarativeClass::Identifier &, Data &); static Data *property(QDeclarativeEngine *, QObject *, const QString &, Data &); - static Data property(const QMetaObject *, const char *); protected: virtual void clear(); -- cgit v0.12 From b6d9979d7703ffb413f6b2d9fe5eb9b8d6b76b11 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Thu, 11 Mar 2010 09:57:00 +1000 Subject: Add AnchorAnimation for animating AnchorChanges. Task-number: QT-2825 --- doc/src/declarative/elements.qdoc | 1 + src/declarative/util/qdeclarativeanimation.cpp | 95 ++++++ src/declarative/util/qdeclarativeanimation_p.h | 21 ++ src/declarative/util/qdeclarativeanimation_p_p.h | 13 + src/declarative/util/qdeclarativestate.cpp | 62 ++-- src/declarative/util/qdeclarativestate_p.h | 8 +- .../util/qdeclarativestateoperations.cpp | 244 ++++++++++---- .../util/qdeclarativestateoperations_p.h | 9 +- .../util/qdeclarativetransitionmanager.cpp | 26 +- src/declarative/util/qdeclarativeutilmodule.cpp | 1 + .../animation/parentAnimation/parentAnimation.qml | 2 +- .../visual/animation/reanchor/data/reanchor.0.png | Bin 622 -> 637 bytes .../visual/animation/reanchor/data/reanchor.1.png | Bin 626 -> 642 bytes .../visual/animation/reanchor/data/reanchor.2.png | Bin 622 -> 637 bytes .../visual/animation/reanchor/data/reanchor.3.png | Bin 622 -> 637 bytes .../visual/animation/reanchor/data/reanchor.4.png | Bin 632 -> 647 bytes .../visual/animation/reanchor/data/reanchor.5.png | Bin 622 -> 637 bytes .../visual/animation/reanchor/data/reanchor.6.png | Bin 622 -> 637 bytes .../visual/animation/reanchor/data/reanchor.7.png | Bin 622 -> 637 bytes .../visual/animation/reanchor/data/reanchor.8.png | Bin 634 -> 642 bytes .../visual/animation/reanchor/data/reanchor.qml | 366 ++++++++++----------- .../visual/animation/reanchor/reanchor.qml | 2 +- 22 files changed, 545 insertions(+), 305 deletions(-) diff --git a/doc/src/declarative/elements.qdoc b/doc/src/declarative/elements.qdoc index 67aadcf..0d7fe3b 100644 --- a/doc/src/declarative/elements.qdoc +++ b/doc/src/declarative/elements.qdoc @@ -76,6 +76,7 @@ The following table lists the QML elements provided by the Qt Declarative module \o \l ParallelAnimation \o \l PauseAnimation \o \l ParentAnimation +\o \l AnchorAnimation \o \l PropertyAction \o \l ParentAction \o \l ScriptAction diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index 20449d7..170b455 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -2743,4 +2743,99 @@ QAbstractAnimation *QDeclarativeParentAnimation::qtAnimation() return d->topLevelGroup; } +/*! + \qmlclass AnchorAnimation QDeclarativeAnchorAnimation + \since 4.7 + \inherits Animation + \brief The AnchorAnimation element allows you to animate anchor changes. + + AnchorAnimation will animated any changes specified by a state's AnchorChanges. + In the following snippet we animate the addition of a right anchor to our item. + \qml + Item { + id: myItem + width: 100 + } + ... + State { + AnchorChanges { + target: myItem + anchors.right: container.right + } + } + ... + Transition { + //smoothly reanchor myItem and move into new position + AnchorAnimation {} + } + \endqml + + \sa AnchorChanges +*/ + +QDeclarativeAnchorAnimation::QDeclarativeAnchorAnimation(QObject *parent) +: QDeclarativeAbstractAnimation(*(new QDeclarativeAnchorAnimationPrivate), parent) +{ + Q_D(QDeclarativeAnchorAnimation); + d->va = new QDeclarativeBulkValueAnimator; + QDeclarative_setParent_noEvent(d->va, this); +} + +QDeclarativeAnchorAnimation::~QDeclarativeAnchorAnimation() +{ +} + +QAbstractAnimation *QDeclarativeAnchorAnimation::qtAnimation() +{ + Q_D(QDeclarativeAnchorAnimation); + return d->va; +} + +/*! + \qmlproperty list AnchorAnimation::targets + The items to reanchor. + + If no targets are specified all AnchorChanges will be + animated by the AnchorAnimation. +*/ +QDeclarativeListProperty QDeclarativeAnchorAnimation::targets() +{ + Q_D(QDeclarativeAnchorAnimation); + return QDeclarativeListProperty(this, d->targets); +} + +void QDeclarativeAnchorAnimation::transition(QDeclarativeStateActions &actions, + QDeclarativeProperties &modified, + TransitionDirection direction) +{ + Q_D(QDeclarativeAnchorAnimation); + PropertyUpdater *data = new PropertyUpdater; + data->interpolatorType = QMetaType::QReal; + data->interpolator = d->interpolator; + + data->reverse = direction == Backward ? true : false; + data->fromSourced = false; + data->fromDefined = false; + + for (int ii = 0; ii < actions.count(); ++ii) { + QDeclarativeAction &action = actions[ii]; + if (action.event && action.event->typeName() == QLatin1String("AnchorChanges") + && (d->targets.isEmpty() || d->targets.contains(static_cast(action.event)->object()))) { + data->actions << static_cast(action.event)->additionalActions(); + } + } + + if (data->actions.count()) { + if (!d->rangeIsSet) { + d->va->setStartValue(qreal(0)); + d->va->setEndValue(qreal(1)); + d->rangeIsSet = true; + } + d->va->setAnimValue(data, QAbstractAnimation::DeleteWhenStopped); + d->va->setFromSourcedValue(&data->fromSourced); + } else { + delete data; + } +} + QT_END_NAMESPACE diff --git a/src/declarative/util/qdeclarativeanimation_p.h b/src/declarative/util/qdeclarativeanimation_p.h index af48309..eb339f6 100644 --- a/src/declarative/util/qdeclarativeanimation_p.h +++ b/src/declarative/util/qdeclarativeanimation_p.h @@ -480,6 +480,26 @@ protected: virtual QAbstractAnimation *qtAnimation(); }; +class QDeclarativeAnchorAnimationPrivate; +class QDeclarativeAnchorAnimation : public QDeclarativeAbstractAnimation +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QDeclarativeAnchorAnimation) + Q_PROPERTY(QDeclarativeListProperty targets READ targets) + +public: + QDeclarativeAnchorAnimation(QObject *parent=0); + virtual ~QDeclarativeAnchorAnimation(); + + QDeclarativeListProperty targets(); + +protected: + virtual void transition(QDeclarativeStateActions &actions, + QDeclarativeProperties &modified, + TransitionDirection direction); + virtual QAbstractAnimation *qtAnimation(); +}; + QT_END_NAMESPACE QML_DECLARE_TYPE(QDeclarativeAbstractAnimation) @@ -495,6 +515,7 @@ QML_DECLARE_TYPE(QDeclarativeParallelAnimation) QML_DECLARE_TYPE(QDeclarativeVector3dAnimation) QML_DECLARE_TYPE(QDeclarativeRotationAnimation) QML_DECLARE_TYPE(QDeclarativeParentAnimation) +QML_DECLARE_TYPE(QDeclarativeAnchorAnimation) QT_END_HEADER diff --git a/src/declarative/util/qdeclarativeanimation_p_p.h b/src/declarative/util/qdeclarativeanimation_p_p.h index ae82a90..0460312 100644 --- a/src/declarative/util/qdeclarativeanimation_p_p.h +++ b/src/declarative/util/qdeclarativeanimation_p_p.h @@ -393,6 +393,19 @@ public: QPointF computeTransformOrigin(QDeclarativeItem::TransformOrigin origin, qreal width, qreal height) const; }; +class QDeclarativeAnchorAnimationPrivate : public QDeclarativeAbstractAnimationPrivate +{ + Q_DECLARE_PUBLIC(QDeclarativeAnchorAnimation) +public: + QDeclarativeAnchorAnimationPrivate() : rangeIsSet(false), va(0), + interpolator(QVariantAnimationPrivate::getInterpolator(QMetaType::QReal)) {} + + bool rangeIsSet; + QDeclarativeBulkValueAnimator *va; + QVariantAnimation::Interpolator interpolator; + QList targets; +}; + QT_END_NAMESPACE #endif // QDECLARATIVEANIMATION_P_H diff --git a/src/declarative/util/qdeclarativestate.cpp b/src/declarative/util/qdeclarativestate.cpp index 1d70d33..802ff1c 100644 --- a/src/declarative/util/qdeclarativestate.cpp +++ b/src/declarative/util/qdeclarativestate.cpp @@ -96,21 +96,12 @@ void QDeclarativeActionEvent::reverse() { } -QList QDeclarativeActionEvent::extraActions() -{ - return QList(); -} - bool QDeclarativeActionEvent::changesBindings() { return false; } -void QDeclarativeActionEvent::clearForwardBindings() -{ -} - -void QDeclarativeActionEvent::clearReverseBindings() +void QDeclarativeActionEvent::clearBindings() { } @@ -368,47 +359,60 @@ void QDeclarativeState::apply(QDeclarativeStateGroup *group, QDeclarativeTransit for (int ii = 0; ii < applyList.count(); ++ii) { QDeclarativeAction &action = applyList[ii]; - bool found = false; - - int jj; if (action.event) { if (!action.event->isReversable()) continue; - for (jj = 0; jj < d->revertList.count(); ++jj) { + bool found = false; + for (int jj = 0; jj < d->revertList.count(); ++jj) { QDeclarativeActionEvent *event = d->revertList.at(jj).event; if (event && event->typeName() == action.event->typeName()) { if (action.event->override(event)) { found = true; + + if (action.event != d->revertList.at(jj).event) { + action.event->copyOriginals(d->revertList.at(jj).event); + + QDeclarativeSimpleAction r(action); + additionalReverts << r; + d->revertList.removeAt(jj); + } else if (action.event->isRewindable()) //###why needed? + action.event->saveCurrentValues(); + break; } } } - if (!found || action.event != d->revertList.at(jj).event) + if (!found) { action.event->saveOriginals(); - else if (action.event->isRewindable()) - action.event->saveCurrentValues(); + // Only need to revert the applyList action if the previous + // state doesn't have a higher priority revert already + QDeclarativeSimpleAction r(action); + additionalReverts << r; + } } else { + bool found = false; action.fromBinding = QDeclarativePropertyPrivate::binding(action.property); - for (jj = 0; jj < d->revertList.count(); ++jj) { + for (int jj = 0; jj < d->revertList.count(); ++jj) { if (d->revertList.at(jj).property == action.property) { found = true; + if (d->revertList.at(jj).binding != action.fromBinding) { + action.deleteFromBinding(); + } break; } } - } - if (!found) { - if (!action.restore) { - action.deleteFromBinding(); - } else { - // Only need to revert the applyList action if the previous - // state doesn't have a higher priority revert already - QDeclarativeSimpleAction r(action); - additionalReverts << r; + if (!found) { + if (!action.restore) { + action.deleteFromBinding(); + } else { + // Only need to revert the applyList action if the previous + // state doesn't have a higher priority revert already + QDeclarativeSimpleAction r(action); + additionalReverts << r; + } } - } else if (d->revertList.at(jj).binding != action.fromBinding) { - action.deleteFromBinding(); } } diff --git a/src/declarative/util/qdeclarativestate_p.h b/src/declarative/util/qdeclarativestate_p.h index 0c6e7a3..ee2b7e8 100644 --- a/src/declarative/util/qdeclarativestate_p.h +++ b/src/declarative/util/qdeclarativestate_p.h @@ -92,17 +92,15 @@ public: virtual bool isReversable(); virtual void reverse(); virtual void saveOriginals() {} + virtual void copyOriginals(QDeclarativeActionEvent *) {} virtual bool isRewindable() { return isReversable(); } virtual void rewind() {} virtual void saveCurrentValues() {} - - //virtual bool hasExtraActions(); - virtual QList extraActions(); + virtual void saveTargetValues() {} virtual bool changesBindings(); - virtual void clearForwardBindings(); - virtual void clearReverseBindings(); + virtual void clearBindings(); virtual bool override(QDeclarativeActionEvent*other); }; diff --git a/src/declarative/util/qdeclarativestateoperations.cpp b/src/declarative/util/qdeclarativestateoperations.cpp index f13c691..6f5bb66 100644 --- a/src/declarative/util/qdeclarativestateoperations.cpp +++ b/src/declarative/util/qdeclarativestateoperations.cpp @@ -403,6 +403,17 @@ void QDeclarativeParentChange::saveOriginals() d->origStackBefore = d->rewindStackBefore; } +void QDeclarativeParentChange::copyOriginals(QDeclarativeActionEvent *other) +{ + Q_D(QDeclarativeParentChange); + QDeclarativeParentChange *pc = static_cast(other); + + d->origParent = pc->d_func()->rewindParent; + d->origStackBefore = pc->d_func()->rewindStackBefore; + + saveCurrentValues(); +} + void QDeclarativeParentChange::execute() { Q_D(QDeclarativeParentChange); @@ -568,11 +579,10 @@ QString QDeclarativeStateChangeScript::typeName() const } \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: + AnchorChanges can be animated using AnchorAnimation. \qml //animate our anchor changes - NumberAnimation { targets: content; properties: "x,y,width,height" } + AnchorAnimation {} \endqml For more information on anchors see \l {anchor-layout}{Anchor Layouts}. @@ -585,10 +595,10 @@ class QDeclarativeAnchorChangesPrivate : public QObjectPrivate public: QDeclarativeAnchorChangesPrivate() : target(0) {} - QString name; QDeclarativeItem *target; QString resetString; QStringList resetList; + QDeclarativeAnchorLine left; QDeclarativeAnchorLine right; QDeclarativeAnchorLine horizontalCenter; @@ -617,6 +627,24 @@ public: qreal fromY; qreal fromWidth; qreal fromHeight; + + qreal toX; + qreal toY; + qreal toWidth; + qreal toHeight; + + qreal rewindX; + qreal rewindY; + qreal rewindWidth; + qreal rewindHeight; + + bool applyOrigLeft; + bool applyOrigRight; + bool applyOrigHCenter; + bool applyOrigTop; + bool applyOrigBottom; + bool applyOrigVCenter; + bool applyOrigBaseline; }; /*! @@ -769,6 +797,38 @@ void QDeclarativeAnchorChanges::execute() if (!d->target) return; + //incorporate any needed "reverts" + if (d->applyOrigLeft) + d->target->anchors()->setLeft(d->origLeft); + if (d->applyOrigRight) + d->target->anchors()->setRight(d->origRight); + if (d->applyOrigHCenter) + d->target->anchors()->setHorizontalCenter(d->origHCenter); + if (d->applyOrigTop) + d->target->anchors()->setTop(d->origTop); + if (d->applyOrigBottom) + d->target->anchors()->setBottom(d->origBottom); + if (d->applyOrigVCenter) + d->target->anchors()->setVerticalCenter(d->origVCenter); + if (d->applyOrigBaseline) + d->target->anchors()->setBaseline(d->origBaseline); + + //reset any anchors that have been specified + if (d->resetList.contains(QLatin1String("left"))) + d->target->anchors()->resetLeft(); + if (d->resetList.contains(QLatin1String("right"))) + d->target->anchors()->resetRight(); + if (d->resetList.contains(QLatin1String("horizontalCenter"))) + d->target->anchors()->resetHorizontalCenter(); + if (d->resetList.contains(QLatin1String("top"))) + d->target->anchors()->resetTop(); + if (d->resetList.contains(QLatin1String("bottom"))) + d->target->anchors()->resetBottom(); + if (d->resetList.contains(QLatin1String("verticalCenter"))) + d->target->anchors()->resetVerticalCenter(); + if (d->resetList.contains(QLatin1String("baseline"))) + d->target->anchors()->resetBaseline(); + //set any anchors that have been specified if (d->left.anchorLine != QDeclarativeAnchorLine::Invalid) d->target->anchors()->setLeft(d->left); @@ -797,6 +857,22 @@ void QDeclarativeAnchorChanges::reverse() if (!d->target) return; + //reset any anchors set by the state + if (d->left.anchorLine != QDeclarativeAnchorLine::Invalid) + d->target->anchors()->resetLeft(); + if (d->right.anchorLine != QDeclarativeAnchorLine::Invalid) + d->target->anchors()->resetRight(); + if (d->horizontalCenter.anchorLine != QDeclarativeAnchorLine::Invalid) + d->target->anchors()->resetHorizontalCenter(); + if (d->top.anchorLine != QDeclarativeAnchorLine::Invalid) + d->target->anchors()->resetTop(); + if (d->bottom.anchorLine != QDeclarativeAnchorLine::Invalid) + d->target->anchors()->resetBottom(); + if (d->verticalCenter.anchorLine != QDeclarativeAnchorLine::Invalid) + d->target->anchors()->resetVerticalCenter(); + if (d->baseline.anchorLine != QDeclarativeAnchorLine::Invalid) + d->target->anchors()->resetBaseline(); + //restore previous anchors if (d->origLeft.anchorLine != QDeclarativeAnchorLine::Invalid) d->target->anchors()->setLeft(d->origLeft); @@ -819,31 +895,33 @@ QString QDeclarativeAnchorChanges::typeName() const return QLatin1String("AnchorChanges"); } -QList QDeclarativeAnchorChanges::extraActions() +QList QDeclarativeAnchorChanges::additionalActions() { Q_D(QDeclarativeAnchorChanges); QList extra; - //### try to be smarter about which ones we add. - // or short-circuit later on if they haven't actually changed. - // we shouldn't set explicit width if there wasn't one before. if (d->target) { QDeclarativeAction a; - a.fromValue = d->fromX; - a.property = QDeclarativeProperty(d->target, QLatin1String("x")); - extra << a; - - a.fromValue = d->fromY; - a.property = QDeclarativeProperty(d->target, QLatin1String("y")); - extra << a; - - a.fromValue = d->fromWidth; - a.property = QDeclarativeProperty(d->target, QLatin1String("width")); - extra << a; - - a.fromValue = d->fromHeight; - a.property = QDeclarativeProperty(d->target, QLatin1String("height")); - extra << a; + if (d->fromX != d->toX) { + a.property = QDeclarativeProperty(d->target, QLatin1String("x")); + a.toValue = d->toX; + extra << a; + } + if (d->fromY != d->toY) { + a.property = QDeclarativeProperty(d->target, QLatin1String("y")); + a.toValue = d->toY; + extra << a; + } + if (d->fromWidth != d->toWidth) { + a.property = QDeclarativeProperty(d->target, QLatin1String("width")); + a.toValue = d->toWidth; + extra << a; + } + if (d->fromHeight != d->toHeight) { + a.property = QDeclarativeProperty(d->target, QLatin1String("height")); + a.toValue = d->toHeight; + extra << a; + } } return extra; @@ -865,10 +943,52 @@ void QDeclarativeAnchorChanges::saveOriginals() d->origVCenter = d->target->anchors()->verticalCenter(); d->origBaseline = d->target->anchors()->baseline(); + d->applyOrigLeft = d->applyOrigRight = d->applyOrigHCenter = d->applyOrigTop + = d->applyOrigBottom = d->applyOrigHCenter = d->applyOrigBaseline = false; + saveCurrentValues(); } -void QDeclarativeAnchorChanges::clearForwardBindings() +void QDeclarativeAnchorChanges::copyOriginals(QDeclarativeActionEvent *other) +{ + Q_D(QDeclarativeAnchorChanges); + QDeclarativeAnchorChanges *ac = static_cast(other); + QDeclarativeAnchorChangesPrivate *acp = ac->d_func(); + + //probably also need to revert some things + d->applyOrigLeft = (acp->left.anchorLine != QDeclarativeAnchorLine::Invalid || + acp->resetList.contains(QLatin1String("left"))); + + d->applyOrigRight = (acp->right.anchorLine != QDeclarativeAnchorLine::Invalid || + acp->resetList.contains(QLatin1String("right"))); + + d->applyOrigHCenter = (acp->horizontalCenter.anchorLine != QDeclarativeAnchorLine::Invalid || + acp->resetList.contains(QLatin1String("horizontalCenter"))); + + d->applyOrigTop = (acp->top.anchorLine != QDeclarativeAnchorLine::Invalid || + acp->resetList.contains(QLatin1String("top"))); + + d->applyOrigBottom = (acp->bottom.anchorLine != QDeclarativeAnchorLine::Invalid || + acp->resetList.contains(QLatin1String("bottom"))); + + d->applyOrigVCenter = (acp->verticalCenter.anchorLine != QDeclarativeAnchorLine::Invalid || + acp->resetList.contains(QLatin1String("verticalCenter"))); + + d->applyOrigBaseline = (acp->baseline.anchorLine != QDeclarativeAnchorLine::Invalid || + acp->resetList.contains(QLatin1String("baseline"))); + + d->origLeft = ac->d_func()->origLeft; + d->origRight = ac->d_func()->origRight; + d->origHCenter = ac->d_func()->origHCenter; + d->origTop = ac->d_func()->origTop; + d->origBottom = ac->d_func()->origBottom; + d->origVCenter = ac->d_func()->origVCenter; + d->origBaseline = ac->d_func()->origBaseline; + + saveCurrentValues(); +} + +void QDeclarativeAnchorChanges::clearBindings() { Q_D(QDeclarativeAnchorChanges); d->fromX = d->target->x(); @@ -876,6 +996,22 @@ void QDeclarativeAnchorChanges::clearForwardBindings() d->fromWidth = d->target->width(); d->fromHeight = d->target->height(); + //reset any anchors with corresponding reverts + if (d->applyOrigLeft) + d->target->anchors()->resetLeft(); + if (d->applyOrigRight) + d->target->anchors()->resetRight(); + if (d->applyOrigHCenter) + d->target->anchors()->resetHorizontalCenter(); + if (d->applyOrigTop) + d->target->anchors()->resetTop(); + if (d->applyOrigBottom) + d->target->anchors()->resetBottom(); + if (d->applyOrigVCenter) + d->target->anchors()->resetVerticalCenter(); + if (d->applyOrigBaseline) + d->target->anchors()->resetBaseline(); + //reset any anchors that have been specified if (d->resetList.contains(QLatin1String("left"))) d->target->anchors()->resetLeft(); @@ -909,47 +1045,6 @@ void QDeclarativeAnchorChanges::clearForwardBindings() d->target->anchors()->resetBaseline(); } -void QDeclarativeAnchorChanges::clearReverseBindings() -{ - Q_D(QDeclarativeAnchorChanges); - d->fromX = d->target->x(); - d->fromY = d->target->y(); - d->fromWidth = d->target->width(); - d->fromHeight = d->target->height(); - - //reset any anchors that were set in the state - if (d->left.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->resetLeft(); - if (d->right.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->resetRight(); - if (d->horizontalCenter.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->resetHorizontalCenter(); - if (d->top.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->resetTop(); - if (d->bottom.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->resetBottom(); - if (d->verticalCenter.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->resetVerticalCenter(); - if (d->baseline.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->resetBaseline(); - - //reset any anchors that were set in the original state - if (d->origLeft.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->resetLeft(); - if (d->origRight.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->resetRight(); - if (d->origHCenter.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->resetHorizontalCenter(); - if (d->origTop.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->resetTop(); - if (d->origBottom.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->resetBottom(); - if (d->origVCenter.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->resetVerticalCenter(); - if (d->origBaseline.anchorLine != QDeclarativeAnchorLine::Invalid) - d->target->anchors()->resetBaseline(); -} - bool QDeclarativeAnchorChanges::override(QDeclarativeActionEvent*other) { if (other->typeName() != QLatin1String("AnchorChanges")) @@ -982,6 +1077,11 @@ void QDeclarativeAnchorChanges::rewind() d->target->anchors()->setVerticalCenter(d->rewindVCenter); if (d->rewindBaseline.anchorLine != QDeclarativeAnchorLine::Invalid) d->target->anchors()->setBaseline(d->rewindBaseline); + + d->target->setX(d->rewindX); + d->target->setY(d->rewindY); + d->target->setWidth(d->rewindWidth); + d->target->setHeight(d->rewindHeight); } void QDeclarativeAnchorChanges::saveCurrentValues() @@ -994,6 +1094,20 @@ void QDeclarativeAnchorChanges::saveCurrentValues() d->rewindBottom = d->target->anchors()->bottom(); d->rewindVCenter = d->target->anchors()->verticalCenter(); d->rewindBaseline = d->target->anchors()->baseline(); + + d->rewindX = d->target->x(); + d->rewindY = d->target->y(); + d->rewindWidth = d->target->width(); + d->rewindHeight = d->target->height(); +} + +void QDeclarativeAnchorChanges::saveTargetValues() +{ + Q_D(QDeclarativeAnchorChanges); + d->toX = d->target->x(); + d->toY = d->target->y(); + d->toWidth = d->target->width(); + d->toHeight = d->target->height(); } #include diff --git a/src/declarative/util/qdeclarativestateoperations_p.h b/src/declarative/util/qdeclarativestateoperations_p.h index dd4248023..66a8717 100644 --- a/src/declarative/util/qdeclarativestateoperations_p.h +++ b/src/declarative/util/qdeclarativestateoperations_p.h @@ -107,6 +107,7 @@ public: virtual ActionList actions(); virtual void saveOriginals(); + virtual void copyOriginals(QDeclarativeActionEvent*); virtual void execute(); virtual bool isReversable(); virtual void reverse(); @@ -196,13 +197,15 @@ public: virtual void reverse(); virtual QString typeName() const; virtual bool override(QDeclarativeActionEvent*other); - virtual QList extraActions(); virtual bool changesBindings(); virtual void saveOriginals(); - virtual void clearForwardBindings(); - virtual void clearReverseBindings(); + virtual void copyOriginals(QDeclarativeActionEvent*); + virtual void clearBindings(); virtual void rewind(); virtual void saveCurrentValues(); + + QList additionalActions(); + virtual void saveTargetValues(); }; QT_END_NAMESPACE diff --git a/src/declarative/util/qdeclarativetransitionmanager.cpp b/src/declarative/util/qdeclarativetransitionmanager.cpp index e1143fa..f07fb23 100644 --- a/src/declarative/util/qdeclarativetransitionmanager.cpp +++ b/src/declarative/util/qdeclarativetransitionmanager.cpp @@ -126,10 +126,7 @@ void QDeclarativeTransitionManager::transition(const QList & QDeclarativePropertyPrivate::setBinding(action.property, 0); // Disable current binding if (action.event && action.event->changesBindings()) { //### assume isReversable()? d->bindingsList << action; - if (action.reverseEvent) - action.event->clearReverseBindings(); - else - action.event->clearForwardBindings(); + action.event->clearBindings(); } } @@ -144,8 +141,6 @@ void QDeclarativeTransitionManager::transition(const QList & if (!d->bindingsList.isEmpty()) { - //### do extra actions here? - // Apply all the property and binding changes for (int ii = 0; ii < applyList.size(); ++ii) { const QDeclarativeAction &action = applyList.at(ii); @@ -158,17 +153,18 @@ void QDeclarativeTransitionManager::transition(const QList & action.event->reverse(); else action.event->execute(); - applyList << action.event->extraActions(); } } // Read all the end values for binding changes for (int ii = 0; ii < applyList.size(); ++ii) { QDeclarativeAction *action = &applyList[ii]; - if (action->event) + if (action->event) { + action->event->saveTargetValues(); continue; + } const QDeclarativeProperty &prop = action->property; - if (action->toBinding || !action->toValue.isValid()) { //### is this always right (used for exta actions) + if (action->toBinding || !action->toValue.isValid()) { action->toValue = prop.read(); } } @@ -177,15 +173,9 @@ void QDeclarativeTransitionManager::transition(const QList & foreach(const QDeclarativeAction &action, applyList) { if (action.event) { if (action.event->isReversable()) { - if (action.reverseEvent) { //reverse the reverse - action.event->clearForwardBindings(); - action.event->rewind(); - action.event->clearReverseBindings(); - } else { - action.event->clearReverseBindings(); - action.event->rewind(); - action.event->clearForwardBindings(); - } + action.event->clearBindings(); + action.event->rewind(); + action.event->clearBindings(); } continue; } diff --git a/src/declarative/util/qdeclarativeutilmodule.cpp b/src/declarative/util/qdeclarativeutilmodule.cpp index 9c3b0aa..4d4678a 100644 --- a/src/declarative/util/qdeclarativeutilmodule.cpp +++ b/src/declarative/util/qdeclarativeutilmodule.cpp @@ -75,6 +75,7 @@ void QDeclarativeUtilModule::defineModule() { + qmlRegisterType("Qt",4,6,"AnchorAnimation"); qmlRegisterType("Qt",4,6,"AnchorChanges"); qmlRegisterType("Qt",4,6,"Behavior"); qmlRegisterType("Qt",4,6,"Binding"); diff --git a/tests/auto/declarative/visual/animation/parentAnimation/parentAnimation.qml b/tests/auto/declarative/visual/animation/parentAnimation/parentAnimation.qml index 1833cf0..5db2cc6 100644 --- a/tests/auto/declarative/visual/animation/parentAnimation/parentAnimation.qml +++ b/tests/auto/declarative/visual/animation/parentAnimation/parentAnimation.qml @@ -10,7 +10,7 @@ Rectangle { width: 100; height: 100 } - MouseRegion { + MouseArea { id: mouser anchors.fill: parent } diff --git a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.0.png b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.0.png index c7bbf38..454f6c1 100644 Binary files a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.0.png and b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.0.png differ diff --git a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.1.png b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.1.png index 612500b..9dde537 100644 Binary files a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.1.png and b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.1.png differ diff --git a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.2.png b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.2.png index c7bbf38..454f6c1 100644 Binary files a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.2.png and b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.2.png differ diff --git a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.3.png b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.3.png index c7bbf38..454f6c1 100644 Binary files a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.3.png and b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.3.png differ diff --git a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.4.png b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.4.png index 1910eb4..043b487 100644 Binary files a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.4.png and b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.4.png differ diff --git a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.5.png b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.5.png index 3b8eebd..79c791d 100644 Binary files a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.5.png and b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.5.png differ diff --git a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.6.png b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.6.png index c7bbf38..454f6c1 100644 Binary files a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.6.png and b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.6.png differ diff --git a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.7.png b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.7.png index c7bbf38..454f6c1 100644 Binary files a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.7.png and b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.7.png differ diff --git a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.8.png b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.8.png index 960be31..a7d6674 100644 Binary files a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.8.png and b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.8.png differ diff --git a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.qml b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.qml index 0f58de5..a130b75 100644 --- a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.qml +++ b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.qml @@ -386,115 +386,115 @@ VisualTest { } Frame { msec: 1472 - hash: "c2d6dd91f3e9cdcacbadcb449c8a9896" + hash: "eb3eeb37ab7b26692cbf100adfaf3772" } Frame { msec: 1488 - hash: "1098ea19aecebd71208e101d522c1981" + hash: "e1a8cdcb1f3ec097a968b3b20964c6e8" } Frame { msec: 1504 - hash: "8cc59c20d796c073038518d2855fb6f0" + hash: "44fc52479251327d0612de17ddb056eb" } Frame { msec: 1520 - hash: "914a89d0cfdc68145024ce2305a5e76e" + hash: "fa7e4a910aa60500575a34852c0c7cb8" } Frame { msec: 1536 - hash: "7a2e3ca2660df24d9a6ec49a7422ebe1" + hash: "66d205a02e35221e7684ab995acc1312" } Frame { msec: 1552 - hash: "b71496d986d5f0aa76b4f1663627f1f7" + hash: "4ebe8dba6d9f3179b610b2298a7484a2" } Frame { msec: 1568 - hash: "41b29a523db919bc0a4e0a9a88bfc873" + hash: "9b2582fccffa34fe389ba427ce47619a" } Frame { msec: 1584 - hash: "97632a0de766b9ffbf71f21eeb0ff9a2" + hash: "e6f15478bda9995f82976b9e16659c8e" } Frame { msec: 1600 - hash: "94cc196e62c150008461ff9996b4cae8" + hash: "f08df0885fff04819ada6c10b25dd489" } Frame { msec: 1616 - hash: "32e96ad2d15fa2386d365ab249ddf4f4" + hash: "0f57c152306747cfa27171f1947ca65d" } Frame { msec: 1632 - hash: "209394314f971b12fbc61ca45010cc62" + hash: "89d9c988abd55063e210b81193c6a8f0" } Frame { msec: 1648 - hash: "b917c2684dda8af00278b34ababdcf5c" + hash: "91e0d0a5d57210c790c2d2399d1f7022" } Frame { msec: 1664 - hash: "92b506860c1c5dc52f87c24c89921b05" + hash: "267874fdc09459b3e854c06d9ae99a54" } Frame { msec: 1680 - hash: "7b7e96113fa9359954be9b3ac87943c3" + hash: "2f58a508f439c40c6f2bd7da1f30deff" } Frame { msec: 1696 - hash: "42bc69db42c5df902038cec414246ec5" + hash: "1451548d9f0002a6c4765cb616ab7f59" } Frame { msec: 1712 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1728 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1744 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1760 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1776 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1792 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1808 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1824 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1840 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1856 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1872 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1888 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1904 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1920 @@ -502,47 +502,47 @@ VisualTest { } Frame { msec: 1936 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1952 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1968 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 1984 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 2000 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 2016 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 2032 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 2048 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 2064 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 2080 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 2096 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Mouse { type: 2 @@ -554,31 +554,31 @@ VisualTest { } Frame { msec: 2112 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 2128 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 2144 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 2160 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 2176 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 2192 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 2208 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Mouse { type: 3 @@ -590,67 +590,67 @@ VisualTest { } Frame { msec: 2224 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 2240 - hash: "2d1aa011f2008a6147ba593e3cf272d7" + hash: "8ceca291e28f52368346f171c2f31664" } Frame { msec: 2256 - hash: "206699ea84ce9fd60c1603b7a48a5134" + hash: "903877286f3ef112e6a661abde5c17bd" } Frame { msec: 2272 - hash: "68eb6df93a2b6db7023f7c3cc71d5b5f" + hash: "cc2d15c96571f9328b929f96849c8f9e" } Frame { msec: 2288 - hash: "5a4cd0620959dde92eeeaaa4dcd13091" + hash: "26e6c03b1b91b725d6e0fe9216a7413e" } Frame { msec: 2304 - hash: "17b763187a777253b25b22f5dd7253ae" + hash: "213e8e9905bea32ddb97d38b75cd19cc" } Frame { msec: 2320 - hash: "1de9dcf4d385266f4482e2d0967d9119" + hash: "17d5726a282d42fcde7796be84606fcd" } Frame { msec: 2336 - hash: "833496add6dbc3103a28a47e453a738b" + hash: "f4629bf9f5837f687ae49008c9d28d02" } Frame { msec: 2352 - hash: "b3bab2e9c56db60cd54e68369e6b790d" + hash: "fbc927cb136d8d29b2578e78c4793e41" } Frame { msec: 2368 - hash: "ee91c6cd909bec401a1a7eebd10b8b02" + hash: "c7099e732490dd2f3205986a7c43a165" } Frame { msec: 2384 - hash: "0ed679ad0ab7bd3544947bccda88647b" + hash: "b3b464a8e67fab05109b49604f1ce705" } Frame { msec: 2400 - hash: "d7dfcdc8a4233821919f1732d8c39712" + hash: "7629b2a77f9f87aa0ef2535aa9b8d390" } Frame { msec: 2416 - hash: "c52829ee689e4c312a9dff8dbd4a79f9" + hash: "6a329c289236782e095cfa6f15409726" } Frame { msec: 2432 - hash: "7962badda0e80a61b67943d3b31f892d" + hash: "1cfbf6f4c292e1520b44d84dd59b93a8" } Frame { msec: 2448 - hash: "fc5f2c24e3d8743ab5b20aaa122bacc2" + hash: "a8d3d838bffb39053eb705aefcb39c46" } Frame { msec: 2464 - hash: "201b9ee6c9ac6208ef812fe2e95020ef" + hash: "a56ad66a949e07e3174a58c80145c85e" } Frame { msec: 2480 @@ -774,123 +774,123 @@ VisualTest { } Frame { msec: 2896 - hash: "c2d6dd91f3e9cdcacbadcb449c8a9896" + hash: "eb3eeb37ab7b26692cbf100adfaf3772" } Frame { msec: 2912 - hash: "1098ea19aecebd71208e101d522c1981" + hash: "e1a8cdcb1f3ec097a968b3b20964c6e8" } Frame { msec: 2928 - hash: "8cc59c20d796c073038518d2855fb6f0" + hash: "44fc52479251327d0612de17ddb056eb" } Frame { msec: 2944 - hash: "914a89d0cfdc68145024ce2305a5e76e" + hash: "fa7e4a910aa60500575a34852c0c7cb8" } Frame { msec: 2960 - hash: "7a2e3ca2660df24d9a6ec49a7422ebe1" + hash: "66d205a02e35221e7684ab995acc1312" } Frame { msec: 2976 - hash: "b71496d986d5f0aa76b4f1663627f1f7" + hash: "4ebe8dba6d9f3179b610b2298a7484a2" } Frame { msec: 2992 - hash: "41b29a523db919bc0a4e0a9a88bfc873" + hash: "9b2582fccffa34fe389ba427ce47619a" } Frame { msec: 3008 - hash: "97632a0de766b9ffbf71f21eeb0ff9a2" + hash: "e6f15478bda9995f82976b9e16659c8e" } Frame { msec: 3024 - hash: "94cc196e62c150008461ff9996b4cae8" + hash: "f08df0885fff04819ada6c10b25dd489" } Frame { msec: 3040 - hash: "32e96ad2d15fa2386d365ab249ddf4f4" + hash: "0f57c152306747cfa27171f1947ca65d" } Frame { msec: 3056 - hash: "209394314f971b12fbc61ca45010cc62" + hash: "89d9c988abd55063e210b81193c6a8f0" } Frame { msec: 3072 - hash: "b917c2684dda8af00278b34ababdcf5c" + hash: "91e0d0a5d57210c790c2d2399d1f7022" } Frame { msec: 3088 - hash: "92b506860c1c5dc52f87c24c89921b05" + hash: "267874fdc09459b3e854c06d9ae99a54" } Frame { msec: 3104 - hash: "7b7e96113fa9359954be9b3ac87943c3" + hash: "2f58a508f439c40c6f2bd7da1f30deff" } Frame { msec: 3120 - hash: "42bc69db42c5df902038cec414246ec5" + hash: "1451548d9f0002a6c4765cb616ab7f59" } Frame { msec: 3136 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3152 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3168 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3184 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3200 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3216 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3232 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3248 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3264 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3280 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3296 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3312 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3328 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3344 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3360 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Mouse { type: 2 @@ -902,31 +902,31 @@ VisualTest { } Frame { msec: 3376 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3392 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3408 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3424 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3440 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3456 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3472 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Mouse { type: 3 @@ -938,67 +938,67 @@ VisualTest { } Frame { msec: 3488 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 3504 - hash: "2d1aa011f2008a6147ba593e3cf272d7" + hash: "8ceca291e28f52368346f171c2f31664" } Frame { msec: 3520 - hash: "206699ea84ce9fd60c1603b7a48a5134" + hash: "903877286f3ef112e6a661abde5c17bd" } Frame { msec: 3536 - hash: "68eb6df93a2b6db7023f7c3cc71d5b5f" + hash: "cc2d15c96571f9328b929f96849c8f9e" } Frame { msec: 3552 - hash: "5a4cd0620959dde92eeeaaa4dcd13091" + hash: "26e6c03b1b91b725d6e0fe9216a7413e" } Frame { msec: 3568 - hash: "17b763187a777253b25b22f5dd7253ae" + hash: "213e8e9905bea32ddb97d38b75cd19cc" } Frame { msec: 3584 - hash: "1de9dcf4d385266f4482e2d0967d9119" + hash: "17d5726a282d42fcde7796be84606fcd" } Frame { msec: 3600 - hash: "833496add6dbc3103a28a47e453a738b" + hash: "f4629bf9f5837f687ae49008c9d28d02" } Frame { msec: 3616 - hash: "b3bab2e9c56db60cd54e68369e6b790d" + hash: "fbc927cb136d8d29b2578e78c4793e41" } Frame { msec: 3632 - hash: "ee91c6cd909bec401a1a7eebd10b8b02" + hash: "c7099e732490dd2f3205986a7c43a165" } Frame { msec: 3648 - hash: "0ed679ad0ab7bd3544947bccda88647b" + hash: "b3b464a8e67fab05109b49604f1ce705" } Frame { msec: 3664 - hash: "d7dfcdc8a4233821919f1732d8c39712" + hash: "7629b2a77f9f87aa0ef2535aa9b8d390" } Frame { msec: 3680 - hash: "c52829ee689e4c312a9dff8dbd4a79f9" + hash: "6a329c289236782e095cfa6f15409726" } Frame { msec: 3696 - hash: "7962badda0e80a61b67943d3b31f892d" + hash: "1cfbf6f4c292e1520b44d84dd59b93a8" } Frame { msec: 3712 - hash: "fc5f2c24e3d8743ab5b20aaa122bacc2" + hash: "a8d3d838bffb39053eb705aefcb39c46" } Frame { msec: 3728 - hash: "201b9ee6c9ac6208ef812fe2e95020ef" + hash: "a56ad66a949e07e3174a58c80145c85e" } Frame { msec: 3744 @@ -2038,183 +2038,183 @@ VisualTest { } Frame { msec: 7696 - hash: "c2d6dd91f3e9cdcacbadcb449c8a9896" + hash: "eb3eeb37ab7b26692cbf100adfaf3772" } Frame { msec: 7712 - hash: "1098ea19aecebd71208e101d522c1981" + hash: "e1a8cdcb1f3ec097a968b3b20964c6e8" } Frame { msec: 7728 - hash: "8cc59c20d796c073038518d2855fb6f0" + hash: "44fc52479251327d0612de17ddb056eb" } Frame { msec: 7744 - hash: "914a89d0cfdc68145024ce2305a5e76e" + hash: "fa7e4a910aa60500575a34852c0c7cb8" } Frame { msec: 7760 - hash: "7a2e3ca2660df24d9a6ec49a7422ebe1" + hash: "66d205a02e35221e7684ab995acc1312" } Frame { msec: 7776 - hash: "b71496d986d5f0aa76b4f1663627f1f7" + hash: "4ebe8dba6d9f3179b610b2298a7484a2" } Frame { msec: 7792 - hash: "41b29a523db919bc0a4e0a9a88bfc873" + hash: "9b2582fccffa34fe389ba427ce47619a" } Frame { msec: 7808 - hash: "97632a0de766b9ffbf71f21eeb0ff9a2" + hash: "e6f15478bda9995f82976b9e16659c8e" } Frame { msec: 7824 - hash: "94cc196e62c150008461ff9996b4cae8" + hash: "f08df0885fff04819ada6c10b25dd489" } Frame { msec: 7840 - hash: "32e96ad2d15fa2386d365ab249ddf4f4" + hash: "0f57c152306747cfa27171f1947ca65d" } Frame { msec: 7856 - hash: "209394314f971b12fbc61ca45010cc62" + hash: "89d9c988abd55063e210b81193c6a8f0" } Frame { msec: 7872 - hash: "b917c2684dda8af00278b34ababdcf5c" + hash: "91e0d0a5d57210c790c2d2399d1f7022" } Frame { msec: 7888 - hash: "92b506860c1c5dc52f87c24c89921b05" + hash: "267874fdc09459b3e854c06d9ae99a54" } Frame { msec: 7904 - hash: "7b7e96113fa9359954be9b3ac87943c3" + hash: "2f58a508f439c40c6f2bd7da1f30deff" } Frame { msec: 7920 - hash: "42bc69db42c5df902038cec414246ec5" + hash: "1451548d9f0002a6c4765cb616ab7f59" } Frame { msec: 7936 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 7952 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 7968 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 7984 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8000 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8016 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8032 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8048 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8064 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8080 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8096 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8112 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8128 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8144 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8160 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8176 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8192 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8208 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8224 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8240 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8256 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8272 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8288 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8304 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8320 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8336 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8352 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8368 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8384 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8400 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Mouse { type: 2 @@ -2226,31 +2226,31 @@ VisualTest { } Frame { msec: 8416 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8432 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8448 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8464 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8480 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8496 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8512 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Mouse { type: 3 @@ -2262,31 +2262,31 @@ VisualTest { } Frame { msec: 8528 - hash: "7eb4027421fd6aa7d668a704e40a6e61" + hash: "ad3837dcf3e69274ac2918d796974f29" } Frame { msec: 8544 - hash: "b4f30663a9b21e42375645e970f57d0b" + hash: "49a6ed64f80094b41348eda19fa5a55e" } Frame { msec: 8560 - hash: "6c12dbf4af8801573515b61123d4b1d7" + hash: "3ee42fb431d7824c1cd6ddf95af91d10" } Frame { msec: 8576 - hash: "facc61397c734bb4409d5664dc059a14" + hash: "d807890cc0670eda9fac267769366771" } Frame { msec: 8592 - hash: "897e15e37276454d11fac6a528e967a6" + hash: "50cb68de9ca0c3a8db1df58d7cbb0d21" } Frame { msec: 8608 - hash: "cf8173519f1e042c227ff61c62308640" + hash: "0af06233156b3a469ce9e7d80a5767c0" } Frame { msec: 8624 - hash: "d0fcda14ea4bcfebf04ccf99e292ac6a" + hash: "9b2c77f004e480fd485e092c08feaf81" } Frame { msec: 8640 @@ -2294,35 +2294,35 @@ VisualTest { } Frame { msec: 8656 - hash: "74b4ababa97def538f5340e88a4419a4" + hash: "6ed9b6118a0dc81c22af9fee108b7432" } Frame { msec: 8672 - hash: "b96b5b64505b1814ddd42a52569d7fd9" + hash: "4d3aa8219edffe6fda316482821d4a64" } Frame { msec: 8688 - hash: "0e3e07aad030b2075c4bc61b02ebe49e" + hash: "ea8a7104840254ac2706ca2635b8a95f" } Frame { msec: 8704 - hash: "c5eebc652c58e3a44d5ed481100ef242" + hash: "a8569ef3287da9699809a2ad107b87b1" } Frame { msec: 8720 - hash: "d4a74185304c126739af728ddda40e0c" + hash: "91d09653dbced4ecb3d711737cb89ca1" } Frame { msec: 8736 - hash: "448572d3c1060b8311952429a7f9430d" + hash: "d5391f3b40f2dfada0336d889d438d69" } Frame { msec: 8752 - hash: "00f64c09657a8afd6caa186efb6ad860" + hash: "27cd9690607f97cc84c2a0a4455feccb" } Frame { msec: 8768 - hash: "2a360e6feaaf303e9ee63145085796e6" + hash: "f885588779a5de5d7d47f48bf9a2a6ee" } Frame { msec: 8784 @@ -2419,7 +2419,7 @@ VisualTest { Key { type: 6 key: 16777249 - modifiers: 67108864 + modifiers: 0 text: "" autorep: false count: 1 diff --git a/tests/auto/declarative/visual/animation/reanchor/reanchor.qml b/tests/auto/declarative/visual/animation/reanchor/reanchor.qml index d80631f..e41a254 100644 --- a/tests/auto/declarative/visual/animation/reanchor/reanchor.qml +++ b/tests/auto/declarative/visual/animation/reanchor/reanchor.qml @@ -52,7 +52,7 @@ Rectangle { }] transitions: Transition { - NumberAnimation { properties: "x,y,width,height" } + AnchorAnimation { } } MouseArea { -- cgit v0.12 From 09dc1b3386eb60d7d9f2d644fe114c1daa595049 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 11 Mar 2010 13:05:01 +1000 Subject: Compile fix after e5922ab126f3532483b18720ce893d6be826d50e --- .../declarative/qdeclarativeecmascript/testtypes.cpp | 12 ++++++------ .../declarative/qdeclarativelanguage/testtypes.cpp | 18 +++++++++--------- .../qdeclarativelanguage/tst_qdeclarativelanguage.cpp | 12 ++++++------ .../tst_qdeclarativelistreference.cpp | 2 +- .../qdeclarativemetatype/tst_qdeclarativemetatype.cpp | 8 ++++---- .../qdeclarativeproperty/tst_qdeclarativeproperty.cpp | 6 +++--- .../qdeclarativestates/tst_qdeclarativestates.cpp | 2 +- .../declarative/qdeclarativevaluetypes/testtypes.cpp | 6 +++--- 8 files changed, 33 insertions(+), 33 deletions(-) diff --git a/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp b/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp index 6a04704..ce505f3 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp @@ -74,12 +74,12 @@ private: void registerTypes() { - QML_REGISTER_TYPE(Qt.test, 1,0, MyQmlObject,MyQmlObject); - QML_REGISTER_TYPE(Qt.test, 1,0, MyDeferredObject,MyDeferredObject); - QML_REGISTER_TYPE(Qt.test, 1,0, MyQmlContainer,MyQmlContainer); - QML_REGISTER_EXTENDED_TYPE(Qt.test, 1,0, MyBaseExtendedObject,MyBaseExtendedObject,BaseExtensionObject); - QML_REGISTER_EXTENDED_TYPE(Qt.test, 1,0, MyExtendedObject,MyExtendedObject,ExtensionObject); - QML_REGISTER_TYPE(Qt.test, 1,0, MyTypeObject, MyTypeObject); + qmlRegisterType("Qt.test", 1,0, "MyQmlObject"); + qmlRegisterType("Qt.test", 1,0, "MyDeferredObject"); + qmlRegisterType("Qt.test", 1,0, "MyQmlContainer"); + qmlRegisterExtendedType("Qt.test", 1,0, "MyBaseExtendedObject"); + qmlRegisterExtendedType("Qt.test", 1,0, "MyExtendedObject"); + qmlRegisterType("Qt.test", 1,0, "MyTypeObject"); } #include "testtypes.moc" diff --git a/tests/auto/declarative/qdeclarativelanguage/testtypes.cpp b/tests/auto/declarative/qdeclarativelanguage/testtypes.cpp index 9ffe28a..6efe755 100644 --- a/tests/auto/declarative/qdeclarativelanguage/testtypes.cpp +++ b/tests/auto/declarative/qdeclarativelanguage/testtypes.cpp @@ -42,15 +42,15 @@ void registerTypes() { - QML_REGISTER_INTERFACE(MyInterface); - QML_REGISTER_TYPE(Test,1,0,MyQmlObject,MyQmlObject); - QML_REGISTER_TYPE(Test,1,0,MyTypeObject,MyTypeObject); - QML_REGISTER_TYPE(Test,1,0,MyContainer,MyContainer); - QML_REGISTER_TYPE(Test,1,0,MyPropertyValueSource,MyPropertyValueSource); - QML_REGISTER_TYPE(Test,1,0,MyDotPropertyObject,MyDotPropertyObject); - QML_REGISTER_TYPE(Test,1,0,MyNamespacedType,MyNamespace::MyNamespacedType); - QML_REGISTER_TYPE(Test,1,0,MySecondNamespacedType,MyNamespace::MySecondNamespacedType); - QML_REGISTER_NOCREATE_TYPE(MyGroupedObject); + qmlRegisterInterface("MyInterface"); + qmlRegisterType("Test",1,0,"MyQmlObject"); + qmlRegisterType("Test",1,0,"MyTypeObject"); + qmlRegisterType("Test",1,0,"MyContainer"); + qmlRegisterType("Test",1,0,"MyPropertyValueSource"); + qmlRegisterType("Test",1,0,"MyDotPropertyObject"); + qmlRegisterType("Test",1,0,"MyNamespacedType"); + qmlRegisterType("Test",1,0,"MySecondNamespacedType"); + qmlRegisterType(); } QVariant myCustomVariantTypeConverter(const QString &data) diff --git a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp index 083c551..6b564d4 100644 --- a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp +++ b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp @@ -1418,12 +1418,12 @@ void tst_qdeclarativelanguage::initTestCase() { registerTypes(); - QML_REGISTER_TYPE(com.nokia.Test, 0, 0, TestTP, TestType); - QML_REGISTER_TYPE(com.nokia.Test, 1, 0, Test, TestType); - QML_REGISTER_TYPE(com.nokia.Test, 1, 5, Test, TestType); - QML_REGISTER_TYPE(com.nokia.Test, 1, 8, Test, TestType2); - QML_REGISTER_TYPE(com.nokia.Test, 1, 9, OldTest, TestType); - QML_REGISTER_TYPE(com.nokia.Test, 1, 12, Test, TestType2); + qmlRegisterType("com.nokia.Test", 0, 0, "TestTP"); + qmlRegisterType("com.nokia.Test", 1, 0, "Test"); + qmlRegisterType("com.nokia.Test", 1, 5, "Test"); + qmlRegisterType("com.nokia.Test", 1, 8, "Test"); + qmlRegisterType("com.nokia.Test", 1, 9, "OldTest"); + qmlRegisterType("com.nokia.Test", 1, 12, "Test"); // Create locale-specific file // For POSIX, this will just be data/I18nType.qml, since POSIX is 7-bit diff --git a/tests/auto/declarative/qdeclarativelistreference/tst_qdeclarativelistreference.cpp b/tests/auto/declarative/qdeclarativelistreference/tst_qdeclarativelistreference.cpp index 1b7af19..f3c72d1 100644 --- a/tests/auto/declarative/qdeclarativelistreference/tst_qdeclarativelistreference.cpp +++ b/tests/auto/declarative/qdeclarativelistreference/tst_qdeclarativelistreference.cpp @@ -106,7 +106,7 @@ QML_DECLARE_TYPE(TestType); void tst_qdeclarativelistreference::initTestCase() { - QML_REGISTER_NOCREATE_TYPE(TestType); + qmlRegisterType(); } void tst_qdeclarativelistreference::qmllistreference() diff --git a/tests/auto/declarative/qdeclarativemetatype/tst_qdeclarativemetatype.cpp b/tests/auto/declarative/qdeclarativemetatype/tst_qdeclarativemetatype.cpp index 818f108..279a9b7 100644 --- a/tests/auto/declarative/qdeclarativemetatype/tst_qdeclarativemetatype.cpp +++ b/tests/auto/declarative/qdeclarativemetatype/tst_qdeclarativemetatype.cpp @@ -132,10 +132,10 @@ QML_DECLARE_TYPE(ValueInterceptorTestType); void tst_qdeclarativemetatype::initTestCase() { - QML_REGISTER_TYPE(Test, 1, 0, TestType, TestType); - QML_REGISTER_TYPE(Test, 1, 0, ParserStatusTestType, ParserStatusTestType); - QML_REGISTER_TYPE(Test, 1, 0, ValueSourceTestType, ValueSourceTestType); - QML_REGISTER_TYPE(Test, 1, 0, ValueInterceptorTestType, ValueInterceptorTestType); + qmlRegisterType("Test", 1, 0, "TestType"); + qmlRegisterType("Test", 1, 0, "ParserStatusTestType"); + qmlRegisterType("Test", 1, 0, "ValueSourceTestType"); + qmlRegisterType("Test", 1, 0, "ValueInterceptorTestType"); } void tst_qdeclarativemetatype::copy() diff --git a/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp b/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp index 9b8a643..76c5403 100644 --- a/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp +++ b/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp @@ -1348,9 +1348,9 @@ void tst_qdeclarativeproperty::copy() void tst_qdeclarativeproperty::initTestCase() { - QML_REGISTER_TYPE(Test,1,0,MyQmlObject,MyQmlObject); - QML_REGISTER_TYPE(Test,1,0,PropertyObject,PropertyObject); - QML_REGISTER_TYPE(Test,1,0,MyContainer,MyContainer); + qmlRegisterType("Test",1,0,"MyQmlObject"); + qmlRegisterType("Test",1,0,"PropertyObject"); + qmlRegisterType("Test",1,0,"MyContainer"); } diff --git a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp index 8d3ca7a..eb0e2bd 100644 --- a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp +++ b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp @@ -110,7 +110,7 @@ private slots: void tst_qdeclarativestates::initTestCase() { - QML_REGISTER_TYPE(Qt.test, 1, 0, MyRectangle,MyRect); + qmlRegisterType("Qt.test", 1, 0, "MyRectangle"); } QByteArray tst_qdeclarativestates::fullDataPath(const QString &path) diff --git a/tests/auto/declarative/qdeclarativevaluetypes/testtypes.cpp b/tests/auto/declarative/qdeclarativevaluetypes/testtypes.cpp index aa8bd6e..e30a319 100644 --- a/tests/auto/declarative/qdeclarativevaluetypes/testtypes.cpp +++ b/tests/auto/declarative/qdeclarativevaluetypes/testtypes.cpp @@ -42,7 +42,7 @@ void registerTypes() { - QML_REGISTER_TYPE(Test, 1, 0, MyTypeObject, MyTypeObject); - QML_REGISTER_TYPE(Test, 1, 0, MyConstantValueSource, MyConstantValueSource); - QML_REGISTER_TYPE(Test, 1, 0, MyOffsetValueInterceptor, MyOffsetValueInterceptor); + qmlRegisterType("Test", 1, 0, "MyTypeObject"); + qmlRegisterType("Test", 1, 0, "MyConstantValueSource"); + qmlRegisterType("Test", 1, 0, "MyOffsetValueInterceptor"); } -- cgit v0.12 From f42c8faec825126d335e3c5a63c2e034476865e0 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 11 Mar 2010 15:18:33 +1000 Subject: Add a positioning 'mode' to positionViewAtIndex() Provides more control over where and how the view is positioned. --- examples/declarative/colorbrowser/colorbrowser.qml | 4 +- src/declarative/QmlChanges.txt | 1 + .../graphicsitems/qdeclarativegridview.cpp | 71 ++++++++++++++++------ .../graphicsitems/qdeclarativegridview_p.h | 5 +- .../graphicsitems/qdeclarativelistview.cpp | 70 ++++++++++++++++----- .../graphicsitems/qdeclarativelistview_p.h | 5 +- .../tst_qdeclarativegridview.cpp | 49 +++++++++++++-- .../tst_qdeclarativelistview.cpp | 49 +++++++++++++-- 8 files changed, 209 insertions(+), 45 deletions(-) diff --git a/examples/declarative/colorbrowser/colorbrowser.qml b/examples/declarative/colorbrowser/colorbrowser.qml index 421ae07..d4c21e7 100644 --- a/examples/declarative/colorbrowser/colorbrowser.qml +++ b/examples/declarative/colorbrowser/colorbrowser.qml @@ -16,7 +16,7 @@ Rectangle { GridView { id: gridView; model: visualModel.parts.grid; width: mainWindow.width; height: mainWindow.height cellWidth: 160; cellHeight: 160; interactive: false - onCurrentIndexChanged: listView.positionViewAtIndex(currentIndex) + onCurrentIndexChanged: listView.positionViewAtIndex(currentIndex, ListView.Contain) } } @@ -25,7 +25,7 @@ Rectangle { ListView { id: listView; model: visualModel.parts.list; orientation: Qt.Horizontal width: mainWindow.width; height: mainWindow.height; interactive: false - onCurrentIndexChanged: gridView.positionViewAtIndex(currentIndex) + onCurrentIndexChanged: gridView.positionViewAtIndex(currentIndex, GridView.Contain) highlightRangeMode: ListView.StrictlyEnforceRange; snapMode: ListView.SnapOneItem } } diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt index 591fb3d..f83dd58 100644 --- a/src/declarative/QmlChanges.txt +++ b/src/declarative/QmlChanges.txt @@ -1,6 +1,7 @@ ============================================================================= The changes below are pre Qt 4.7.0 alpha +ListView, GridView::positionViewAtIndex() gained a 'mode' parameter Flickable: renamed viewportWidth -> contentWidth Flickable: renamed viewportHeight -> contentHeight Flickable: renamed viewportX -> contentX diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index e66bcf6..b1391f9 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -1666,47 +1666,84 @@ void QDeclarativeGridView::moveCurrentIndexRight() } /*! - \qmlmethod GridView::positionViewAtIndex(int index) + \qmlmethod GridView::positionViewAtIndex(int index, PositionMode mode) + + Positions the view such that the \a index is at the position specified by + \a mode: + + \list + \o Beginning - position item at the top (or left for TopToBottom flow) of the view. + \o Center- position item in the center of the view. + \o End - position item at bottom (or right for horizontal orientation) of the view. + \o Visible - if any part of the item is visible then take no action, otherwise + bring the item into view. + \o Contain - ensure the entire item is visible. If the item is larger than + the view the item is positioned at the top (or left for TopToBottom flow) of the view. + \endlist - Positions the view such that the \a index is at the top (or left for horizontal orientation) of the view. If positioning the view at the index would cause empty space to be displayed at - the end of the view, the view will be positioned at the end. + the beginning or end of the view, the view will be positioned at the boundary. It is not recommended to use contentX or contentY to position the view at a particular index. This is unreliable since removing items from the start - of the list does not cause all other items to be repositioned. + of the view does not cause all other items to be repositioned. The correct way to bring an item into view is with positionViewAtIndex. */ -void QDeclarativeGridView::positionViewAtIndex(int index) +void QDeclarativeGridView::positionViewAtIndex(int index, int mode) { Q_D(QDeclarativeGridView); if (!d->isValid() || index < 0 || index >= d->model->count()) return; + if (mode < Beginning || mode > Contain) + return; - qreal maxExtent = d->flow == QDeclarativeGridView::LeftToRight ? -maxYExtent() : -maxXExtent(); + qreal pos = d->position(); FxGridItem *item = d->visibleItem(index); - if (item) { - // Already created - just move to top of view - int pos = qMin(item->rowPos(), maxExtent); - d->setPosition(pos); - } else { - int pos = d->rowPosAt(index); + if (!item) { + int itemPos = d->rowPosAt(index); // save the currently visible items in case any of them end up visible again QList oldVisible = d->visibleItems; d->visibleItems.clear(); d->visibleIndex = index - index % d->columns; - d->setPosition(pos); - // setPosition() will cause refill. Adjust if we have moved beyond range - if (d->position() > maxExtent) - d->setPosition(maxExtent); + d->setPosition(itemPos); // now release the reference to all the old visible items. for (int i = 0; i < oldVisible.count(); ++i) d->releaseItem(oldVisible.at(i)); + item = d->visibleItem(index); + } + if (item) { + qreal itemPos = item->rowPos(); + switch (mode) { + case Beginning: + pos = itemPos; + break; + case Center: + pos = itemPos - (d->size() - d->rowSize())/2; + break; + case End: + pos = itemPos - d->size() + d->rowSize(); + break; + case Visible: + if (itemPos > pos + d->size()) + pos = itemPos - d->size() + d->rowSize(); + else if (item->endRowPos() < pos) + pos = itemPos; + break; + case Contain: + if (item->endRowPos() > pos + d->size()) + pos = itemPos - d->size() + d->rowSize(); + if (itemPos < pos) + pos = itemPos; + } + qreal maxExtent = d->flow == QDeclarativeGridView::LeftToRight ? -maxYExtent() : -maxXExtent(); + pos = qMin(pos, maxExtent); + qreal minExtent = d->flow == QDeclarativeGridView::LeftToRight ? -minYExtent() : -minXExtent(); + pos = qMax(pos, minExtent); + d->setPosition(pos); } d->fixupPosition(); } - void QDeclarativeGridView::componentComplete() { Q_D(QDeclarativeGridView); diff --git a/src/declarative/graphicsitems/qdeclarativegridview_p.h b/src/declarative/graphicsitems/qdeclarativegridview_p.h index 8e253e5..f14ec14 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview_p.h +++ b/src/declarative/graphicsitems/qdeclarativegridview_p.h @@ -137,6 +137,9 @@ public: SnapMode snapMode() const; void setSnapMode(SnapMode mode); + enum PositionMode { Beginning, Center, End, Visible, Contain }; + Q_ENUMS(PositionMode) + static QDeclarativeGridViewAttached *qmlAttachedProperties(QObject *); public Q_SLOTS: @@ -144,7 +147,7 @@ public Q_SLOTS: void moveCurrentIndexDown(); void moveCurrentIndexLeft(); void moveCurrentIndexRight(); - void positionViewAtIndex(int index); + void positionViewAtIndex(int index, int mode); Q_SIGNALS: void countChanged(); diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index b988e6e..9e6a67a 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -2180,11 +2180,23 @@ void QDeclarativeListView::decrementCurrentIndex() } /*! - \qmlmethod ListView::positionViewAtIndex(int index) + \qmlmethod ListView::positionViewAtIndex(int index, PositionMode mode) + + Positions the view such that the \a index is at the position specified by + \a mode: + + \list + \o Beginning - position item at the top (or left for horizontal orientation) of the view. + \o Center- position item in the center of the view. + \o End - position item at bottom (or right for horizontal orientation) of the view. + \o Visible - if any part of the item is visible then take no action, otherwise + bring the item into view. + \o Contain - ensure the entire item is visible. If the item is larger than + the view the item is positioned at the top (or left for horizontal orientation) of the view. + \endlist - Positions the view such that the \a index is at the top (or left for horizontal orientation) of the view. If positioning the view at the index would cause empty space to be displayed at - the end of the view, the view will be positioned at the end. + the beginning or end of the view, the view will be positioned at the boundary. It is not recommended to use contentX or contentY to position the view at a particular index. This is unreliable since removing items from the start @@ -2192,32 +2204,58 @@ void QDeclarativeListView::decrementCurrentIndex() the actual start of the view can vary based on the size of the delegates. The correct way to bring an item into view is with positionViewAtIndex. */ -void QDeclarativeListView::positionViewAtIndex(int index) +void QDeclarativeListView::positionViewAtIndex(int index, int mode) { Q_D(QDeclarativeListView); if (!d->isValid() || index < 0 || index >= d->model->count()) return; + if (mode < Beginning || mode > Contain) + return; - qreal maxExtent = d->orient == QDeclarativeListView::Vertical ? -maxYExtent() : -maxXExtent(); + qreal pos = d->position(); FxListItem *item = d->visibleItem(index); - if (item) { - // Already created - just move to top of view - int pos = qMin(item->position(), maxExtent); - d->setPosition(pos); - } else { - int pos = d->positionAt(index); + if (!item) { + int itemPos = d->positionAt(index); // save the currently visible items in case any of them end up visible again QList oldVisible = d->visibleItems; d->visibleItems.clear(); - d->visiblePos = pos; + d->visiblePos = itemPos; d->visibleIndex = index; - d->setPosition(pos); - // setPosition() will cause refill. Adjust if we have moved beyond range. - if (d->position() > maxExtent) - d->setPosition(maxExtent); + d->setPosition(itemPos); // now release the reference to all the old visible items. for (int i = 0; i < oldVisible.count(); ++i) d->releaseItem(oldVisible.at(i)); + item = d->visibleItem(index); + } + if (item) { + const qreal itemPos = item->position(); + switch (mode) { + case Beginning: + pos = itemPos; + break; + case Center: + pos = itemPos - (d->size() - item->size())/2; + break; + case End: + pos = itemPos - d->size() + item->size(); + break; + case Visible: + if (itemPos > pos + d->size()) + pos = itemPos - d->size() + item->size(); + else if (item->endPosition() < pos) + pos = itemPos; + break; + case Contain: + if (item->endPosition() > pos + d->size()) + pos = itemPos - d->size() + item->size(); + if (itemPos < pos) + pos = itemPos; + } + qreal maxExtent = d->orient == QDeclarativeListView::Vertical ? -maxYExtent() : -maxXExtent(); + pos = qMin(pos, maxExtent); + qreal minExtent = d->orient == QDeclarativeListView::Vertical ? -minYExtent() : -minXExtent(); + pos = qMax(pos, minExtent); + d->setPosition(pos); } d->fixupPosition(); } diff --git a/src/declarative/graphicsitems/qdeclarativelistview_p.h b/src/declarative/graphicsitems/qdeclarativelistview_p.h index 1bf9652..0c2677c 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview_p.h +++ b/src/declarative/graphicsitems/qdeclarativelistview_p.h @@ -191,10 +191,13 @@ public: static QDeclarativeListViewAttached *qmlAttachedProperties(QObject *); + enum PositionMode { Beginning, Center, End, Visible, Contain }; + Q_ENUMS(PositionMode) + public Q_SLOTS: void incrementCurrentIndex(); void decrementCurrentIndex(); - void positionViewAtIndex(int index); + void positionViewAtIndex(int index, int mode); Q_SIGNALS: void countChanged(); diff --git a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp index aaf8291..385d6f5 100644 --- a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp +++ b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp @@ -949,7 +949,7 @@ void tst_QDeclarativeGridView::positionViewAtIndex() } // Position on a currently visible item - gridview->positionViewAtIndex(4); + gridview->positionViewAtIndex(4, QDeclarativeGridView::Beginning); QCOMPARE(gridview->contentY(), 60.); // Confirm items positioned correctly @@ -963,7 +963,7 @@ void tst_QDeclarativeGridView::positionViewAtIndex() } // Position on an item beyond the visible items - gridview->positionViewAtIndex(21); + gridview->positionViewAtIndex(21, QDeclarativeGridView::Beginning); QCOMPARE(gridview->contentY(), 420.); // Confirm items positioned correctly @@ -977,7 +977,7 @@ void tst_QDeclarativeGridView::positionViewAtIndex() } // Position on an item that would leave empty space if positioned at the top - gridview->positionViewAtIndex(31); + gridview->positionViewAtIndex(31, QDeclarativeGridView::Beginning); QCOMPARE(gridview->contentY(), 520.); // Confirm items positioned correctly @@ -991,7 +991,7 @@ void tst_QDeclarativeGridView::positionViewAtIndex() } // Position at the beginning again - gridview->positionViewAtIndex(0); + gridview->positionViewAtIndex(0, QDeclarativeGridView::Beginning); QCOMPARE(gridview->contentY(), 0.); // Confirm items positioned correctly @@ -1004,6 +1004,47 @@ void tst_QDeclarativeGridView::positionViewAtIndex() QCOMPARE(item->y(), (i/3)*60.); } + // Position at End + gridview->positionViewAtIndex(30, QDeclarativeGridView::End); + QCOMPARE(gridview->contentY(), 340.); + + // Position in Center + gridview->positionViewAtIndex(15, QDeclarativeGridView::Center); + QCOMPARE(gridview->contentY(), 170.); + + // Ensure at least partially visible + gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible); + QCOMPARE(gridview->contentY(), 170.); + + gridview->setContentY(302); + gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible); + QCOMPARE(gridview->contentY(), 302.); + + gridview->setContentY(360); + gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible); + QCOMPARE(gridview->contentY(), 300.); + + gridview->setContentY(60); + gridview->positionViewAtIndex(20, QDeclarativeGridView::Visible); + QCOMPARE(gridview->contentY(), 60.); + + gridview->setContentY(20); + gridview->positionViewAtIndex(20, QDeclarativeGridView::Visible); + QCOMPARE(gridview->contentY(), 100.); + + // Ensure completely visible + gridview->setContentY(120); + gridview->positionViewAtIndex(20, QDeclarativeGridView::Contain); + QCOMPARE(gridview->contentY(), 120.); + + gridview->setContentY(302); + gridview->positionViewAtIndex(15, QDeclarativeGridView::Contain); + QCOMPARE(gridview->contentY(), 300.); + + gridview->setContentY(60); + gridview->positionViewAtIndex(20, QDeclarativeGridView::Contain); + QCOMPARE(gridview->contentY(), 100.); + delete canvas; } diff --git a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp index e5542c2..5b57487 100644 --- a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp +++ b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp @@ -1193,7 +1193,7 @@ void tst_QDeclarativeListView::positionViewAtIndex() } // Position on a currently visible item - listview->positionViewAtIndex(3); + listview->positionViewAtIndex(3, QDeclarativeListView::Beginning); QCOMPARE(listview->contentY(), 60.); // Confirm items positioned correctly @@ -1206,7 +1206,7 @@ void tst_QDeclarativeListView::positionViewAtIndex() } // Position on an item beyond the visible items - listview->positionViewAtIndex(22); + listview->positionViewAtIndex(22, QDeclarativeListView::Beginning); QCOMPARE(listview->contentY(), 440.); // Confirm items positioned correctly @@ -1219,7 +1219,7 @@ void tst_QDeclarativeListView::positionViewAtIndex() } // Position on an item that would leave empty space if positioned at the top - listview->positionViewAtIndex(28); + listview->positionViewAtIndex(28, QDeclarativeListView::Beginning); QCOMPARE(listview->contentY(), 480.); // Confirm items positioned correctly @@ -1232,7 +1232,7 @@ void tst_QDeclarativeListView::positionViewAtIndex() } // Position at the beginning again - listview->positionViewAtIndex(0); + listview->positionViewAtIndex(0, QDeclarativeListView::Beginning); QCOMPARE(listview->contentY(), 0.); // Confirm items positioned correctly @@ -1244,6 +1244,47 @@ void tst_QDeclarativeListView::positionViewAtIndex() QCOMPARE(item->y(), i*20.); } + // Position at End + listview->positionViewAtIndex(20, QDeclarativeListView::End); + QCOMPARE(listview->contentY(), 100.); + + // Position in Center + listview->positionViewAtIndex(15, QDeclarativeListView::Center); + QCOMPARE(listview->contentY(), 150.); + + // Ensure at least partially visible + listview->positionViewAtIndex(15, QDeclarativeListView::Visible); + QCOMPARE(listview->contentY(), 150.); + + listview->setContentY(302); + listview->positionViewAtIndex(15, QDeclarativeListView::Visible); + QCOMPARE(listview->contentY(), 302.); + + listview->setContentY(320); + listview->positionViewAtIndex(15, QDeclarativeListView::Visible); + QCOMPARE(listview->contentY(), 300.); + + listview->setContentY(85); + listview->positionViewAtIndex(20, QDeclarativeListView::Visible); + QCOMPARE(listview->contentY(), 85.); + + listview->setContentY(75); + listview->positionViewAtIndex(20, QDeclarativeListView::Visible); + QCOMPARE(listview->contentY(), 100.); + + // Ensure completely visible + listview->setContentY(120); + listview->positionViewAtIndex(20, QDeclarativeListView::Contain); + QCOMPARE(listview->contentY(), 120.); + + listview->setContentY(302); + listview->positionViewAtIndex(15, QDeclarativeListView::Contain); + QCOMPARE(listview->contentY(), 300.); + + listview->setContentY(85); + listview->positionViewAtIndex(20, QDeclarativeListView::Contain); + QCOMPARE(listview->contentY(), 100.); + delete canvas; } -- cgit v0.12 From fcea69d5136749827439fd6b2b45371034ca9599 Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Thu, 11 Mar 2010 15:26:42 +1000 Subject: Move particles in their own plugin (Qt.labs.particles) Task-number: QT-2846 --- .../minehunt/MinehuntCore/Explosion.qml | 1 + .../samegame/SamegameCore/BoomBlock.qml | 1 + demos/declarative/snake/content/Cookie.qml | 1 + demos/declarative/snake/content/Link.qml | 1 + .../declarative/animations/color-animation.qml | 1 + examples/declarative/dynamic/dynamic.qml | 1 + .../samegame/samegame4/content/BoomBlock.qml | 1 + src/declarative/graphicsitems/graphicsitems.pri | 4 +- .../graphicsitems/qdeclarativeitemsmodule.cpp | 6 - .../graphicsitems/qdeclarativeparticles.cpp | 1317 -------------------- .../graphicsitems/qdeclarativeparticles_p.h | 258 ---- src/imports/imports.pro | 2 +- src/imports/particles/particles.cpp | 69 + src/imports/particles/particles.pro | 21 + src/imports/particles/qdeclarativeparticles.cpp | 1316 +++++++++++++++++++ src/imports/particles/qdeclarativeparticles_p.h | 258 ++++ src/imports/particles/qmldir | 1 + 17 files changed, 1674 insertions(+), 1585 deletions(-) delete mode 100644 src/declarative/graphicsitems/qdeclarativeparticles.cpp delete mode 100644 src/declarative/graphicsitems/qdeclarativeparticles_p.h create mode 100644 src/imports/particles/particles.cpp create mode 100644 src/imports/particles/particles.pro create mode 100644 src/imports/particles/qdeclarativeparticles.cpp create mode 100644 src/imports/particles/qdeclarativeparticles_p.h create mode 100644 src/imports/particles/qmldir diff --git a/demos/declarative/minehunt/MinehuntCore/Explosion.qml b/demos/declarative/minehunt/MinehuntCore/Explosion.qml index e337c46..172fcc0 100644 --- a/demos/declarative/minehunt/MinehuntCore/Explosion.qml +++ b/demos/declarative/minehunt/MinehuntCore/Explosion.qml @@ -1,4 +1,5 @@ import Qt 4.6 +import Qt.labs.particles 1.0 Item { property bool explode : false diff --git a/demos/declarative/samegame/SamegameCore/BoomBlock.qml b/demos/declarative/samegame/SamegameCore/BoomBlock.qml index e48194a..b14531d 100644 --- a/demos/declarative/samegame/SamegameCore/BoomBlock.qml +++ b/demos/declarative/samegame/SamegameCore/BoomBlock.qml @@ -1,4 +1,5 @@ import Qt 4.6 +import Qt.labs.particles 1.0 Item { id:block property bool dying: false diff --git a/demos/declarative/snake/content/Cookie.qml b/demos/declarative/snake/content/Cookie.qml index 0ea95cb..b64987e 100644 --- a/demos/declarative/snake/content/Cookie.qml +++ b/demos/declarative/snake/content/Cookie.qml @@ -1,4 +1,5 @@ import Qt 4.6 +import Qt.labs.particles 1.0 Item { id: root diff --git a/demos/declarative/snake/content/Link.qml b/demos/declarative/snake/content/Link.qml index 31ac4b9..4171247 100644 --- a/demos/declarative/snake/content/Link.qml +++ b/demos/declarative/snake/content/Link.qml @@ -1,4 +1,5 @@ import Qt 4.6 +import Qt.labs.particles 1.0 Item { id:link property bool dying: false diff --git a/examples/declarative/animations/color-animation.qml b/examples/declarative/animations/color-animation.qml index 6740522..025134b 100644 --- a/examples/declarative/animations/color-animation.qml +++ b/examples/declarative/animations/color-animation.qml @@ -1,4 +1,5 @@ import Qt 4.6 +import Qt.labs.particles 1.0 Item { id: window diff --git a/examples/declarative/dynamic/dynamic.qml b/examples/declarative/dynamic/dynamic.qml index 6af3e81..7de4d38 100644 --- a/examples/declarative/dynamic/dynamic.qml +++ b/examples/declarative/dynamic/dynamic.qml @@ -1,4 +1,5 @@ import Qt 4.6 +import Qt.labs.particles 1.0 import "qml" Item { diff --git a/examples/declarative/tutorials/samegame/samegame4/content/BoomBlock.qml b/examples/declarative/tutorials/samegame/samegame4/content/BoomBlock.qml index 9ef455a..a6ef62c 100644 --- a/examples/declarative/tutorials/samegame/samegame4/content/BoomBlock.qml +++ b/examples/declarative/tutorials/samegame/samegame4/content/BoomBlock.qml @@ -1,4 +1,5 @@ import Qt 4.6 +import Qt.labs.particles 1.0 Item { id:block property int type: 0 diff --git a/src/declarative/graphicsitems/graphicsitems.pri b/src/declarative/graphicsitems/graphicsitems.pri index 3ff92b1..d30651b 100644 --- a/src/declarative/graphicsitems/graphicsitems.pri +++ b/src/declarative/graphicsitems/graphicsitems.pri @@ -48,7 +48,6 @@ HEADERS += \ $$PWD/qdeclarativevisualitemmodel_p.h \ $$PWD/qdeclarativelistview_p.h \ $$PWD/qdeclarativegraphicsobjectcontainer_p.h \ - $$PWD/qdeclarativeparticles_p.h \ $$PWD/qdeclarativelayoutitem_p.h \ $$PWD/qdeclarativeitemchangelistener_p.h \ $$PWD/qdeclarativeeffects.cpp @@ -82,5 +81,4 @@ SOURCES += \ $$PWD/qdeclarativevisualitemmodel.cpp \ $$PWD/qdeclarativelistview.cpp \ $$PWD/qdeclarativegraphicsobjectcontainer.cpp \ - $$PWD/qdeclarativeparticles.cpp \ - $$PWD/qdeclarativelayoutitem.cpp \ + $$PWD/qdeclarativelayoutitem.cpp diff --git a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp index 2d05c7c..2ac55a4 100644 --- a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp @@ -65,7 +65,6 @@ #include "qdeclarativelistview_p.h" #include "qdeclarativeloader_p.h" #include "qdeclarativemousearea_p.h" -#include "qdeclarativeparticles_p.h" #include "qdeclarativepath_p.h" #include "qdeclarativepathview_p.h" #include "qdeclarativerectangle_p.h" @@ -108,11 +107,6 @@ void QDeclarativeItemModule::defineModule() qmlRegisterType("Qt",4,6,"Loader"); qmlRegisterType("Qt",4,6,"MouseArea"); qmlRegisterType("Qt",4,6,"Opacity"); - qmlRegisterType("Qt",4,6,"ParticleMotion"); - qmlRegisterType("Qt",4,6,"ParticleMotionGravity"); - qmlRegisterType("Qt",4,6,"ParticleMotionLinear"); - qmlRegisterType("Qt",4,6,"ParticleMotionWander"); - qmlRegisterType("Qt",4,6,"Particles"); qmlRegisterType("Qt",4,6,"Path"); qmlRegisterType("Qt",4,6,"PathAttribute"); qmlRegisterType("Qt",4,6,"PathCubic"); diff --git a/src/declarative/graphicsitems/qdeclarativeparticles.cpp b/src/declarative/graphicsitems/qdeclarativeparticles.cpp deleted file mode 100644 index 593c80a..0000000 --- a/src/declarative/graphicsitems/qdeclarativeparticles.cpp +++ /dev/null @@ -1,1317 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qdeclarativeparticles_p.h" - -#include "qdeclarativeitem_p.h" - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#define M_PI_2 (M_PI / 2.) -#endif -#ifndef INT_MAX -#define INT_MAX 2147483647 -#endif - -QT_BEGIN_NAMESPACE -#define PI_SQR 9.8696044 -// parabolic approximation -inline qreal fastSin(qreal theta) -{ - const qreal b = 4 / M_PI; - const qreal c = -4 / PI_SQR; - - qreal y = b * theta + c * theta * qAbs(theta); - return y; -} - -inline qreal fastCos(qreal theta) -{ - theta += M_PI_2; - if (theta > M_PI) - theta -= 2 * M_PI; - - return fastSin(theta); -} - -class QDeclarativeParticle -{ -public: - QDeclarativeParticle(int time) : lifeSpan(1000), fadeOutAge(800) - , opacity(0), birthTime(time), x_velocity(0), y_velocity(0) - , state(FadeIn), data(0) - { - } - - int lifeSpan; - int fadeOutAge; - qreal x; - qreal y; - qreal opacity; - int birthTime; - qreal x_velocity; - qreal y_velocity; - enum State { FadeIn, Solid, FadeOut }; - State state; - void *data; -}; - -//--------------------------------------------------------------------------- - -/*! - \class QDeclarativeParticleMotion - \ingroup group_effects - \brief The QDeclarativeParticleMotion class is the base class for particle motion. - \internal - - This class causes the particles to remain static. -*/ - -/*! - Constructs a QDeclarativeParticleMotion with parent object \a parent. -*/ -QDeclarativeParticleMotion::QDeclarativeParticleMotion(QObject *parent) : - QObject(parent) -{ -} - -/*! - Move the \a particle to its new position. \a interval is the number of - milliseconds elapsed since it was last moved. -*/ -void QDeclarativeParticleMotion::advance(QDeclarativeParticle &particle, int interval) -{ - Q_UNUSED(particle); - Q_UNUSED(interval); -} - -/*! - The \a particle has just been created. Some motion strategies require - additional state information. This can be allocated by this function. -*/ -void QDeclarativeParticleMotion::created(QDeclarativeParticle &particle) -{ - Q_UNUSED(particle); -} - -/*! - The \a particle is about to be destroyed. Any additional memory - that has been allocated for the particle should be freed. -*/ -void QDeclarativeParticleMotion::destroy(QDeclarativeParticle &particle) -{ - Q_UNUSED(particle); -} - -/*! - \qmlclass ParticleMotionLinear - \since 4.7 - \brief The ParticleMotionLinear object moves particles linearly. - - \sa Particles -*/ - -/*! - \internal - \class QDeclarativeParticleMotionLinear - \ingroup group_effects - \brief The QDeclarativeParticleMotionLinear class moves the particles linearly. -*/ - -void QDeclarativeParticleMotionLinear::advance(QDeclarativeParticle &p, int interval) -{ - p.x += interval * p.x_velocity; - p.y += interval * p.y_velocity; -} - -/*! - \qmlclass ParticleMotionGravity - \since 4.7 - \brief The ParticleMotionGravity object moves particles towards a point. - - \sa Particles -*/ - -/*! - \internal - \class QDeclarativeParticleMotionGravity - \ingroup group_effects - \brief The QDeclarativeParticleMotionGravity class moves the particles towards a point. -*/ - -/*! - \qmlproperty qreal ParticleMotionGravity::xattractor - \qmlproperty qreal ParticleMotionGravity::yattractor - These properties hold the x and y coordinates of the point attracting the particles. -*/ - -/*! - \qmlproperty qreal ParticleMotionGravity::acceleration - This property holds the acceleration to apply to the particles. -*/ - -/*! - \property QDeclarativeParticleMotionGravity::xattractor - \brief the x coordinate of the point attracting the particles. -*/ - -/*! - \property QDeclarativeParticleMotionGravity::yattractor - \brief the y coordinate of the point attracting the particles. -*/ - -/*! - \property QDeclarativeParticleMotionGravity::acceleration - \brief the acceleration to apply to the particles. -*/ - -void QDeclarativeParticleMotionGravity::setXAttractor(qreal x) -{ - if (qFuzzyCompare(x, _xAttr)) - return; - _xAttr = x; - emit xattractorChanged(); -} - -void QDeclarativeParticleMotionGravity::setYAttractor(qreal y) -{ - if (qFuzzyCompare(y, _yAttr)) - return; - _yAttr = y; - emit yattractorChanged(); -} - -void QDeclarativeParticleMotionGravity::setAcceleration(qreal accel) -{ - qreal scaledAccel = accel/1000000.0; - if (qFuzzyCompare(scaledAccel, _accel)) - return; - _accel = scaledAccel; - emit accelerationChanged(); -} - -void QDeclarativeParticleMotionGravity::advance(QDeclarativeParticle &p, int interval) -{ - qreal xdiff = p.x - _xAttr; - qreal ydiff = p.y - _yAttr; - - qreal xcomp = xdiff / (xdiff + ydiff); - qreal ycomp = ydiff / (xdiff + ydiff); - - p.x_velocity += xcomp * _accel * interval; - p.y_velocity += ycomp * _accel * interval; - - p.x += interval * p.x_velocity; - p.y += interval * p.y_velocity; -} - -/*! - \qmlclass ParticleMotionWander - \since 4.7 - \brief The ParticleMotionWander object moves particles in a somewhat random fashion. - - The particles will continue roughly in the original direction, however will randomly - drift to each side. - - The code below produces an effect similar to falling snow. - - \qml -Rectangle { - width: 240 - height: 320 - color: "black" - - Particles { - y: 0 - width: parent.width - height: 30 - source: "star.png" - lifeSpan: 5000 - count: 50 - angle: 70 - angleDeviation: 36 - velocity: 30 - velocityDeviation: 10 - ParticleMotionWander { - xvariance: 30 - pace: 100 - } - } -} - \endqml - - \sa Particles -*/ - -/*! - \internal - \class QDeclarativeParticleMotionWander - \ingroup group_effects - \brief The QDeclarativeParticleMotionWander class moves particles in a somewhat random fashion. - - The particles will continue roughly in the original direction, however will randomly - drift to each side. -*/ - -/*! - \qmlproperty qreal QDeclarativeParticleMotionWander::xvariance - \qmlproperty qreal QDeclarativeParticleMotionWander::yvariance - - These properties set the amount to wander in the x and y directions. -*/ - -/*! - \qmlproperty qreal QDeclarativeParticleMotionWander::pace - This property holds how quickly the paricles will move from side to side. -*/ - -void QDeclarativeParticleMotionWander::advance(QDeclarativeParticle &p, int interval) -{ - if (!particles) - particles = qobject_cast(parent()); - if (particles) { - Data *d = (Data*)p.data; - if (_xvariance != 0.) { - qreal xdiff = p.x_velocity - d->x_targetV; - if ((xdiff > d->x_peak && d->x_var > 0.0) || (xdiff < -d->x_peak && d->x_var < 0.0)) { - d->x_var = -d->x_var; - d->x_peak = _xvariance + _xvariance * qreal(qrand()) / RAND_MAX; - } - p.x_velocity += d->x_var * interval; - } - p.x += interval * p.x_velocity; - - if (_yvariance != 0.) { - qreal ydiff = p.y_velocity - d->y_targetV; - if ((ydiff > d->y_peak && d->y_var > 0.0) || (ydiff < -d->y_peak && d->y_var < 0.0)) { - d->y_var = -d->y_var; - d->y_peak = _yvariance + _yvariance * qreal(qrand()) / RAND_MAX; - } - p.y_velocity += d->y_var * interval; - } - p.y += interval * p.y_velocity; - } -} - -void QDeclarativeParticleMotionWander::created(QDeclarativeParticle &p) -{ - if (!p.data) { - Data *d = new Data; - p.data = (void*)d; - d->x_targetV = p.x_velocity; - d->y_targetV = p.y_velocity; - d->x_peak = _xvariance; - d->y_peak = _yvariance; - d->x_var = _pace * qreal(qrand()) / RAND_MAX / 1000.0; - d->y_var = _pace * qreal(qrand()) / RAND_MAX / 1000.0; - } -} - -void QDeclarativeParticleMotionWander::destroy(QDeclarativeParticle &p) -{ - if (p.data) - delete (Data*)p.data; -} - -void QDeclarativeParticleMotionWander::setXVariance(qreal var) -{ - qreal scaledVar = var / 1000.0; - if (qFuzzyCompare(scaledVar, _xvariance)) - return; - _xvariance = scaledVar; - emit xvarianceChanged(); -} - -void QDeclarativeParticleMotionWander::setYVariance(qreal var) -{ - qreal scaledVar = var / 1000.0; - if (qFuzzyCompare(scaledVar, _yvariance)) - return; - _yvariance = scaledVar; - emit yvarianceChanged(); -} - -void QDeclarativeParticleMotionWander::setPace(qreal pace) -{ - qreal scaledPace = pace / 1000.0; - if (qFuzzyCompare(scaledPace, _pace)) - return; - _pace = scaledPace; - emit paceChanged(); -} - -//--------------------------------------------------------------------------- -class QDeclarativeParticlesPainter : public QDeclarativeItem -{ -public: - QDeclarativeParticlesPainter(QDeclarativeParticlesPrivate *p, QDeclarativeItem* parent) - : QDeclarativeItem(parent), d(p) - { - setFlag(QGraphicsItem::ItemHasNoContents, false); - maxX = minX = maxY = minY = 0; - } - - void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *); - - void updateSize(); - - qreal maxX; - qreal minX; - qreal maxY; - qreal minY; - QDeclarativeParticlesPrivate* d; -}; - -//--------------------------------------------------------------------------- -class QDeclarativeParticlesPrivate : public QDeclarativeItemPrivate -{ - Q_DECLARE_PUBLIC(QDeclarativeParticles) -public: - QDeclarativeParticlesPrivate() - : count(1), emissionRate(-1), emissionVariance(0.5), lifeSpan(1000) - , lifeSpanDev(1000), fadeInDur(200), fadeOutDur(300) - , angle(0), angleDev(0), velocity(0), velocityDev(0), emissionCarry(0.) - , addParticleTime(0), addParticleCount(0), lastAdvTime(0) - , motion(0), pendingPixmapCache(false), clock(this) - { - } - - ~QDeclarativeParticlesPrivate() - { - } - - void init() - { - Q_Q(QDeclarativeParticles); - paintItem = new QDeclarativeParticlesPainter(this, q); - } - - void tick(int time); - void createParticle(int time); - void updateOpacity(QDeclarativeParticle &p, int age); - - QUrl url; - QPixmap image; - int count; - int emissionRate; - qreal emissionVariance; - int lifeSpan; - int lifeSpanDev; - int fadeInDur; - int fadeOutDur; - qreal angle; - qreal angleDev; - qreal velocity; - qreal velocityDev; - qreal emissionCarry; - int addParticleTime; - int addParticleCount; - int lastAdvTime; - QDeclarativeParticleMotion *motion; - QDeclarativeParticlesPainter *paintItem; - - bool pendingPixmapCache; - - QList > bursts;//countLeft, emissionRate pairs - QList particles; - QTickAnimationProxy clock; - -}; - -void QDeclarativeParticlesPrivate::tick(int time) -{ - Q_Q(QDeclarativeParticles); - if (!motion) - motion = new QDeclarativeParticleMotionLinear(q); - - int oldCount = particles.count(); - int removed = 0; - int interval = time - lastAdvTime; - for (int i = 0; i < particles.count(); ) { - QDeclarativeParticle &particle = particles[i]; - int age = time - particle.birthTime; - if (age >= particle.lifeSpan) { - QDeclarativeParticle part = particles.takeAt(i); - motion->destroy(part); - ++removed; - } else { - updateOpacity(particle, age); - motion->advance(particle, interval); - ++i; - } - } - - if(emissionRate == -1)//Otherwise leave emission to the emission rate - while(removed-- && ((count == -1) || particles.count() < count)) - createParticle(time); - - if (!addParticleTime) - addParticleTime = time; - - //Possibly emit new particles - if (((count == -1) || particles.count() < count) && emissionRate - && !(count==-1 && emissionRate==-1)) { - int emissionCount = -1; - if (emissionRate != -1){ - qreal variance = 1.; - if (emissionVariance > 0.){ - variance += (qreal(qrand())/RAND_MAX) * emissionVariance * (qrand()%2?-1.:1.); - } - qreal emission = emissionRate * (qreal(interval)/1000.); - emission = emission * variance + emissionCarry; - double tmpDbl; - emissionCarry = modf(emission, &tmpDbl); - emissionCount = (int)tmpDbl; - emissionCount = qMax(0,emissionCount); - } - while(((count == -1) || particles.count() < count) && - (emissionRate==-1 || emissionCount--)) - createParticle(time); - } - - //Deal with emissions from requested bursts - for(int i=0; i 0.){ - variance += (qreal(qrand())/RAND_MAX) * emissionVariance * (qrand()%2?-1.:1.); - } - qreal workingEmission = bursts[i].second * (qreal(interval)/1000.); - workingEmission *= variance; - emission = (int)workingEmission; - emission = qMax(emission, 0); - } - emission = qMin(emission, bursts[i].first); - bursts[i].first -= emission; - while(emission--) - createParticle(time); - } - for(int i=bursts.size()-1; i>=0; i--) - if(bursts[i].first <= 0) - bursts.removeAt(i); - - lastAdvTime = time; - paintItem->updateSize(); - paintItem->update(); - if (!(oldCount || particles.count()) && (!count || !emissionRate) && bursts.isEmpty()) { - lastAdvTime = 0; - clock.stop(); - } -} - -void QDeclarativeParticlesPrivate::createParticle(int time) -{ -#ifdef Q_ENABLE_PERFORMANCE_LOG - QDeclarativePerfTimer x; -#endif - Q_Q(QDeclarativeParticles); - QDeclarativeParticle p(time); - p.x = q->x() + q->width() * qreal(qrand()) / RAND_MAX - image.width()/2.0; - p.y = q->y() + q->height() * qreal(qrand()) / RAND_MAX - image.height()/2.0; - p.lifeSpan = lifeSpan; - if (lifeSpanDev) - p.lifeSpan += int(lifeSpanDev/2 - lifeSpanDev * qreal(qrand()) / RAND_MAX); - p.fadeOutAge = p.lifeSpan - fadeOutDur; - if (fadeInDur == 0.) { - p.state= QDeclarativeParticle::Solid; - p.opacity = 1.0; - } - qreal a = angle; - if (angleDev) - a += angleDev/2 - angleDev * qreal(qrand()) / RAND_MAX; - if (a > M_PI) - a = a - 2 * M_PI; - qreal v = velocity; - if (velocityDev) - v += velocityDev/2 - velocityDev * qreal(qrand()) / RAND_MAX; - p.x_velocity = v * fastCos(a); - p.y_velocity = v * fastSin(a); - particles.append(p); - motion->created(particles.last()); -} - -void QDeclarativeParticlesPrivate::updateOpacity(QDeclarativeParticle &p, int age) -{ - switch (p.state) { - case QDeclarativeParticle::FadeIn: - if (age <= fadeInDur) { - p.opacity = qreal(age) / fadeInDur; - break; - } else { - p.opacity = 1.0; - p.state = QDeclarativeParticle::Solid; - // Fall through - } - case QDeclarativeParticle::Solid: - if (age <= p.fadeOutAge) { - break; - } else { - p.state = QDeclarativeParticle::FadeOut; - // Fall through - } - case QDeclarativeParticle::FadeOut: - p.opacity = qreal(p.lifeSpan - age) / fadeOutDur; - break; - } -} - -/*! - \qmlclass Particles - \since 4.7 - \brief The Particles object generates and moves particles. - \inherits Item - - This element provides preliminary support for particles in QML, - and may be heavily changed or removed in later versions. - - The particles created by this object cannot be dealt with - directly, they can only be controlled through the parameters of - the Particles object. The particles are all the same pixmap, - specified by the user. - - The particles are painted relative to the parent of the Particles - object. Moving the Particles object will not move the particles - already emitted. - - The below example creates two differently behaving particle - sources. The top one has particles falling from the top like - snow, the lower one has particles expelled up like a fountain. - - \qml -Rectangle { - width: 240 - height: 320 - color: "black" - Particles { - y: 0 - width: parent.width - height: 30 - source: "star.png" - lifeSpan: 5000 - count: 50 - angle: 70 - angleDeviation: 36 - velocity: 30 - velocityDeviation: 10 - ParticleMotionWander { - xvariance: 30 - pace: 100 - } - } - Particles { - y: 300 - x: 120 - width: 1 - height: 1 - source: "star.png" - lifeSpan: 5000 - count: 200 - angle: 270 - angleDeviation: 45 - velocity: 50 - velocityDeviation: 30 - ParticleMotionGravity { - yattractor: 1000 - xattractor: 0 - acceleration: 25 - } - } -} - \endqml - \image particles.gif -*/ - -/*! - \internal - \class QDeclarativeParticles - \ingroup group_effects - \brief The QDeclarativeParticles class generates and moves particles. -*/ - -QDeclarativeParticles::QDeclarativeParticles(QDeclarativeItem *parent) - : QDeclarativeItem(*(new QDeclarativeParticlesPrivate), parent) -{ - Q_D(QDeclarativeParticles); - d->init(); -} - -QDeclarativeParticles::~QDeclarativeParticles() -{ - Q_D(QDeclarativeParticles); - if (d->pendingPixmapCache) - QDeclarativePixmapCache::cancel(d->url, this); -} - -/*! - \qmlproperty string Particles::source - This property holds the URL of the particle image. -*/ - -/*! - \property QDeclarativeParticles::source - \brief the URL of the particle image. -*/ -QUrl QDeclarativeParticles::source() const -{ - Q_D(const QDeclarativeParticles); - return d->url; -} - -void QDeclarativeParticles::imageLoaded() -{ - Q_D(QDeclarativeParticles); - d->pendingPixmapCache = false; - QDeclarativePixmapCache::get(d->url, &d->image); - d->paintItem->updateSize(); - d->paintItem->update(); -} - -void QDeclarativeParticles::setSource(const QUrl &name) -{ - Q_D(QDeclarativeParticles); - - if ((d->url.isEmpty() == name.isEmpty()) && name == d->url) - return; - - if (d->pendingPixmapCache) { - QDeclarativePixmapCache::cancel(d->url, this); - d->pendingPixmapCache = false; - } - if (name.isEmpty()) { - d->url = name; - d->image = QPixmap(); - d->paintItem->updateSize(); - d->paintItem->update(); - } else { - d->url = name; - Q_ASSERT(!name.isRelative()); - QDeclarativePixmapReply::Status status = QDeclarativePixmapCache::get(d->url, &d->image); - if (status != QDeclarativePixmapReply::Ready && status != QDeclarativePixmapReply::Error) { - QDeclarativePixmapReply *reply = QDeclarativePixmapCache::request(qmlEngine(this), d->url); - connect(reply, SIGNAL(finished()), this, SLOT(imageLoaded())); - d->pendingPixmapCache = true; - } else { - //### unify with imageLoaded - d->paintItem->updateSize(); - d->paintItem->update(); - } - } - emit sourceChanged(); -} - -/*! - \qmlproperty int Particles::count - This property holds the maximum number of particles - - The particles element emits particles until it has count active - particles. When this number is reached, new particles are not emitted until - some of the current particles reach the end of their lifespan. - - If count is -1 then there is no maximum number of active particles, and - particles will be constantly emitted at the rate specified by emissionRate. - - The default value for count is 1. - - If both count and emissionRate are set to -1, nothing will be emitted. - -*/ - -/*! - \property QDeclarativeParticles::count - \brief the maximum number of particles -*/ -int QDeclarativeParticles::count() const -{ - Q_D(const QDeclarativeParticles); - return d->count; -} - -void QDeclarativeParticles::setCount(int cnt) -{ - Q_D(QDeclarativeParticles); - if (cnt == d->count) - return; - - int oldCount = d->count; - d->count = cnt; - d->addParticleTime = 0; - d->addParticleCount = d->particles.count(); - if (!oldCount && d->clock.state() != QAbstractAnimation::Running && d->count && d->emissionRate) { - d->clock.start(); - } - d->paintItem->updateSize(); - d->paintItem->update(); - emit countChanged(); -} - - -/*! - \qmlproperty int Particles::emissionRate - This property holds the target number of particles to emit every second. - - The particles element will emit up to emissionRate particles every - second. Fewer particles may be emitted per second if the maximum number of - particles has been reached. - - If emissionRate is set to -1 there is no limit to the number of - particles emitted per second, and particles will be instantly emitted to - reach the maximum number of particles specified by count. - - The default value for emissionRate is -1. - - If both count and emissionRate are set to -1, nothing will be emitted. -*/ - -/*! - \property QDeclarativeParticles::emissionRate - \brief the emission rate of particles -*/ -int QDeclarativeParticles::emissionRate() const -{ - Q_D(const QDeclarativeParticles); - return d->emissionRate; -} -void QDeclarativeParticles::setEmissionRate(int er) -{ - Q_D(QDeclarativeParticles); - if(er == d->emissionRate) - return; - d->emissionRate = er; - if (d->clock.state() != QAbstractAnimation::Running && d->count && d->emissionRate) { - d->clock.start(); - } - emit emissionRateChanged(); -} - -/*! - \qmlproperty qreal Particles::emissionVariance - This property holds how inconsistent the rate of particle emissions are. - It is a number between 0 (no variance) and 1 (some variance). - - The expected number of particles emitted per second is emissionRate. If - emissionVariance is 0 then particles will be emitted consistently throughout - each second to reach that number. If emissionVariance is greater than 0 the - rate of particle emission will vary randomly throughout the second, with the - consequence that the actual number of particles emitted in one second will - vary randomly as well. - - emissionVariance is the maximum deviation from emitting - emissionRate particles per second. An emissionVariance of 0 means you should - get exactly emissionRate particles emitted per second, - and an emissionVariance of 1 means you will get between zero and two times - emissionRate particles per second, but you should get emissionRate particles - per second on average. - - Note that even with an emissionVariance of 0 there may be some variance due - to performance and hardware constraints. - - The default value of emissionVariance is 0.5 -*/ - -/*! - \property QDeclarativeParticles::emissionVariance - \brief how much the particle emission amounts vary per tick -*/ - -qreal QDeclarativeParticles::emissionVariance() const -{ - Q_D(const QDeclarativeParticles); - return d->emissionVariance; -} - -void QDeclarativeParticles::setEmissionVariance(qreal ev) -{ - Q_D(QDeclarativeParticles); - if(d->emissionVariance == ev) - return; - d->emissionVariance = ev; - emit emissionVarianceChanged(); -} - -/*! - \qmlproperty int Particles::lifeSpan - \qmlproperty int Particles::lifeSpanDeviation - - These properties describe the life span of each particle. - - The default lifespan for a particle is 1000ms. - - lifeSpanDeviation randomly varies the lifeSpan up to the specified variation. For - example, the following creates particles whose lifeSpan will vary - from 150ms to 250ms: - - \qml -Particles { - source: "star.png" - lifeSpan: 200 - lifeSpanDeviation: 100 -} - \endqml -*/ - -/*! - \property QDeclarativeParticles::lifeSpan - \brief the life span of each particle. - - Default value is 1000ms. - - \sa QDeclarativeParticles::lifeSpanDeviation -*/ -int QDeclarativeParticles::lifeSpan() const -{ - Q_D(const QDeclarativeParticles); - return d->lifeSpan; -} - -void QDeclarativeParticles::setLifeSpan(int ls) -{ - Q_D(QDeclarativeParticles); - if(d->lifeSpan == ls) - return; - d->lifeSpan = ls; - emit lifeSpanChanged(); -} - -/*! - \property QDeclarativeParticles::lifeSpanDeviation - \brief the maximum possible deviation from the set lifeSpan. - - Randomly varies the lifeSpan up to the specified variation. For - example, the following creates particles whose lifeSpan will vary - from 150ms to 250ms: - -\qml -Particles { - source: "star.png" - lifeSpan: 200 - lifeSpanDeviation: 100 -} -\endqml - - \sa QDeclarativeParticles::lifeSpan -*/ -int QDeclarativeParticles::lifeSpanDeviation() const -{ - Q_D(const QDeclarativeParticles); - return d->lifeSpanDev; -} - -void QDeclarativeParticles::setLifeSpanDeviation(int dev) -{ - Q_D(QDeclarativeParticles); - if(d->lifeSpanDev == dev) - return; - d->lifeSpanDev = dev; - emit lifeSpanDeviationChanged(); -} - -/*! - \qmlproperty int Particles::fadeInDuration - \qmlproperty int Particles::fadeOutDuration - These properties hold the time taken to fade the particles in and out. - - By default fade in is 200ms and fade out is 300ms. -*/ - -/*! - \property QDeclarativeParticles::fadeInDuration - \brief the time taken to fade in the particles. - - Default value is 200ms. -*/ -int QDeclarativeParticles::fadeInDuration() const -{ - Q_D(const QDeclarativeParticles); - return d->fadeInDur; -} - -void QDeclarativeParticles::setFadeInDuration(int dur) -{ - Q_D(QDeclarativeParticles); - if (dur < 0.0 || dur == d->fadeInDur) - return; - d->fadeInDur = dur; - emit fadeInDurationChanged(); -} - -/*! - \property QDeclarativeParticles::fadeOutDuration - \brief the time taken to fade out the particles. - - Default value is 300ms. -*/ -int QDeclarativeParticles::fadeOutDuration() const -{ - Q_D(const QDeclarativeParticles); - return d->fadeOutDur; -} - -void QDeclarativeParticles::setFadeOutDuration(int dur) -{ - Q_D(QDeclarativeParticles); - if (dur < 0.0 || d->fadeOutDur == dur) - return; - d->fadeOutDur = dur; - emit fadeOutDurationChanged(); -} - -/*! - \qmlproperty real Particles::angle - \qmlproperty real Particles::angleDeviation - - These properties control particle direction. - - angleDeviation randomly varies the direction up to the specified variation. For - example, the following creates particles whose initial direction will - vary from 15 degrees to 105 degrees: - - \qml -Particles { - source: "star.png" - angle: 60 - angleDeviation: 90 -} - \endqml -*/ - -/*! - \property QDeclarativeParticles::angle - \brief the initial angle of direction. - - \sa QDeclarativeParticles::angleDeviation -*/ -qreal QDeclarativeParticles::angle() const -{ - Q_D(const QDeclarativeParticles); - return d->angle * 180.0 / M_PI; -} - -void QDeclarativeParticles::setAngle(qreal angle) -{ - Q_D(QDeclarativeParticles); - qreal radAngle = angle * M_PI / 180.0; - if(radAngle == d->angle) - return; - d->angle = radAngle; - emit angleChanged(); -} - -/*! - \property QDeclarativeParticles::angleDeviation - \brief the maximum possible deviation from the set angle. - - Randomly varies the direction up to the specified variation. For - example, the following creates particles whose initial direction will - vary from 15 degrees to 105 degrees: - -\qml -Particles { - source: "star.png" - angle: 60 - angleDeviation: 90 -} -\endqml - - \sa QDeclarativeParticles::angle -*/ -qreal QDeclarativeParticles::angleDeviation() const -{ - Q_D(const QDeclarativeParticles); - return d->angleDev * 180.0 / M_PI; -} - -void QDeclarativeParticles::setAngleDeviation(qreal dev) -{ - Q_D(QDeclarativeParticles); - qreal radDev = dev * M_PI / 180.0; - if(radDev == d->angleDev) - return; - d->angleDev = radDev; - emit angleDeviationChanged(); -} - -/*! - \qmlproperty real Particles::velocity - \qmlproperty real Particles::velocityDeviation - - These properties control the velocity of the particles. - - velocityDeviation randomly varies the velocity up to the specified variation. For - example, the following creates particles whose initial velocity will - vary from 40 to 60. - - \qml -Particles { - source: "star.png" - velocity: 50 - velocityDeviation: 20 -} - \endqml -*/ - -/*! - \property QDeclarativeParticles::velocity - \brief the initial velocity of the particles. - - \sa QDeclarativeParticles::velocityDeviation -*/ -qreal QDeclarativeParticles::velocity() const -{ - Q_D(const QDeclarativeParticles); - return d->velocity * 1000.0; -} - -void QDeclarativeParticles::setVelocity(qreal velocity) -{ - Q_D(QDeclarativeParticles); - qreal realVel = velocity / 1000.0; - if(realVel == d->velocity) - return; - d->velocity = realVel; - emit velocityChanged(); -} - -/*! - \property QDeclarativeParticles::velocityDeviation - \brief the maximum possible deviation from the set velocity. - - Randomly varies the velocity up to the specified variation. For - example, the following creates particles whose initial velocity will - vary from 40 to 60. - -\qml -Particles { - source: "star.png" - velocity: 50 - velocityDeviation: 20 -} -\endqml - - \sa QDeclarativeParticles::velocity -*/ -qreal QDeclarativeParticles::velocityDeviation() const -{ - Q_D(const QDeclarativeParticles); - return d->velocityDev * 1000.0; -} - -void QDeclarativeParticles::setVelocityDeviation(qreal velocity) -{ - Q_D(QDeclarativeParticles); - qreal realDev = velocity / 1000.0; - if(realDev == d->velocityDev) - return; - d->velocityDev = realDev; - emit velocityDeviationChanged(); -} - -/*! - \qmlproperty ParticleMotion Particles::motion - This property sets the type of motion to apply to the particles. - - When a particle is created it will have an initial direction and velocity. - The motion of the particle during its lifeSpan is then influenced by the - motion property. - - Default motion is ParticleMotionLinear. -*/ - -/*! - \property QDeclarativeParticles::motion - \brief sets the type of motion to apply to the particles. - - When a particle is created it will have an initial direction and velocity. - The motion of the particle during its lifeSpan is then influenced by the - motion property. - - Default motion is QDeclarativeParticleMotionLinear. -*/ -QDeclarativeParticleMotion *QDeclarativeParticles::motion() const -{ - Q_D(const QDeclarativeParticles); - return d->motion; -} - -void QDeclarativeParticles::setMotion(QDeclarativeParticleMotion *motion) -{ - Q_D(QDeclarativeParticles); - if (motion == d->motion) - return; - d->motion = motion; - emit motionChanged(); -} - -/*! - \qmlmethod Particles::burst(int count, int emissionRate) - - Initiates a burst of particles. - - This method takes two arguments. The first argument is the number - of particles to emit and the second argument is the emissionRate for the - burst. If the second argument is omitted, it is treated as -1. The burst - of particles has a separate emissionRate and count to the normal emission of - particles. The burst uses the same values as normal emission for all other - properties, including emissionVariance. - - The normal emission of particles will continue during the burst, however - the particles created by the burst count towards the maximum number used by - normal emission. To avoid this behavior, use two Particles elements. - -*/ -void QDeclarativeParticles::burst(int count, int emissionRate) -{ - Q_D(QDeclarativeParticles); - d->bursts << qMakePair(count, emissionRate); - if (d->clock.state() != QAbstractAnimation::Running) - d->clock.start(); -} - -void QDeclarativeParticlesPainter::updateSize() -{ - if (!d->_componentComplete) - return; - - const int parentX = parentItem()->x(); - const int parentY = parentItem()->y(); - for (int i = 0; i < d->particles.count(); ++i) { - const QDeclarativeParticle &particle = d->particles.at(i); - if(particle.x > maxX) - maxX = particle.x; - if(particle.x < minX) - minX = particle.x; - if(particle.y > maxY) - maxY = particle.y; - if(particle.y < minY) - minY = particle.y; - } - - int myWidth = (int)(maxX-minX+0.5)+d->image.width(); - int myX = (int)(minX - parentX); - int myHeight = (int)(maxY-minY+0.5)+d->image.height(); - int myY = (int)(minY - parentY); - setWidth(myWidth); - setHeight(myHeight); - setX(myX); - setY(myY); -} - -void QDeclarativeParticles::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *) -{ - Q_UNUSED(p); - //painting is done by the ParticlesPainter, so it can have the right size -} - -void QDeclarativeParticlesPainter::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *) -{ - if (d->image.isNull() || d->particles.isEmpty()) - return; - - const int myX = x() + parentItem()->x(); - const int myY = y() + parentItem()->y(); - -#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) - QVarLengthArray pixmapData; -#else - QVarLengthArray pixmapData; -#endif - pixmapData.resize(d->particles.count()); - - const QRectF sourceRect = d->image.rect(); - qreal halfPWidth = sourceRect.width()/2.; - qreal halfPHeight = sourceRect.height()/2.; - for (int i = 0; i < d->particles.count(); ++i) { - const QDeclarativeParticle &particle = d->particles.at(i); -#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) - pixmapData[i].x = particle.x - myX + halfPWidth; - pixmapData[i].y = particle.y - myY + halfPHeight; -#else - pixmapData[i].point = QPointF(particle.x - myX + halfPWidth, particle.y - myY + halfPHeight); -#endif - pixmapData[i].opacity = particle.opacity; - - //these never change - pixmapData[i].rotation = 0; - pixmapData[i].scaleX = 1; - pixmapData[i].scaleY = 1; -#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) - pixmapData[i].sourceLeft = sourceRect.left(); - pixmapData[i].sourceTop = sourceRect.top(); - pixmapData[i].width = sourceRect.width(); - pixmapData[i].height = sourceRect.height(); -#else - pixmapData[i].source = sourceRect; -#endif - } -#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) - p->drawPixmapFragments(pixmapData.data(), d->particles.count(), d->image); -#else - qDrawPixmaps(p, pixmapData.data(), d->particles.count(), d->image); -#endif -} - -void QDeclarativeParticles::componentComplete() -{ - Q_D(QDeclarativeParticles); - QDeclarativeItem::componentComplete(); - if (d->count && d->emissionRate) { - d->paintItem->updateSize(); - d->clock.start(); - } - if (d->lifeSpanDev > d->lifeSpan) - d->lifeSpanDev = d->lifeSpan; -} - -QT_END_NAMESPACE diff --git a/src/declarative/graphicsitems/qdeclarativeparticles_p.h b/src/declarative/graphicsitems/qdeclarativeparticles_p.h deleted file mode 100644 index 06acbb9..0000000 --- a/src/declarative/graphicsitems/qdeclarativeparticles_p.h +++ /dev/null @@ -1,258 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QDECLARATIVEPARTICLES_H -#define QDECLARATIVEPARTICLES_H - -#include "qdeclarativeitem.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class QDeclarativeParticle; -class QDeclarativeParticles; -class Q_DECLARATIVE_EXPORT QDeclarativeParticleMotion : public QObject -{ - Q_OBJECT -public: - QDeclarativeParticleMotion(QObject *parent=0); - - virtual void advance(QDeclarativeParticle &, int interval); - virtual void created(QDeclarativeParticle &); - virtual void destroy(QDeclarativeParticle &); -}; - -class Q_DECLARATIVE_EXPORT QDeclarativeParticleMotionLinear : public QDeclarativeParticleMotion -{ - Q_OBJECT -public: - QDeclarativeParticleMotionLinear(QObject *parent=0) - : QDeclarativeParticleMotion(parent) {} - - virtual void advance(QDeclarativeParticle &, int interval); -}; - -class Q_DECLARATIVE_EXPORT QDeclarativeParticleMotionGravity : public QDeclarativeParticleMotion -{ - Q_OBJECT - - Q_PROPERTY(qreal xattractor READ xAttractor WRITE setXAttractor NOTIFY xattractorChanged) - Q_PROPERTY(qreal yattractor READ yAttractor WRITE setYAttractor NOTIFY yattractorChanged) - Q_PROPERTY(qreal acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged) -public: - QDeclarativeParticleMotionGravity(QObject *parent=0) - : QDeclarativeParticleMotion(parent), _xAttr(0.0), _yAttr(0.0), _accel(0.00005) {} - - qreal xAttractor() const { return _xAttr; } - void setXAttractor(qreal x); - - qreal yAttractor() const { return _yAttr; } - void setYAttractor(qreal y); - - qreal acceleration() const { return _accel * 1000000; } - void setAcceleration(qreal accel); - - virtual void advance(QDeclarativeParticle &, int interval); - -Q_SIGNALS: - void xattractorChanged(); - void yattractorChanged(); - void accelerationChanged(); - -private: - qreal _xAttr; - qreal _yAttr; - qreal _accel; -}; - -class Q_DECLARATIVE_EXPORT QDeclarativeParticleMotionWander : public QDeclarativeParticleMotion -{ - Q_OBJECT -public: - QDeclarativeParticleMotionWander() - : QDeclarativeParticleMotion(), particles(0), _xvariance(0), _yvariance(0) {} - - virtual void advance(QDeclarativeParticle &, int interval); - virtual void created(QDeclarativeParticle &); - virtual void destroy(QDeclarativeParticle &); - - struct Data { - qreal x_targetV; - qreal y_targetV; - qreal x_peak; - qreal y_peak; - qreal x_var; - qreal y_var; - }; - - Q_PROPERTY(qreal xvariance READ xVariance WRITE setXVariance NOTIFY xvarianceChanged) - qreal xVariance() const { return _xvariance * 1000.0; } - void setXVariance(qreal var); - - Q_PROPERTY(qreal yvariance READ yVariance WRITE setYVariance NOTIFY yvarianceChanged) - qreal yVariance() const { return _yvariance * 1000.0; } - void setYVariance(qreal var); - - Q_PROPERTY(qreal pace READ pace WRITE setPace NOTIFY paceChanged) - qreal pace() const { return _pace * 1000.0; } - void setPace(qreal pace); - -Q_SIGNALS: - void xvarianceChanged(); - void yvarianceChanged(); - void paceChanged(); - -private: - QDeclarativeParticles *particles; - qreal _xvariance; - qreal _yvariance; - qreal _pace; -}; - -class QDeclarativeParticlesPrivate; -class Q_DECLARATIVE_EXPORT QDeclarativeParticles : public QDeclarativeItem -{ - Q_OBJECT - - Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) - Q_PROPERTY(int count READ count WRITE setCount NOTIFY countChanged) - Q_PROPERTY(int emissionRate READ emissionRate WRITE setEmissionRate NOTIFY emissionRateChanged) - Q_PROPERTY(qreal emissionVariance READ emissionVariance WRITE setEmissionVariance NOTIFY emissionVarianceChanged) - Q_PROPERTY(int lifeSpan READ lifeSpan WRITE setLifeSpan NOTIFY lifeSpanChanged) - Q_PROPERTY(int lifeSpanDeviation READ lifeSpanDeviation WRITE setLifeSpanDeviation NOTIFY lifeSpanDeviationChanged) - Q_PROPERTY(int fadeInDuration READ fadeInDuration WRITE setFadeInDuration NOTIFY fadeInDurationChanged) - Q_PROPERTY(int fadeOutDuration READ fadeOutDuration WRITE setFadeOutDuration NOTIFY fadeOutDurationChanged) - Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged) - Q_PROPERTY(qreal angleDeviation READ angleDeviation WRITE setAngleDeviation NOTIFY angleDeviationChanged) - Q_PROPERTY(qreal velocity READ velocity WRITE setVelocity NOTIFY velocityChanged) - Q_PROPERTY(qreal velocityDeviation READ velocityDeviation WRITE setVelocityDeviation NOTIFY velocityDeviationChanged) - Q_PROPERTY(QDeclarativeParticleMotion *motion READ motion WRITE setMotion NOTIFY motionChanged) - Q_CLASSINFO("DefaultProperty", "motion") - -public: - QDeclarativeParticles(QDeclarativeItem *parent=0); - ~QDeclarativeParticles(); - - QUrl source() const; - void setSource(const QUrl &); - - int count() const; - void setCount(int cnt); - - int emissionRate() const; - void setEmissionRate(int); - - qreal emissionVariance() const; - void setEmissionVariance(qreal); - - int lifeSpan() const; - void setLifeSpan(int); - - int lifeSpanDeviation() const; - void setLifeSpanDeviation(int); - - int fadeInDuration() const; - void setFadeInDuration(int); - - int fadeOutDuration() const; - void setFadeOutDuration(int); - - qreal angle() const; - void setAngle(qreal); - - qreal angleDeviation() const; - void setAngleDeviation(qreal); - - qreal velocity() const; - void setVelocity(qreal); - - qreal velocityDeviation() const; - void setVelocityDeviation(qreal); - - QDeclarativeParticleMotion *motion() const; - void setMotion(QDeclarativeParticleMotion *); - - void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *); - -public Q_SLOTS: - void burst(int count, int emissionRate=-1); - -protected: - virtual void componentComplete(); - -Q_SIGNALS: - void sourceChanged(); - void countChanged(); - void emissionRateChanged(); - void emissionVarianceChanged(); - void lifeSpanChanged(); - void lifeSpanDeviationChanged(); - void fadeInDurationChanged(); - void fadeOutDurationChanged(); - void angleChanged(); - void angleDeviationChanged(); - void velocityChanged(); - void velocityDeviationChanged(); - void emittingChanged(); - void motionChanged(); - -private Q_SLOTS: - void imageLoaded(); - -private: - Q_DISABLE_COPY(QDeclarativeParticles) - Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QDeclarativeParticles) -}; - -QT_END_NAMESPACE - -QML_DECLARE_TYPE(QDeclarativeParticleMotion) -QML_DECLARE_TYPE(QDeclarativeParticleMotionLinear) -QML_DECLARE_TYPE(QDeclarativeParticleMotionGravity) -QML_DECLARE_TYPE(QDeclarativeParticleMotionWander) -QML_DECLARE_TYPE(QDeclarativeParticles) - -QT_END_HEADER - -#endif diff --git a/src/imports/imports.pro b/src/imports/imports.pro index 8b47043..3886f5c 100644 --- a/src/imports/imports.pro +++ b/src/imports/imports.pro @@ -1,6 +1,6 @@ TEMPLATE = subdirs -SUBDIRS += widgets +SUBDIRS += widgets particles contains(QT_CONFIG, webkit): SUBDIRS += webkit contains(QT_CONFIG, multimedia): SUBDIRS += multimedia diff --git a/src/imports/particles/particles.cpp b/src/imports/particles/particles.cpp new file mode 100644 index 0000000..ae3f318 --- /dev/null +++ b/src/imports/particles/particles.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#include "qdeclarativeparticles_p.h" + +QT_BEGIN_NAMESPACE + +class QParticlesQmlModule : public QDeclarativeExtensionPlugin +{ + Q_OBJECT +public: + virtual void registerTypes(const char *uri) + { + Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.labs.particles")); + qmlRegisterType(uri,1,0,"ParticleMotion"); + qmlRegisterType(uri,1,0,"ParticleMotionGravity"); + qmlRegisterType(uri,1,0,"ParticleMotionLinear"); + qmlRegisterType(uri,1,0,"ParticleMotionWander"); + qmlRegisterType(uri,1,0,"Particles"); + } +}; + +QT_END_NAMESPACE + +#include "particles.moc" + +Q_EXPORT_PLUGIN2(particlesqmlmodule, QT_PREPEND_NAMESPACE(QParticlesQmlModule)); + diff --git a/src/imports/particles/particles.pro b/src/imports/particles/particles.pro new file mode 100644 index 0000000..2a0b8f5 --- /dev/null +++ b/src/imports/particles/particles.pro @@ -0,0 +1,21 @@ +TARGET = particles +TARGETPATH = Qt/labs/particles +include(../qimportbase.pri) + +QT += declarative + +SOURCES += \ + qdeclarativeparticles.cpp \ + particles.cpp + +HEADERS += \ + qdeclarativeparticles_p.h + +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/$$TARGETPATH +target.path = $$TARGETPATH + +# install qmldir file +qmldir.files += qmldir +qmldir.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH + +INSTALLS += target qmldir diff --git a/src/imports/particles/qdeclarativeparticles.cpp b/src/imports/particles/qdeclarativeparticles.cpp new file mode 100644 index 0000000..caa0754 --- /dev/null +++ b/src/imports/particles/qdeclarativeparticles.cpp @@ -0,0 +1,1316 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdeclarativeparticles_p.h" + +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#define M_PI_2 (M_PI / 2.) +#endif +#ifndef INT_MAX +#define INT_MAX 2147483647 +#endif + +QT_BEGIN_NAMESPACE +#define PI_SQR 9.8696044 +// parabolic approximation +inline qreal fastSin(qreal theta) +{ + const qreal b = 4 / M_PI; + const qreal c = -4 / PI_SQR; + + qreal y = b * theta + c * theta * qAbs(theta); + return y; +} + +inline qreal fastCos(qreal theta) +{ + theta += M_PI_2; + if (theta > M_PI) + theta -= 2 * M_PI; + + return fastSin(theta); +} + +class QDeclarativeParticle +{ +public: + QDeclarativeParticle(int time) : lifeSpan(1000), fadeOutAge(800) + , opacity(0), birthTime(time), x_velocity(0), y_velocity(0) + , state(FadeIn), data(0) + { + } + + int lifeSpan; + int fadeOutAge; + qreal x; + qreal y; + qreal opacity; + int birthTime; + qreal x_velocity; + qreal y_velocity; + enum State { FadeIn, Solid, FadeOut }; + State state; + void *data; +}; + +//--------------------------------------------------------------------------- + +/*! + \class QDeclarativeParticleMotion + \ingroup group_effects + \brief The QDeclarativeParticleMotion class is the base class for particle motion. + \internal + + This class causes the particles to remain static. +*/ + +/*! + Constructs a QDeclarativeParticleMotion with parent object \a parent. +*/ +QDeclarativeParticleMotion::QDeclarativeParticleMotion(QObject *parent) : + QObject(parent) +{ +} + +/*! + Move the \a particle to its new position. \a interval is the number of + milliseconds elapsed since it was last moved. +*/ +void QDeclarativeParticleMotion::advance(QDeclarativeParticle &particle, int interval) +{ + Q_UNUSED(particle); + Q_UNUSED(interval); +} + +/*! + The \a particle has just been created. Some motion strategies require + additional state information. This can be allocated by this function. +*/ +void QDeclarativeParticleMotion::created(QDeclarativeParticle &particle) +{ + Q_UNUSED(particle); +} + +/*! + The \a particle is about to be destroyed. Any additional memory + that has been allocated for the particle should be freed. +*/ +void QDeclarativeParticleMotion::destroy(QDeclarativeParticle &particle) +{ + Q_UNUSED(particle); +} + +/*! + \qmlclass ParticleMotionLinear + \since 4.7 + \brief The ParticleMotionLinear object moves particles linearly. + + \sa Particles +*/ + +/*! + \internal + \class QDeclarativeParticleMotionLinear + \ingroup group_effects + \brief The QDeclarativeParticleMotionLinear class moves the particles linearly. +*/ + +void QDeclarativeParticleMotionLinear::advance(QDeclarativeParticle &p, int interval) +{ + p.x += interval * p.x_velocity; + p.y += interval * p.y_velocity; +} + +/*! + \qmlclass ParticleMotionGravity + \since 4.7 + \brief The ParticleMotionGravity object moves particles towards a point. + + \sa Particles +*/ + +/*! + \internal + \class QDeclarativeParticleMotionGravity + \ingroup group_effects + \brief The QDeclarativeParticleMotionGravity class moves the particles towards a point. +*/ + +/*! + \qmlproperty qreal ParticleMotionGravity::xattractor + \qmlproperty qreal ParticleMotionGravity::yattractor + These properties hold the x and y coordinates of the point attracting the particles. +*/ + +/*! + \qmlproperty qreal ParticleMotionGravity::acceleration + This property holds the acceleration to apply to the particles. +*/ + +/*! + \property QDeclarativeParticleMotionGravity::xattractor + \brief the x coordinate of the point attracting the particles. +*/ + +/*! + \property QDeclarativeParticleMotionGravity::yattractor + \brief the y coordinate of the point attracting the particles. +*/ + +/*! + \property QDeclarativeParticleMotionGravity::acceleration + \brief the acceleration to apply to the particles. +*/ + +void QDeclarativeParticleMotionGravity::setXAttractor(qreal x) +{ + if (qFuzzyCompare(x, _xAttr)) + return; + _xAttr = x; + emit xattractorChanged(); +} + +void QDeclarativeParticleMotionGravity::setYAttractor(qreal y) +{ + if (qFuzzyCompare(y, _yAttr)) + return; + _yAttr = y; + emit yattractorChanged(); +} + +void QDeclarativeParticleMotionGravity::setAcceleration(qreal accel) +{ + qreal scaledAccel = accel/1000000.0; + if (qFuzzyCompare(scaledAccel, _accel)) + return; + _accel = scaledAccel; + emit accelerationChanged(); +} + +void QDeclarativeParticleMotionGravity::advance(QDeclarativeParticle &p, int interval) +{ + qreal xdiff = p.x - _xAttr; + qreal ydiff = p.y - _yAttr; + + qreal xcomp = xdiff / (xdiff + ydiff); + qreal ycomp = ydiff / (xdiff + ydiff); + + p.x_velocity += xcomp * _accel * interval; + p.y_velocity += ycomp * _accel * interval; + + p.x += interval * p.x_velocity; + p.y += interval * p.y_velocity; +} + +/*! + \qmlclass ParticleMotionWander + \since 4.7 + \brief The ParticleMotionWander object moves particles in a somewhat random fashion. + + The particles will continue roughly in the original direction, however will randomly + drift to each side. + + The code below produces an effect similar to falling snow. + + \qml +Rectangle { + width: 240 + height: 320 + color: "black" + + Particles { + y: 0 + width: parent.width + height: 30 + source: "star.png" + lifeSpan: 5000 + count: 50 + angle: 70 + angleDeviation: 36 + velocity: 30 + velocityDeviation: 10 + ParticleMotionWander { + xvariance: 30 + pace: 100 + } + } +} + \endqml + + \sa Particles +*/ + +/*! + \internal + \class QDeclarativeParticleMotionWander + \ingroup group_effects + \brief The QDeclarativeParticleMotionWander class moves particles in a somewhat random fashion. + + The particles will continue roughly in the original direction, however will randomly + drift to each side. +*/ + +/*! + \qmlproperty qreal QDeclarativeParticleMotionWander::xvariance + \qmlproperty qreal QDeclarativeParticleMotionWander::yvariance + + These properties set the amount to wander in the x and y directions. +*/ + +/*! + \qmlproperty qreal QDeclarativeParticleMotionWander::pace + This property holds how quickly the paricles will move from side to side. +*/ + +void QDeclarativeParticleMotionWander::advance(QDeclarativeParticle &p, int interval) +{ + if (!particles) + particles = qobject_cast(parent()); + if (particles) { + Data *d = (Data*)p.data; + if (_xvariance != 0.) { + qreal xdiff = p.x_velocity - d->x_targetV; + if ((xdiff > d->x_peak && d->x_var > 0.0) || (xdiff < -d->x_peak && d->x_var < 0.0)) { + d->x_var = -d->x_var; + d->x_peak = _xvariance + _xvariance * qreal(qrand()) / RAND_MAX; + } + p.x_velocity += d->x_var * interval; + } + p.x += interval * p.x_velocity; + + if (_yvariance != 0.) { + qreal ydiff = p.y_velocity - d->y_targetV; + if ((ydiff > d->y_peak && d->y_var > 0.0) || (ydiff < -d->y_peak && d->y_var < 0.0)) { + d->y_var = -d->y_var; + d->y_peak = _yvariance + _yvariance * qreal(qrand()) / RAND_MAX; + } + p.y_velocity += d->y_var * interval; + } + p.y += interval * p.y_velocity; + } +} + +void QDeclarativeParticleMotionWander::created(QDeclarativeParticle &p) +{ + if (!p.data) { + Data *d = new Data; + p.data = (void*)d; + d->x_targetV = p.x_velocity; + d->y_targetV = p.y_velocity; + d->x_peak = _xvariance; + d->y_peak = _yvariance; + d->x_var = _pace * qreal(qrand()) / RAND_MAX / 1000.0; + d->y_var = _pace * qreal(qrand()) / RAND_MAX / 1000.0; + } +} + +void QDeclarativeParticleMotionWander::destroy(QDeclarativeParticle &p) +{ + if (p.data) + delete (Data*)p.data; +} + +void QDeclarativeParticleMotionWander::setXVariance(qreal var) +{ + qreal scaledVar = var / 1000.0; + if (qFuzzyCompare(scaledVar, _xvariance)) + return; + _xvariance = scaledVar; + emit xvarianceChanged(); +} + +void QDeclarativeParticleMotionWander::setYVariance(qreal var) +{ + qreal scaledVar = var / 1000.0; + if (qFuzzyCompare(scaledVar, _yvariance)) + return; + _yvariance = scaledVar; + emit yvarianceChanged(); +} + +void QDeclarativeParticleMotionWander::setPace(qreal pace) +{ + qreal scaledPace = pace / 1000.0; + if (qFuzzyCompare(scaledPace, _pace)) + return; + _pace = scaledPace; + emit paceChanged(); +} + +//--------------------------------------------------------------------------- +class QDeclarativeParticlesPainter : public QDeclarativeItem +{ +public: + QDeclarativeParticlesPainter(QDeclarativeParticlesPrivate *p, QDeclarativeItem* parent) + : QDeclarativeItem(parent), d(p) + { + setFlag(QGraphicsItem::ItemHasNoContents, false); + maxX = minX = maxY = minY = 0; + } + + void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *); + + void updateSize(); + + qreal maxX; + qreal minX; + qreal maxY; + qreal minY; + QDeclarativeParticlesPrivate* d; +}; + +//--------------------------------------------------------------------------- +class QDeclarativeParticlesPrivate : public QDeclarativeItemPrivate +{ + Q_DECLARE_PUBLIC(QDeclarativeParticles) +public: + QDeclarativeParticlesPrivate() + : count(1), emissionRate(-1), emissionVariance(0.5), lifeSpan(1000) + , lifeSpanDev(1000), fadeInDur(200), fadeOutDur(300) + , angle(0), angleDev(0), velocity(0), velocityDev(0), emissionCarry(0.) + , addParticleTime(0), addParticleCount(0), lastAdvTime(0) + , motion(0), pendingPixmapCache(false), clock(this) + { + } + + ~QDeclarativeParticlesPrivate() + { + } + + void init() + { + Q_Q(QDeclarativeParticles); + paintItem = new QDeclarativeParticlesPainter(this, q); + } + + void tick(int time); + void createParticle(int time); + void updateOpacity(QDeclarativeParticle &p, int age); + + QUrl url; + QPixmap image; + int count; + int emissionRate; + qreal emissionVariance; + int lifeSpan; + int lifeSpanDev; + int fadeInDur; + int fadeOutDur; + qreal angle; + qreal angleDev; + qreal velocity; + qreal velocityDev; + qreal emissionCarry; + int addParticleTime; + int addParticleCount; + int lastAdvTime; + QDeclarativeParticleMotion *motion; + QDeclarativeParticlesPainter *paintItem; + + bool pendingPixmapCache; + + QList > bursts;//countLeft, emissionRate pairs + QList particles; + QTickAnimationProxy clock; + +}; + +void QDeclarativeParticlesPrivate::tick(int time) +{ + Q_Q(QDeclarativeParticles); + if (!motion) + motion = new QDeclarativeParticleMotionLinear(q); + + int oldCount = particles.count(); + int removed = 0; + int interval = time - lastAdvTime; + for (int i = 0; i < particles.count(); ) { + QDeclarativeParticle &particle = particles[i]; + int age = time - particle.birthTime; + if (age >= particle.lifeSpan) { + QDeclarativeParticle part = particles.takeAt(i); + motion->destroy(part); + ++removed; + } else { + updateOpacity(particle, age); + motion->advance(particle, interval); + ++i; + } + } + + if(emissionRate == -1)//Otherwise leave emission to the emission rate + while(removed-- && ((count == -1) || particles.count() < count)) + createParticle(time); + + if (!addParticleTime) + addParticleTime = time; + + //Possibly emit new particles + if (((count == -1) || particles.count() < count) && emissionRate + && !(count==-1 && emissionRate==-1)) { + int emissionCount = -1; + if (emissionRate != -1){ + qreal variance = 1.; + if (emissionVariance > 0.){ + variance += (qreal(qrand())/RAND_MAX) * emissionVariance * (qrand()%2?-1.:1.); + } + qreal emission = emissionRate * (qreal(interval)/1000.); + emission = emission * variance + emissionCarry; + double tmpDbl; + emissionCarry = modf(emission, &tmpDbl); + emissionCount = (int)tmpDbl; + emissionCount = qMax(0,emissionCount); + } + while(((count == -1) || particles.count() < count) && + (emissionRate==-1 || emissionCount--)) + createParticle(time); + } + + //Deal with emissions from requested bursts + for(int i=0; i 0.){ + variance += (qreal(qrand())/RAND_MAX) * emissionVariance * (qrand()%2?-1.:1.); + } + qreal workingEmission = bursts[i].second * (qreal(interval)/1000.); + workingEmission *= variance; + emission = (int)workingEmission; + emission = qMax(emission, 0); + } + emission = qMin(emission, bursts[i].first); + bursts[i].first -= emission; + while(emission--) + createParticle(time); + } + for(int i=bursts.size()-1; i>=0; i--) + if(bursts[i].first <= 0) + bursts.removeAt(i); + + lastAdvTime = time; + paintItem->updateSize(); + paintItem->update(); + if (!(oldCount || particles.count()) && (!count || !emissionRate) && bursts.isEmpty()) { + lastAdvTime = 0; + clock.stop(); + } +} + +void QDeclarativeParticlesPrivate::createParticle(int time) +{ +#ifdef Q_ENABLE_PERFORMANCE_LOG + QDeclarativePerfTimer x; +#endif + Q_Q(QDeclarativeParticles); + QDeclarativeParticle p(time); + p.x = q->x() + q->width() * qreal(qrand()) / RAND_MAX - image.width()/2.0; + p.y = q->y() + q->height() * qreal(qrand()) / RAND_MAX - image.height()/2.0; + p.lifeSpan = lifeSpan; + if (lifeSpanDev) + p.lifeSpan += int(lifeSpanDev/2 - lifeSpanDev * qreal(qrand()) / RAND_MAX); + p.fadeOutAge = p.lifeSpan - fadeOutDur; + if (fadeInDur == 0.) { + p.state= QDeclarativeParticle::Solid; + p.opacity = 1.0; + } + qreal a = angle; + if (angleDev) + a += angleDev/2 - angleDev * qreal(qrand()) / RAND_MAX; + if (a > M_PI) + a = a - 2 * M_PI; + qreal v = velocity; + if (velocityDev) + v += velocityDev/2 - velocityDev * qreal(qrand()) / RAND_MAX; + p.x_velocity = v * fastCos(a); + p.y_velocity = v * fastSin(a); + particles.append(p); + motion->created(particles.last()); +} + +void QDeclarativeParticlesPrivate::updateOpacity(QDeclarativeParticle &p, int age) +{ + switch (p.state) { + case QDeclarativeParticle::FadeIn: + if (age <= fadeInDur) { + p.opacity = qreal(age) / fadeInDur; + break; + } else { + p.opacity = 1.0; + p.state = QDeclarativeParticle::Solid; + // Fall through + } + case QDeclarativeParticle::Solid: + if (age <= p.fadeOutAge) { + break; + } else { + p.state = QDeclarativeParticle::FadeOut; + // Fall through + } + case QDeclarativeParticle::FadeOut: + p.opacity = qreal(p.lifeSpan - age) / fadeOutDur; + break; + } +} + +/*! + \qmlclass Particles + \since 4.7 + \brief The Particles object generates and moves particles. + \inherits Item + + This element provides preliminary support for particles in QML, + and may be heavily changed or removed in later versions. + + The particles created by this object cannot be dealt with + directly, they can only be controlled through the parameters of + the Particles object. The particles are all the same pixmap, + specified by the user. + + The particles are painted relative to the parent of the Particles + object. Moving the Particles object will not move the particles + already emitted. + + The below example creates two differently behaving particle + sources. The top one has particles falling from the top like + snow, the lower one has particles expelled up like a fountain. + + \qml +Rectangle { + width: 240 + height: 320 + color: "black" + Particles { + y: 0 + width: parent.width + height: 30 + source: "star.png" + lifeSpan: 5000 + count: 50 + angle: 70 + angleDeviation: 36 + velocity: 30 + velocityDeviation: 10 + ParticleMotionWander { + xvariance: 30 + pace: 100 + } + } + Particles { + y: 300 + x: 120 + width: 1 + height: 1 + source: "star.png" + lifeSpan: 5000 + count: 200 + angle: 270 + angleDeviation: 45 + velocity: 50 + velocityDeviation: 30 + ParticleMotionGravity { + yattractor: 1000 + xattractor: 0 + acceleration: 25 + } + } +} + \endqml + \image particles.gif +*/ + +/*! + \internal + \class QDeclarativeParticles + \ingroup group_effects + \brief The QDeclarativeParticles class generates and moves particles. +*/ + +QDeclarativeParticles::QDeclarativeParticles(QDeclarativeItem *parent) + : QDeclarativeItem(*(new QDeclarativeParticlesPrivate), parent) +{ + Q_D(QDeclarativeParticles); + d->init(); +} + +QDeclarativeParticles::~QDeclarativeParticles() +{ + Q_D(QDeclarativeParticles); + if (d->pendingPixmapCache) + QDeclarativePixmapCache::cancel(d->url, this); +} + +/*! + \qmlproperty string Particles::source + This property holds the URL of the particle image. +*/ + +/*! + \property QDeclarativeParticles::source + \brief the URL of the particle image. +*/ +QUrl QDeclarativeParticles::source() const +{ + Q_D(const QDeclarativeParticles); + return d->url; +} + +void QDeclarativeParticles::imageLoaded() +{ + Q_D(QDeclarativeParticles); + d->pendingPixmapCache = false; + QDeclarativePixmapCache::get(d->url, &d->image); + d->paintItem->updateSize(); + d->paintItem->update(); +} + +void QDeclarativeParticles::setSource(const QUrl &name) +{ + Q_D(QDeclarativeParticles); + + if ((d->url.isEmpty() == name.isEmpty()) && name == d->url) + return; + + if (d->pendingPixmapCache) { + QDeclarativePixmapCache::cancel(d->url, this); + d->pendingPixmapCache = false; + } + if (name.isEmpty()) { + d->url = name; + d->image = QPixmap(); + d->paintItem->updateSize(); + d->paintItem->update(); + } else { + d->url = name; + Q_ASSERT(!name.isRelative()); + QDeclarativePixmapReply::Status status = QDeclarativePixmapCache::get(d->url, &d->image); + if (status != QDeclarativePixmapReply::Ready && status != QDeclarativePixmapReply::Error) { + QDeclarativePixmapReply *reply = QDeclarativePixmapCache::request(qmlEngine(this), d->url); + connect(reply, SIGNAL(finished()), this, SLOT(imageLoaded())); + d->pendingPixmapCache = true; + } else { + //### unify with imageLoaded + d->paintItem->updateSize(); + d->paintItem->update(); + } + } + emit sourceChanged(); +} + +/*! + \qmlproperty int Particles::count + This property holds the maximum number of particles + + The particles element emits particles until it has count active + particles. When this number is reached, new particles are not emitted until + some of the current particles reach the end of their lifespan. + + If count is -1 then there is no maximum number of active particles, and + particles will be constantly emitted at the rate specified by emissionRate. + + The default value for count is 1. + + If both count and emissionRate are set to -1, nothing will be emitted. + +*/ + +/*! + \property QDeclarativeParticles::count + \brief the maximum number of particles +*/ +int QDeclarativeParticles::count() const +{ + Q_D(const QDeclarativeParticles); + return d->count; +} + +void QDeclarativeParticles::setCount(int cnt) +{ + Q_D(QDeclarativeParticles); + if (cnt == d->count) + return; + + int oldCount = d->count; + d->count = cnt; + d->addParticleTime = 0; + d->addParticleCount = d->particles.count(); + if (!oldCount && d->clock.state() != QAbstractAnimation::Running && d->count && d->emissionRate) { + d->clock.start(); + } + d->paintItem->updateSize(); + d->paintItem->update(); + emit countChanged(); +} + + +/*! + \qmlproperty int Particles::emissionRate + This property holds the target number of particles to emit every second. + + The particles element will emit up to emissionRate particles every + second. Fewer particles may be emitted per second if the maximum number of + particles has been reached. + + If emissionRate is set to -1 there is no limit to the number of + particles emitted per second, and particles will be instantly emitted to + reach the maximum number of particles specified by count. + + The default value for emissionRate is -1. + + If both count and emissionRate are set to -1, nothing will be emitted. +*/ + +/*! + \property QDeclarativeParticles::emissionRate + \brief the emission rate of particles +*/ +int QDeclarativeParticles::emissionRate() const +{ + Q_D(const QDeclarativeParticles); + return d->emissionRate; +} +void QDeclarativeParticles::setEmissionRate(int er) +{ + Q_D(QDeclarativeParticles); + if(er == d->emissionRate) + return; + d->emissionRate = er; + if (d->clock.state() != QAbstractAnimation::Running && d->count && d->emissionRate) { + d->clock.start(); + } + emit emissionRateChanged(); +} + +/*! + \qmlproperty qreal Particles::emissionVariance + This property holds how inconsistent the rate of particle emissions are. + It is a number between 0 (no variance) and 1 (some variance). + + The expected number of particles emitted per second is emissionRate. If + emissionVariance is 0 then particles will be emitted consistently throughout + each second to reach that number. If emissionVariance is greater than 0 the + rate of particle emission will vary randomly throughout the second, with the + consequence that the actual number of particles emitted in one second will + vary randomly as well. + + emissionVariance is the maximum deviation from emitting + emissionRate particles per second. An emissionVariance of 0 means you should + get exactly emissionRate particles emitted per second, + and an emissionVariance of 1 means you will get between zero and two times + emissionRate particles per second, but you should get emissionRate particles + per second on average. + + Note that even with an emissionVariance of 0 there may be some variance due + to performance and hardware constraints. + + The default value of emissionVariance is 0.5 +*/ + +/*! + \property QDeclarativeParticles::emissionVariance + \brief how much the particle emission amounts vary per tick +*/ + +qreal QDeclarativeParticles::emissionVariance() const +{ + Q_D(const QDeclarativeParticles); + return d->emissionVariance; +} + +void QDeclarativeParticles::setEmissionVariance(qreal ev) +{ + Q_D(QDeclarativeParticles); + if(d->emissionVariance == ev) + return; + d->emissionVariance = ev; + emit emissionVarianceChanged(); +} + +/*! + \qmlproperty int Particles::lifeSpan + \qmlproperty int Particles::lifeSpanDeviation + + These properties describe the life span of each particle. + + The default lifespan for a particle is 1000ms. + + lifeSpanDeviation randomly varies the lifeSpan up to the specified variation. For + example, the following creates particles whose lifeSpan will vary + from 150ms to 250ms: + + \qml +Particles { + source: "star.png" + lifeSpan: 200 + lifeSpanDeviation: 100 +} + \endqml +*/ + +/*! + \property QDeclarativeParticles::lifeSpan + \brief the life span of each particle. + + Default value is 1000ms. + + \sa QDeclarativeParticles::lifeSpanDeviation +*/ +int QDeclarativeParticles::lifeSpan() const +{ + Q_D(const QDeclarativeParticles); + return d->lifeSpan; +} + +void QDeclarativeParticles::setLifeSpan(int ls) +{ + Q_D(QDeclarativeParticles); + if(d->lifeSpan == ls) + return; + d->lifeSpan = ls; + emit lifeSpanChanged(); +} + +/*! + \property QDeclarativeParticles::lifeSpanDeviation + \brief the maximum possible deviation from the set lifeSpan. + + Randomly varies the lifeSpan up to the specified variation. For + example, the following creates particles whose lifeSpan will vary + from 150ms to 250ms: + +\qml +Particles { + source: "star.png" + lifeSpan: 200 + lifeSpanDeviation: 100 +} +\endqml + + \sa QDeclarativeParticles::lifeSpan +*/ +int QDeclarativeParticles::lifeSpanDeviation() const +{ + Q_D(const QDeclarativeParticles); + return d->lifeSpanDev; +} + +void QDeclarativeParticles::setLifeSpanDeviation(int dev) +{ + Q_D(QDeclarativeParticles); + if(d->lifeSpanDev == dev) + return; + d->lifeSpanDev = dev; + emit lifeSpanDeviationChanged(); +} + +/*! + \qmlproperty int Particles::fadeInDuration + \qmlproperty int Particles::fadeOutDuration + These properties hold the time taken to fade the particles in and out. + + By default fade in is 200ms and fade out is 300ms. +*/ + +/*! + \property QDeclarativeParticles::fadeInDuration + \brief the time taken to fade in the particles. + + Default value is 200ms. +*/ +int QDeclarativeParticles::fadeInDuration() const +{ + Q_D(const QDeclarativeParticles); + return d->fadeInDur; +} + +void QDeclarativeParticles::setFadeInDuration(int dur) +{ + Q_D(QDeclarativeParticles); + if (dur < 0.0 || dur == d->fadeInDur) + return; + d->fadeInDur = dur; + emit fadeInDurationChanged(); +} + +/*! + \property QDeclarativeParticles::fadeOutDuration + \brief the time taken to fade out the particles. + + Default value is 300ms. +*/ +int QDeclarativeParticles::fadeOutDuration() const +{ + Q_D(const QDeclarativeParticles); + return d->fadeOutDur; +} + +void QDeclarativeParticles::setFadeOutDuration(int dur) +{ + Q_D(QDeclarativeParticles); + if (dur < 0.0 || d->fadeOutDur == dur) + return; + d->fadeOutDur = dur; + emit fadeOutDurationChanged(); +} + +/*! + \qmlproperty real Particles::angle + \qmlproperty real Particles::angleDeviation + + These properties control particle direction. + + angleDeviation randomly varies the direction up to the specified variation. For + example, the following creates particles whose initial direction will + vary from 15 degrees to 105 degrees: + + \qml +Particles { + source: "star.png" + angle: 60 + angleDeviation: 90 +} + \endqml +*/ + +/*! + \property QDeclarativeParticles::angle + \brief the initial angle of direction. + + \sa QDeclarativeParticles::angleDeviation +*/ +qreal QDeclarativeParticles::angle() const +{ + Q_D(const QDeclarativeParticles); + return d->angle * 180.0 / M_PI; +} + +void QDeclarativeParticles::setAngle(qreal angle) +{ + Q_D(QDeclarativeParticles); + qreal radAngle = angle * M_PI / 180.0; + if(radAngle == d->angle) + return; + d->angle = radAngle; + emit angleChanged(); +} + +/*! + \property QDeclarativeParticles::angleDeviation + \brief the maximum possible deviation from the set angle. + + Randomly varies the direction up to the specified variation. For + example, the following creates particles whose initial direction will + vary from 15 degrees to 105 degrees: + +\qml +Particles { + source: "star.png" + angle: 60 + angleDeviation: 90 +} +\endqml + + \sa QDeclarativeParticles::angle +*/ +qreal QDeclarativeParticles::angleDeviation() const +{ + Q_D(const QDeclarativeParticles); + return d->angleDev * 180.0 / M_PI; +} + +void QDeclarativeParticles::setAngleDeviation(qreal dev) +{ + Q_D(QDeclarativeParticles); + qreal radDev = dev * M_PI / 180.0; + if(radDev == d->angleDev) + return; + d->angleDev = radDev; + emit angleDeviationChanged(); +} + +/*! + \qmlproperty real Particles::velocity + \qmlproperty real Particles::velocityDeviation + + These properties control the velocity of the particles. + + velocityDeviation randomly varies the velocity up to the specified variation. For + example, the following creates particles whose initial velocity will + vary from 40 to 60. + + \qml +Particles { + source: "star.png" + velocity: 50 + velocityDeviation: 20 +} + \endqml +*/ + +/*! + \property QDeclarativeParticles::velocity + \brief the initial velocity of the particles. + + \sa QDeclarativeParticles::velocityDeviation +*/ +qreal QDeclarativeParticles::velocity() const +{ + Q_D(const QDeclarativeParticles); + return d->velocity * 1000.0; +} + +void QDeclarativeParticles::setVelocity(qreal velocity) +{ + Q_D(QDeclarativeParticles); + qreal realVel = velocity / 1000.0; + if(realVel == d->velocity) + return; + d->velocity = realVel; + emit velocityChanged(); +} + +/*! + \property QDeclarativeParticles::velocityDeviation + \brief the maximum possible deviation from the set velocity. + + Randomly varies the velocity up to the specified variation. For + example, the following creates particles whose initial velocity will + vary from 40 to 60. + +\qml +Particles { + source: "star.png" + velocity: 50 + velocityDeviation: 20 +} +\endqml + + \sa QDeclarativeParticles::velocity +*/ +qreal QDeclarativeParticles::velocityDeviation() const +{ + Q_D(const QDeclarativeParticles); + return d->velocityDev * 1000.0; +} + +void QDeclarativeParticles::setVelocityDeviation(qreal velocity) +{ + Q_D(QDeclarativeParticles); + qreal realDev = velocity / 1000.0; + if(realDev == d->velocityDev) + return; + d->velocityDev = realDev; + emit velocityDeviationChanged(); +} + +/*! + \qmlproperty ParticleMotion Particles::motion + This property sets the type of motion to apply to the particles. + + When a particle is created it will have an initial direction and velocity. + The motion of the particle during its lifeSpan is then influenced by the + motion property. + + Default motion is ParticleMotionLinear. +*/ + +/*! + \property QDeclarativeParticles::motion + \brief sets the type of motion to apply to the particles. + + When a particle is created it will have an initial direction and velocity. + The motion of the particle during its lifeSpan is then influenced by the + motion property. + + Default motion is QDeclarativeParticleMotionLinear. +*/ +QDeclarativeParticleMotion *QDeclarativeParticles::motion() const +{ + Q_D(const QDeclarativeParticles); + return d->motion; +} + +void QDeclarativeParticles::setMotion(QDeclarativeParticleMotion *motion) +{ + Q_D(QDeclarativeParticles); + if (motion == d->motion) + return; + d->motion = motion; + emit motionChanged(); +} + +/*! + \qmlmethod Particles::burst(int count, int emissionRate) + + Initiates a burst of particles. + + This method takes two arguments. The first argument is the number + of particles to emit and the second argument is the emissionRate for the + burst. If the second argument is omitted, it is treated as -1. The burst + of particles has a separate emissionRate and count to the normal emission of + particles. The burst uses the same values as normal emission for all other + properties, including emissionVariance. + + The normal emission of particles will continue during the burst, however + the particles created by the burst count towards the maximum number used by + normal emission. To avoid this behavior, use two Particles elements. + +*/ +void QDeclarativeParticles::burst(int count, int emissionRate) +{ + Q_D(QDeclarativeParticles); + d->bursts << qMakePair(count, emissionRate); + if (d->clock.state() != QAbstractAnimation::Running) + d->clock.start(); +} + +void QDeclarativeParticlesPainter::updateSize() +{ + if (!d->_componentComplete) + return; + + const int parentX = parentItem()->x(); + const int parentY = parentItem()->y(); + for (int i = 0; i < d->particles.count(); ++i) { + const QDeclarativeParticle &particle = d->particles.at(i); + if(particle.x > maxX) + maxX = particle.x; + if(particle.x < minX) + minX = particle.x; + if(particle.y > maxY) + maxY = particle.y; + if(particle.y < minY) + minY = particle.y; + } + + int myWidth = (int)(maxX-minX+0.5)+d->image.width(); + int myX = (int)(minX - parentX); + int myHeight = (int)(maxY-minY+0.5)+d->image.height(); + int myY = (int)(minY - parentY); + setWidth(myWidth); + setHeight(myHeight); + setX(myX); + setY(myY); +} + +void QDeclarativeParticles::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *) +{ + Q_UNUSED(p); + //painting is done by the ParticlesPainter, so it can have the right size +} + +void QDeclarativeParticlesPainter::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *) +{ + if (d->image.isNull() || d->particles.isEmpty()) + return; + + const int myX = x() + parentItem()->x(); + const int myY = y() + parentItem()->y(); + +#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) + QVarLengthArray pixmapData; +#else + QVarLengthArray pixmapData; +#endif + pixmapData.resize(d->particles.count()); + + const QRectF sourceRect = d->image.rect(); + qreal halfPWidth = sourceRect.width()/2.; + qreal halfPHeight = sourceRect.height()/2.; + for (int i = 0; i < d->particles.count(); ++i) { + const QDeclarativeParticle &particle = d->particles.at(i); +#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) + pixmapData[i].x = particle.x - myX + halfPWidth; + pixmapData[i].y = particle.y - myY + halfPHeight; +#else + pixmapData[i].point = QPointF(particle.x - myX + halfPWidth, particle.y - myY + halfPHeight); +#endif + pixmapData[i].opacity = particle.opacity; + + //these never change + pixmapData[i].rotation = 0; + pixmapData[i].scaleX = 1; + pixmapData[i].scaleY = 1; +#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) + pixmapData[i].sourceLeft = sourceRect.left(); + pixmapData[i].sourceTop = sourceRect.top(); + pixmapData[i].width = sourceRect.width(); + pixmapData[i].height = sourceRect.height(); +#else + pixmapData[i].source = sourceRect; +#endif + } +#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) + p->drawPixmapFragments(pixmapData.data(), d->particles.count(), d->image); +#else + qDrawPixmaps(p, pixmapData.data(), d->particles.count(), d->image); +#endif +} + +void QDeclarativeParticles::componentComplete() +{ + Q_D(QDeclarativeParticles); + QDeclarativeItem::componentComplete(); + if (d->count && d->emissionRate) { + d->paintItem->updateSize(); + d->clock.start(); + } + if (d->lifeSpanDev > d->lifeSpan) + d->lifeSpanDev = d->lifeSpan; +} + +QT_END_NAMESPACE diff --git a/src/imports/particles/qdeclarativeparticles_p.h b/src/imports/particles/qdeclarativeparticles_p.h new file mode 100644 index 0000000..993796d --- /dev/null +++ b/src/imports/particles/qdeclarativeparticles_p.h @@ -0,0 +1,258 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDECLARATIVEPARTICLES_H +#define QDECLARATIVEPARTICLES_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QDeclarativeParticle; +class QDeclarativeParticles; +class QDeclarativeParticleMotion : public QObject +{ + Q_OBJECT +public: + QDeclarativeParticleMotion(QObject *parent=0); + + virtual void advance(QDeclarativeParticle &, int interval); + virtual void created(QDeclarativeParticle &); + virtual void destroy(QDeclarativeParticle &); +}; + +class QDeclarativeParticleMotionLinear : public QDeclarativeParticleMotion +{ + Q_OBJECT +public: + QDeclarativeParticleMotionLinear(QObject *parent=0) + : QDeclarativeParticleMotion(parent) {} + + virtual void advance(QDeclarativeParticle &, int interval); +}; + +class QDeclarativeParticleMotionGravity : public QDeclarativeParticleMotion +{ + Q_OBJECT + + Q_PROPERTY(qreal xattractor READ xAttractor WRITE setXAttractor NOTIFY xattractorChanged) + Q_PROPERTY(qreal yattractor READ yAttractor WRITE setYAttractor NOTIFY yattractorChanged) + Q_PROPERTY(qreal acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged) +public: + QDeclarativeParticleMotionGravity(QObject *parent=0) + : QDeclarativeParticleMotion(parent), _xAttr(0.0), _yAttr(0.0), _accel(0.00005) {} + + qreal xAttractor() const { return _xAttr; } + void setXAttractor(qreal x); + + qreal yAttractor() const { return _yAttr; } + void setYAttractor(qreal y); + + qreal acceleration() const { return _accel * 1000000; } + void setAcceleration(qreal accel); + + virtual void advance(QDeclarativeParticle &, int interval); + +Q_SIGNALS: + void xattractorChanged(); + void yattractorChanged(); + void accelerationChanged(); + +private: + qreal _xAttr; + qreal _yAttr; + qreal _accel; +}; + +class QDeclarativeParticleMotionWander : public QDeclarativeParticleMotion +{ + Q_OBJECT +public: + QDeclarativeParticleMotionWander() + : QDeclarativeParticleMotion(), particles(0), _xvariance(0), _yvariance(0) {} + + virtual void advance(QDeclarativeParticle &, int interval); + virtual void created(QDeclarativeParticle &); + virtual void destroy(QDeclarativeParticle &); + + struct Data { + qreal x_targetV; + qreal y_targetV; + qreal x_peak; + qreal y_peak; + qreal x_var; + qreal y_var; + }; + + Q_PROPERTY(qreal xvariance READ xVariance WRITE setXVariance NOTIFY xvarianceChanged) + qreal xVariance() const { return _xvariance * 1000.0; } + void setXVariance(qreal var); + + Q_PROPERTY(qreal yvariance READ yVariance WRITE setYVariance NOTIFY yvarianceChanged) + qreal yVariance() const { return _yvariance * 1000.0; } + void setYVariance(qreal var); + + Q_PROPERTY(qreal pace READ pace WRITE setPace NOTIFY paceChanged) + qreal pace() const { return _pace * 1000.0; } + void setPace(qreal pace); + +Q_SIGNALS: + void xvarianceChanged(); + void yvarianceChanged(); + void paceChanged(); + +private: + QDeclarativeParticles *particles; + qreal _xvariance; + qreal _yvariance; + qreal _pace; +}; + +class QDeclarativeParticlesPrivate; +class QDeclarativeParticles : public QDeclarativeItem +{ + Q_OBJECT + + Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) + Q_PROPERTY(int count READ count WRITE setCount NOTIFY countChanged) + Q_PROPERTY(int emissionRate READ emissionRate WRITE setEmissionRate NOTIFY emissionRateChanged) + Q_PROPERTY(qreal emissionVariance READ emissionVariance WRITE setEmissionVariance NOTIFY emissionVarianceChanged) + Q_PROPERTY(int lifeSpan READ lifeSpan WRITE setLifeSpan NOTIFY lifeSpanChanged) + Q_PROPERTY(int lifeSpanDeviation READ lifeSpanDeviation WRITE setLifeSpanDeviation NOTIFY lifeSpanDeviationChanged) + Q_PROPERTY(int fadeInDuration READ fadeInDuration WRITE setFadeInDuration NOTIFY fadeInDurationChanged) + Q_PROPERTY(int fadeOutDuration READ fadeOutDuration WRITE setFadeOutDuration NOTIFY fadeOutDurationChanged) + Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged) + Q_PROPERTY(qreal angleDeviation READ angleDeviation WRITE setAngleDeviation NOTIFY angleDeviationChanged) + Q_PROPERTY(qreal velocity READ velocity WRITE setVelocity NOTIFY velocityChanged) + Q_PROPERTY(qreal velocityDeviation READ velocityDeviation WRITE setVelocityDeviation NOTIFY velocityDeviationChanged) + Q_PROPERTY(QDeclarativeParticleMotion *motion READ motion WRITE setMotion NOTIFY motionChanged) + Q_CLASSINFO("DefaultProperty", "motion") + +public: + QDeclarativeParticles(QDeclarativeItem *parent=0); + ~QDeclarativeParticles(); + + QUrl source() const; + void setSource(const QUrl &); + + int count() const; + void setCount(int cnt); + + int emissionRate() const; + void setEmissionRate(int); + + qreal emissionVariance() const; + void setEmissionVariance(qreal); + + int lifeSpan() const; + void setLifeSpan(int); + + int lifeSpanDeviation() const; + void setLifeSpanDeviation(int); + + int fadeInDuration() const; + void setFadeInDuration(int); + + int fadeOutDuration() const; + void setFadeOutDuration(int); + + qreal angle() const; + void setAngle(qreal); + + qreal angleDeviation() const; + void setAngleDeviation(qreal); + + qreal velocity() const; + void setVelocity(qreal); + + qreal velocityDeviation() const; + void setVelocityDeviation(qreal); + + QDeclarativeParticleMotion *motion() const; + void setMotion(QDeclarativeParticleMotion *); + + void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *); + +public Q_SLOTS: + void burst(int count, int emissionRate=-1); + +protected: + virtual void componentComplete(); + +Q_SIGNALS: + void sourceChanged(); + void countChanged(); + void emissionRateChanged(); + void emissionVarianceChanged(); + void lifeSpanChanged(); + void lifeSpanDeviationChanged(); + void fadeInDurationChanged(); + void fadeOutDurationChanged(); + void angleChanged(); + void angleDeviationChanged(); + void velocityChanged(); + void velocityDeviationChanged(); + void emittingChanged(); + void motionChanged(); + +private Q_SLOTS: + void imageLoaded(); + +private: + Q_DISABLE_COPY(QDeclarativeParticles) + Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QDeclarativeParticles) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QDeclarativeParticleMotion) +QML_DECLARE_TYPE(QDeclarativeParticleMotionLinear) +QML_DECLARE_TYPE(QDeclarativeParticleMotionGravity) +QML_DECLARE_TYPE(QDeclarativeParticleMotionWander) +QML_DECLARE_TYPE(QDeclarativeParticles) + +QT_END_HEADER + +#endif diff --git a/src/imports/particles/qmldir b/src/imports/particles/qmldir new file mode 100644 index 0000000..15456bb --- /dev/null +++ b/src/imports/particles/qmldir @@ -0,0 +1 @@ +plugin particles -- cgit v0.12 From 0e9bb332eec2bee29fe736aea76c30c66c69a9d0 Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Thu, 11 Mar 2010 15:42:56 +1000 Subject: Don't export symbols in webkit plugin. --- src/imports/webkit/qdeclarativewebview_p.h | 6 ++-- src/imports/webkit/qdeclarativewebview_p_p.h | 4 +-- src/imports/webkit/webkit.pro | 4 +-- src/imports/webkit/webkitqmlplugin_export.h | 53 ---------------------------- 4 files changed, 4 insertions(+), 63 deletions(-) delete mode 100644 src/imports/webkit/webkitqmlplugin_export.h diff --git a/src/imports/webkit/qdeclarativewebview_p.h b/src/imports/webkit/qdeclarativewebview_p.h index 95f51d1..36b18a6 100644 --- a/src/imports/webkit/qdeclarativewebview_p.h +++ b/src/imports/webkit/qdeclarativewebview_p.h @@ -42,8 +42,6 @@ #ifndef QDECLARATIVEWEBVIEW_H #define QDECLARATIVEWEBVIEW_H -#include "webkitqmlplugin_export.h" - #include #include @@ -64,7 +62,7 @@ class QDeclarativeWebViewPrivate; class QNetworkRequest; class QDeclarativeWebView; -class WEBKITQMLPLUGIN_EXPORT QDeclarativeWebPage : public QWebPage +class QDeclarativeWebPage : public QWebPage { Q_OBJECT public: @@ -88,7 +86,7 @@ class QDeclarativeWebViewAttached; //### TODO: browser plugins -class WEBKITQMLPLUGIN_EXPORT QDeclarativeWebView : public QDeclarativePaintedItem +class QDeclarativeWebView : public QDeclarativePaintedItem { Q_OBJECT diff --git a/src/imports/webkit/qdeclarativewebview_p_p.h b/src/imports/webkit/qdeclarativewebview_p_p.h index 3ad9e9a..258b472 100644 --- a/src/imports/webkit/qdeclarativewebview_p_p.h +++ b/src/imports/webkit/qdeclarativewebview_p_p.h @@ -42,8 +42,6 @@ #ifndef QDECLARATIVEWEBVIEW_P_H #define QDECLARATIVEWEBVIEW_P_H -#include "webkitqmlplugin_export.h" - #include #include @@ -54,7 +52,7 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) -class WEBKITQMLPLUGIN_EXPORT QDeclarativeWebSettings : public QObject { +class QDeclarativeWebSettings : public QObject { Q_OBJECT Q_PROPERTY(QString standardFontFamily READ standardFontFamily WRITE setStandardFontFamily) diff --git a/src/imports/webkit/webkit.pro b/src/imports/webkit/webkit.pro index 9ad9c68..858d3ba 100644 --- a/src/imports/webkit/webkit.pro +++ b/src/imports/webkit/webkit.pro @@ -3,12 +3,10 @@ TARGETPATH = org/webkit include(../qimportbase.pri) QT += webkit declarative -DEFINES += WEBKITQMLPLUGIN_EXPORTS SOURCES += qdeclarativewebview.cpp plugin.cpp HEADERS += qdeclarativewebview_p.h \ - qdeclarativewebview_p_p.h \ - webkitqmlplugin_export.h + qdeclarativewebview_p_p.h QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/$$TARGETPATH target.path = $$TARGETPATH diff --git a/src/imports/webkit/webkitqmlplugin_export.h b/src/imports/webkit/webkitqmlplugin_export.h deleted file mode 100644 index 974fd24..0000000 --- a/src/imports/webkit/webkitqmlplugin_export.h +++ /dev/null @@ -1,53 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef WEBKITQMLPLUGIN_EXPORT_H -#define WEBKITQMLPLUGIN_EXPORT_H - -#include - -#if defined WEBKITQMLPLUGIN_EXPORTS -# define WEBKITQMLPLUGIN_EXPORT Q_DECL_EXPORT -#else -# define WEBKITQMLPLUGIN_EXPORT Q_DECL_IMPORT -#endif - -#endif // WEBKITQMLPLUGIN_EXPORT_H -- cgit v0.12 From fef9bb355f964f7a520da0c5e24d165644be1473 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Thu, 11 Mar 2010 16:26:30 +1000 Subject: Minor construction optimizations. --- src/declarative/graphicsitems/qdeclarativefocuspanel.cpp | 5 ++++- src/declarative/graphicsitems/qdeclarativefocuspanel_p.h | 1 + src/declarative/graphicsitems/qdeclarativefocusscope.cpp | 5 ++++- src/declarative/graphicsitems/qdeclarativefocusscope_p.h | 1 + src/declarative/util/qdeclarativeanimation.cpp | 3 +++ 5 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativefocuspanel.cpp b/src/declarative/graphicsitems/qdeclarativefocuspanel.cpp index 0323a59..20524b6 100644 --- a/src/declarative/graphicsitems/qdeclarativefocuspanel.cpp +++ b/src/declarative/graphicsitems/qdeclarativefocuspanel.cpp @@ -41,6 +41,8 @@ #include "qdeclarativefocuspanel_p.h" +#include "qdeclarativeitem_p.h" + #include #include @@ -65,7 +67,8 @@ QT_BEGIN_NAMESPACE QDeclarativeFocusPanel::QDeclarativeFocusPanel(QDeclarativeItem *parent) : QDeclarativeItem(parent) { - setFlag(ItemIsPanel); + Q_D(QDeclarativeItem); + d->flags |= QGraphicsItem::ItemIsPanel; } QDeclarativeFocusPanel::~QDeclarativeFocusPanel() diff --git a/src/declarative/graphicsitems/qdeclarativefocuspanel_p.h b/src/declarative/graphicsitems/qdeclarativefocuspanel_p.h index 1ad8b6e..d9ca0b0 100644 --- a/src/declarative/graphicsitems/qdeclarativefocuspanel_p.h +++ b/src/declarative/graphicsitems/qdeclarativefocuspanel_p.h @@ -66,6 +66,7 @@ protected: private: Q_DISABLE_COPY(QDeclarativeFocusPanel) + Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QDeclarativeItem) }; QT_END_NAMESPACE diff --git a/src/declarative/graphicsitems/qdeclarativefocusscope.cpp b/src/declarative/graphicsitems/qdeclarativefocusscope.cpp index 384a47b..484df13 100644 --- a/src/declarative/graphicsitems/qdeclarativefocusscope.cpp +++ b/src/declarative/graphicsitems/qdeclarativefocusscope.cpp @@ -41,6 +41,8 @@ #include "qdeclarativefocusscope_p.h" +#include "qdeclarativeitem_p.h" + QT_BEGIN_NAMESPACE /*! @@ -62,7 +64,8 @@ QT_BEGIN_NAMESPACE QDeclarativeFocusScope::QDeclarativeFocusScope(QDeclarativeItem *parent) : QDeclarativeItem(parent) { - setFlag(QGraphicsItem::ItemIsFocusScope); + Q_D(QDeclarativeItem); + d->flags |= QGraphicsItem::ItemIsFocusScope; } QDeclarativeFocusScope::~QDeclarativeFocusScope() diff --git a/src/declarative/graphicsitems/qdeclarativefocusscope_p.h b/src/declarative/graphicsitems/qdeclarativefocusscope_p.h index cd480b4..c65a07c 100644 --- a/src/declarative/graphicsitems/qdeclarativefocusscope_p.h +++ b/src/declarative/graphicsitems/qdeclarativefocusscope_p.h @@ -54,6 +54,7 @@ QT_MODULE(Declarative) class Q_DECLARATIVE_EXPORT QDeclarativeFocusScope : public QDeclarativeItem { Q_OBJECT + Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QDeclarativeItem) public: QDeclarativeFocusScope(QDeclarativeItem *parent=0); virtual ~QDeclarativeFocusScope(); diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index 170b455..d77ef40 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -2447,12 +2447,15 @@ QDeclarativeParentAnimation::QDeclarativeParentAnimation(QObject *parent) QDeclarative_setParent_noEvent(d->topLevelGroup, this); d->startAction = new QActionAnimation; + QDeclarative_setParent_noEvent(d->startAction, d->topLevelGroup); d->topLevelGroup->addAnimation(d->startAction); d->ag = new QParallelAnimationGroup; + QDeclarative_setParent_noEvent(d->ag, d->topLevelGroup); d->topLevelGroup->addAnimation(d->ag); d->endAction = new QActionAnimation; + QDeclarative_setParent_noEvent(d->endAction, d->topLevelGroup); d->topLevelGroup->addAnimation(d->endAction); } -- cgit v0.12 From 3548ee78b268a1ece0fe295528bf0dad871fb6af Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Thu, 11 Mar 2010 16:39:34 +1000 Subject: Truncate title at right if too long (cannot currently ElideRight and center). --- demos/declarative/webbrowser/content/RetractingWebBrowserHeader.qml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/demos/declarative/webbrowser/content/RetractingWebBrowserHeader.qml b/demos/declarative/webbrowser/content/RetractingWebBrowserHeader.qml index 94c94f2..46dbc98 100644 --- a/demos/declarative/webbrowser/content/RetractingWebBrowserHeader.qml +++ b/demos/declarative/webbrowser/content/RetractingWebBrowserHeader.qml @@ -18,7 +18,7 @@ Image { anchors.top: header.top anchors.topMargin: 4 - anchors.horizontalCenter: parent.horizontalCenter + x: parent.width > headerIcon.width+headerText.width+6 ? (parent.width-headerIcon.width-headerText.width-6)/2 : 0 spacing: 6 Image { @@ -30,8 +30,6 @@ Image { id: headerText text: webView.title!='' || webView.progress == 1.0 ? webView.title : 'Loading...' - elide: Text.ElideRight - //width: parent.width - headerIcon.width-4 color: "white" styleColor: "black" -- cgit v0.12 From 54bdab8b88777488f9f0d944698fbb155cf703af Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 11 Mar 2010 16:35:41 +1000 Subject: Improve value type binding behavior Changing value type bindings in state changes, and implicitly removing them on property assignment was not reliable. Internally the system considered a binding on "font" and one on "font.x" as a binding on two separate properties, even though the "font" binding completely overrides the "font.x" property. Following this change a binding to "font.x" creates a proxy binding object on the "font" property in addition to the "font.x" binding itself. This allows behavior to be consistent across all operations. QT-2920 --- src/declarative/qml/qdeclarativebinding.cpp | 142 +++++++++++++++++++-- src/declarative/qml/qdeclarativebinding_p.h | 28 ++++ .../qml/qdeclarativeobjectscriptclass.cpp | 3 +- src/declarative/qml/qdeclarativeproperty.cpp | 64 ++++++---- src/declarative/qml/qdeclarativeproperty_p.h | 3 +- .../qml/qdeclarativevaluetypescriptclass.cpp | 7 + .../qdeclarativevaluetypes/data/conflicting.1.qml | 42 ++++++ .../qdeclarativevaluetypes/data/conflicting.2.qml | 42 ++++++ .../qdeclarativevaluetypes/data/conflicting.3.qml | 42 ++++++ .../tst_qdeclarativevaluetypes.cpp | 66 +++++++++- 10 files changed, 401 insertions(+), 38 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativevaluetypes/data/conflicting.1.qml create mode 100644 tests/auto/declarative/qdeclarativevaluetypes/data/conflicting.2.qml create mode 100644 tests/auto/declarative/qdeclarativevaluetypes/data/conflicting.3.qml diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp index 88ca5cd..bc78b5b 100644 --- a/src/declarative/qml/qdeclarativebinding.cpp +++ b/src/declarative/qml/qdeclarativebinding.cpp @@ -223,7 +223,7 @@ void QDeclarativeBinding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteF int QDeclarativeBinding::propertyIndex() { Q_D(QDeclarativeBinding); - return d->bindingData()->property.index(); + return QDeclarativePropertyPrivate::bindingIndex(d->bindingData()->property); } bool QDeclarativeBinding::enabled() const @@ -259,23 +259,57 @@ void QDeclarativeAbstractBinding::addToObject(QObject *object) { Q_ASSERT(object); + if (m_object == object) + return; + + int index = propertyIndex(); + removeFromObject(); Q_ASSERT(!m_prevBinding); - QDeclarativeDeclarativeData *data = QDeclarativeDeclarativeData::get(object, true); - m_nextBinding = data->bindings; - if (m_nextBinding) m_nextBinding->m_prevBinding = &m_nextBinding; - m_prevBinding = &data->bindings; - data->bindings = this; m_object = object; + QDeclarativeDeclarativeData *data = QDeclarativeDeclarativeData::get(object, true); + + if (index & 0xFF000000) { + // Value type - data->setBindingBit(m_object, propertyIndex()); + int coreIndex = index & 0xFFFFFF; + + // Find the value type proxy (if there is one) + QDeclarativeValueTypeProxyBinding *proxy = 0; + if (data->hasBindingBit(coreIndex)) { + QDeclarativeAbstractBinding *b = data->bindings; + while (b && b->propertyIndex() != coreIndex) + b = b->m_nextBinding; + Q_ASSERT(b && b->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy); + proxy = static_cast(b); + } + + if (!proxy) + proxy = new QDeclarativeValueTypeProxyBinding(object, coreIndex); + proxy->addToObject(object); + + m_nextBinding = proxy->m_bindings; + if (m_nextBinding) m_nextBinding->m_prevBinding = &m_nextBinding; + m_prevBinding = &proxy->m_bindings; + proxy->m_bindings = this; + + } else { + m_nextBinding = data->bindings; + if (m_nextBinding) m_nextBinding->m_prevBinding = &m_nextBinding; + m_prevBinding = &data->bindings; + data->bindings = this; + + data->setBindingBit(m_object, index); + } } void QDeclarativeAbstractBinding::removeFromObject() { if (m_prevBinding) { + int index = propertyIndex(); + Q_ASSERT(m_object); *m_prevBinding = m_nextBinding; @@ -283,8 +317,14 @@ void QDeclarativeAbstractBinding::removeFromObject() m_prevBinding = 0; m_nextBinding = 0; - QDeclarativeDeclarativeData *data = QDeclarativeDeclarativeData::get(m_object, false); - if (data) data->clearBindingBit(propertyIndex()); + if (index & 0xFF000000) { + // Value type - we don't remove the proxy from the object. It will sit their happily + // doing nothing for ever more. + } else { + QDeclarativeDeclarativeData *data = QDeclarativeDeclarativeData::get(m_object, false); + if (data) data->clearBindingBit(index); + } + m_object = 0; } } @@ -305,4 +345,88 @@ void QDeclarativeAbstractBinding::setEnabled(bool e, QDeclarativePropertyPrivate if (e) m_mePtr = 0; } +QDeclarativeValueTypeProxyBinding::QDeclarativeValueTypeProxyBinding(QObject *o, int index) +: m_object(o), m_index(index), m_bindings(0) +{ +} + +QDeclarativeValueTypeProxyBinding::~QDeclarativeValueTypeProxyBinding() +{ + while (m_bindings) { + QDeclarativeAbstractBinding *binding = m_bindings; + binding->setEnabled(false, 0); + binding->destroy(); + } +} + +void QDeclarativeValueTypeProxyBinding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteFlags flags) +{ + if (e) { + addToObject(m_object); + + QDeclarativeAbstractBinding *bindings = m_bindings; + m_bindings = 0; + recursiveEnable(bindings, flags); + } else { + removeFromObject(); + + QDeclarativeAbstractBinding *bindings = m_bindings; + m_bindings = 0; + recursiveDisable(bindings); + } +} + +void QDeclarativeValueTypeProxyBinding::recursiveEnable(QDeclarativeAbstractBinding *b, QDeclarativePropertyPrivate::WriteFlags flags) +{ + if (!b) + return; + + QDeclarativeAbstractBinding *next = b->m_nextBinding; + b->m_prevBinding = 0; + b->m_nextBinding = 0; + Q_ASSERT(b->m_mePtr == 0); + b->m_mePtr = &b; + + recursiveEnable(next, flags); + + if (b) + b->setEnabled(true, flags); +} + +void QDeclarativeValueTypeProxyBinding::recursiveDisable(QDeclarativeAbstractBinding *b) +{ + if (!b) + return; + + recursiveDisable(b->m_nextBinding); + + b->setEnabled(false, 0); + + Q_ASSERT(b->m_prevBinding == 0); + Q_ASSERT(b->m_nextBinding == 0); + b->m_nextBinding = m_bindings; + if (b->m_nextBinding) b->m_nextBinding->m_prevBinding = &b->m_nextBinding; + b->m_prevBinding = &m_bindings; + m_bindings = b; +} + +int QDeclarativeValueTypeProxyBinding::propertyIndex() +{ + return m_index; +} + +void QDeclarativeValueTypeProxyBinding::update(QDeclarativePropertyPrivate::WriteFlags) +{ +} + +QDeclarativeAbstractBinding *QDeclarativeValueTypeProxyBinding::binding(int propertyIndex) +{ + QDeclarativeAbstractBinding *binding = m_bindings; + + while (binding && binding->propertyIndex() != propertyIndex) + binding = binding->m_nextBinding; + + return binding; +} + QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativebinding_p.h b/src/declarative/qml/qdeclarativebinding_p.h index 1a714f0..21e3248 100644 --- a/src/declarative/qml/qdeclarativebinding_p.h +++ b/src/declarative/qml/qdeclarativebinding_p.h @@ -74,6 +74,9 @@ public: virtual QString expression() const; + enum Type { PropertyBinding, ValueTypeProxy }; + virtual Type bindingType() const { return PropertyBinding; } + void setEnabled(bool e) { setEnabled(e, QDeclarativePropertyPrivate::DontRemoveBinding); } virtual void setEnabled(bool, QDeclarativePropertyPrivate::WriteFlags) = 0; virtual int propertyIndex() = 0; @@ -92,6 +95,7 @@ private: friend class QDeclarativeProperty; friend class QDeclarativePropertyPrivate; friend class QDeclarativeVME; + friend class QDeclarativeValueTypeProxyBinding; QObject *m_object; QDeclarativeAbstractBinding **m_mePtr; @@ -99,6 +103,30 @@ private: QDeclarativeAbstractBinding *m_nextBinding; }; +class QDeclarativeValueTypeProxyBinding : public QDeclarativeAbstractBinding +{ +public: + QDeclarativeValueTypeProxyBinding(QObject *o, int coreIndex); + virtual ~QDeclarativeValueTypeProxyBinding(); + + virtual Type bindingType() const { return ValueTypeProxy; } + + virtual void setEnabled(bool, QDeclarativePropertyPrivate::WriteFlags); + virtual int propertyIndex(); + virtual void update(QDeclarativePropertyPrivate::WriteFlags); + + QDeclarativeAbstractBinding *binding(int propertyIndex); + +private: + void recursiveEnable(QDeclarativeAbstractBinding *, QDeclarativePropertyPrivate::WriteFlags); + void recursiveDisable(QDeclarativeAbstractBinding *); + + friend class QDeclarativeAbstractBinding; + QObject *m_object; + int m_index; + QDeclarativeAbstractBinding *m_bindings; +}; + class QDeclarativeContext; class QDeclarativeBindingPrivate; class Q_DECLARATIVE_EXPORT QDeclarativeBinding : public QDeclarativeExpression, public QDeclarativeAbstractBinding diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp index dc4a676..68780b6 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp @@ -351,7 +351,8 @@ void QDeclarativeObjectScriptClass::setProperty(QObject *obj, } } - QDeclarativeAbstractBinding *delBinding = QDeclarativePropertyPrivate::setBinding(obj, *lastData, 0); + QDeclarativeAbstractBinding *delBinding = + QDeclarativePropertyPrivate::setBinding(obj, lastData->coreIndex, -1, 0); if (delBinding) delBinding->destroy(); diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp index 945d098..8ca5406 100644 --- a/src/declarative/qml/qdeclarativeproperty.cpp +++ b/src/declarative/qml/qdeclarativeproperty.cpp @@ -598,7 +598,6 @@ QMetaMethod QDeclarativeProperty::method() const return QMetaMethod(); } - /*! Returns the binding associated with this property, or 0 if no binding exists. @@ -617,13 +616,18 @@ QDeclarativePropertyPrivate::binding(const QDeclarativeProperty &that) return 0; QDeclarativeAbstractBinding *binding = data->bindings; - while (binding) { - // ### This wont work for value types - if (binding->propertyIndex() == that.d->core.coreIndex) - return binding; + while (binding && binding->propertyIndex() != that.d->core.coreIndex) binding = binding->m_nextBinding; + + if (binding && that.d->valueType.valueTypeCoreIdx != -1) { + if (binding->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy) { + QDeclarativeValueTypeProxyBinding *proxy = static_cast(binding); + + binding = proxy->binding(bindingIndex(that)); + } } - return 0; + + return binding; } /*! @@ -650,36 +654,36 @@ QDeclarativePropertyPrivate::setBinding(const QDeclarativeProperty &that, return 0; } - return that.d->setBinding(that.d->object, that.d->core, newBinding, flags); + return that.d->setBinding(that.d->object, that.d->core.coreIndex, + that.d->valueType.valueTypeCoreIdx, newBinding, flags); } QDeclarativeAbstractBinding * -QDeclarativePropertyPrivate::setBinding(QObject *object, const QDeclarativePropertyCache::Data &core, - QDeclarativeAbstractBinding *newBinding, WriteFlags flags) +QDeclarativePropertyPrivate::setBinding(QObject *object, int coreIndex, int valueTypeIndex, + QDeclarativeAbstractBinding *newBinding, WriteFlags flags) { QDeclarativeDeclarativeData *data = QDeclarativeDeclarativeData::get(object, 0 != newBinding); + QDeclarativeAbstractBinding *binding = 0; - if (data && data->hasBindingBit(core.coreIndex)) { - QDeclarativeAbstractBinding *binding = data->bindings; - while (binding) { - // ### This wont work for value types - if (binding->propertyIndex() == core.coreIndex) { - binding->setEnabled(false); + if (data && data->hasBindingBit(coreIndex)) { + binding = data->bindings; - if (newBinding) - newBinding->setEnabled(true, flags); + while (binding && binding->propertyIndex() != coreIndex) + binding = binding->m_nextBinding; + } - return binding; // ### QDeclarativeAbstractBinding; - } + if (binding && valueTypeIndex != -1 && binding->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy) { + int index = coreIndex | (valueTypeIndex << 24); + binding = static_cast(binding)->binding(index); + } - binding = binding->m_nextBinding; - } - } + if (binding) + binding->setEnabled(false); - if (newBinding) + if (newBinding) newBinding->setEnabled(true, flags); - return 0; + return binding; } /*! @@ -1253,6 +1257,18 @@ int QDeclarativePropertyPrivate::valueTypeCoreIndex(const QDeclarativeProperty & return that.d->valueType.valueTypeCoreIdx; } +/*! + Returns the "property index" for use in bindings. The top 8 bits are the value type + offset, and 0 otherwise. The bottom 24-bits are the regular property index. +*/ +int QDeclarativePropertyPrivate::bindingIndex(const QDeclarativeProperty &that) +{ + int rv = that.d->core.coreIndex; + if (rv != -1 && that.d->valueType.valueTypeCoreIdx != -1) + rv = rv | (that.d->valueType.valueTypeCoreIdx << 24); + return rv; +} + struct SerializedData { bool isValueType; QDeclarativePropertyCache::Data core; diff --git a/src/declarative/qml/qdeclarativeproperty_p.h b/src/declarative/qml/qdeclarativeproperty_p.h index c31e2d3..26b85b8 100644 --- a/src/declarative/qml/qdeclarativeproperty_p.h +++ b/src/declarative/qml/qdeclarativeproperty_p.h @@ -110,7 +110,7 @@ public: const QVariant &value, int flags); static bool write(QObject *, const QDeclarativePropertyCache::Data &, const QVariant &, QDeclarativeContext *, WriteFlags flags = 0); - static QDeclarativeAbstractBinding *setBinding(QObject *, const QDeclarativePropertyCache::Data &, + static QDeclarativeAbstractBinding *setBinding(QObject *, int coreIndex, int valueTypeIndex /* -1 */, QDeclarativeAbstractBinding *, WriteFlags flags = DontRemoveBinding); @@ -133,6 +133,7 @@ public: QDeclarativeExpression *) ; static bool write(const QDeclarativeProperty &that, const QVariant &, WriteFlags); static int valueTypeCoreIndex(const QDeclarativeProperty &that); + static int bindingIndex(const QDeclarativeProperty &that); }; Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativePropertyPrivate::WriteFlags) diff --git a/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp b/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp index 9cb65f8..a567c38 100644 --- a/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp +++ b/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp @@ -41,6 +41,8 @@ #include "qdeclarativevaluetypescriptclass_p.h" +#include "qdeclarativebinding_p.h" +#include "qdeclarativeproperty_p.h" #include "qdeclarativeengine_p.h" #include "qdeclarativeguard_p.h" @@ -115,6 +117,11 @@ void QDeclarativeValueTypeScriptClass::setProperty(Object *obj, const Identifier { QDeclarativeValueTypeReference *ref = static_cast(obj); + QDeclarativeAbstractBinding *delBinding = + QDeclarativePropertyPrivate::setBinding(ref->object, ref->property, m_lastIndex, 0); + if (delBinding) + delBinding->destroy(); + QVariant v = QDeclarativeScriptClass::toVariant(engine, value); ref->type->read(ref->object, ref->property); diff --git a/tests/auto/declarative/qdeclarativevaluetypes/data/conflicting.1.qml b/tests/auto/declarative/qdeclarativevaluetypes/data/conflicting.1.qml new file mode 100644 index 0000000..2697bb5 --- /dev/null +++ b/tests/auto/declarative/qdeclarativevaluetypes/data/conflicting.1.qml @@ -0,0 +1,42 @@ +import Qt 4.6 + +Rectangle { + id: root + + width: 800 + height: 600 + + property alias font: myText.font + + property int myPixelSize: 12 + property int myPixelSize2: 24 + + Text { + id: other + font.pixelSize: 6 + } + + Text { + id: myText + + text: "Hello world!" + font.pixelSize: myPixelSize + } + + states: State { + name: "Swapped" + PropertyChanges { + target: myText + font: other.font + } + } + + function toggle() { + if (root.state == "") root.state = "Swapped"; else root.state = ""; + } + + MouseArea { + anchors.fill: parent + onClicked: { if (root.state == "") root.state = "Swapped"; else root.state = "";} + } +} diff --git a/tests/auto/declarative/qdeclarativevaluetypes/data/conflicting.2.qml b/tests/auto/declarative/qdeclarativevaluetypes/data/conflicting.2.qml new file mode 100644 index 0000000..478104e1 --- /dev/null +++ b/tests/auto/declarative/qdeclarativevaluetypes/data/conflicting.2.qml @@ -0,0 +1,42 @@ +import Qt 4.6 + +Rectangle { + id: root + + width: 800 + height: 600 + + property alias font: myText.font + + property int myPixelSize: 12 + property int myPixelSize2: 24 + + Text { + id: other + font.pixelSize: 6 + } + + Text { + id: myText + + text: "Hello world!" + font: other.font + } + + states: State { + name: "Swapped" + PropertyChanges { + target: myText + font.pixelSize: myPixelSize + } + } + + function toggle() { + if (root.state == "") root.state = "Swapped"; else root.state = ""; + } + + MouseArea { + anchors.fill: parent + onClicked: { if (root.state == "") root.state = "Swapped"; else root.state = "";} + } +} diff --git a/tests/auto/declarative/qdeclarativevaluetypes/data/conflicting.3.qml b/tests/auto/declarative/qdeclarativevaluetypes/data/conflicting.3.qml new file mode 100644 index 0000000..d35c72e --- /dev/null +++ b/tests/auto/declarative/qdeclarativevaluetypes/data/conflicting.3.qml @@ -0,0 +1,42 @@ +import Qt 4.6 + +Rectangle { + id: root + + width: 800 + height: 600 + + property alias font: myText.font + + property int myPixelSize: 12 + property int myPixelSize2: 24 + + Text { + id: other + font.pixelSize: 6 + } + + Text { + id: myText + + text: "Hello world!" + font.pixelSize: myPixelSize + } + + states: State { + name: "Swapped" + PropertyChanges { + target: myText + font.pixelSize: myPixelSize2 + } + } + + function toggle() { + if (root.state == "") root.state = "Swapped"; else root.state = ""; + } + + MouseArea { + anchors.fill: parent + onClicked: { if (root.state == "") root.state = "Swapped"; else root.state = "";} + } +} diff --git a/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp b/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp index eba83ce..a5cb16f 100644 --- a/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp +++ b/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp @@ -77,6 +77,7 @@ private slots: void scriptVariantCopy(); void cppClasses(); void enums(); + void conflictingBindings(); private: QDeclarativeEngine engine; @@ -431,12 +432,13 @@ void tst_qdeclarativevaluetypes::autoBindingRemoval() object->setProperty("value", QVariant(92)); - QEXPECT_FAIL("", "QT-2920", Continue); + //QEXPECT_FAIL("", "QT-2920", Continue); QCOMPARE(object->rect().x(), 42); delete object; } + /* { QDeclarativeComponent component(&engine, TEST_FILE("autoBindingRemoval.2.qml")); MyTypeObject *object = qobject_cast(component.create()); @@ -474,12 +476,11 @@ void tst_qdeclarativevaluetypes::autoBindingRemoval() object->setProperty("value", QVariant(QRect(19, 3, 4, 8))); - QEXPECT_FAIL("", "QT-2920", Continue); QCOMPARE(object->rect(), QRect(44, 22, 33, 44)); delete object; } - +*/ } // Test that property value sources assign to value types @@ -635,6 +636,65 @@ void tst_qdeclarativevaluetypes::enums() } } +// Tests switching between "conflicting" bindings (eg. a binding on the core +// property, to a binding on the value-type sub-property) +void tst_qdeclarativevaluetypes::conflictingBindings() +{ + { + QDeclarativeComponent component(&engine, TEST_FILE("conflicting.1.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(qvariant_cast(object->property("font")).pixelSize(), 12); + + QMetaObject::invokeMethod(object, "toggle"); + + QCOMPARE(qvariant_cast(object->property("font")).pixelSize(), 6); + + QMetaObject::invokeMethod(object, "toggle"); + + QCOMPARE(qvariant_cast(object->property("font")).pixelSize(), 12); + + delete object; + } + + { + QDeclarativeComponent component(&engine, TEST_FILE("conflicting.2.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(qvariant_cast(object->property("font")).pixelSize(), 6); + + QMetaObject::invokeMethod(object, "toggle"); + + QCOMPARE(qvariant_cast(object->property("font")).pixelSize(), 12); + + QMetaObject::invokeMethod(object, "toggle"); + + QCOMPARE(qvariant_cast(object->property("font")).pixelSize(), 6); + + delete object; + } + + { + QDeclarativeComponent component(&engine, TEST_FILE("conflicting.3.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(qvariant_cast(object->property("font")).pixelSize(), 12); + + QMetaObject::invokeMethod(object, "toggle"); + + QCOMPARE(qvariant_cast(object->property("font")).pixelSize(), 24); + + QMetaObject::invokeMethod(object, "toggle"); + + QCOMPARE(qvariant_cast(object->property("font")).pixelSize(), 12); + + delete object; + } +} + QTEST_MAIN(tst_qdeclarativevaluetypes) #include "tst_qdeclarativevaluetypes.moc" -- cgit v0.12 From 162287900e724947e976ec5bdcc1bcb99639b5ab Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Thu, 11 Mar 2010 17:32:52 +1000 Subject: Fix test, fix warning consistency. address.com must really get sick of test robots. --- src/declarative/util/qdeclarativefontloader.cpp | 1 + .../declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/declarative/util/qdeclarativefontloader.cpp b/src/declarative/util/qdeclarativefontloader.cpp index 0509242..bf98d40 100644 --- a/src/declarative/util/qdeclarativefontloader.cpp +++ b/src/declarative/util/qdeclarativefontloader.cpp @@ -231,6 +231,7 @@ void QDeclarativeFontLoader::replyFinished() d->addFontToDatabase(ba); } else { d->status = Error; + qWarning() << "Cannot load font:" << d->reply->url(); emit statusChanged(); } d->reply->deleteLater(); diff --git a/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp b/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp index a9762df..add3c7b 100644 --- a/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp +++ b/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp @@ -139,8 +139,8 @@ void tst_qdeclarativefontloader::webFont() void tst_qdeclarativefontloader::failWebFont() { - QString componentStr = "import Qt 4.6\nFontLoader { source: \"http://wrong.address.com/Starburst.ttf\" }"; - QTest::ignoreMessage(QtWarningMsg, "Cannot load font: QUrl( \"http://wrong.address.com/Starburst.ttf\" ) "); + QString componentStr = "import Qt 4.6\nFontLoader { source: \"http://wrong.address.nokia.com/Starburst.ttf\" }"; + QTest::ignoreMessage(QtWarningMsg, "Cannot load font: QUrl( \"http://wrong.address.nokia.com/Starburst.ttf\" ) "); QDeclarativeComponent component(&engine); component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); QDeclarativeFontLoader *fontObject = qobject_cast(component.create()); -- cgit v0.12 From 303730a3fdd399a3e0a65b08338b4db75aa2acee Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 11 Mar 2010 17:53:42 +1000 Subject: Replace QDeclarativeContext::addDefaultObject() -> setContextObject() It is faster and easier to use to just support a single context object. --- demos/declarative/minehunt/minehunt.cpp | 2 +- .../graphicsitems/qdeclarativeloader.cpp | 2 +- .../graphicsitems/qdeclarativevisualitemmodel.cpp | 6 ++-- .../qml/qdeclarativecompiledbindings.cpp | 4 +-- src/declarative/qml/qdeclarativecontext.cpp | 29 ++++++++++++-------- src/declarative/qml/qdeclarativecontext.h | 7 +++-- src/declarative/qml/qdeclarativecontext_p.h | 3 +- .../qml/qdeclarativecontextscriptclass.cpp | 26 ++++++------------ .../qml/qdeclarativecontextscriptclass_p.h | 1 - src/declarative/qml/qdeclarativevme.cpp | 2 +- .../tst_qdeclarativecontext.cpp | 32 ++++------------------ .../declarative/qdeclarativeecmascript/testtypes.h | 10 +------ .../tst_qdeclarativeecmascript.cpp | 12 ++++---- .../tst_qdeclarativelistmodel.cpp | 2 +- 14 files changed, 50 insertions(+), 88 deletions(-) diff --git a/demos/declarative/minehunt/minehunt.cpp b/demos/declarative/minehunt/minehunt.cpp index 2e1b5b3..5e44d1b 100644 --- a/demos/declarative/minehunt/minehunt.cpp +++ b/demos/declarative/minehunt/minehunt.cpp @@ -303,7 +303,7 @@ class MinehuntExtensionPlugin : public QDeclarativeExtensionPlugin MinehuntGame* game = new MinehuntGame(); - engine->rootContext()->addDefaultObject(game); + engine->rootContext()->setContextObject(game); } }; diff --git a/src/declarative/graphicsitems/qdeclarativeloader.cpp b/src/declarative/graphicsitems/qdeclarativeloader.cpp index c9e80ee..61a32e5 100644 --- a/src/declarative/graphicsitems/qdeclarativeloader.cpp +++ b/src/declarative/graphicsitems/qdeclarativeloader.cpp @@ -273,7 +273,7 @@ void QDeclarativeLoaderPrivate::_q_sourceLoaded() if (component) { QDeclarativeContext *ctxt = new QDeclarativeContext(qmlContext(q)); - ctxt->addDefaultObject(q); + ctxt->setContextObject(q); if (!component->errors().isEmpty()) { qWarning() << component->errors(); diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp index 6bad4da..6341764 100644 --- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp +++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp @@ -196,7 +196,7 @@ QVariant QDeclarativeVisualItemModel::evaluate(int index, const QString &express return QVariant(); QDeclarativeContext *ccontext = qmlContext(this); QDeclarativeContext *ctxt = new QDeclarativeContext(ccontext); - ctxt->addDefaultObject(d->children.at(index)); + ctxt->setContextObject(d->children.at(index)); QDeclarativeExpression e(ctxt, expression, objectContext); QVariant value = e.value(); delete ctxt; @@ -991,7 +991,7 @@ QDeclarativeItem *QDeclarativeVisualDataModel::item(int index, const QByteArray QDeclarativeContext *ctxt = new QDeclarativeContext(ccontext); QDeclarativeVisualDataModelData *data = new QDeclarativeVisualDataModelData(index, this); ctxt->setContextProperty(QLatin1String("model"), data); - ctxt->addDefaultObject(data); + ctxt->setContextObject(data); nobj = d->m_delegate->beginCreate(ctxt); if (complete) d->m_delegate->completeCreate(); @@ -1104,7 +1104,7 @@ QVariant QDeclarativeVisualDataModel::evaluate(int index, const QString &express if (!ccontext) ccontext = qmlContext(this); QDeclarativeContext *ctxt = new QDeclarativeContext(ccontext); QDeclarativeVisualDataModelData *data = new QDeclarativeVisualDataModelData(index, this); - ctxt->addDefaultObject(data); + ctxt->setContextObject(data); QDeclarativeExpression e(ctxt, expression, objectContext); value = e.value(); delete data; diff --git a/src/declarative/qml/qdeclarativecompiledbindings.cpp b/src/declarative/qml/qdeclarativecompiledbindings.cpp index b35b5b5..c66a417 100644 --- a/src/declarative/qml/qdeclarativecompiledbindings.cpp +++ b/src/declarative/qml/qdeclarativecompiledbindings.cpp @@ -845,7 +845,7 @@ void QDeclarativeCompiledBindingsPrivate::findgeneric(Register *output, } } - if (QObject *root = context->defaultObjects.isEmpty()?0:context->defaultObjects.first()) { + if (QObject *root = context->contextObject) { if (findproperty(root, output, enginePriv, subIdx, name, isTerminal)) return; @@ -1086,7 +1086,7 @@ void QDeclarativeCompiledBindingsPrivate::run(int instrIndex, break; case Instr::LoadRoot: - registers[instr->load.reg].setQObject(context->defaultObjects.at(0)); + registers[instr->load.reg].setQObject(context->contextObject); break; case Instr::LoadAttached: diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp index 356a4ab..58de1a7 100644 --- a/src/declarative/qml/qdeclarativecontext.cpp +++ b/src/declarative/qml/qdeclarativecontext.cpp @@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE QDeclarativeContextPrivate::QDeclarativeContextPrivate() : parent(0), engine(0), isInternal(false), propertyNames(0), - notifyIndex(-1), highPriorityCount(0), imports(0), expressions(0), contextObjects(0), + notifyIndex(-1), contextObject(0), imports(0), expressions(0), contextObjects(0), idValues(0), idValueCount(0), optimizedBindings(0) { } @@ -172,7 +172,7 @@ void QDeclarativeContextPrivate::init() MyDataSet myDataSet; QDeclarativeEngine engine; QDeclarativeContext context(engine.rootContext()); - context.addDefaultObject(&myDataSet); + context.setContextObject(&myDataSet); QDeclarativeComponent component(&engine, "ListView { model=myModel }"); component.create(&context); @@ -365,13 +365,21 @@ QDeclarativeContext *QDeclarativeContext::parentContext() const } /*! - Add \a defaultObject to this context. The object will be added after - any existing default objects. + Return the context object, or 0 if there is no context object. */ -void QDeclarativeContext::addDefaultObject(QObject *defaultObject) +QObject *QDeclarativeContext::contextObject() const +{ + Q_D(const QDeclarativeContext); + return d->contextObject; +} + +/*! + Set the context \a object. +*/ +void QDeclarativeContext::setContextObject(QObject *object) { Q_D(QDeclarativeContext); - d->defaultObjects.prepend(defaultObject); + d->contextObject = object; } /*! @@ -466,15 +474,12 @@ QVariant QDeclarativeContext::contextProperty(const QString &name) const if (idx == -1) { QByteArray utf8Name = name.toUtf8(); - for (int ii = d->defaultObjects.count() - 1; ii >= 0; --ii) { - QObject *obj = d->defaultObjects.at(ii); + if (d->contextObject) { + QObject *obj = d->contextObject; QDeclarativePropertyCache::Data local; QDeclarativePropertyCache::Data *property = QDeclarativePropertyCache::property(d->engine, obj, name, local); - if (property) { - value = obj->metaObject()->property(property->coreIndex).read(obj); - break; - } + if (property) value = obj->metaObject()->property(property->coreIndex).read(obj); } if (!value.isValid() && parentContext()) value = parentContext()->contextProperty(name); diff --git a/src/declarative/qml/qdeclarativecontext.h b/src/declarative/qml/qdeclarativecontext.h index 0fb9bee..3ad9863 100644 --- a/src/declarative/qml/qdeclarativecontext.h +++ b/src/declarative/qml/qdeclarativecontext.h @@ -72,11 +72,12 @@ public: QDeclarativeEngine *engine() const; QDeclarativeContext *parentContext() const; - void addDefaultObject(QObject *); - void setContextProperty(const QString &, QObject *); - void setContextProperty(const QString &, const QVariant &); + QObject *contextObject() const; + void setContextObject(QObject *); QVariant contextProperty(const QString &) const; + void setContextProperty(const QString &, QObject *); + void setContextProperty(const QString &, const QVariant &); QUrl resolvedUrl(const QUrl &); diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h index 5b597fa..ba9aa41 100644 --- a/src/declarative/qml/qdeclarativecontext_p.h +++ b/src/declarative/qml/qdeclarativecontext_p.h @@ -94,8 +94,7 @@ public: QList propertyValues; int notifyIndex; - QObjectList defaultObjects; - int highPriorityCount; + QObject *contextObject; QList scripts; void addScript(const QDeclarativeParser::Object::ScriptBlock &, QObject *); diff --git a/src/declarative/qml/qdeclarativecontextscriptclass.cpp b/src/declarative/qml/qdeclarativecontextscriptclass.cpp index 5fcf4e2..874eeac 100644 --- a/src/declarative/qml/qdeclarativecontextscriptclass.cpp +++ b/src/declarative/qml/qdeclarativecontextscriptclass.cpp @@ -80,7 +80,7 @@ struct ContextData : public QScriptDeclarativeClass::Object { */ QDeclarativeContextScriptClass::QDeclarativeContextScriptClass(QDeclarativeEngine *bindEngine) : QDeclarativeScriptClass(QDeclarativeEnginePrivate::getScriptEngine(bindEngine)), engine(bindEngine), - lastScopeObject(0), lastContext(0), lastData(0), lastPropertyIndex(-1), lastDefaultObject(-1) + lastScopeObject(0), lastContext(0), lastData(0), lastPropertyIndex(-1) { } @@ -132,7 +132,6 @@ QDeclarativeContextScriptClass::queryProperty(Object *object, const Identifier & lastContext = 0; lastData = 0; lastPropertyIndex = -1; - lastDefaultObject = -1; QDeclarativeContext *bindContext = ((ContextData *)object)->getContext(engine); QObject *scopeObject = ((ContextData *)object)->getScope(engine); @@ -210,13 +209,13 @@ QDeclarativeContextScriptClass::queryProperty(QDeclarativeContext *bindContext, } } - for (int ii = cp->defaultObjects.count() - 1; ii >= 0; --ii) { + if (cp->contextObject) { QScriptClass::QueryFlags rv = - ep->objectClass->queryProperty(cp->defaultObjects.at(ii), name, flags, bindContext, + ep->objectClass->queryProperty(cp->contextObject, name, flags, bindContext, QDeclarativeObjectScriptClass::ImplicitObject | QDeclarativeObjectScriptClass::SkipAttachedProperties); if (rv) { - lastDefaultObject = ii; + lastScopeObject = cp->contextObject; lastContext = bindContext; return rv; } @@ -244,9 +243,9 @@ QDeclarativeContextScriptClass::property(Object *object, const Identifier &name) } else if (lastData) { if (lastData->type) - return Value(scriptEngine, ep->typeNameClass->newObject(cp->defaultObjects.at(0), lastData->type)); + return Value(scriptEngine, ep->typeNameClass->newObject(cp->contextObject, lastData->type)); else - return Value(scriptEngine, ep->typeNameClass->newObject(cp->defaultObjects.at(0), lastData->typeNamespace)); + return Value(scriptEngine, ep->typeNameClass->newObject(cp->contextObject, lastData->typeNamespace)); } else if (lastPropertyIndex != -1) { @@ -267,10 +266,6 @@ QDeclarativeContextScriptClass::property(Object *object, const Identifier &name) return Value(scriptEngine, rv); - } else if(lastDefaultObject != -1) { - - // Default object property - return ep->objectClass->property(cp->defaultObjects.at(lastDefaultObject), name); } else { @@ -283,7 +278,7 @@ void QDeclarativeContextScriptClass::setProperty(Object *object, const Identifie const QScriptValue &value) { Q_UNUSED(object); - Q_ASSERT(lastScopeObject || lastDefaultObject != -1); + Q_ASSERT(lastScopeObject); QDeclarativeContext *bindContext = lastContext; Q_ASSERT(bindContext); @@ -291,12 +286,7 @@ void QDeclarativeContextScriptClass::setProperty(Object *object, const Identifie QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); QDeclarativeContextPrivate *cp = QDeclarativeContextPrivate::get(bindContext); - if (lastScopeObject) { - ep->objectClass->setProperty(lastScopeObject, name, value, bindContext); - } else { - ep->objectClass->setProperty(cp->defaultObjects.at(lastDefaultObject), name, value, - bindContext); - } + ep->objectClass->setProperty(lastScopeObject, name, value, bindContext); } QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativecontextscriptclass_p.h b/src/declarative/qml/qdeclarativecontextscriptclass_p.h index 4b0dca0..32c117c 100644 --- a/src/declarative/qml/qdeclarativecontextscriptclass_p.h +++ b/src/declarative/qml/qdeclarativecontextscriptclass_p.h @@ -90,7 +90,6 @@ private: QDeclarativeContext *lastContext; QDeclarativeTypeNameCache::Data *lastData; int lastPropertyIndex; - int lastDefaultObject; QScriptValue lastFunction; uint m_id; diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp index d916900..055a857 100644 --- a/src/declarative/qml/qdeclarativevme.cpp +++ b/src/declarative/qml/qdeclarativevme.cpp @@ -237,7 +237,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, QDeclarati case QDeclarativeInstruction::SetDefault: { QObject *target = stack.top(); - ctxt->addDefaultObject(target); + ctxt->setContextObject(target); } break; diff --git a/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp b/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp index f0117f5..b212820 100644 --- a/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp +++ b/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp @@ -58,7 +58,7 @@ private slots: void engineMethod(); void parentContext(); void setContextProperty(); - void addDefaultObject(); + void setContextObject(); void destruction(); void idAsContextProperty(); @@ -224,24 +224,6 @@ private: int _c; }; -class TestObject2 : public QObject -{ - Q_OBJECT - Q_PROPERTY(int b READ b NOTIFY bChanged) - -public: - TestObject2() : _b(10) {} - - int b() const { return _b; } - void setB(int b) { _b = b; emit bChanged(); } - -signals: - void bChanged(); - -private: - int _b; -}; - #define TEST_CONTEXT_PROPERTY(ctxt, name, value) \ { \ QDeclarativeComponent component(&engine); \ @@ -367,35 +349,31 @@ void tst_qdeclarativecontext::setContextProperty() } } -void tst_qdeclarativecontext::addDefaultObject() +void tst_qdeclarativecontext::setContextObject() { QDeclarativeContext ctxt(&engine); TestObject to; - TestObject2 to2; to.setA(2); to.setB(192); to.setC(18); - to2.setB(111999); - ctxt.addDefaultObject(&to2); - ctxt.addDefaultObject(&to); + ctxt.setContextObject(&to); ctxt.setContextProperty("c", QVariant(9)); // Static context properties TEST_CONTEXT_PROPERTY(&ctxt, a, QVariant(2)); - TEST_CONTEXT_PROPERTY(&ctxt, b, QVariant(111999)); + TEST_CONTEXT_PROPERTY(&ctxt, b, QVariant(192)); TEST_CONTEXT_PROPERTY(&ctxt, c, QVariant(9)); to.setA(12); to.setB(100); to.setC(7); - to2.setB(1612); ctxt.setContextProperty("c", QVariant(3)); TEST_CONTEXT_PROPERTY(&ctxt, a, QVariant(12)); - TEST_CONTEXT_PROPERTY(&ctxt, b, QVariant(1612)); + TEST_CONTEXT_PROPERTY(&ctxt, b, QVariant(100)); TEST_CONTEXT_PROPERTY(&ctxt, c, QVariant(3)); // Changes in context properties diff --git a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h index a283e3f..78a5e0f 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h +++ b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h @@ -207,18 +207,10 @@ class MyDefaultObject1 : public QObject Q_OBJECT Q_PROPERTY(int horseLegs READ horseLegs CONSTANT); Q_PROPERTY(int antLegs READ antLegs CONSTANT); + Q_PROPERTY(int emuLegs READ emuLegs CONSTANT); public: int horseLegs() const { return 4; } int antLegs() const { return 6; } -}; - -class MyDefaultObject2 : public QObject -{ - Q_OBJECT - Q_PROPERTY(int antLegs READ antLegs CONSTANT); - Q_PROPERTY(int emuLegs READ emuLegs CONSTANT); -public: - int antLegs() const { return 5; } // Had an accident int emuLegs() const { return 2; } }; diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index bdd2c93..caefdbf 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -350,7 +350,6 @@ void tst_qdeclarativeecmascript::basicExpressions() MyQmlObject object2; MyQmlObject object3; MyDefaultObject1 default1; - MyDefaultObject2 default2; MyDefaultObject3 default3; object1.setStringProperty("Object1"); object2.setStringProperty("Object2"); @@ -359,13 +358,12 @@ void tst_qdeclarativeecmascript::basicExpressions() QDeclarativeContext context(engine.rootContext()); QDeclarativeContext nestedContext(&context); - context.addDefaultObject(&default1); - context.addDefaultObject(&default2); + context.setContextObject(&default1); context.setContextProperty("a", QVariant(1944)); context.setContextProperty("b", QVariant("Milk")); context.setContextProperty("object", &object1); context.setContextProperty("objectOverride", &object2); - nestedContext.addDefaultObject(&default3); + nestedContext.setContextObject(&default3); nestedContext.setContextProperty("b", QVariant("Cow")); nestedContext.setContextProperty("objectOverride", &object3); nestedContext.setContextProperty("millipedeLegs", QVariant(100)); @@ -1639,7 +1637,7 @@ void tst_qdeclarativeecmascript::listToVariant() MyQmlContainer container; QDeclarativeContext context(engine.rootContext()); - context.addDefaultObject(&container); + context.setContextObject(&container); QObject *object = component.create(&context); QVERIFY(object != 0); @@ -1911,7 +1909,7 @@ void tst_qdeclarativeecmascript::ownership() { OwnershipObject own; QDeclarativeContext *context = new QDeclarativeContext(engine.rootContext()); - context->addDefaultObject(&own); + context->setContextObject(&own); { QDeclarativeComponent component(&engine, TEST_FILE("ownership.qml")); @@ -1971,7 +1969,7 @@ void tst_qdeclarativeecmascript::qlistqobjectMethods() { QListQObjectMethodsObject obj; QDeclarativeContext *context = new QDeclarativeContext(engine.rootContext()); - context->addDefaultObject(&obj); + context->setContextObject(&obj); QDeclarativeComponent component(&engine, TEST_FILE("qlistqobjectMethods.qml")); diff --git a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp index a1e6d6b..1b59608 100644 --- a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp +++ b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp @@ -214,7 +214,7 @@ void tst_QDeclarativeListModel::dynamic() QDeclarativeEngine engine; QDeclarativeListModel model; QDeclarativeEngine::setContextForObject(&model,engine.rootContext()); - engine.rootContext()->addDefaultObject(&model); + engine.rootContext()->setContextObject(&model); QDeclarativeExpression e(engine.rootContext(), script, &model); if (!warning.isEmpty()) QTest::ignoreMessage(QtWarningMsg, warning.toLatin1()); -- cgit v0.12 From 9e504323b679d7fedfcfd975f202cc6dd96c9dcb Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 11 Mar 2010 17:58:03 +1000 Subject: Update QmlChanges.txt --- src/declarative/QmlChanges.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt index f83dd58..5386144 100644 --- a/src/declarative/QmlChanges.txt +++ b/src/declarative/QmlChanges.txt @@ -51,6 +51,9 @@ should also consider using the QmlExtensionPlugin (previously named QmlModulePlu as a cleaner mechanism for publishing libraries of QML types, or the upcoming application plugin features of the qmlviewer / qmlruntime / qml. +QDeclarativeContext::addDefaultObject() has been replaced with +QDeclarativeContext::setContextObject() + PropertyAnimation ------------------ matchProperties and matchTargets have been renamed back to properties and targets. -- cgit v0.12 From af7e91af39ea6e9bb64794d7be2f4ade52c17be2 Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Thu, 11 Mar 2010 17:59:23 +1000 Subject: fix particles plugin --- src/imports/particles/qdeclarativeparticles.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/imports/particles/qdeclarativeparticles.cpp b/src/imports/particles/qdeclarativeparticles.cpp index caa0754..9adf780 100644 --- a/src/imports/particles/qdeclarativeparticles.cpp +++ b/src/imports/particles/qdeclarativeparticles.cpp @@ -411,6 +411,20 @@ public: QDeclarativeParticlesPrivate* d; }; +//an animation that just gives a tick +template +class TickAnimationProxy : public QAbstractAnimation +{ +public: + TickAnimationProxy(T *p, QObject *parent = 0) : QAbstractAnimation(parent), m_p(p) {} + virtual int duration() const { return -1; } +protected: + virtual void updateCurrentTime(int msec) { (m_p->*method)(msec); } + +private: + T *m_p; +}; + //--------------------------------------------------------------------------- class QDeclarativeParticlesPrivate : public QDeclarativeItemPrivate { @@ -463,7 +477,7 @@ public: QList > bursts;//countLeft, emissionRate pairs QList particles; - QTickAnimationProxy clock; + TickAnimationProxy clock; }; -- cgit v0.12 From 02c95426f67d7e664cb02ef6bbf3697ce8dac373 Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Thu, 11 Mar 2010 18:20:41 +1000 Subject: no need to include this private header --- src/imports/particles/qdeclarativeparticles.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/imports/particles/qdeclarativeparticles.cpp b/src/imports/particles/qdeclarativeparticles.cpp index 9adf780..bb6669a 100644 --- a/src/imports/particles/qdeclarativeparticles.cpp +++ b/src/imports/particles/qdeclarativeparticles.cpp @@ -45,7 +45,7 @@ #include #include -#include +#include #include #include -- cgit v0.12 From dc234e69f73ec7d83a0e63b7bdf197f88bc1fad9 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 11 Mar 2010 18:25:35 +1000 Subject: Cosmetic tweaks --- src/declarative/qml/qdeclarativevme.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp index 055a857..05553fd 100644 --- a/src/declarative/qml/qdeclarativevme.cpp +++ b/src/declarative/qml/qdeclarativevme.cpp @@ -130,9 +130,9 @@ void QDeclarativeVME::runDeferred(QObject *object) } QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, QDeclarativeContext *ctxt, - QDeclarativeCompiledData *comp, - int start, int count, - const QBitField &bindingSkipList) + QDeclarativeCompiledData *comp, + int start, int count, + const QBitField &bindingSkipList) { Q_ASSERT(comp); Q_ASSERT(ctxt); @@ -834,11 +834,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, QDeclarati if (parserStatus.count) ep->parserStatus << parserStatus; - if (stack.isEmpty()) - return 0; - else - return stack.top(); - return 0; + Q_ASSERT(stack.count() == 1); + return stack.top(); } bool QDeclarativeVME::isError() const -- cgit v0.12 From 631a574fbefb6f7c104ebbf1f4da4c02267030a7 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 11 Mar 2010 19:30:09 +1000 Subject: Crash --- src/declarative/qml/qdeclarativevme_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarative/qml/qdeclarativevme_p.h b/src/declarative/qml/qdeclarativevme_p.h index 951f6a7..bcd3ac9 100644 --- a/src/declarative/qml/qdeclarativevme_p.h +++ b/src/declarative/qml/qdeclarativevme_p.h @@ -71,7 +71,7 @@ template class QDeclarativeVMEStack { public: QDeclarativeVMEStack() : index(-1), maxSize(N), data(fixedData) {} - ~QDeclarativeVMEStack() { if (data != fixedData) qFree(fixedData); } + ~QDeclarativeVMEStack() { if (data != fixedData) qFree(data); } bool isEmpty() const { return index == -1; } const T &top() const { return data[index]; } -- cgit v0.12 From 62c72ed2fd4aa6f5e62a190abf2dde2ba0f5ff0b Mon Sep 17 00:00:00 2001 From: mae Date: Thu, 11 Mar 2010 18:32:04 +0100 Subject: Fix importing qml modules from rcc resources Done with Roberto. Reviewed-by: Roberto Raggi --- src/corelib/io/qresource.cpp | 8 +- .../qml/qdeclarativecompositetypemanager.cpp | 13 +--- src/declarative/qml/qdeclarativeengine.cpp | 87 ++++++++++++---------- src/declarative/qml/qdeclarativeengine_p.h | 2 +- 4 files changed, 56 insertions(+), 54 deletions(-) diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index 6d33c8b..8e76e9e 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -1411,8 +1411,12 @@ QString QResourceFileEngine::fileName(FileName file) const } else if(file == PathName || file == AbsolutePathName) { const QString path = (file == AbsolutePathName) ? d->resource.absoluteFilePath() : d->resource.fileName(); const int slash = path.lastIndexOf(QLatin1Char('/')); - if (slash != -1) - return path.left(slash); + if (slash == -1) + return QLatin1String(":"); + else if (slash <= 1) + return QLatin1String(":/"); + return path.left(slash); + } else if(file == CanonicalName || file == CanonicalPathName) { const QString absoluteFilePath = d->resource.absoluteFilePath(); if(file == CanonicalPathName) { diff --git a/src/declarative/qml/qdeclarativecompositetypemanager.cpp b/src/declarative/qml/qdeclarativecompositetypemanager.cpp index 9b3a8b4..b0c2f6d 100644 --- a/src/declarative/qml/qdeclarativecompositetypemanager.cpp +++ b/src/declarative/qml/qdeclarativecompositetypemanager.cpp @@ -506,17 +506,6 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData int waiting = 0; foreach (QDeclarativeScriptParser::Import imp, unit->data.imports()) { - QString qmldir; - if (imp.type == QDeclarativeScriptParser::Import::File && imp.qualifier.isEmpty()) { - QString importUrl = unit->imports.baseUrl().resolved(QUrl(imp.uri + QLatin1String("/qmldir"))).toString(); - for (int ii = 0; ii < unit->resources.count(); ++ii) { - if (unit->resources.at(ii)->url == importUrl) { - qmldir = QString::fromUtf8(unit->resources.at(ii)->data); - break; - } - } - } - int vmaj = -1; int vmin = -1; if (!imp.version.isEmpty()) { @@ -531,7 +520,7 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData } if (!QDeclarativeEnginePrivate::get(engine)-> - addToImport(&unit->imports, qmldir, imp.uri, imp.qualifier, vmaj, vmin, imp.type)) + addToImport(&unit->imports, imp.uri, imp.qualifier, vmaj, vmin, imp.type)) { QDeclarativeError error; error.setUrl(unit->imports.baseUrl()); diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 41c0f5c..a32e6c3 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1361,10 +1361,13 @@ QVariant QDeclarativeScriptClass::toVariant(QDeclarativeEngine *engine, const QS // XXX this beyonds in QUrl::toLocalFile() static QString toLocalFileOrQrc(const QUrl& url) { - QString r = url.toLocalFile(); - if (r.isEmpty() && url.scheme() == QLatin1String("qrc")) - r = QLatin1Char(':') + url.path(); - return r; + if (url.scheme() == QLatin1String("qrc")) { + if (url.authority().isEmpty()) + return QLatin1Char(':') + url.path(); + qWarning() << "Invalid url:" << url.toString() << "authority" << url.authority() << "not known."; + return QString(); + } + return url.toLocalFile(); } ///////////////////////////////////////////////////////////// @@ -1376,7 +1379,7 @@ struct QDeclarativeEnginePrivate::ImportedNamespace { QList isLibrary; QList qmlDirContent; - bool find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return, QUrl* url_return) const + bool find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return, QUrl* url_return) { for (int i=0; i=0 || !qmldircontent.isEmpty()) { - // Check version file - XXX cache these in QDeclarativeEngine! - if (qmldircontent.isEmpty()) { - QFile qmldir(toLocalFileOrQrc(QUrl(urls.at(i)+QLatin1String("/qmldir")))); - if (qmldir.open(QIODevice::ReadOnly)) { - qmldircontent = QString::fromUtf8(qmldir.readAll()); - } - } + if (vmaj>=0 && !qmldircontent.isEmpty()) { const QString typeName = QString::fromUtf8(type); @@ -1422,7 +1414,6 @@ struct QDeclarativeEnginePrivate::ImportedNamespace { if (c.typeName == typeName) { if (url_return) *url_return = url.resolved(QUrl(c.fileName)); - return true; } } @@ -1456,8 +1447,9 @@ public: QSet qmlDirFilesForWhichPluginsHaveBeenLoaded; - bool add(const QUrl& base, const QString& qmldircontent, const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType, const QStringList& importPath, QDeclarativeEngine *engine) + bool add(const QUrl& base, const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType, const QStringList& importPath, QDeclarativeEngine *engine) { + QString qmldircontent; QDeclarativeEnginePrivate::ImportedNamespace *s; if (prefix.isEmpty()) { s = &unqualifiedset; @@ -1470,15 +1462,21 @@ public: if (importType == QDeclarativeScriptParser::Import::Library) { url.replace(QLatin1Char('.'), QLatin1Char('/')); bool found = false; - QString content; QString dir; // user import paths QStringList paths; // base.. - paths += QFileInfo(base.toLocalFile()).path(); + QString localFileOrQrc = toLocalFileOrQrc(base); + QString localFileOrQrcPath = QFileInfo(localFileOrQrc).path(); + paths += localFileOrQrcPath; paths += importPath; + + QString applicationDirPath = QCoreApplication::applicationDirPath(); + if (!applicationDirPath.isEmpty()) + paths += applicationDirPath; + paths += QDeclarativeEnginePrivate::get(engine)->environmentImportPath; #if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) QString builtinPath = QLibraryInfo::location(QLibraryInfo::ImportsPath); @@ -1490,6 +1488,7 @@ public: foreach (const QString &p, paths) { dir = p+QLatin1Char('/')+url; + QFileInfo fi(dir+QLatin1String("/qmldir")); const QString absoluteFilePath = fi.absoluteFilePath(); @@ -1499,22 +1498,31 @@ public: url = QUrl::fromLocalFile(fi.absolutePath()).toString(); QFile file(absoluteFilePath); - if (file.open(QFile::ReadOnly)) - content = QString::fromUtf8(file.readAll()); + if (file.open(QFile::ReadOnly)) { + qmldircontent = QString::fromUtf8(file.readAll()); + if (qmlImportTrace()) + qDebug() << "QDeclarativeEngine::add: loaded" << absoluteFilePath; + } if (! qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(absoluteFilePath)) { qmlDirFilesForWhichPluginsHaveBeenLoaded.insert(absoluteFilePath); QDeclarativeDirParser qmldirParser; - qmldirParser.setSource(content); + qmldirParser.setSource(qmldircontent); qmldirParser.parse(); foreach (const QDeclarativeDirParser::Plugin &plugin, qmldirParser.plugins()) { - QString resolvedFilePath = QDeclarativeEnginePrivate::get(engine)->resolvePlugin(QDir(dir + QDir::separator() + plugin.path), - plugin.name); - - if (!resolvedFilePath.isEmpty()) + QDir pluginDir(dir + QDir::separator() + plugin.path); + if (p.startsWith(QLatin1Char(':'))) + pluginDir = QDir(QCoreApplication::applicationDirPath()); + QString resolvedFilePath = + QDeclarativeEnginePrivate::get(engine) + ->resolvePlugin(pluginDir, + plugin.name); + + if (!resolvedFilePath.isEmpty()) { engine->importExtension(resolvedFilePath, uri); + } } } @@ -1702,9 +1710,10 @@ QUrl QDeclarativeEnginePrivate::Imports::baseUrl() const type version mapping and possibly declarative extensions plugins. The engine searches in the base directory of the qml file, then - the paths added via addImportPath(), then the paths specified in the - \c QML_IMPORT_PATH environment variable, then the builtin \c ImportsPath from - QLibraryInfo. + the paths added via addImportPath(), then in the directory containing the + application executable (QCoreApplication::applicationDirPath()), + then the paths specified in the \c QML_IMPORT_PATH environment variable, then the + builtin \c ImportsPath from QLibraryInfo. */ void QDeclarativeEngine::addImportPath(const QString& path) @@ -1721,6 +1730,8 @@ void QDeclarativeEngine::addImportPath(const QString& path) */ bool QDeclarativeEngine::importExtension(const QString &fileName, const QString &uri) { + if (qmlImportTrace()) + qDebug() << "QDeclarativeEngine::importExtension" << uri << "from" << fileName; QFileInfo fileInfo(fileName); const QString absoluteFilePath = fileInfo.absoluteFilePath(); QPluginLoader loader(absoluteFilePath); @@ -1893,12 +1904,12 @@ QString QDeclarativeEnginePrivate::resolvePlugin(const QDir &dir, const QString The base URL must already have been set with Import::setBaseUrl(). */ -bool QDeclarativeEnginePrivate::addToImport(Imports* imports, const QString& qmldircontent, const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType) const +bool QDeclarativeEnginePrivate::addToImport(Imports* imports, const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType) const { QDeclarativeEngine *engine = QDeclarativeEnginePrivate::get(const_cast(this)); - bool ok = imports->d->add(imports->d->base,qmldircontent,uri,prefix,vmaj,vmin,importType,fileImportPath, engine); if (qmlImportTrace()) - qDebug() << "QDeclarativeEngine::addToImport(" << imports << uri << prefix << vmaj << '.' << vmin << (importType==QDeclarativeScriptParser::Import::Library? "Library" : "File") << ": " << ok; + qDebug() << "QDeclarativeEngine::addToImport(" << imports << uri << prefix << vmaj << '.' << vmin << (importType==QDeclarativeScriptParser::Import::Library? "Library" : "File"); + bool ok = imports->d->add(imports->d->base,uri,prefix,vmaj,vmin,importType,fileImportPath, engine); return ok; } @@ -1918,8 +1929,6 @@ bool QDeclarativeEnginePrivate::resolveType(const Imports& imports, const QByteA { ImportedNamespace* ns = imports.d->findNamespace(QString::fromUtf8(type)); if (ns) { - if (qmlImportTrace()) - qDebug() << "QDeclarativeEngine::resolveType" << type << "is namespace for" << ns->urls; if (ns_return) *ns_return = ns; return true; @@ -1927,15 +1936,15 @@ bool QDeclarativeEnginePrivate::resolveType(const Imports& imports, const QByteA if (type_return || url_return) { if (imports.d->find(type,vmaj,vmin,type_return,url_return)) { if (qmlImportTrace()) { + if (type_return && *type_return && url_return && !url_return->isEmpty()) + qDebug() << "QDeclarativeEngine::resolveType" << type << '=' << (*type_return)->typeName() << *url_return; if (type_return && *type_return) qDebug() << "QDeclarativeEngine::resolveType" << type << '=' << (*type_return)->typeName(); - if (url_return) + if (url_return && !url_return->isEmpty()) qDebug() << "QDeclarativeEngine::resolveType" << type << '=' << *url_return; } return true; } - if (qmlImportTrace()) - qDebug() << "QDeclarativeEngine::resolveType" << type << "not found"; } return false; } diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h index 459a325..fb63164 100644 --- a/src/declarative/qml/qdeclarativeengine_p.h +++ b/src/declarative/qml/qdeclarativeengine_p.h @@ -276,7 +276,7 @@ public: QString resolvePlugin(const QDir &dir, const QString &baseName); - bool addToImport(Imports*, const QString& qmlDirContent,const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType) const; + bool addToImport(Imports*, const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType) const; bool resolveType(const Imports&, const QByteArray& type, QDeclarativeType** type_return, QUrl* url_return, int *version_major, int *version_minor, -- cgit v0.12 From 9388a088f91a46d8378c5fd9f16d682d41fe6a9a Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Fri, 12 Mar 2010 10:32:15 +1000 Subject: Remove Qt.closestAngle(). This functionality is now built in to RotationAnimation. --- doc/src/declarative/globalobject.qdoc | 12 ------------ src/declarative/qml/qdeclarativeengine.cpp | 20 -------------------- src/declarative/qml/qdeclarativeengine_p.h | 1 - .../declarative/qdeclarativeqt/data/closestangle.qml | 12 ------------ .../qdeclarativeqt/tst_qdeclarativeqt.cpp | 18 ------------------ 5 files changed, 63 deletions(-) delete mode 100644 tests/auto/declarative/qdeclarativeqt/data/closestangle.qml diff --git a/doc/src/declarative/globalobject.qdoc b/doc/src/declarative/globalobject.qdoc index 4b1c7d3..9f6be12 100644 --- a/doc/src/declarative/globalobject.qdoc +++ b/doc/src/declarative/globalobject.qdoc @@ -182,18 +182,6 @@ This function returns a color 50% darker than \c baseColor. See QColor::darker() \image declarative-rect_tint.png Tint is most useful when a subtle change is intended to be conveyed due to some event; you can then use tinting to more effectively tune the visible color. -\section3 Qt.closestAngle(number fromAngle, number toAngle) -This function returns an equivalent angle to toAngle, such that the difference between fromAngle and toAngle is never more than 180 degrees. This is useful when animating angles using a NumberAnimation, which does not know about equivalent angles, when you always want to take the shortest path. - -For example, the following would rotate myItem counterclockwise from 350 degrees to 10 degrees, for a total of 340 degrees of rotation. -\qml -NumberAnimation { target: myItem; property: "rotation"; from: 350; to: 10 } -\endqml - -while the following would rotate myItem clockwise from 350 degrees to 370 degrees (which is visually equivilant to 10 degrees), for a total of 20 degrees of rotation. -\qml -NumberAnimation { target: myItem; property: "rotation"; from: 350; to: Qt.closetAngle(350, 10) } -\endqml \section3 Qt.openUrlExternally(url target) This function attempts to open the specified \c target url in an external application, based on the user's desktop preferences. It will return true if it succeeds, and false otherwise. diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index a32e6c3..72335d4 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -243,7 +243,6 @@ QDeclarativeScriptEngine::QDeclarativeScriptEngine(QDeclarativeEnginePrivate *pr qtObject.setProperty(QLatin1String("formatDateTime"),newFunction(QDeclarativeEnginePrivate::formatDateTime, 2)); //misc methods - qtObject.setProperty(QLatin1String("closestAngle"), newFunction(QDeclarativeEnginePrivate::closestAngle, 2)); qtObject.setProperty(QLatin1String("openUrlExternally"),newFunction(QDeclarativeEnginePrivate::desktopOpenUrl, 1)); qtObject.setProperty(QLatin1String("md5"),newFunction(QDeclarativeEnginePrivate::md5, 1)); qtObject.setProperty(QLatin1String("btoa"),newFunction(QDeclarativeEnginePrivate::btoa, 1)); @@ -1237,25 +1236,6 @@ QScriptValue QDeclarativeEnginePrivate::quit(QScriptContext * /*ctxt*/, QScriptE return QScriptValue(); } -QScriptValue QDeclarativeEnginePrivate::closestAngle(QScriptContext *ctxt, QScriptEngine *e) -{ - if(ctxt->argumentCount() < 2) - return e->newVariant(QVariant(0.0)); - qreal a = ctxt->argument(0).toNumber(); - qreal b = ctxt->argument(1).toNumber(); - qreal ret = b; - qreal diff = b-a; - while(diff > 180.0){ - ret -= 360.0; - diff -= 360.0; - } - while(diff < -180.0){ - ret += 360.0; - diff += 360.0; - } - return e->newVariant(QVariant(ret)); -} - QScriptValue QDeclarativeEnginePrivate::tint(QScriptContext *ctxt, QScriptEngine *engine) { if(ctxt->argumentCount() != 2) diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h index fb63164..0f8b90a 100644 --- a/src/declarative/qml/qdeclarativeengine_p.h +++ b/src/declarative/qml/qdeclarativeengine_p.h @@ -318,7 +318,6 @@ public: static QScriptValue darker(QScriptContext*, QScriptEngine*); static QScriptValue tint(QScriptContext*, QScriptEngine*); - static QScriptValue closestAngle(QScriptContext*, QScriptEngine*); static QScriptValue desktopOpenUrl(QScriptContext*, QScriptEngine*); static QScriptValue md5(QScriptContext*, QScriptEngine*); static QScriptValue btoa(QScriptContext*, QScriptEngine*); diff --git a/tests/auto/declarative/qdeclarativeqt/data/closestangle.qml b/tests/auto/declarative/qdeclarativeqt/data/closestangle.qml deleted file mode 100644 index b5f7fc6..0000000 --- a/tests/auto/declarative/qdeclarativeqt/data/closestangle.qml +++ /dev/null @@ -1,12 +0,0 @@ -import Qt 4.6 - -QtObject { - property var testSame: Qt.closestAngle(0,1) - property var testLess: Qt.closestAngle(0,-359) - property var testMore: Qt.closestAngle(0,361) - property var testFail: Qt.closestAngle(0) - property var test5: Qt.closestAngle(0,1,2) - property var test6: Qt.closestAngle(123.45465768,1.11) - property var test7: Qt.closestAngle(-3.1415,1.11) -} - diff --git a/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp b/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp index b70011b..debec02 100644 --- a/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp +++ b/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp @@ -66,7 +66,6 @@ private slots: void lighter(); void darker(); void tint(); - void closestAngle(); void openUrlExternally(); void md5(); void createComponent(); @@ -262,23 +261,6 @@ void tst_qdeclarativeqt::tint() delete object; } -void tst_qdeclarativeqt::closestAngle() -{ - QDeclarativeComponent component(&engine, TEST_FILE("closestangle.qml")); - QObject *object = component.create(); - QVERIFY(object != 0); - - QCOMPARE(qvariant_cast(object->property("testSame")), 1.0); - QCOMPARE(qvariant_cast(object->property("testLess")), 1.0); - QCOMPARE(qvariant_cast(object->property("testMore")), 1.0); - QCOMPARE(qvariant_cast(object->property("testFail")), 0.0); - QCOMPARE(qvariant_cast(object->property("test5")), 1.0); - QCOMPARE(qvariant_cast(object->property("test6")), 1.11); - QCOMPARE(qvariant_cast(object->property("test7")), 1.11); - - delete object; -} - void tst_qdeclarativeqt::openUrlExternally() { QEXPECT_FAIL("", "How do we test this?", Abort); -- cgit v0.12 From 8d8eee3821a5ae25516a17db2ccc1ca7ec614485 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Fri, 12 Mar 2010 10:36:21 +1000 Subject: Update QmlChanges.txt --- src/declarative/QmlChanges.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt index 5386144..ffdb02f 100644 --- a/src/declarative/QmlChanges.txt +++ b/src/declarative/QmlChanges.txt @@ -8,6 +8,7 @@ Flickable: renamed viewportX -> contentX Flickable: renamed viewportY -> contentY Removed Flickable.reportedVelocitySmoothing Removed Qt.playSound (replaced by SoundEffect element) +Removed Qt.closestAngle (use RotationAnimation instead) Removed NumberFormatter Removed DateTimeFormatter (use Qt.formatDateTime() instead) Renamed MouseRegion -> MouseArea @@ -17,6 +18,7 @@ Connection: syntax and rename: becomes: Connections { target: a; onFoo: xxx; onBar: yyy } Using WebView now requires "import org.webkit 1.0" +AnchorAnimation must now be used to animate anchor changes (and not NumberAnimation) QmlView ------- -- cgit v0.12 From 6936b5b2a1078a591d0bc5f2e49411c52156eb3d Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Fri, 12 Mar 2010 11:25:43 +1000 Subject: Revert "Use one thread for all instances." This reverts commit d4abbfdd1959a65ecfb997c962aa8ea132c77eaf. --- src/declarative/util/qdeclarativexmllistmodel.cpp | 34 ++++++++++------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp index 249880e..01ae2ed 100644 --- a/src/declarative/util/qdeclarativexmllistmodel.cpp +++ b/src/declarative/util/qdeclarativexmllistmodel.cpp @@ -61,6 +61,9 @@ QT_BEGIN_NAMESPACE + + + typedef QPair QDeclarativeXmlListRange; /*! @@ -111,6 +114,9 @@ class QDeclarativeXmlQuery : public QThread { Q_OBJECT public: + QDeclarativeXmlQuery(QObject *parent=0) + : QThread(parent), m_quit(false), m_restart(false), m_abort(false), m_queryId(0) { + } ~QDeclarativeXmlQuery() { m_mutex.lock(); m_quit = true; @@ -120,11 +126,6 @@ public: wait(); } - static QDeclarativeXmlQuery *instance() { - static QDeclarativeXmlQuery *query = new QDeclarativeXmlQuery; - return query; - } - void abort() { QMutexLocker locker(&m_mutex); m_abort = true; @@ -163,11 +164,6 @@ public: return m_removedItemRanges; } -private: - QDeclarativeXmlQuery(QObject *parent=0) - : QThread(parent), m_quit(false), m_restart(false), m_abort(false), m_queryId(0) { - } - Q_SIGNALS: void queryCompleted(int queryId, int size); @@ -217,8 +213,6 @@ private: QList m_removedItemRanges; }; -//Q_GLOBAL_STATIC(QDeclarativeXmlQuery, QDeclarativeXmlQuery::instance()); - void QDeclarativeXmlQuery::doQueryJob() { QString r; @@ -410,6 +404,7 @@ public: QNetworkReply *reply; QDeclarativeXmlListModel::Status status; qreal progress; + QDeclarativeXmlQuery qmlXmlQuery; int queryId; QList roleObjects; static void append_role(QDeclarativeListProperty *list, QDeclarativeXmlListModelRole *role); @@ -494,7 +489,8 @@ void QDeclarativeXmlListModelPrivate::clear_role(QDeclarativeListPropertyqmlXmlQuery, SIGNAL(queryCompleted(int,int)), this, SLOT(queryCompleted(int,int))); } @@ -727,7 +723,7 @@ void QDeclarativeXmlListModel::reload() if (!d->isComponentComplete) return; - QDeclarativeXmlQuery::instance()->abort(); + d->qmlXmlQuery.abort(); d->queryId = -1; int count = d->size; @@ -759,7 +755,7 @@ void QDeclarativeXmlListModel::reload() } if (!d->xml.isEmpty()) { - d->queryId = QDeclarativeXmlQuery::instance()->doQuery(d->query, d->namespaces, d->xml.toUtf8(), &d->roleObjects); + d->queryId = d->qmlXmlQuery.doQuery(d->query, d->namespaces, d->xml.toUtf8(), &d->roleObjects); d->progress = 1.0; d->status = Ready; emit progressChanged(d->progress); @@ -806,7 +802,7 @@ void QDeclarativeXmlListModel::requestFinished() } else { d->status = Ready; QByteArray data = d->reply->readAll(); - d->queryId = QDeclarativeXmlQuery::instance()->doQuery(d->query, d->namespaces, data, &d->roleObjects); + d->queryId = d->qmlXmlQuery.doQuery(d->query, d->namespaces, data, &d->roleObjects); disconnect(d->reply, 0, this, 0); d->reply->deleteLater(); d->reply = 0; @@ -832,10 +828,10 @@ void QDeclarativeXmlListModel::queryCompleted(int id, int size) return; bool sizeChanged = size != d->size; d->size = size; - d->data = QDeclarativeXmlQuery::instance()->modelData(); + d->data = d->qmlXmlQuery.modelData(); - QList removed = QDeclarativeXmlQuery::instance()->removedItemRanges(); - QList inserted = QDeclarativeXmlQuery::instance()->insertedItemRanges(); + QList removed = d->qmlXmlQuery.removedItemRanges(); + QList inserted = d->qmlXmlQuery.insertedItemRanges(); for (int i=0; i Date: Thu, 11 Mar 2010 20:16:05 +1000 Subject: Crash --- src/declarative/qml/qdeclarativeinstruction.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarative/qml/qdeclarativeinstruction.cpp b/src/declarative/qml/qdeclarativeinstruction.cpp index cf485fe..a23ff75 100644 --- a/src/declarative/qml/qdeclarativeinstruction.cpp +++ b/src/declarative/qml/qdeclarativeinstruction.cpp @@ -90,7 +90,7 @@ void QDeclarativeCompiledData::dump(QDeclarativeInstruction *instr, int idx) qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_STRING\t\t" << instr->storeString.propertyIndex << "\t" << instr->storeString.value << "\t\t" << primitives.at(instr->storeString.value); break; case QDeclarativeInstruction::StoreUrl: - qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_URL\t\t" << instr->storeUrl.propertyIndex << "\t" << instr->storeUrl.value << "\t\t" << primitives.at(instr->storeUrl.value); + qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_URL\t\t" << instr->storeUrl.propertyIndex << "\t" << instr->storeUrl.value << "\t\t" << urls.at(instr->storeUrl.value); break; case QDeclarativeInstruction::StoreColor: qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_COLOR\t\t" << instr->storeColor.propertyIndex << "\t\t\t" << QString::number(instr->storeColor.value, 16); -- cgit v0.12 From 93b789f196868f958b4d7dcfd45dbe27179b1b0f Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Fri, 12 Mar 2010 12:23:50 +1000 Subject: Reenable the QML binding optimizer for "safe" optimizations --- .../qml/qdeclarativecompiledbindings.cpp | 72 ++++++++++++++++++---- src/declarative/qml/qdeclarativecompiler.cpp | 29 +++++---- src/declarative/qml/qdeclarativenotifier.cpp | 3 +- src/declarative/qml/qdeclarativeparser.cpp | 5 +- src/declarative/qml/qdeclarativeparser_p.h | 2 + 5 files changed, 81 insertions(+), 30 deletions(-) diff --git a/src/declarative/qml/qdeclarativecompiledbindings.cpp b/src/declarative/qml/qdeclarativecompiledbindings.cpp index c66a417..aa549a9 100644 --- a/src/declarative/qml/qdeclarativecompiledbindings.cpp +++ b/src/declarative/qml/qdeclarativecompiledbindings.cpp @@ -48,12 +48,17 @@ #include #include #include +#include #include #include #include +#include QT_BEGIN_NAMESPACE +DEFINE_BOOL_CONFIG_OPTION(qmlExperimental, QML_EXPERIMENTAL); +DEFINE_BOOL_CONFIG_OPTION(qmlDisableOptimizer, QML_DISABLE_OPTIMIZER); + using namespace QDeclarativeJS; namespace { @@ -219,7 +224,6 @@ void QDeclarativeCompiledBindingsPrivate::Binding::setEnabled(bool e, QDeclarati { if (e) { addToObject(target); - update(flags); } else { removeFromObject(); } @@ -274,8 +278,6 @@ void QDeclarativeCompiledBindingsPrivate::run(Binding *binding) if (!binding->enabled) return; - if (binding->updating) - qWarning("ERROR: Circular binding"); QDeclarativeContext *context = q->QDeclarativeAbstractExpression::context(); if (!context) { @@ -284,6 +286,25 @@ void QDeclarativeCompiledBindingsPrivate::run(Binding *binding) } QDeclarativeContextPrivate *cp = QDeclarativeContextPrivate::get(context); + if (binding->updating) { + QString name; + if (binding->property & 0xFFFF0000) { + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(cp->engine); + + QDeclarativeValueType *vt = ep->valueTypes[(binding->property >> 16) & 0xFF]; + Q_ASSERT(vt); + + name = QLatin1String(binding->target->metaObject()->property(binding->property & 0xFFFF).name()); + name.append(QLatin1String(".")); + name.append(QLatin1String(vt->metaObject()->property(binding->property >> 24).name())); + } else { + name = binding->target->metaObject()->property(binding->property).name(); + } + qmlInfo(binding->target) << QCoreApplication::translate("QDeclarativeCompiledBindings", "Binding loop detected for property \"%1\"").arg(name); + return; + } + + binding->updating = true; if (binding->property & 0xFFFF0000) { QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(cp->engine); @@ -299,6 +320,7 @@ void QDeclarativeCompiledBindingsPrivate::run(Binding *binding) } else { run(binding->index, cp, binding, binding->scope, binding->target); } + binding->updating = false; } namespace { @@ -624,6 +646,7 @@ void QDeclarativeCompiledBindingsPrivate::subscribeId(QDeclarativeContextPrivate QDeclarativeCompiledBindingsPrivate::Subscription *sub = (subscriptions + subIndex); sub->target = q; sub->targetMethod = methodCount + subIndex; + sub->connect(&p->idValues[idIndex].bindings); } } @@ -634,7 +657,10 @@ void QDeclarativeCompiledBindingsPrivate::subscribe(QObject *o, int notifyIndex, QDeclarativeCompiledBindingsPrivate::Subscription *sub = (subscriptions + subIndex); sub->target = q; sub->targetMethod = methodCount + subIndex; - sub->connect(o, notifyIndex); + if (o) + sub->connect(o, notifyIndex); + else + sub->disconnect(); } // Conversion functions - these MUST match the QtScript expression path @@ -728,9 +754,9 @@ static QObject *variantToQObject(const QVariant &value, bool *ok) } bool QDeclarativeCompiledBindingsPrivate::findproperty(QObject *obj, Register *output, - QDeclarativeEnginePrivate *enginePriv, - int subIdx, const QScriptDeclarativeClass::Identifier &name, - bool isTerminal) + QDeclarativeEnginePrivate *enginePriv, + int subIdx, const QScriptDeclarativeClass::Identifier &name, + bool isTerminal) { if (!obj) { output->setUndefined(); @@ -801,10 +827,10 @@ bool QDeclarativeCompiledBindingsPrivate::findproperty(QObject *obj, Register *o } void QDeclarativeCompiledBindingsPrivate::findgeneric(Register *output, - int subIdx, - QDeclarativeContextPrivate *context, - const QScriptDeclarativeClass::Identifier &name, - bool isTerminal) + int subIdx, + QDeclarativeContextPrivate *context, + const QScriptDeclarativeClass::Identifier &name, + bool isTerminal) { QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(context->engine); @@ -1529,6 +1555,9 @@ bool QDeclarativeBindingCompilerPrivate::compile(QDeclarativeJS::AST::Node *node return false; if (type.unknownType) { + if (!qmlExperimental()) + return false; + if (destination->type != QMetaType::QReal && destination->type != QVariant::String && destination->type != QMetaType::Bool && @@ -1812,7 +1841,7 @@ bool QDeclarativeBindingCompilerPrivate::parseName(AST::Node *node, Result &type if (!fetch(type, component->metaObject(), reg, d1Idx, subscribeName, nameNodes.at(ii))) return false; - } else { + } else if (qmlExperimental()) { Instr find; if (nameParts.count() == 1) find.common.type = Instr::FindGenericTerminal; @@ -1968,7 +1997,11 @@ bool QDeclarativeBindingCompilerPrivate::numberArith(Result &type, const Result int lhsTmp = -1; int rhsTmp = -1; + if (lhs.unknownType) { + if (!qmlExperimental()) + return false; + lhsTmp = acquireReg(); Instr conv; @@ -1979,6 +2012,9 @@ bool QDeclarativeBindingCompilerPrivate::numberArith(Result &type, const Result } if (rhs.unknownType) { + if (!qmlExperimental()) + return false; + rhsTmp = acquireReg(); Instr conv; @@ -2024,6 +2060,9 @@ bool QDeclarativeBindingCompilerPrivate::stringArith(Result &type, const Result int rhsTmp = -1; if (lhs.unknownType) { + if (!qmlExperimental()) + return false; + lhsTmp = acquireReg(Instr::CleanupString); Instr convert; @@ -2034,6 +2073,9 @@ bool QDeclarativeBindingCompilerPrivate::stringArith(Result &type, const Result } if (rhs.unknownType) { + if (!qmlExperimental()) + return false; + rhsTmp = acquireReg(Instr::CleanupString); Instr convert; @@ -2554,6 +2596,12 @@ int QDeclarativeBindingCompiler::compile(const Expression &expression, QDeclarat { if (!expression.expression.asAST()) return false; + if (!qmlExperimental() && expression.property->isValueTypeSubProperty) + return -1; + + if (qmlDisableOptimizer()) + return -1; + d->context = expression.context; d->component = expression.component; d->destination = expression.property; diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index ef1032b..06ff47c 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -82,7 +82,7 @@ QT_BEGIN_NAMESPACE DEFINE_BOOL_CONFIG_OPTION(compilerDump, QML_COMPILER_DUMP); DEFINE_BOOL_CONFIG_OPTION(compilerStatDump, QML_COMPILER_STATISTICS_DUMP); -DEFINE_BOOL_CONFIG_OPTION(qmlExperimental, QML_EXPERIMENTAL); +DEFINE_BOOL_CONFIG_OPTION(bindingsDump, QML_BINDINGS_DUMP); using namespace QDeclarativeParser; @@ -1850,6 +1850,7 @@ bool QDeclarativeCompiler::buildValueTypeProperty(QObject *type, QMetaProperty p = type->metaObject()->property(idx); prop->index = idx; prop->type = p.userType(); + prop->isValueTypeSubProperty = true; if (prop->value) COMPILE_EXCEPTION(prop, QCoreApplication::translate("QDeclarativeCompiler","Property assignment expected")); @@ -2712,7 +2713,9 @@ bool QDeclarativeCompiler::completeComponentBuild() QDeclarativeBindingCompiler bindingCompiler; - for (QHash::Iterator iter = compileState.bindings.begin(); iter != compileState.bindings.end(); ++iter) { + for (QHash::Iterator iter = compileState.bindings.begin(); + iter != compileState.bindings.end(); ++iter) { + BindingReference &binding = *iter; expr.context = binding.bindingContext.object; @@ -2720,18 +2723,13 @@ bool QDeclarativeCompiler::completeComponentBuild() expr.expression = binding.expression; expr.imports = unit->imports; - if (qmlExperimental()) { - int index = bindingCompiler.compile(expr, QDeclarativeEnginePrivate::get(engine)); - if (index != -1) { - qWarning() << "Accepted for optimization:" << qPrintable(expr.expression.asScript()); - binding.dataType = BindingReference::Experimental; - binding.compiledIndex = index; - componentStat.optimizedBindings++; - continue; - } else { - qWarning() << "Rejected for optimization:" << qPrintable(expr.expression.asScript()); - } - } + int index = bindingCompiler.compile(expr, QDeclarativeEnginePrivate::get(engine)); + if (index != -1) { + binding.dataType = BindingReference::Experimental; + binding.compiledIndex = index; + componentStat.optimizedBindings++; + continue; + } binding.dataType = BindingReference::QtScript; @@ -2768,7 +2766,8 @@ bool QDeclarativeCompiler::completeComponentBuild() if (bindingCompiler.isValid()) { compileState.compiledBindingData = bindingCompiler.program(); - QDeclarativeBindingCompiler::dump(compileState.compiledBindingData); + if (bindingsDump()) + QDeclarativeBindingCompiler::dump(compileState.compiledBindingData); } saveComponentState(); diff --git a/src/declarative/qml/qdeclarativenotifier.cpp b/src/declarative/qml/qdeclarativenotifier.cpp index 0a8783a..8e5904c 100644 --- a/src/declarative/qml/qdeclarativenotifier.cpp +++ b/src/declarative/qml/qdeclarativenotifier.cpp @@ -59,7 +59,8 @@ void QDeclarativeNotifier::emitNotify(QDeclarativeNotifierEndpoint *endpoint) QMetaObject::metacall(endpoint->target, QMetaObject::InvokeMetaMethod, endpoint->targetMethod, args); - n->disconnected = oldDisconnected; + if (n) + n->disconnected = oldDisconnected; } if (oldDisconnected) *oldDisconnected = n; diff --git a/src/declarative/qml/qdeclarativeparser.cpp b/src/declarative/qml/qdeclarativeparser.cpp index b0599ad..51f1660 100644 --- a/src/declarative/qml/qdeclarativeparser.cpp +++ b/src/declarative/qml/qdeclarativeparser.cpp @@ -207,13 +207,14 @@ QDeclarativeParser::Object::DynamicSlot::DynamicSlot(const DynamicSlot &o) } QDeclarativeParser::Property::Property() -: parent(0), type(0), index(-1), value(0), isDefault(true), isDeferred(false) +: parent(0), type(0), index(-1), value(0), isDefault(true), isDeferred(false), + isValueTypeSubProperty(false) { } QDeclarativeParser::Property::Property(const QByteArray &n) : parent(0), type(0), index(-1), value(0), name(n), isDefault(false), - isDeferred(false) + isDeferred(false), isValueTypeSubProperty(false) { } diff --git a/src/declarative/qml/qdeclarativeparser_p.h b/src/declarative/qml/qdeclarativeparser_p.h index 5bf4b68..9dfb86b 100644 --- a/src/declarative/qml/qdeclarativeparser_p.h +++ b/src/declarative/qml/qdeclarativeparser_p.h @@ -351,6 +351,8 @@ namespace QDeclarativeParser // True if the setting of this property will be deferred. Set by the // QDeclarativeCompiler bool isDeferred; + // True if this property is a value-type psuedo-property + bool isValueTypeSubProperty; LocationSpan location; LocationRange listValueRange; -- cgit v0.12 From 353ed892d1d57edb98e3f640287be2be6177acab Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Fri, 12 Mar 2010 12:30:00 +1000 Subject: Update particles autotests --- .../qdeclarativeparticles/data/particlemotion.qml | 6 +- .../qdeclarativeparticles/data/particles.qml | 4 +- .../tst_qdeclarativeparticles.cpp | 125 +++++++++++---------- 3 files changed, 72 insertions(+), 63 deletions(-) diff --git a/tests/auto/declarative/qdeclarativeparticles/data/particlemotion.qml b/tests/auto/declarative/qdeclarativeparticles/data/particlemotion.qml index ace61fe..f1e4909 100644 --- a/tests/auto/declarative/qdeclarativeparticles/data/particlemotion.qml +++ b/tests/auto/declarative/qdeclarativeparticles/data/particlemotion.qml @@ -1,10 +1,12 @@ import Qt 4.6 +import Qt.labs.particles 1.0 + Rectangle { width: 240 height: 320 color: "black" Particles { - objectName: "particles" + objectName: "particles" anchors.fill: parent width: 1 height: 1 @@ -30,4 +32,4 @@ Rectangle { pace: 100 } ] -} \ No newline at end of file +} diff --git a/tests/auto/declarative/qdeclarativeparticles/data/particles.qml b/tests/auto/declarative/qdeclarativeparticles/data/particles.qml index 0d42645..4f168a9 100644 --- a/tests/auto/declarative/qdeclarativeparticles/data/particles.qml +++ b/tests/auto/declarative/qdeclarativeparticles/data/particles.qml @@ -1,4 +1,6 @@ import Qt 4.6 +import Qt.labs.particles 1.0 + Rectangle{ width: 100 height: 100 @@ -7,7 +9,7 @@ Rectangle{ Particles { id: particles objectName: "particles" width:1; height:1; anchors.centerIn: parent; opacity: 1 - lifeSpan: 100; lifeSpanDeviation: 20; count:1000; + lifeSpan: 100; lifeSpanDeviation: 20; count:1000; fadeInDuration: 20; fadeOutDuration: 20; emissionRate: 1000 angle: 0; angleDeviation: 360; velocity: 500; velocityDeviation:30 source: "particle.png" diff --git a/tests/auto/declarative/qdeclarativeparticles/tst_qdeclarativeparticles.cpp b/tests/auto/declarative/qdeclarativeparticles/tst_qdeclarativeparticles.cpp index 6090a07..f4e9a27 100644 --- a/tests/auto/declarative/qdeclarativeparticles/tst_qdeclarativeparticles.cpp +++ b/tests/auto/declarative/qdeclarativeparticles/tst_qdeclarativeparticles.cpp @@ -41,7 +41,7 @@ #include #include #include -#include +#include class tst_QDeclarativeParticles : public QObject { @@ -67,73 +67,75 @@ void tst_QDeclarativeParticles::properties() { QDeclarativeView *canvas = createView(SRCDIR "/data/particles.qml"); QVERIFY(canvas->rootObject()); - QDeclarativeParticles* particles = canvas->rootObject()->findChild("particles"); + + QObject* particles = canvas->rootObject()->findChild("particles"); QVERIFY(particles); - particles->setSource(QUrl::fromLocalFile(SRCDIR "/data/particle.png")); - QCOMPARE(particles->source(), QUrl::fromLocalFile(SRCDIR "/data/particle.png")); + particles->setProperty("source", QUrl::fromLocalFile(SRCDIR "/data/particle.png")); + QCOMPARE(particles->property("source").toUrl(), QUrl::fromLocalFile(SRCDIR "/data/particle.png")); - particles->setLifeSpanDeviation(1000); - QCOMPARE(particles->lifeSpanDeviation(), 1000); + particles->setProperty("lifeSpanDeviation", (1000)); + QCOMPARE(particles->property("lifeSpanDeviation").toInt(), 1000); - particles->setFadeInDuration(1000); - QCOMPARE(particles->fadeInDuration(), 1000); + particles->setProperty("fadeInDuration", 1000); + QCOMPARE(particles->property("fadeInDuration").toInt(), 1000); - particles->setFadeOutDuration(1000); - QCOMPARE(particles->fadeOutDuration(), 1000); + particles->setProperty("fadeOutDuration", 1000); + QCOMPARE(particles->property("fadeOutDuration").toInt(), 1000); - particles->setAngle(100.0); - QCOMPARE(particles->angle(), 100.0); + particles->setProperty("angle", 100.0); + QCOMPARE(particles->property("angle").toDouble(), 100.0); - particles->setAngleDeviation(100.0); - QCOMPARE(particles->angleDeviation(), 100.0); + particles->setProperty("angleDeviation", 100.0); + QCOMPARE(particles->property("angleDeviation").toDouble(), 100.0); - particles->setVelocity(100.0); - QCOMPARE(particles->velocity(), 100.0); + particles->setProperty("velocity", 100.0); + QCOMPARE(particles->property("velocity").toDouble(), 100.0); - particles->setVelocityDeviation(100.0); - QCOMPARE(particles->velocityDeviation(), 100.0); + particles->setProperty("velocityDeviation", 100.0); + QCOMPARE(particles->property("velocityDeviation").toDouble(), 100.0); - particles->setEmissionVariance(0.5); - QCOMPARE(particles->emissionVariance(),0.5); + particles->setProperty("emissionVariance", 0.5); + QCOMPARE(particles->property("emissionVariance").toDouble(),0.5); - particles->setEmissionRate(12); - QCOMPARE(particles->emissionRate(), 12); + particles->setProperty("emissionRate", 12); + QCOMPARE(particles->property("emissionRate").toInt(), 12); } void tst_QDeclarativeParticles::motionGravity() { QDeclarativeView *canvas = createView(SRCDIR "/data/particlemotion.qml"); QVERIFY(canvas->rootObject()); - QDeclarativeParticles* particles = canvas->rootObject()->findChild("particles"); + + QObject* particles = canvas->rootObject()->findChild("particles"); QVERIFY(particles); - QDeclarativeParticleMotionGravity* motionGravity = canvas->rootObject()->findChild("motionGravity"); - QCOMPARE(particles->motion(), motionGravity); + QObject* motionGravity = canvas->rootObject()->findChild("motionGravity"); + //QCOMPARE(qvariant_cast(particles->property("motion")), motionGravity); QSignalSpy xattractorSpy(motionGravity, SIGNAL(xattractorChanged())); QSignalSpy yattractorSpy(motionGravity, SIGNAL(yattractorChanged())); QSignalSpy accelerationSpy(motionGravity, SIGNAL(accelerationChanged())); - QCOMPARE(motionGravity->xAttractor(), 0.0); - QCOMPARE(motionGravity->yAttractor(), 1000.0); - QCOMPARE(motionGravity->acceleration(), 25.0); + QCOMPARE(motionGravity->property("xattractor").toDouble(), 0.0); + QCOMPARE(motionGravity->property("yattractor").toDouble(), 1000.0); + QCOMPARE(motionGravity->property("acceleration").toDouble(), 25.0); - motionGravity->setXAttractor(20.0); - motionGravity->setYAttractor(10.0); - motionGravity->setAcceleration(10.0); + motionGravity->setProperty("xattractor", 20.0); + motionGravity->setProperty("yattractor", 10.0); + motionGravity->setProperty("acceleration", 10.0); - QCOMPARE(motionGravity->xAttractor(), 20.0); - QCOMPARE(motionGravity->yAttractor(), 10.0); - QCOMPARE(motionGravity->acceleration(), 10.0); + QCOMPARE(motionGravity->property("xattractor").toDouble(), 20.0); + QCOMPARE(motionGravity->property("yattractor").toDouble(), 10.0); + QCOMPARE(motionGravity->property("acceleration").toDouble(), 10.0); QCOMPARE(xattractorSpy.count(), 1); QCOMPARE(yattractorSpy.count(), 1); QCOMPARE(accelerationSpy.count(), 1); - motionGravity->setXAttractor(20.0); - motionGravity->setYAttractor(10.0); - motionGravity->setAcceleration(10.0); + motionGravity->setProperty("xattractor", 20.0); + motionGravity->setProperty("yattractor", 10.0); + motionGravity->setProperty("acceleration", 10.0); QCOMPARE(xattractorSpy.count(), 1); QCOMPARE(yattractorSpy.count(), 1); @@ -144,42 +146,44 @@ void tst_QDeclarativeParticles::motionWander() { QDeclarativeView *canvas = createView(SRCDIR "/data/particlemotion.qml"); QVERIFY(canvas->rootObject()); - QDeclarativeParticles* particles = canvas->rootObject()->findChild("particles"); + + QObject* particles = canvas->rootObject()->findChild("particles"); QVERIFY(particles); - + QSignalSpy motionSpy(particles, SIGNAL(motionChanged())); - QDeclarativeParticleMotionWander* motionWander = canvas->rootObject()->findChild("motionWander"); - - particles->setMotion(motionWander); - QCOMPARE(particles->motion(),motionWander); - QCOMPARE(motionSpy.count(), 1); - - particles->setMotion(motionWander); - QCOMPARE(motionSpy.count(), 1); + QObject* motionWander = canvas->rootObject()->findChild("motionWander"); + + QCOMPARE(motionSpy.count(), 0); + particles->setProperty("motion", QVariant::fromValue(motionWander)); + //QCOMPARE(particles->property("motion"), QVariant::fromValue(motionWander)); + //QCOMPARE(motionSpy.count(), 1); + + particles->setProperty("motion", QVariant::fromValue(motionWander)); + //QCOMPARE(motionSpy.count(), 1); QSignalSpy xvarianceSpy(motionWander, SIGNAL(xvarianceChanged())); QSignalSpy yvarianceSpy(motionWander, SIGNAL(yvarianceChanged())); QSignalSpy paceSpy(motionWander, SIGNAL(paceChanged())); - QCOMPARE(motionWander->xVariance(), 30.0); - QCOMPARE(motionWander->yVariance(), 30.0); - QCOMPARE(motionWander->pace(), 100.0); + QCOMPARE(motionWander->property("xvariance").toDouble(), 30.0); + QCOMPARE(motionWander->property("yvariance").toDouble(), 30.0); + QCOMPARE(motionWander->property("pace").toDouble(), 100.0); - motionWander->setXVariance(20.0); - motionWander->setYVariance(10.0); - motionWander->setPace(10.0); + motionWander->setProperty("xvariance", 20.0); + motionWander->setProperty("yvariance", 10.0); + motionWander->setProperty("pace", 10.0); - QCOMPARE(motionWander->xVariance(), 20.0); - QCOMPARE(motionWander->yVariance(), 10.0); - QCOMPARE(motionWander->pace(), 10.0); + QCOMPARE(motionWander->property("xvariance").toDouble(), 20.0); + QCOMPARE(motionWander->property("yvariance").toDouble(), 10.0); + QCOMPARE(motionWander->property("pace").toDouble(), 10.0); QCOMPARE(xvarianceSpy.count(), 1); QCOMPARE(yvarianceSpy.count(), 1); QCOMPARE(paceSpy.count(), 1); - motionWander->setXVariance(20.0); - motionWander->setYVariance(10.0); - motionWander->setPace(10.0); + QCOMPARE(motionWander->property("xvariance").toDouble(), 20.0); + QCOMPARE(motionWander->property("yvariance").toDouble(), 10.0); + QCOMPARE(motionWander->property("pace").toDouble(), 10.0); QCOMPARE(xvarianceSpy.count(), 1); QCOMPARE(yvarianceSpy.count(), 1); @@ -190,7 +194,8 @@ void tst_QDeclarativeParticles::runs() { QDeclarativeView *canvas = createView(SRCDIR "/data/particles.qml"); QVERIFY(canvas->rootObject()); - QDeclarativeParticles* particles = canvas->rootObject()->findChild("particles"); + + QObject* particles = canvas->rootObject()->findChild("particles"); QVERIFY(particles); QTest::qWait(1000);//Run for one second. Test passes if it doesn't crash. } -- cgit v0.12 From b5d5e1df4d03e45dbcff5fa1e289cd7dbd5b3e5b Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Fri, 12 Mar 2010 12:33:26 +1000 Subject: Update QmlChanges.txt --- src/declarative/QmlChanges.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt index ffdb02f..a60a9de 100644 --- a/src/declarative/QmlChanges.txt +++ b/src/declarative/QmlChanges.txt @@ -18,6 +18,7 @@ Connection: syntax and rename: becomes: Connections { target: a; onFoo: xxx; onBar: yyy } Using WebView now requires "import org.webkit 1.0" +Using Particles now requires "import Qt.labs.particles 1.0" AnchorAnimation must now be used to animate anchor changes (and not NumberAnimation) QmlView @@ -50,10 +51,10 @@ C++ API QML_DEFINE_... definition macros, previously global macros, are replaced by QML_REGISTER_... registration macros, which must be called explicitly. C++ API users should also consider using the QmlExtensionPlugin (previously named QmlModulePlugin) -as a cleaner mechanism for publishing libraries of QML types, or the upcoming +as a cleaner mechanism for publishing libraries of QML types, or the upcoming application plugin features of the qmlviewer / qmlruntime / qml. -QDeclarativeContext::addDefaultObject() has been replaced with +QDeclarativeContext::addDefaultObject() has been replaced with QDeclarativeContext::setContextObject() PropertyAnimation -- cgit v0.12 From 32f92350d8f253582cf2385d5c0731b1a277e84c Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Fri, 12 Mar 2010 12:52:31 +1000 Subject: Fix test --- .../tst_qdeclarativeinstruction.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp b/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp index 636c5e3..5f6d9a4 100644 --- a/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp +++ b/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp @@ -93,7 +93,7 @@ void tst_qdeclarativeinstruction::dump() QDeclarativeInstruction i; i.line = 2; i.type = QDeclarativeInstruction::SetId; - i.setId.value = 0; + i.setId.value = data->primitives.count() - 1; i.setId.index = 0; data->bytecode << i; } @@ -171,17 +171,17 @@ void tst_qdeclarativeinstruction::dump() i.line = 10; i.type = QDeclarativeInstruction::StoreString; i.storeString.propertyIndex = 7; - i.storeString.value = 1; + i.storeString.value = data->primitives.count() - 1; data->bytecode << i; } { - data->primitives << "http://www.nokia.com"; + data->urls << QUrl("http://www.nokia.com"); QDeclarativeInstruction i; i.line = 11; i.type = QDeclarativeInstruction::StoreUrl; i.storeUrl.propertyIndex = 8; - i.storeUrl.value = 2; + i.storeUrl.value = data->urls.count() - 1; data->bytecode << i; } @@ -290,7 +290,7 @@ void tst_qdeclarativeinstruction::dump() i.line = 23; i.type = QDeclarativeInstruction::StoreVariant; i.storeString.propertyIndex = 20; - i.storeString.value = 3; + i.storeString.value = data->primitives.count() - 1; data->bytecode << i; } @@ -326,7 +326,7 @@ void tst_qdeclarativeinstruction::dump() i.line = 27; i.type = QDeclarativeInstruction::StoreSignal; i.storeSignal.signalIndex = 2; - i.storeSignal.value = 4; + i.storeSignal.value = data->primitives.count() - 1; data->bytecode << i; } @@ -527,7 +527,7 @@ void tst_qdeclarativeinstruction::dump() << "8\t\t8\tSTORE_INTEGER\t\t5\t9" << "9\t\t9\tSTORE_BOOL\t\t6\ttrue" << "10\t\t10\tSTORE_STRING\t\t7\t1\t\t\"Test String\"" - << "11\t\t11\tSTORE_URL\t\t8\t2\t\t\"http://www.nokia.com\"" + << "11\t\t11\tSTORE_URL\t\t8\t0\t\tQUrl(\"http://www.nokia.com\") " << "12\t\t12\tSTORE_COLOR\t\t9\t\t\t\"ff00ff00\"" << "13\t\t13\tSTORE_DATE\t\t10\t9" << "14\t\t14\tSTORE_TIME\t\t11\t33" @@ -539,11 +539,11 @@ void tst_qdeclarativeinstruction::dump() << "20\t\t20\tSTORE_RECT\t\t17\t2" << "21\t\t21\tSTORE_RECTF\t\t18\t19" << "22\t\t22\tSTORE_VECTOR3D\t\t19\t9" - << "23\t\t23\tSTORE_VARIANT\t\t20\t3\t\t\"color(1, 1, 1, 1)\"" + << "23\t\t23\tSTORE_VARIANT\t\t20\t2\t\t\"color(1, 1, 1, 1)\"" << "24\t\t24\tSTORE_OBJECT\t\t21" << "25\t\t25\tSTORE_VARIANT_OBJECT\t22" << "26\t\t26\tSTORE_INTERFACE\t\t23" - << "27\t\t27\tSTORE_SIGNAL\t\t2\t4\t\t\"console.log(1921)\"" + << "27\t\t27\tSTORE_SIGNAL\t\t2\t3\t\t\"console.log(1921)\"" << "28\t\t28\tSTORE_SCRIPT\t\t2" << "29\t\t29\tSTORE_SCRIPT_STRING\t24\t3\t1" << "30\t\t30\tASSIGN_SIGNAL_OBJECT\t0\t\t\t\"mySignal\"" -- cgit v0.12 From 45ef66f690966eb39b3b8ebef1708e1b87c55140 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Fri, 12 Mar 2010 13:23:05 +1000 Subject: Enable GL samplebuffers by default on Mac OS X --- tools/qml/qmlruntime.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/qml/qmlruntime.cpp b/tools/qml/qmlruntime.cpp index f12ec6f..c7acf2c 100644 --- a/tools/qml/qmlruntime.cpp +++ b/tools/qml/qmlruntime.cpp @@ -1444,10 +1444,15 @@ void QDeclarativeViewer::setUseGL(bool useGL) #ifdef GL_SUPPORTED if (useGL) { QGLFormat format = QGLFormat::defaultFormat(); +#ifdef Q_WS_MAC + format.setSampleBuffers(true); +#else format.setSampleBuffers(false); +#endif QGLWidget *glWidget = new QGLWidget(format); glWidget->setAutoFillBackground(false); + canvas->setViewport(glWidget); } #endif -- cgit v0.12 From df861cb0f6d6ae0b6971342adc199be7d7ec6009 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Fri, 12 Mar 2010 14:08:14 +1000 Subject: Fix crash on 32-bit platforms --- src/declarative/qml/qdeclarativeobjectscriptclass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp index 68780b6..32a28fe 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp @@ -588,7 +588,7 @@ private: inline void cleanup(); - char data[2 * sizeof(void *)]; + void *data[4]; int type; }; } -- cgit v0.12 From a1c5296a9feb7dd6c50b217c6ea68ad062884aab Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Fri, 12 Mar 2010 14:54:36 +1000 Subject: Make QML the object allocator more flexible By allocating memory internally we improve the opportunity for optimization. --- src/declarative/qml/qdeclarative.h | 25 +++++-------------------- src/declarative/qml/qdeclarativemetatype.cpp | 12 +++++++++--- src/declarative/qml/qdeclarativeprivate.h | 6 +++++- src/declarative/qml/qdeclarativevaluetype.cpp | 2 +- 4 files changed, 20 insertions(+), 25 deletions(-) diff --git a/src/declarative/qml/qdeclarative.h b/src/declarative/qml/qdeclarative.h index 2a7a9cf..dfdef11 100644 --- a/src/declarative/qml/qdeclarative.h +++ b/src/declarative/qml/qdeclarative.h @@ -99,7 +99,7 @@ int qmlRegisterType() qRegisterMetaType(pointerName.constData()), qRegisterMetaType >(listName.constData()), - 0, + 0, 0, 0, 0, 0, 0, &T::staticMetaObject, @@ -131,7 +131,7 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c qRegisterMetaType(pointerName.constData()), qRegisterMetaType >(listName.constData()), - QDeclarativePrivate::create, + sizeof(T), QDeclarativePrivate::createInto, uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, @@ -163,7 +163,7 @@ int qmlRegisterExtendedType() qRegisterMetaType(pointerName.constData()), qRegisterMetaType >(listName.constData()), - 0, + 0, 0, 0, 0, 0, 0, &T::staticMetaObject, @@ -203,7 +203,7 @@ int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor, qRegisterMetaType(pointerName.constData()), qRegisterMetaType >(listName.constData()), - QDeclarativePrivate::create, + sizeof(T), QDeclarativePrivate::createInto, uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, @@ -256,7 +256,7 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor, qRegisterMetaType(pointerName.constData()), qRegisterMetaType >(listName.constData()), - QDeclarativePrivate::create, + sizeof(T), QDeclarativePrivate::createInto, uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, @@ -275,21 +275,6 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor, return QDeclarativePrivate::registerType(type); } -#if 0 -#define QML_REGISTER_INTERFACE(INTERFACE) \ - qmlRegisterInterface(#INTERFACE) - -#define QML_REGISTER_EXTENDED_TYPE(URI, VERSION_MAJ, VERSION_MIN, NAME, CLASS, EXTENSION) \ - qmlRegisterExtendedType(#URI, VERSION_MAJ, VERSION_MIN, #NAME) - -#define QML_REGISTER_TYPE(URI,VMAJ,VMIN,NAME,CLASS) \ - qmlRegisterType(#URI, VMAJ, VMIN, #NAME) - -#define QML_REGISTER_NOCREATE_TYPE(CLASS) \ - qmlRegisterType() - -#endif - class QDeclarativeContext; class QDeclarativeEngine; Q_DECLARATIVE_EXPORT void qmlExecuteDeferred(QObject *); diff --git a/src/declarative/qml/qdeclarativemetatype.cpp b/src/declarative/qml/qdeclarativemetatype.cpp index 50ab56b..55c7413 100644 --- a/src/declarative/qml/qdeclarativemetatype.cpp +++ b/src/declarative/qml/qdeclarativemetatype.cpp @@ -124,7 +124,10 @@ public: int m_version_maj; int m_version_min; int m_typeId; int m_listId; - QObject *(*m_newFunc)(); + + int m_allocationSize; + void (*m_newFunc)(void *); + const QMetaObject *m_baseMetaObject; QDeclarativeAttachedPropertiesFunc m_attachedPropertiesFunc; const QMetaObject *m_attachedPropertiesType; @@ -141,7 +144,7 @@ public: QDeclarativeTypePrivate::QDeclarativeTypePrivate() : m_isInterface(false), m_iid(0), m_typeId(0), m_listId(0), - m_newFunc(0), m_baseMetaObject(0), m_attachedPropertiesFunc(0), m_attachedPropertiesType(0), + m_allocationSize(0), m_newFunc(0), m_baseMetaObject(0), m_attachedPropertiesFunc(0), m_attachedPropertiesType(0), m_parserStatusCast(-1), m_propertyValueSourceCast(-1), m_propertyValueInterceptorCast(-1), m_extFunc(0), m_extMetaObject(0), m_index(-1), m_customParser(0), m_isSetup(false) { @@ -174,6 +177,7 @@ QDeclarativeType::QDeclarativeType(int index, const QDeclarativePrivate::Registe d->m_version_min = type.versionMinor; d->m_typeId = type.typeId; d->m_listId = type.listId; + d->m_allocationSize = type.objectSize; d->m_newFunc = type.create; d->m_baseMetaObject = type.metaObject; d->m_attachedPropertiesFunc = type.attachedPropertiesFunction; @@ -274,7 +278,9 @@ QObject *QDeclarativeType::create() const { d->init(); - QObject *rv = d->m_newFunc(); + QObject *rv = (QObject *)operator new(d->m_allocationSize); + d->m_newFunc(rv); + if (rv && !d->m_metaObjects.isEmpty()) (void *)new QDeclarativeProxyMetaObject(rv, &d->m_metaObjects); diff --git a/src/declarative/qml/qdeclarativeprivate.h b/src/declarative/qml/qdeclarativeprivate.h index 01369d4..bebe82c 100644 --- a/src/declarative/qml/qdeclarativeprivate.h +++ b/src/declarative/qml/qdeclarativeprivate.h @@ -73,6 +73,9 @@ namespace QDeclarativePrivate QObject *create() { return new T; } template + void createInto(void *memory) { new (memory) T; } + + template QObject *createParent(QObject *p) { return new T(p); } template @@ -172,7 +175,8 @@ namespace QDeclarativePrivate int typeId; int listId; - QObject *(*create)(); + int objectSize; + void (*create)(void *); const char *uri; int versionMajor; diff --git a/src/declarative/qml/qdeclarativevaluetype.cpp b/src/declarative/qml/qdeclarativevaluetype.cpp index c070123..00e6704 100644 --- a/src/declarative/qml/qdeclarativevaluetype.cpp +++ b/src/declarative/qml/qdeclarativevaluetype.cpp @@ -61,7 +61,7 @@ int qmlRegisterValueTypeEnums(const char *qmlName) QDeclarativePrivate::RegisterType type = { 0, - qRegisterMetaType(pointerName.constData()), 0, 0, + qRegisterMetaType(pointerName.constData()), 0, 0, 0, "Qt", 4, 6, qmlName, &T::staticMetaObject, -- cgit v0.12 From 58fcfaecd1ce82ef19feb25eca8b3bf2f3f3d4c1 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Fri, 12 Mar 2010 15:04:25 +1000 Subject: Remove dead code --- src/declarative/qml/qdeclarativecontext_p.h | 31 ----------------------------- 1 file changed, 31 deletions(-) diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h index ba9aa41..682adb5 100644 --- a/src/declarative/qml/qdeclarativecontext_p.h +++ b/src/declarative/qml/qdeclarativecontext_p.h @@ -113,19 +113,6 @@ public: QDeclarativeDeclarativeData *contextObjects; - struct IdNotifier - { - inline IdNotifier(); - inline ~IdNotifier(); - - inline void clear(); - - IdNotifier *next; - IdNotifier**prev; - QObject *target; - int methodIndex; - }; - struct ContextGuard : public QDeclarativeGuard { inline ContextGuard(); @@ -157,24 +144,6 @@ public: static QObject *context_at(QDeclarativeListProperty *, int); }; -QDeclarativeContextPrivate::IdNotifier::IdNotifier() -: next(0), prev(0), target(0), methodIndex(-1) -{ -} - -QDeclarativeContextPrivate::IdNotifier::~IdNotifier() -{ - clear(); -} - -void QDeclarativeContextPrivate::IdNotifier::clear() -{ - if (next) next->prev = prev; - if (prev) *prev = next; - next = 0; prev = 0; target = 0; - methodIndex = -1; -} - QDeclarativeContextPrivate::ContextGuard::ContextGuard() : priv(0) { -- cgit v0.12 From f42cbe210f00ab0f700c8b4ccba852b6c5a2fd26 Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Fri, 12 Mar 2010 15:26:37 +1000 Subject: Add new declarative photoviewer demo --- demos/declarative/declarative.pro | 1 + .../photoviewer/PhotoViewerCore/AlbumDelegate.qml | 86 +++++++++++++ .../photoviewer/PhotoViewerCore/PhotoDelegate.qml | 141 +++++++++++++++++++++ .../photoviewer/PhotoViewerCore/ProgressBar.qml | 16 +++ .../photoviewer/PhotoViewerCore/RssModel.qml | 13 ++ .../photoviewer/PhotoViewerCore/Tag.qml | 22 ++++ .../PhotoViewerCore/images/background.png | Bin 0 -> 2097 bytes .../PhotoViewerCore/images/box-shadow.png | Bin 0 -> 588 bytes .../PhotoViewerCore/images/cardboard.png | Bin 0 -> 8844 bytes .../declarative/photoviewer/PhotoViewerCore/qmldir | 5 + .../photoviewer/PhotoViewerCore/script/script.js | 25 ++++ demos/declarative/photoviewer/photoviewer.qml | 45 +++++++ 12 files changed, 354 insertions(+) create mode 100644 demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml create mode 100644 demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml create mode 100644 demos/declarative/photoviewer/PhotoViewerCore/ProgressBar.qml create mode 100644 demos/declarative/photoviewer/PhotoViewerCore/RssModel.qml create mode 100644 demos/declarative/photoviewer/PhotoViewerCore/Tag.qml create mode 100644 demos/declarative/photoviewer/PhotoViewerCore/images/background.png create mode 100644 demos/declarative/photoviewer/PhotoViewerCore/images/box-shadow.png create mode 100644 demos/declarative/photoviewer/PhotoViewerCore/images/cardboard.png create mode 100644 demos/declarative/photoviewer/PhotoViewerCore/qmldir create mode 100644 demos/declarative/photoviewer/PhotoViewerCore/script/script.js create mode 100644 demos/declarative/photoviewer/photoviewer.qml diff --git a/demos/declarative/declarative.pro b/demos/declarative/declarative.pro index 4d169e3..aa60db0 100644 --- a/demos/declarative/declarative.pro +++ b/demos/declarative/declarative.pro @@ -8,6 +8,7 @@ SUBDIRS = \ sources.files = \ calculator \ flickr \ + photoviewer \ samegame \ snake \ twitter \ diff --git a/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml b/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml new file mode 100644 index 0000000..0821cea --- /dev/null +++ b/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml @@ -0,0 +1,86 @@ +import Qt 4.6 + +Component { + id: albumDelegate + Package { + + Item { + Package.name: 'browser' + GridView { + id: photosGridView; model: visualModel.parts.grid; width: mainWindow.width; height: mainWindow.height - 21 + x: 0; y: 21; cellWidth: 160; cellHeight: 153; interactive: false + onCurrentIndexChanged: photosListView.positionViewAtIndex(currentIndex, ListView.Contain) + } + } + + Item { + Package.name: 'fullscreen' + ListView { + id: photosListView; model: visualModel.parts.list; orientation: Qt.Horizontal + width: mainWindow.width; height: mainWindow.height; interactive: false + onCurrentIndexChanged: photosGridView.positionViewAtIndex(currentIndex, GridView.Contain) + highlightRangeMode: ListView.StrictlyEnforceRange; snapMode: ListView.SnapOneItem + } + } + + Item { + Package.name: 'album' + id: albumWrapper + width: 210; height: 220 + + VisualDataModel { + id: visualModel; delegate: PhotoDelegate { } + model: RssModel { tags: tag } + } + + PathView { + id: photosPathView; model: visualModel.parts.stack + anchors.centerIn: parent; anchors.verticalCenterOffset: -20 + pathItemCount: 5 + path: Path { + PathAttribute { name: 'z'; value: 9999.0 } + PathLine { x: 1; y: 1 } + PathAttribute { name: 'z'; value: 0.0 } + } + } + + Tag { + anchors.horizontalCenter: parent.horizontalCenter; anchors.bottom: parent.bottom + label: tag; rotation: Math.random() * (2 * 6 + 1) - 6 + } + + MouseArea { anchors.fill: parent; onClicked: albumWrapper.state = 'inGrid' } + + states: [ + State { + name: 'inGrid' + PropertyChanges { target: photosGridView; interactive: true } + PropertyChanges { target: albumsShade; opacity: 1 } + PropertyChanges{ target: backTag; onClicked: albumWrapper.state = ''; y: 6 } + }, + State { + name: 'fullscreen'; extend: 'inGrid' + PropertyChanges { target: photosGridView; interactive: false } + PropertyChanges { target: photosListView; interactive: true } + PropertyChanges { target: photosShade; opacity: 1 } + PropertyChanges{ target: backTag; y: -backTag.height - 8 } + } + ] + + transitions: [ + Transition { + from: '*'; to: 'inGrid' + SequentialAnimation { + NumberAnimation { properties: 'opacity'; duration: 250 } + PauseAnimation { duration: 350 } + NumberAnimation { target: backTag; properties: "y"; duration: 200; easing.type: "OutQuad" } + } + }, + Transition { + from: 'inGrid'; to: '*' + NumberAnimation { properties: "y,opacity"; easing.type: "OutQuad"; duration: 300 } + } + ] + } + } +} diff --git a/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml b/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml new file mode 100644 index 0000000..5a4e63e --- /dev/null +++ b/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml @@ -0,0 +1,141 @@ +import Qt 4.6 + +Package { + Item { id: stackItem; Package.name: 'stack'; width: 160; height: 153; z: stackItem.PathView.z } + Item { id: listItem; Package.name: 'list'; width: mainWindow.width + 40; height: 153 } + Item { id: gridItem; Package.name: 'grid'; width: 160; height: 153 } + + Item { + width: 160; height: 153 + + Item { + id: photoWrapper + + property double randomAngle: Math.random() * (2 * 6 + 1) - 6 + property double randomAngle2: Math.random() * (2 * 6 + 1) - 6 + + x: 0; y: 0; width: 140; height: 133 + z: stackItem.PathView.z; rotation: photoWrapper.randomAngle + + BorderImage { + anchors { + fill: border.visible ? border : placeHolder + leftMargin: -6; topMargin: -6; rightMargin: -8; bottomMargin: -8 + } + source: 'images/box-shadow.png'; smooth: true + border.left: 10; border.top: 10; border.right: 10; border.bottom: 10 + } + Rectangle { + id: placeHolder + + property int w: getWidth(content) + property int h: getHeight(content) + property double s: calculateScale(w, h, photoWrapper.width) + + color: '#898989'; anchors.centerIn: parent; smooth: true; border.color: 'white'; border.width: 3 + width: w * s; height: h * s; visible: originalImage.status != Image.Ready + } + Rectangle { + id: border; color: 'white'; anchors.centerIn: parent; smooth: true + width: originalImage.paintedWidth + 6; height: originalImage.paintedHeight + 6 + visible: !placeHolder.visible + } + Image { + id: originalImage; smooth: true; source: "http://" + getImagePath(content) + fillMode: Image.PreserveAspectFit; width: photoWrapper.width; height: photoWrapper.height + } + Image { + id: hqImage; smooth: true; source: ""; visible: false + fillMode: Image.PreserveAspectFit; width: photoWrapper.width; height: photoWrapper.height + } + Binding { + target: mainWindow; property: "downloadProgress"; value: hqImage.progress + when: listItem.ListView.isCurrentItem + } + Binding { + target: mainWindow; property: "imageLoading" + value: (hqImage.status == Image.Loading) ? 1 : 0; when: listItem.ListView.isCurrentItem + } + MouseArea { + width: originalImage.paintedWidth; height: originalImage.paintedHeight; anchors.centerIn: originalImage + onClicked: { + if (albumWrapper.state == 'inGrid') { + gridItem.GridView.view.currentIndex = index; + albumWrapper.state = 'fullscreen' + } else { + gridItem.GridView.view.currentIndex = index; + albumWrapper.state = 'inGrid' + } + } + } + + states: [ + State { + name: 'stacked'; when: albumWrapper.state == '' + ParentChange { target: photoWrapper; parent: stackItem; x: 10; y: 10 } + PropertyChanges { target: photoWrapper; opacity: stackItem.PathView.onPath ? 1.0 : 0.0 } + }, + State { + name: 'inGrid'; when: albumWrapper.state == 'inGrid' + ParentChange { target: photoWrapper; parent: gridItem; x: 10; y: 10; rotation: photoWrapper.randomAngle2 } + }, + State { + name: 'fullscreen'; when: albumWrapper.state == 'fullscreen' + ParentChange { + target: photoWrapper; parent: listItem; x: 0; y: 0; rotation: 0 + width: mainWindow.width; height: mainWindow.height + } + PropertyChanges { target: border; opacity: 0 } + PropertyChanges { target: hqImage; source: listItem.ListView.isCurrentItem ? hq : ""; visible: true } + } + ] + + transitions: [ + Transition { + from: 'stacked'; to: 'inGrid' + SequentialAnimation { + PauseAnimation { duration: 10 * index } + ParentAnimation { + target: photoWrapper; via: foreground + NumberAnimation { + target: photoWrapper; properties: 'x,y,rotation,opacity'; duration: 600; easing.type: 'OutQuart' + } + } + } + }, + Transition { + from: 'inGrid'; to: 'stacked' + ParentAnimation { + target: photoWrapper; via: foreground + NumberAnimation { properties: 'x,y,rotation,opacity'; duration: 600; easing.type: 'OutQuart' } + } + }, + Transition { + from: 'inGrid'; to: 'fullscreen' + SequentialAnimation { + PauseAnimation { duration: gridItem.GridView.isCurrentItem ? 0 : 600 } + ParentAnimation { + target: photoWrapper; via: foreground + NumberAnimation { + targets: [ photoWrapper, border ] + properties: 'x,y,width,height,opacity,rotation' + duration: gridItem.GridView.isCurrentItem ? 600 : 1; easing.type: 'OutQuart' + } + } + } + }, + Transition { + from: 'fullscreen'; to: 'inGrid' + ParentAnimation { + target: photoWrapper; via: foreground + NumberAnimation { + targets: [ photoWrapper, border ] + properties: 'x,y,width,height,rotation,opacity' + duration: gridItem.GridView.isCurrentItem ? 600 : 1; easing.type: 'OutQuart' + } + } + } + ] + } + } +} diff --git a/demos/declarative/photoviewer/PhotoViewerCore/ProgressBar.qml b/demos/declarative/photoviewer/PhotoViewerCore/ProgressBar.qml new file mode 100644 index 0000000..bd6b30f --- /dev/null +++ b/demos/declarative/photoviewer/PhotoViewerCore/ProgressBar.qml @@ -0,0 +1,16 @@ +import Qt 4.6 + +Item { + id: container + + property real progress: 0 + + Behavior on opacity { NumberAnimation { duration: 600 } } + + Rectangle { anchors.fill: parent; color: "black"; opacity: 0.5 } + + Rectangle { + id: fill; color: "white"; height: container.height + width: container.width * container.progress + } +} diff --git a/demos/declarative/photoviewer/PhotoViewerCore/RssModel.qml b/demos/declarative/photoviewer/PhotoViewerCore/RssModel.qml new file mode 100644 index 0000000..ddbc02b --- /dev/null +++ b/demos/declarative/photoviewer/PhotoViewerCore/RssModel.qml @@ -0,0 +1,13 @@ +import Qt 4.6 + +XmlListModel { + property string tags : "" + + source: "http://api.flickr.com/services/feeds/photos_public.gne?"+(tags ? "tags="+tags+"&" : "") + query: "/feed/entry" + namespaceDeclarations: "declare default element namespace 'http://www.w3.org/2005/Atom';" + + XmlRole { name: "title"; query: "title/string()" } + XmlRole { name: "content"; query: "content/string()" } + XmlRole { name: "hq"; query: "link[@rel='enclosure']/@href/string()" } +} diff --git a/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml b/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml new file mode 100644 index 0000000..ee11d05 --- /dev/null +++ b/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml @@ -0,0 +1,22 @@ +import Qt 4.6 + +Item { + id: container + + property alias label: labelText.text + signal clicked + + width: labelText.width + 70 ; height: labelText.height + 18 + + BorderImage { + anchors { fill: container; leftMargin: -6; topMargin: -6; rightMargin: -8; bottomMargin: -8 } + source: 'images/box-shadow.png'; smooth: true + border.left: 10; border.top: 10; border.right: 10; border.bottom: 10 + } + Image { anchors.fill: parent; source: "images/cardboard.png"; smooth: true } + Text { id: labelText; font.pixelSize: 15; anchors.centerIn: parent; smooth: true } + MouseArea { + anchors { fill: parent; leftMargin: -20; topMargin: -20; rightMargin: -20; bottomMargin: -20 } + onClicked: container.clicked() + } +} diff --git a/demos/declarative/photoviewer/PhotoViewerCore/images/background.png b/demos/declarative/photoviewer/PhotoViewerCore/images/background.png new file mode 100644 index 0000000..81d9a45 Binary files /dev/null and b/demos/declarative/photoviewer/PhotoViewerCore/images/background.png differ diff --git a/demos/declarative/photoviewer/PhotoViewerCore/images/box-shadow.png b/demos/declarative/photoviewer/PhotoViewerCore/images/box-shadow.png new file mode 100644 index 0000000..431af85 Binary files /dev/null and b/demos/declarative/photoviewer/PhotoViewerCore/images/box-shadow.png differ diff --git a/demos/declarative/photoviewer/PhotoViewerCore/images/cardboard.png b/demos/declarative/photoviewer/PhotoViewerCore/images/cardboard.png new file mode 100644 index 0000000..1847ab5 Binary files /dev/null and b/demos/declarative/photoviewer/PhotoViewerCore/images/cardboard.png differ diff --git a/demos/declarative/photoviewer/PhotoViewerCore/qmldir b/demos/declarative/photoviewer/PhotoViewerCore/qmldir new file mode 100644 index 0000000..1adce10 --- /dev/null +++ b/demos/declarative/photoviewer/PhotoViewerCore/qmldir @@ -0,0 +1,5 @@ +AlbumDelegate AlbumDelegate.qml +PhotoDelegate PhotoDelegate.qml +ProgressBar ProgressBar.qml +RssModel RssModel.qml +Tag Tag.qml diff --git a/demos/declarative/photoviewer/PhotoViewerCore/script/script.js b/demos/declarative/photoviewer/PhotoViewerCore/script/script.js new file mode 100644 index 0000000..ae24ea1 --- /dev/null +++ b/demos/declarative/photoviewer/PhotoViewerCore/script/script.js @@ -0,0 +1,25 @@ +function getWidth(string) { + return (string.match(/width=\"([0-9]+)\"/))[1] +} + +function getHeight(string) { + return (string.match(/height=\"([0-9]+)\"/))[1] +} + +function getImagePath(string) { + var pattern = /src=\"http:\/\/(\S+)\"/ + return (string.match(pattern))[1] +} + +function calculateScale(width, height, cellSize) { + var widthScale = (cellSize * 1.0) / width + var heightScale = (cellSize * 1.0) / height + var scale = 0 + + if (widthScale <= heightScale) { + scale = widthScale; + } else if (heightScale < widthScale) { + scale = heightScale; + } + return scale; +} diff --git a/demos/declarative/photoviewer/photoviewer.qml b/demos/declarative/photoviewer/photoviewer.qml new file mode 100644 index 0000000..2b0b6a9 --- /dev/null +++ b/demos/declarative/photoviewer/photoviewer.qml @@ -0,0 +1,45 @@ +import Qt 4.6 +import PhotoViewerCore 1.0 + +Image { + id: mainWindow + + property real downloadProgress: 0 + property bool imageLoading: false + + width: 800; height: 480; source: "PhotoViewerCore/images/background.png"; fillMode: Image.Tile + + Script { source: "PhotoViewerCore/script/script.js" } + + ListModel { + id: photosModel + ListElement { tag: "Flowers" } + ListElement { tag: "Savanna" } + ListElement { tag: "Central Park" } + } + + VisualDataModel { + id: albumVisualModel; delegate: AlbumDelegate { } + model: photosModel + } + + GridView { width: parent.width; height: parent.height; cellWidth: 210; cellHeight: 220; model: albumVisualModel.parts.album } + + Image { + id: albumsShade; source: "PhotoViewerCore/images/background.png"; fillMode: Image.Tile + width: parent.width; height: parent.height; opacity: 0 + } + + ListView { anchors.fill: parent; model: albumVisualModel.parts.browser; interactive: false } + + Tag { id: backTag; label: "Back"; rotation: 3; x: parent.width - backTag.width - 6; y: -backTag.height - 8 } + + Rectangle { id: photosShade; color: 'black'; width: parent.width; height: parent.height; opacity: 0 } + ListView { anchors.fill: parent; model: albumVisualModel.parts.fullscreen; interactive: false } + Item { id: foreground; anchors.fill: parent } + + ProgressBar { + progress: mainWindow.downloadProgress; width: parent.width; height: 4 + anchors.bottom: parent.bottom; opacity: mainWindow.imageLoading + } +} -- cgit v0.12 From e16cc0cf7e50a63674a7e36169d0844af6ddb2ce Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Fri, 12 Mar 2010 15:30:17 +1000 Subject: Optimization: Use linked list for context children --- src/declarative/qml/qdeclarativecontext.cpp | 59 ++++++++++++++-------- src/declarative/qml/qdeclarativecontext_p.h | 6 ++- src/declarative/qml/qdeclarativeenginedebug.cpp | 24 ++++----- .../declarative/creation/tst_creation.cpp | 11 ++++ 4 files changed, 67 insertions(+), 33 deletions(-) diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp index 58de1a7..237cb7e 100644 --- a/src/declarative/qml/qdeclarativecontext.cpp +++ b/src/declarative/qml/qdeclarativecontext.cpp @@ -59,12 +59,14 @@ QT_BEGIN_NAMESPACE QDeclarativeContextPrivate::QDeclarativeContextPrivate() : parent(0), engine(0), isInternal(false), propertyNames(0), - notifyIndex(-1), contextObject(0), imports(0), expressions(0), contextObjects(0), + notifyIndex(-1), contextObject(0), imports(0), childContexts(0), + nextChild(0), prevChild(0), expressions(0), contextObjects(0), idValues(0), idValueCount(0), optimizedBindings(0) { } -void QDeclarativeContextPrivate::addScript(const QDeclarativeParser::Object::ScriptBlock &script, QObject *scopeObject) +void QDeclarativeContextPrivate::addScript(const QDeclarativeParser::Object::ScriptBlock &script, + QObject *scopeObject) { Q_Q(QDeclarativeContext); @@ -123,8 +125,13 @@ void QDeclarativeContextPrivate::init() { Q_Q(QDeclarativeContext); - if (parent) - parent->d_func()->childContexts.insert(q); + if (parent) { + QDeclarativeContextPrivate *ppriv = parent->d_func(); + nextChild = ppriv->childContexts; + if (nextChild) nextChild->d_func()->prevChild = &nextChild; + prevChild = &ppriv->childContexts; + ppriv->childContexts = q; + } } /*! @@ -270,15 +277,24 @@ QDeclarativeContext::QDeclarativeContext(QDeclarativeContext *parentContext, QOb QDeclarativeContext::~QDeclarativeContext() { Q_D(QDeclarativeContext); - if (d->parent) - d->parent->d_func()->childContexts.remove(this); - - for (QSet::ConstIterator iter = d->childContexts.begin(); - iter != d->childContexts.end(); - ++iter) { - (*iter)->d_func()->invalidateEngines(); - (*iter)->d_func()->parent = 0; + + if (d->prevChild) { + *d->prevChild = d->nextChild; + if (d->nextChild) d->nextChild->d_func()->prevChild = d->prevChild; + d->nextChild = 0; + d->prevChild = 0; } + + QDeclarativeContext *child = d->childContexts; + while (child) { + QDeclarativeContextPrivate *childpriv = child->d_func(); + childpriv->invalidateEngines(); + childpriv->parent = 0; + child = childpriv->nextChild; + childpriv->nextChild = 0; + childpriv->prevChild = 0; + } + d->childContexts = 0; QDeclarativeAbstractExpression *expression = d->expressions; while (expression) { @@ -317,10 +333,12 @@ void QDeclarativeContextPrivate::invalidateEngines() if (!engine) return; engine = 0; - for (QSet::ConstIterator iter = childContexts.begin(); - iter != childContexts.end(); - ++iter) { - (*iter)->d_func()->invalidateEngines(); + + QDeclarativeContext *child = childContexts; + while (child) { + QDeclarativeContextPrivate *childpriv = child->d_func(); + childpriv->invalidateEngines(); + child = childpriv->nextChild; } } @@ -331,10 +349,11 @@ time the context tree *structure* (not values) changes. */ void QDeclarativeContextPrivate::refreshExpressions() { - for (QSet::ConstIterator iter = childContexts.begin(); - iter != childContexts.end(); - ++iter) { - (*iter)->d_func()->refreshExpressions(); + QDeclarativeContext *child = childContexts; + while (child) { + QDeclarativeContextPrivate *childpriv = child->d_func(); + childpriv->refreshExpressions(); + child = childpriv->nextChild; } QDeclarativeAbstractExpression *expression = expressions; diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h index 682adb5..a1056b1 100644 --- a/src/declarative/qml/qdeclarativecontext_p.h +++ b/src/declarative/qml/qdeclarativecontext_p.h @@ -107,7 +107,11 @@ public: void invalidateEngines(); void refreshExpressions(); - QSet childContexts; + + QDeclarativeContext *childContexts; + + QDeclarativeContext *nextChild; + QDeclarativeContext **prevChild; QDeclarativeAbstractExpression *expressions; diff --git a/src/declarative/qml/qdeclarativeenginedebug.cpp b/src/declarative/qml/qdeclarativeenginedebug.cpp index 3e4acbe..933683c 100644 --- a/src/declarative/qml/qdeclarativeenginedebug.cpp +++ b/src/declarative/qml/qdeclarativeenginedebug.cpp @@ -230,22 +230,22 @@ void QDeclarativeEngineDebugServer::buildObjectList(QDataStream &message, int count = 0; - for (QSet::ConstIterator iter = p->childContexts.begin(); - iter != p->childContexts.end(); ++iter) { - QDeclarativeContextPrivate *p = (QDeclarativeContextPrivate *)QObjectPrivate::get(*iter); - if (p->isInternal) - continue; - ++count; + QDeclarativeContext *child = p->childContexts; + while (child) { + QDeclarativeContextPrivate *p = QDeclarativeContextPrivate::get(child); + if (!p->isInternal) + ++count; + child = p->nextChild; } message << count; - for (QSet::ConstIterator iter = p->childContexts.begin(); - iter != p->childContexts.end(); ++iter) { - QDeclarativeContextPrivate *p = (QDeclarativeContextPrivate *)QObjectPrivate::get(*iter); - if (p->isInternal) - continue; - buildObjectList(message, *iter); + child = p->childContexts; + while (child) { + QDeclarativeContextPrivate *p = QDeclarativeContextPrivate::get(child); + if (!p->isInternal) + buildObjectList(message, child); + child = p->nextChild; } // Clean deleted objects diff --git a/tests/benchmarks/declarative/creation/tst_creation.cpp b/tests/benchmarks/declarative/creation/tst_creation.cpp index 5b0004f..47e4bb7 100644 --- a/tests/benchmarks/declarative/creation/tst_creation.cpp +++ b/tests/benchmarks/declarative/creation/tst_creation.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include #ifdef Q_OS_SYMBIAN @@ -67,6 +68,8 @@ private slots: void qobject_qmltype(); void qobject_alloc(); + void qdeclarativecontext(); + void objects_qmltype_data(); void objects_qmltype(); @@ -150,6 +153,14 @@ void tst_creation::qobject_alloc() } } +void tst_creation::qdeclarativecontext() +{ + QBENCHMARK { + QDeclarativeContext *ctxt = new QDeclarativeContext(&engine); + delete ctxt; + } +} + void tst_creation::objects_qmltype_data() { QTest::addColumn("type"); -- cgit v0.12 From feeda1e9febc1131fd8ed30633c9c5db7806b4fb Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Fri, 12 Mar 2010 15:53:21 +1000 Subject: Tweak benchmark --- tests/benchmarks/declarative/creation/tst_creation.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/benchmarks/declarative/creation/tst_creation.cpp b/tests/benchmarks/declarative/creation/tst_creation.cpp index 47e4bb7..cd69cfe 100644 --- a/tests/benchmarks/declarative/creation/tst_creation.cpp +++ b/tests/benchmarks/declarative/creation/tst_creation.cpp @@ -104,7 +104,8 @@ void tst_creation::qobject_cpp() void tst_creation::qobject_qml() { - QDeclarativeComponent component(&engine, TEST_FILE("qobject.qml")); + QDeclarativeComponent component(&engine); + component.setData("import Qt 4.6\nQtObject {}", QUrl()); QObject *obj = component.create(); delete obj; -- cgit v0.12 From a8e3d5b04607ef6d6ba37090526886bac286abb0 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Fri, 12 Mar 2010 17:38:29 +1000 Subject: Change PathView offset property to use range 0 - 1.0 --- src/declarative/QmlChanges.txt | 1 + .../graphicsitems/qdeclarativepathview.cpp | 96 +++++++++++----------- .../qdeclarativepathview/data/pathview3.qml | 2 +- .../tst_qdeclarativepathview.cpp | 6 +- 4 files changed, 53 insertions(+), 52 deletions(-) diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt index f83dd58..9d24601 100644 --- a/src/declarative/QmlChanges.txt +++ b/src/declarative/QmlChanges.txt @@ -1,6 +1,7 @@ ============================================================================= The changes below are pre Qt 4.7.0 alpha +PathView: offset property now uses range 0-1.0 rather than 0-100 ListView, GridView::positionViewAtIndex() gained a 'mode' parameter Flickable: renamed viewportWidth -> contentWidth Flickable: renamed viewportHeight -> contentHeight diff --git a/src/declarative/graphicsitems/qdeclarativepathview.cpp b/src/declarative/graphicsitems/qdeclarativepathview.cpp index cc17157..b9c8971 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview.cpp +++ b/src/declarative/graphicsitems/qdeclarativepathview.cpp @@ -354,7 +354,7 @@ void QDeclarativePathView::setCurrentIndex(int idx) /*! \qmlproperty real PathView::offset - The offset specifies how far along the path the items are from their initial positions. + The offset specifies how far along the path (0.0-1.0) the items are from their initial positions. */ qreal QDeclarativePathView::offset() const { @@ -373,9 +373,9 @@ void QDeclarativePathViewPrivate::setOffset(qreal o) { Q_Q(QDeclarativePathView); if (_offset != o) { - _offset = qmlMod(o, qreal(100.0)); + _offset = qmlMod(o, qreal(1.0)); if (_offset < 0) - _offset = 100.0 + _offset; + _offset = 1.0 + _offset; q->refill(); } } @@ -503,7 +503,7 @@ QPointF QDeclarativePathViewPrivate::pointNear(const QPointF &point, qreal *near } if (nearPercent) - *nearPercent = nearPc / 10.0; + *nearPercent = nearPc / 1000.0; return nearPoint; } @@ -559,10 +559,10 @@ void QDeclarativePathView::mouseMoveEvent(QGraphicsSceneMouseEvent *event) if (diff) { setOffset(d->_offset + diff); - if (diff > 50) - diff -= 100; - else if (diff < -50) - diff += 100; + if (diff > 0.5) + diff -= 1.0; + else if (diff < -0.5) + diff += 1.0; d->lastElapsed = QDeclarativeItemPrivate::restart(d->lastPosTime); d->lastDist = diff; @@ -579,15 +579,15 @@ void QDeclarativePathView::mouseReleaseEvent(QGraphicsSceneMouseEvent *) qreal elapsed = qreal(d->lastElapsed + QDeclarativeItemPrivate::elapsed(d->lastPosTime)) / 1000.; qreal velocity = elapsed > 0. ? d->lastDist / elapsed : 0; - if (d->model && d->model->count() && qAbs(velocity) > 5) { - if (velocity > 100) - velocity = 100; - else if (velocity < -100) - velocity = -100; - qreal inc = qmlMod(d->_offset - d->snapPos, qreal(100.0 / d->model->count())); - qreal dist = qAbs(velocity/2 - qmlMod(velocity/2, qreal(100.0 / d->model->count()) - inc)); + if (d->model && d->model->count() && qAbs(velocity) > 0.05) { + if (velocity > 1.5) + velocity = 1.5; + else if (velocity < -1.5) + velocity = -1.5; + qreal inc = qmlMod(d->_offset - d->snapPos, qreal(1.0 / d->model->count())); + qreal dist = qAbs(velocity/2 - qmlMod(velocity/2, qreal(1.0 / d->model->count()) - inc)); d->moveOffset.setValue(d->_offset); - d->tl.accel(d->moveOffset, velocity, 10, dist); + d->tl.accel(d->moveOffset, velocity, 0.1, dist); d->tl.callback(QDeclarativeTimeLineCallback(&d->moveOffset, d->fixOffsetCallback, d)); } else { d->fixOffset(); @@ -676,10 +676,10 @@ void QDeclarativePathView::componentComplete() itemIndex += d->pathOffset; itemIndex %= d->items.count(); - qreal targetOffset = qmlMod(100 + (d->snapPos*100) - 100.0 * itemIndex / d->items.count(), qreal(100.0)); + qreal targetOffset = qmlMod(1.0 + d->snapPos - qreal(itemIndex) / d->items.count(), qreal(1.0)); if (targetOffset < 0) - targetOffset = 100.0 + targetOffset; + targetOffset = 1.0 + targetOffset; if (targetOffset != d->_offset) { d->moveOffset.setValue(targetOffset); } @@ -712,8 +712,8 @@ void QDeclarativePathViewPrivate::regenerate() } items.append(item); item->setZValue(i); - qreal percent = i * (100. / numItems) + _offset; - percent = qAbs(qmlMod(percent, qreal(100.0))/100.0); + qreal percent = qreal(i) / numItems + _offset; + percent = qAbs(qmlMod(percent, qreal(1.0))); updateItem(item, percent); model->completeItem(); if (currentIndex == index) { @@ -745,10 +745,10 @@ void QDeclarativePathView::refill() QList positions; for (int i=0; iitems.count(); i++){ - qreal percent = i * (100. / d->items.count()); + qreal percent = qreal(i) / d->items.count(); percent = percent + d->_offset; - percent = qmlMod(percent, qreal(100.0)); - positions << qAbs(percent/100.0); + percent = qmlMod(percent, qreal(1.0)); + positions << qAbs(percent); } if (d->pathItems==-1) { @@ -843,10 +843,10 @@ void QDeclarativePathView::itemsInserted(int modelIndex, int count) int itemIndex = (d->currentIndex - d->firstIndex + d->model->count())%d->model->count(); itemIndex += d->pathOffset; itemIndex %= d->items.count(); - qreal targetOffset = qmlMod(100 + (d->snapPos*100) - 100.0 * itemIndex / d->items.count(), qreal(100.0)); + qreal targetOffset = qmlMod(1.0 + d->snapPos - qreal(itemIndex) / d->items.count(), qreal(1.0)); if (targetOffset < 0) - targetOffset = 100.0 + targetOffset; + targetOffset = 1.0 + targetOffset; if (targetOffset != d->_offset) d->moveOffset.setValue(targetOffset); } @@ -880,10 +880,10 @@ void QDeclarativePathView::itemsRemoved(int modelIndex, int count) int itemIndex = (d->currentIndex - d->firstIndex + d->model->count())%d->model->count(); itemIndex += d->pathOffset; itemIndex %= d->items.count(); - qreal targetOffset = qmlMod(100 + (d->snapPos*100) - 100.0 * itemIndex / d->items.count(), qreal(100.0)); + qreal targetOffset = qmlMod(1.0 + d->snapPos - qreal(itemIndex) / d->items.count(), qreal(1.0)); if (targetOffset < 0) - targetOffset = 100.0 + targetOffset; + targetOffset = 1.0 + targetOffset; if (targetOffset != d->_offset) d->moveOffset.setValue(targetOffset); } @@ -919,15 +919,15 @@ int QDeclarativePathViewPrivate::calcCurrentIndex() { int current = -1; if (model && items.count()) { - _offset = qmlMod(_offset, qreal(100.0)); + _offset = qmlMod(_offset, qreal(1.0)); if (_offset < 0) - _offset += 100.0; + _offset += 1.0; if (pathItems == -1) { - qreal delta = qmlMod(_offset - snapPos, qreal(100.0)); + qreal delta = qmlMod(_offset - snapPos, qreal(1.0)); if (delta < 0) - delta = 100.0 + delta; - int ii = model->count() - qRound(delta * model->count() / 100); + delta = 1.0 + delta; + int ii = model->count() - qRound(delta * model->count()); if (ii < 0) ii = 0; current = ii; @@ -935,10 +935,10 @@ int QDeclarativePathViewPrivate::calcCurrentIndex() qreal bestDiff=1e9; int bestI=-1; for (int i=0; icount() + items.count(); } itemIndex %= items.count(); - qreal targetOffset = qmlMod(100 + (snapPos*100) - 100.0 * itemIndex / items.count(), qreal(100.0)); + qreal targetOffset = qmlMod(1.0 + snapPos - qreal(itemIndex) / items.count(), qreal(1.0)); if (targetOffset < 0) - targetOffset = 100.0 + targetOffset; + targetOffset = 1.0 + targetOffset; if (targetOffset == _offset && rounds == 0) return; @@ -1031,24 +1031,24 @@ void QDeclarativePathViewPrivate::snapToCurrent() if (rounds!=0){ //Compensate if the targetOffset would bring the target in from off the screen qreal distance = targetOffset - _offset; - if (distance <= -50) + if (distance <= -0.5) rounds--; - if (distance > 50) + if (distance > 0.5) rounds++; - tl.move(moveOffset, targetOffset + 100.0*(-rounds), QEasingCurve(QEasingCurve::InOutQuad), - int(100*items.count()*qMax((qreal)(2.0/items.count()),(qreal)qAbs(rounds)))); + tl.move(moveOffset, targetOffset -rounds, QEasingCurve(QEasingCurve::InOutQuad), + int(items.count()*qMax((qreal)(2.0/items.count()),(qreal)qAbs(rounds)))); tl.callback(QDeclarativeTimeLineCallback(&moveOffset, fixOffsetCallback, this)); return; } - if (targetOffset - _offset > 50.0) { - qreal distance = 100 - targetOffset + _offset; + if (targetOffset - _offset > 0.5) { + qreal distance = 1 - targetOffset + _offset; tl.move(moveOffset, 0.0, QEasingCurve(QEasingCurve::OutQuad), int(200 * _offset / distance)); - tl.set(moveOffset, 100.0); - tl.move(moveOffset, targetOffset, QEasingCurve(QEasingCurve::InQuad), int(200 * (100-targetOffset) / distance)); - } else if (targetOffset - _offset <= -50.0) { - qreal distance = 100 - _offset + targetOffset; - tl.move(moveOffset, 100.0, QEasingCurve(QEasingCurve::OutQuad), int(200 * (100-_offset) / distance)); + tl.set(moveOffset, 1.0); + tl.move(moveOffset, targetOffset, QEasingCurve(QEasingCurve::InQuad), int(200 * (1.0-targetOffset) / distance)); + } else if (targetOffset - _offset <= -0.5) { + qreal distance = 1 - _offset + targetOffset; + tl.move(moveOffset, 1.0, QEasingCurve(QEasingCurve::OutQuad), int(200 * (1.0-_offset) / distance)); tl.set(moveOffset, 0.0); tl.move(moveOffset, targetOffset, QEasingCurve(QEasingCurve::InQuad), int(200 * targetOffset / distance)); } else { diff --git a/tests/auto/declarative/qdeclarativepathview/data/pathview3.qml b/tests/auto/declarative/qdeclarativepathview/data/pathview3.qml index f8ed29f..70cfbcd 100644 --- a/tests/auto/declarative/qdeclarativepathview/data/pathview3.qml +++ b/tests/auto/declarative/qdeclarativepathview/data/pathview3.qml @@ -2,7 +2,7 @@ import Qt 4.6 PathView { id: photoPathView - y: 100; width: 800; height: 330; pathItemCount: 4; offset: 10 + y: 100; width: 800; height: 330; pathItemCount: 4; offset: 0.1 dragMargin: 24; snapPosition: 0.50 path: Path { diff --git a/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp b/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp index 62eb8c3..cc1a8d5 100644 --- a/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp +++ b/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp @@ -262,7 +262,7 @@ void tst_QDeclarativePathView::pathview3() QVERIFY(obj->delegate() != 0); QVERIFY(obj->model() != QVariant()); QCOMPARE(obj->currentIndex(), 0); - QCOMPARE(obj->offset(), 50.); // ??? + QCOMPARE(obj->offset(), 0.5); // ??? QCOMPARE(obj->snapPosition(), 0.5); // ??? QCOMPARE(obj->dragMargin(), 24.); QCOMPARE(obj->count(), 8); @@ -422,14 +422,14 @@ void tst_QDeclarativePathView::pathMoved() offset.setX(firstItem->width()/2); offset.setY(firstItem->height()/2); QCOMPARE(firstItem->pos() + offset, start); - pathview->setOffset(10); + pathview->setOffset(0.1); for(int i=0; i(pathview, "wrapper", i); QCOMPARE(curItem->pos() + offset, path->pointAt(0.1 + i*0.25)); } - pathview->setOffset(100); + pathview->setOffset(1.0); QCOMPARE(firstItem->pos() + offset, start); delete canvas; -- cgit v0.12 From 7015f7ae557f04d0ba5d6b86e521686adc5d79a1 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Fri, 12 Mar 2010 09:24:42 +0100 Subject: Fix installation of imports libraries --- src/imports/multimedia/multimedia.pro | 4 ++-- src/imports/webkit/webkit.pro | 4 ++-- src/imports/widgets/widgets.pro | 7 +++---- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/imports/multimedia/multimedia.pro b/src/imports/multimedia/multimedia.pro index f348fef..16b3ace 100644 --- a/src/imports/multimedia/multimedia.pro +++ b/src/imports/multimedia/multimedia.pro @@ -18,9 +18,9 @@ SOURCES += \ qmetadatacontrolmetaobject.cpp QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/$$TARGETPATH -target.path = $$TARGETPATH +target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH -qmldir.files += $$QT_BUILD_TREE/imports/Qt/multimedia/qmldir +qmldir.files += $$QT_BUILD_TREE/imports/$$TARGETPATH/qmldir qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH INSTALLS += target qmldir diff --git a/src/imports/webkit/webkit.pro b/src/imports/webkit/webkit.pro index 858d3ba..ef08efe 100644 --- a/src/imports/webkit/webkit.pro +++ b/src/imports/webkit/webkit.pro @@ -9,9 +9,9 @@ HEADERS += qdeclarativewebview_p.h \ qdeclarativewebview_p_p.h QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/$$TARGETPATH -target.path = $$TARGETPATH +target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH -qmldir.files += $$QT_BUILD_TREE/imports/org/webkit/qmldir +qmldir.files += $$QT_BUILD_TREE/imports/$$TARGETPATH/qmldir qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH INSTALLS += target qmldir diff --git a/src/imports/widgets/widgets.pro b/src/imports/widgets/widgets.pro index de22403..aa09b3c 100644 --- a/src/imports/widgets/widgets.pro +++ b/src/imports/widgets/widgets.pro @@ -13,10 +13,9 @@ HEADERS += \ graphicslayouts_p.h QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/$$TARGETPATH -target.path = $$TARGETPATH +target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH -# install qmldir file -qmldir.files += qmldir -qmldir.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH +qmldir.files += $$QT_BUILD_TREE/imports/$$TARGETPATH/qmldir +qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH INSTALLS += target qmldir -- cgit v0.12 From 5e47575a366d98ab3317f52ab0170f853fd25793 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Mon, 15 Mar 2010 09:04:24 +1000 Subject: Use reliable local server for HTTP testing. Test font redirection. --- .../qdeclarativefontloader.pro | 5 ++-- .../tst_qdeclarativefontloader.cpp | 35 ++++++++++++++++++---- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/tests/auto/declarative/qdeclarativefontloader/qdeclarativefontloader.pro b/tests/auto/declarative/qdeclarativefontloader/qdeclarativefontloader.pro index 0c736b4..3ba50be 100644 --- a/tests/auto/declarative/qdeclarativefontloader/qdeclarativefontloader.pro +++ b/tests/auto/declarative/qdeclarativefontloader/qdeclarativefontloader.pro @@ -1,8 +1,9 @@ load(qttest_p4) -contains(QT_CONFIG,declarative): QT += declarative gui +contains(QT_CONFIG,declarative): QT += declarative gui network macx:CONFIG -= app_bundle -SOURCES += tst_qdeclarativefontloader.cpp +HEADERS += ../shared/testhttpserver.h +SOURCES += tst_qdeclarativefontloader.cpp ../shared/testhttpserver.cpp # Define SRCDIR equal to test's source directory DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp b/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp index add3c7b..375e801 100644 --- a/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp +++ b/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp @@ -43,6 +43,9 @@ #include #include #include "../../../shared/util.h" +#include "../shared/testhttpserver.h" + +#define SERVER_PORT 14445 class tst_qdeclarativefontloader : public QObject @@ -57,16 +60,21 @@ private slots: void localFont(); void failLocalFont(); void webFont(); + void redirWebFont(); void failWebFont(); private slots: private: QDeclarativeEngine engine; + TestHTTPServer server; }; -tst_qdeclarativefontloader::tst_qdeclarativefontloader() +tst_qdeclarativefontloader::tst_qdeclarativefontloader() : + server(SERVER_PORT) { + server.serveDirectory(SRCDIR "/data"); + Q_ASSERT(server.isValid()); } void tst_qdeclarativefontloader::noFont() @@ -126,21 +134,38 @@ void tst_qdeclarativefontloader::failLocalFont() void tst_qdeclarativefontloader::webFont() { - QString componentStr = "import Qt 4.6\nFontLoader { source: \"http://www.princexml.com/fonts/steffmann/Starburst.ttf\" }"; + QString componentStr = "import Qt 4.6\nFontLoader { source: \"http://localhost:14445/tarzeau_ocr_a.ttf\" }"; + QDeclarativeComponent component(&engine); + + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QDeclarativeFontLoader *fontObject = qobject_cast(component.create()); + + QVERIFY(fontObject != 0); + QVERIFY(fontObject->source() != QUrl("")); + QTRY_COMPARE(fontObject->name(), QString("OCRA")); + QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready); +} + +void tst_qdeclarativefontloader::redirWebFont() +{ + server.addRedirect("olddir/oldname.ttf","../tarzeau_ocr_a.ttf"); + + QString componentStr = "import Qt 4.6\nFontLoader { source: \"http://localhost:14445/olddir/oldname.ttf\" }"; QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); QDeclarativeFontLoader *fontObject = qobject_cast(component.create()); QVERIFY(fontObject != 0); QVERIFY(fontObject->source() != QUrl("")); - QTRY_COMPARE(fontObject->name(), QString("Starburst")); + QTRY_COMPARE(fontObject->name(), QString("OCRA")); QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready); } void tst_qdeclarativefontloader::failWebFont() { - QString componentStr = "import Qt 4.6\nFontLoader { source: \"http://wrong.address.nokia.com/Starburst.ttf\" }"; - QTest::ignoreMessage(QtWarningMsg, "Cannot load font: QUrl( \"http://wrong.address.nokia.com/Starburst.ttf\" ) "); + QString componentStr = "import Qt 4.6\nFontLoader { source: \"http://localhost:14445/nonexist.ttf\" }"; + QTest::ignoreMessage(QtWarningMsg, "Cannot load font: QUrl( \"http://localhost:14445/nonexist.ttf\" ) "); QDeclarativeComponent component(&engine); component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); QDeclarativeFontLoader *fontObject = qobject_cast(component.create()); -- cgit v0.12 From 2d0a93bd816b7cfce41acf37da479758c175aa7a Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Mon, 15 Mar 2010 09:19:33 +1000 Subject: Fix typo. --- src/declarative/util/qdeclarativeanimation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index d77ef40..652d359 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -1883,7 +1883,7 @@ void QDeclarativePropertyAnimation::setTo(const QVariant &t) For the easing you can specify the following parameters: type, amplitude, period and overshoot. \qml - PropertyAnimation { properties: "y"; easing.type: "InOutElastc"; easing.amplitude: 2.0; easing.period: 1.5 } + PropertyAnimation { properties: "y"; easing.type: "InOutElastic"; easing.amplitude: 2.0; easing.period: 1.5 } \endqml Available types are: -- cgit v0.12 From 99c3ba94e985520f1095532fa930f0f0591d407c Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Mon, 15 Mar 2010 09:21:42 +1000 Subject: Make the loader a focusscope. --- src/declarative/graphicsitems/qdeclarativeloader.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/declarative/graphicsitems/qdeclarativeloader.cpp b/src/declarative/graphicsitems/qdeclarativeloader.cpp index 61a32e5..6dbcd16 100644 --- a/src/declarative/graphicsitems/qdeclarativeloader.cpp +++ b/src/declarative/graphicsitems/qdeclarativeloader.cpp @@ -155,6 +155,8 @@ void QDeclarativeLoaderPrivate::initResize() QDeclarativeLoader::QDeclarativeLoader(QDeclarativeItem *parent) : QDeclarativeItem(*(new QDeclarativeLoaderPrivate), parent) { + Q_D(QDeclarativeItem); + d->flags |= QGraphicsItem::ItemIsFocusScope; } /*! @@ -348,7 +350,7 @@ QDeclarativeLoader::Status QDeclarativeLoader::status() const /*! \qmlproperty real Loader::progress -This property holds the progress of loading QML data from the network, from +This property holds the progress of loading QML data from the network, from 0.0 (nothing loaded) to 1.0 (finished). Most QML files are quite small, so this value will rapidly change from 0 to 1. -- cgit v0.12 From a89d15916c4b5d01b01eb932ccaaead43cd75d08 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Mon, 15 Mar 2010 09:52:03 +1000 Subject: Make easing docs more consistent with other grouped property docs. --- src/declarative/util/qdeclarativeanimation.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index 652d359..009e07f 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -1877,10 +1877,14 @@ void QDeclarativePropertyAnimation::setTo(const QVariant &t) } /*! - \qmlproperty QEasingCurve PropertyAnimation::easing - \brief the easing curve used for the transition. - - For the easing you can specify the following parameters: type, amplitude, period and overshoot. + \qmlproperty enum PropertyAnimation::easing.type + \qmlproperty real PropertyAnimation::easing.amplitude + \qmlproperty real PropertyAnimation::easing.overshoot + \qmlproperty real PropertyAnimation::easing.period + \brief the easing curve used for the animation. + + To specify an easing curve you need to specify at least the type. For some curves you can also specify + amplitude, period and/or overshoot (more details provided after the table). \qml PropertyAnimation { properties: "y"; easing.type: "InOutElastic"; easing.amplitude: 2.0; easing.period: 1.5 } -- cgit v0.12 From 8b56d83486130e8b95658b3032b25cb6394baaaf Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Mon, 15 Mar 2010 10:34:55 +1000 Subject: QDeclarative::isWritable optimization. --- src/declarative/qml/qdeclarativeproperty.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp index 8ca5406..c55c22f 100644 --- a/src/declarative/qml/qdeclarativeproperty.cpp +++ b/src/declarative/qml/qdeclarativeproperty.cpp @@ -494,15 +494,13 @@ QDeclarativeProperty &QDeclarativeProperty::operator=(const QDeclarativeProperty */ bool QDeclarativeProperty::isWritable() const { - QDeclarativeProperty::PropertyTypeCategory category = propertyTypeCategory(); - if (!d->object) return false; - if (category == List) + if (d->core.flags & QDeclarativePropertyCache::Data::IsQList) //list return true; - else if (type() & SignalProperty) + else if (d->core.flags & QDeclarativePropertyCache::Data::IsFunction) //signal handler return false; - else if (d->core.isValid() && d->object) + else if (d->core.isValid()) //normal property return d->core.flags & QDeclarativePropertyCache::Data::IsWritable; else return false; -- cgit v0.12 From bb06ae50a54df2787daba63e33337f30f67978c4 Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Mon, 15 Mar 2010 10:52:09 +1000 Subject: fix installation of imports libraries --- src/imports/particles/particles.pro | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/imports/particles/particles.pro b/src/imports/particles/particles.pro index 2a0b8f5..02d9ea6 100644 --- a/src/imports/particles/particles.pro +++ b/src/imports/particles/particles.pro @@ -12,10 +12,9 @@ HEADERS += \ qdeclarativeparticles_p.h QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/$$TARGETPATH -target.path = $$TARGETPATH +target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH -# install qmldir file -qmldir.files += qmldir -qmldir.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH +qmldir.files += $$QT_BUILD_TREE/imports/$$TARGETPATH/qmldir +qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH INSTALLS += target qmldir -- cgit v0.12 From acec7123d383840d66fa63e84d0d0a0b72820496 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Mon, 15 Mar 2010 11:15:17 +1000 Subject: Set maximumExtents correctly for highlightRangeMode: StrictlyEnforceRange Task-number: QTBUG-9000 --- src/declarative/graphicsitems/qdeclarativelistview.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 9e6a67a..e5013a9 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -2061,7 +2061,7 @@ qreal QDeclarativeListView::maxYExtent() const return height(); if (d->maxExtentDirty) { if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) - d->maxExtent = -(d->positionAt(count()-1) - d->highlightRangeEnd); + d->maxExtent = -(d->endPosition() - d->highlightRangeEnd); else d->maxExtent = -(d->endPosition() - height() + 1); if (d->footer) @@ -2098,7 +2098,7 @@ qreal QDeclarativeListView::maxXExtent() const return width(); if (d->maxExtentDirty) { if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) - d->maxExtent = -(d->positionAt(count()-1) - d->highlightRangeEnd); + d->maxExtent = -(d->endPosition() - d->highlightRangeEnd); else d->maxExtent = -(d->endPosition() - width() + 1); if (d->footer) -- cgit v0.12 From 8ff26d85a4eb7ff937f9ecdcd3b71133d6478e15 Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Mon, 15 Mar 2010 13:23:38 +1000 Subject: Add busy indicator to photoviewer demo --- .../photoviewer/PhotoViewerCore/AlbumDelegate.qml | 7 ++++++- .../photoviewer/PhotoViewerCore/BusyIndicator.qml | 9 +++++++++ .../photoviewer/PhotoViewerCore/PhotoDelegate.qml | 3 ++- .../photoviewer/PhotoViewerCore/images/busy.png | Bin 0 -> 2629 bytes demos/declarative/photoviewer/PhotoViewerCore/qmldir | 1 + 5 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 demos/declarative/photoviewer/PhotoViewerCore/BusyIndicator.qml create mode 100644 demos/declarative/photoviewer/PhotoViewerCore/images/busy.png diff --git a/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml b/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml index 0821cea..d71834e 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml +++ b/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml @@ -30,7 +30,12 @@ Component { VisualDataModel { id: visualModel; delegate: PhotoDelegate { } - model: RssModel { tags: tag } + model: RssModel { id: rssModel; tags: tag } + } + + BusyIndicator { + anchors { centerIn: parent; verticalCenterOffset: -20 } + on: rssModel.status != XmlListModel.Ready } PathView { diff --git a/demos/declarative/photoviewer/PhotoViewerCore/BusyIndicator.qml b/demos/declarative/photoviewer/PhotoViewerCore/BusyIndicator.qml new file mode 100644 index 0000000..919ac43 --- /dev/null +++ b/demos/declarative/photoviewer/PhotoViewerCore/BusyIndicator.qml @@ -0,0 +1,9 @@ +import Qt 4.6 + +Image { + id: container + property bool on: false + + source: "images/busy.png"; visible: container.on + NumberAnimation on rotation { running: container.on; from: 0; to: 360; repeat: true; duration: 1200 } +} diff --git a/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml b/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml index 5a4e63e..89fe3e8 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml +++ b/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml @@ -32,7 +32,7 @@ Package { property int h: getHeight(content) property double s: calculateScale(w, h, photoWrapper.width) - color: '#898989'; anchors.centerIn: parent; smooth: true; border.color: 'white'; border.width: 3 + color: '#878787'; anchors.centerIn: parent; smooth: true; border.color: 'white'; border.width: 3 width: w * s; height: h * s; visible: originalImage.status != Image.Ready } Rectangle { @@ -40,6 +40,7 @@ Package { width: originalImage.paintedWidth + 6; height: originalImage.paintedHeight + 6 visible: !placeHolder.visible } + BusyIndicator { anchors.centerIn: parent; on: originalImage.status != Image.Ready } Image { id: originalImage; smooth: true; source: "http://" + getImagePath(content) fillMode: Image.PreserveAspectFit; width: photoWrapper.width; height: photoWrapper.height diff --git a/demos/declarative/photoviewer/PhotoViewerCore/images/busy.png b/demos/declarative/photoviewer/PhotoViewerCore/images/busy.png new file mode 100644 index 0000000..664c2b1 Binary files /dev/null and b/demos/declarative/photoviewer/PhotoViewerCore/images/busy.png differ diff --git a/demos/declarative/photoviewer/PhotoViewerCore/qmldir b/demos/declarative/photoviewer/PhotoViewerCore/qmldir index 1adce10..4821faa 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/qmldir +++ b/demos/declarative/photoviewer/PhotoViewerCore/qmldir @@ -3,3 +3,4 @@ PhotoDelegate PhotoDelegate.qml ProgressBar ProgressBar.qml RssModel RssModel.qml Tag Tag.qml +BusyIndicator BusyIndicator.qml -- cgit v0.12 From 2c9d1ac6fb274d4b301a3fa496c01c21b497a49d Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Mon, 15 Mar 2010 13:50:27 +1000 Subject: Add basic QUrl benchmarks. --- tests/benchmarks/corelib/io/qurl/main.cpp | 244 ++++++++++++++++++++++++++++++ tests/benchmarks/corelib/io/qurl/qurl.pro | 7 + 2 files changed, 251 insertions(+) create mode 100644 tests/benchmarks/corelib/io/qurl/main.cpp create mode 100644 tests/benchmarks/corelib/io/qurl/qurl.pro diff --git a/tests/benchmarks/corelib/io/qurl/main.cpp b/tests/benchmarks/corelib/io/qurl/main.cpp new file mode 100644 index 0000000..49ace64 --- /dev/null +++ b/tests/benchmarks/corelib/io/qurl/main.cpp @@ -0,0 +1,244 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +class tst_qurl: public QObject +{ + Q_OBJECT + +private slots: + void emptyUrl(); + void relativeUrl(); + void absoluteUrl(); + void isRelative_data(); + void isRelative(); + void toLocalFile_data(); + void toLocalFile(); + void toString_data(); + void toString(); + void toEncoded_data(); + void toEncoded(); + void resolved_data(); + void resolved(); + void equality_data(); + void equality(); + void qmlPropertyWriteUseCase(); + +private: + void generateFirstRunData(); +}; + +void tst_qurl::emptyUrl() +{ + QBENCHMARK { + QUrl url; + } +} + +void tst_qurl::relativeUrl() +{ + QBENCHMARK { + QUrl url("pics/avatar.png"); + } +} + +void tst_qurl::absoluteUrl() +{ + QBENCHMARK { + QUrl url("/tmp/avatar.png"); + } +} + +void tst_qurl::generateFirstRunData() +{ + QTest::addColumn("firstRun"); + + QTest::newRow("construction + first run") << true; + QTest::newRow("subsequent runs") << false; +} + +void tst_qurl::isRelative_data() +{ + generateFirstRunData(); +} + +void tst_qurl::isRelative() +{ + QFETCH(bool, firstRun); + if (firstRun) { + QBENCHMARK { + QUrl url("pics/avatar.png"); + url.isRelative(); + } + } else { + QUrl url("pics/avatar.png"); + QBENCHMARK { + url.isRelative(); + } + } +} + +void tst_qurl::toLocalFile_data() +{ + generateFirstRunData(); +} + +void tst_qurl::toLocalFile() +{ + QFETCH(bool, firstRun); + if (firstRun) { + QBENCHMARK { + QUrl url("/tmp/avatar.png"); + url.toLocalFile(); + } + } else { + QUrl url("/tmp/avatar.png"); + QBENCHMARK { + url.toLocalFile(); + } + } +} + +void tst_qurl::toString_data() +{ + generateFirstRunData(); +} + +void tst_qurl::toString() +{ + QFETCH(bool, firstRun); + if(firstRun) { + QBENCHMARK { + QUrl url("pics/avatar.png"); + url.toString(); + } + } else { + QUrl url("pics/avatar.png"); + QBENCHMARK { + url.toString(); + } + } +} + +void tst_qurl::toEncoded_data() +{ + generateFirstRunData(); +} + +void tst_qurl::toEncoded() +{ + QFETCH(bool, firstRun); + if(firstRun) { + QBENCHMARK { + QUrl url("pics/avatar.png"); + url.toEncoded(QUrl::FormattingOption(0x100)); + } + } else { + QUrl url("pics/avatar.png"); + QBENCHMARK { + url.toEncoded(QUrl::FormattingOption(0x100)); + } + } +} + +void tst_qurl::resolved_data() +{ + generateFirstRunData(); +} + +void tst_qurl::resolved() +{ + QFETCH(bool, firstRun); + if(firstRun) { + QBENCHMARK { + QUrl baseUrl("/home/user/"); + QUrl url("pics/avatar.png"); + baseUrl.resolved(url); + } + } else { + QUrl baseUrl("/home/user/"); + QUrl url("pics/avatar.png"); + QBENCHMARK { + baseUrl.resolved(url); + } + } +} + +void tst_qurl::equality_data() +{ + generateFirstRunData(); +} + +void tst_qurl::equality() +{ + QFETCH(bool, firstRun); + if(firstRun) { + QBENCHMARK { + QUrl url("pics/avatar.png"); + QUrl url2("pics/avatar2.png"); + //url == url2; + } + } else { + QUrl url("pics/avatar.png"); + QUrl url2("pics/avatar2.png"); + QBENCHMARK { + url == url2; + } + } +} + +void tst_qurl::qmlPropertyWriteUseCase() +{ + QUrl base("file:///home/user/qt/demos/declarative/samegame/SamegameCore/"); + QString str("pics/redStar.png"); + + QBENCHMARK { + QUrl u = QUrl(str); + if (!u.isEmpty() && u.isRelative()) + u = base.resolved(u); + } +} + +QTEST_MAIN(tst_qurl) + +#include "main.moc" diff --git a/tests/benchmarks/corelib/io/qurl/qurl.pro b/tests/benchmarks/corelib/io/qurl/qurl.pro new file mode 100644 index 0000000..1d2d35e --- /dev/null +++ b/tests/benchmarks/corelib/io/qurl/qurl.pro @@ -0,0 +1,7 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_qurl +QT -= gui +win32: DEFINES+= _CRT_SECURE_NO_WARNINGS + +SOURCES += main.cpp -- cgit v0.12 From f97fbd807aa5d4bf217be983fc535cdc33a0bd03 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Mon, 15 Mar 2010 13:53:51 +1000 Subject: Fix benchmark. --- .../declarative/qdeclarativecomponent/data/samegame/BoomBlock.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/benchmarks/declarative/qdeclarativecomponent/data/samegame/BoomBlock.qml b/tests/benchmarks/declarative/qdeclarativecomponent/data/samegame/BoomBlock.qml index e48194a..b14531d 100644 --- a/tests/benchmarks/declarative/qdeclarativecomponent/data/samegame/BoomBlock.qml +++ b/tests/benchmarks/declarative/qdeclarativecomponent/data/samegame/BoomBlock.qml @@ -1,4 +1,5 @@ import Qt 4.6 +import Qt.labs.particles 1.0 Item { id:block property bool dying: false -- cgit v0.12 From 29edb69a909126448c4c73b2c216d0ccb7981418 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Mon, 15 Mar 2010 14:22:49 +1000 Subject: Little more doc on QabstractItemModel and QML. --- doc/src/declarative/qdeclarativemodels.qdoc | 20 +++++++++++++++++--- src/declarative/qml/qdeclarativeengine.cpp | 6 ++++-- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/doc/src/declarative/qdeclarativemodels.qdoc b/doc/src/declarative/qdeclarativemodels.qdoc index f7d1a73..e80824d 100644 --- a/doc/src/declarative/qdeclarativemodels.qdoc +++ b/doc/src/declarative/qdeclarativemodels.qdoc @@ -191,6 +191,23 @@ will be positioned by the view. \section2 QAbstractItemModel QAbstractItemModel provides the roles set via the QAbstractItemModel::setRoleNames() method. +The default role names set by Qt are: + +\table +\header +\o Qt Role +\o QML Role Name +\row +\o Qt::DisplayRole +\o display +\row +\o Qt::DecorationRole +\o decoration +\endtable + +QAbstractItemModel presents a heirachy of tables. Views currently provided by QML +can only display list data. In order to display child lists of a heirachical model +use the VisualDataModel element with \e rootIndex set to a parent node. \section2 QStringList @@ -198,9 +215,6 @@ QAbstractItemModel provides the roles set via the QAbstractItemModel::setRoleNam QStringList provides the contents of the list via the \e modelData role: \table -\header -\o -\o \row \o \code diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 72335d4..60dcc36 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -673,14 +673,16 @@ void QDeclarativeEngine::setContextForObject(QObject *object, QDeclarativeContex 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 +\list +\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 +\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. +\endlist 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 -- cgit v0.12 From 3e53cd1f486db2170e1ae984fb86c24e1c52c766 Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Mon, 15 Mar 2010 15:02:57 +1000 Subject: Small fixes to photoviewer demo --- .../PhotoViewerCore/images/background.png | Bin 2097 -> 0 bytes demos/declarative/photoviewer/photoviewer.qml | 26 +++++++++++---------- 2 files changed, 14 insertions(+), 12 deletions(-) delete mode 100644 demos/declarative/photoviewer/PhotoViewerCore/images/background.png diff --git a/demos/declarative/photoviewer/PhotoViewerCore/images/background.png b/demos/declarative/photoviewer/PhotoViewerCore/images/background.png deleted file mode 100644 index 81d9a45..0000000 Binary files a/demos/declarative/photoviewer/PhotoViewerCore/images/background.png and /dev/null differ diff --git a/demos/declarative/photoviewer/photoviewer.qml b/demos/declarative/photoviewer/photoviewer.qml index 2b0b6a9..5ce02f3 100644 --- a/demos/declarative/photoviewer/photoviewer.qml +++ b/demos/declarative/photoviewer/photoviewer.qml @@ -1,13 +1,13 @@ import Qt 4.6 import PhotoViewerCore 1.0 -Image { +Rectangle { id: mainWindow property real downloadProgress: 0 property bool imageLoading: false - width: 800; height: 480; source: "PhotoViewerCore/images/background.png"; fillMode: Image.Tile + width: 800; height: 480; color: "#d5d6d8" Script { source: "PhotoViewerCore/script/script.js" } @@ -18,28 +18,30 @@ Image { ListElement { tag: "Central Park" } } - VisualDataModel { - id: albumVisualModel; delegate: AlbumDelegate { } - model: photosModel - } + VisualDataModel { id: albumVisualModel; model: photosModel; delegate: AlbumDelegate {} } - GridView { width: parent.width; height: parent.height; cellWidth: 210; cellHeight: 220; model: albumVisualModel.parts.album } + GridView { + width: parent.width; height: parent.height; cellWidth: 210; cellHeight: 220; model: albumVisualModel.parts.album + visible: albumsShade.opacity != 1.0 + } - Image { - id: albumsShade; source: "PhotoViewerCore/images/background.png"; fillMode: Image.Tile - width: parent.width; height: parent.height; opacity: 0 + Rectangle { + id: albumsShade; color: mainWindow.color + width: parent.width; height: parent.height; opacity: 0.0 } ListView { anchors.fill: parent; model: albumVisualModel.parts.browser; interactive: false } Tag { id: backTag; label: "Back"; rotation: 3; x: parent.width - backTag.width - 6; y: -backTag.height - 8 } - Rectangle { id: photosShade; color: 'black'; width: parent.width; height: parent.height; opacity: 0 } + Rectangle { id: photosShade; color: 'black'; width: parent.width; height: parent.height; opacity: 0; visible: opacity != 0.0 } + ListView { anchors.fill: parent; model: albumVisualModel.parts.fullscreen; interactive: false } + Item { id: foreground; anchors.fill: parent } ProgressBar { progress: mainWindow.downloadProgress; width: parent.width; height: 4 - anchors.bottom: parent.bottom; opacity: mainWindow.imageLoading + anchors.bottom: parent.bottom; opacity: mainWindow.imageLoading; visible: opacity != 0.0 } } -- cgit v0.12 From 642e73beb83012ec243014bf34ec97f880fc1d37 Mon Sep 17 00:00:00 2001 From: mae Date: Mon, 15 Mar 2010 10:33:43 +0100 Subject: Import "content" with as qualifier to support network without qmldir --- demos/declarative/snake/snake.qml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/demos/declarative/snake/snake.qml b/demos/declarative/snake/snake.qml index f9d02c7..317c7de 100644 --- a/demos/declarative/snake/snake.qml +++ b/demos/declarative/snake/snake.qml @@ -1,5 +1,5 @@ import Qt 4.6 -import "content" +import "content" as Content Rectangle { id: screen; @@ -27,7 +27,7 @@ Rectangle { property var head; - HighScoreModel { + Content.HighScoreModel { id: highScores game: "Snake" } @@ -46,7 +46,7 @@ Rectangle { onTriggered: { moveSkull() } } Timer { - id: startNewGameTimer; + interval: 700; onTriggered: {startNewGame(); } } @@ -97,7 +97,7 @@ Rectangle { height: numRowsAvailable * gridSize + 2*margin - Skull { + Content.Skull { id: skull } @@ -148,7 +148,7 @@ Rectangle { height: 32; width: parent.width anchors.bottom: screen.bottom - Button { + Content.Button { id: btnA; text: "New Game"; onClicked: {startNewGame();} anchors.left: parent.left; anchors.leftMargin: 3 anchors.verticalCenter: parent.verticalCenter -- cgit v0.12 From e8da7d174a93e4c2c75ccdb4baacf676c91048ff Mon Sep 17 00:00:00 2001 From: mae Date: Mon, 15 Mar 2010 10:34:28 +0100 Subject: Fix regression from previous commit Support quoted imports without qualitifier id but with qmldir. This makes it possible again to launch the flickr demo from a remote site. --- src/declarative/qml/qdeclarativecompositetypemanager.cpp | 14 +++++++++++++- src/declarative/qml/qdeclarativeengine.cpp | 11 ++++++----- src/declarative/qml/qdeclarativeengine_p.h | 2 +- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/declarative/qml/qdeclarativecompositetypemanager.cpp b/src/declarative/qml/qdeclarativecompositetypemanager.cpp index b0c2f6d..e2a6e0c 100644 --- a/src/declarative/qml/qdeclarativecompositetypemanager.cpp +++ b/src/declarative/qml/qdeclarativecompositetypemanager.cpp @@ -506,6 +506,18 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData int waiting = 0; foreach (QDeclarativeScriptParser::Import imp, unit->data.imports()) { + QString qmldircontentnetwork; + if (imp.type == QDeclarativeScriptParser::Import::File && imp.qualifier.isEmpty()) { + QString importUrl = unit->imports.baseUrl().resolved(QUrl(imp.uri + QLatin1String("/qmldir"))).toString(); + for (int ii = 0; ii < unit->resources.count(); ++ii) { + if (unit->resources.at(ii)->url == importUrl) { + qmldircontentnetwork = QString::fromUtf8(unit->resources.at(ii)->data); + break; + } + } + } + + int vmaj = -1; int vmin = -1; if (!imp.version.isEmpty()) { @@ -520,7 +532,7 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData } if (!QDeclarativeEnginePrivate::get(engine)-> - addToImport(&unit->imports, imp.uri, imp.qualifier, vmaj, vmin, imp.type)) + addToImport(&unit->imports, qmldircontentnetwork, imp.uri, imp.qualifier, vmaj, vmin, imp.type)) { QDeclarativeError error; error.setUrl(unit->imports.baseUrl()); diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 72335d4..e82d91a 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1380,7 +1380,8 @@ struct QDeclarativeEnginePrivate::ImportedNamespace { QUrl url = QUrl(urls.at(i) + QLatin1Char('/') + QString::fromUtf8(type) + QLatin1String(".qml")); QString qmldircontent = qmlDirContent.at(i); - if (vmaj>=0 && !qmldircontent.isEmpty()) { + + if (!qmldircontent.isEmpty()) { const QString typeName = QString::fromUtf8(type); @@ -1427,9 +1428,9 @@ public: QSet qmlDirFilesForWhichPluginsHaveBeenLoaded; - bool add(const QUrl& base, const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType, const QStringList& importPath, QDeclarativeEngine *engine) + bool add(const QUrl& base, const QString &qmldircontentnetwork, const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType, const QStringList& importPath, QDeclarativeEngine *engine) { - QString qmldircontent; + QString qmldircontent = qmldircontentnetwork; QDeclarativeEnginePrivate::ImportedNamespace *s; if (prefix.isEmpty()) { s = &unqualifiedset; @@ -1884,12 +1885,12 @@ QString QDeclarativeEnginePrivate::resolvePlugin(const QDir &dir, const QString The base URL must already have been set with Import::setBaseUrl(). */ -bool QDeclarativeEnginePrivate::addToImport(Imports* imports, const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType) const +bool QDeclarativeEnginePrivate::addToImport(Imports* imports, const QString &qmldircontentnetwork, const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType) const { QDeclarativeEngine *engine = QDeclarativeEnginePrivate::get(const_cast(this)); if (qmlImportTrace()) qDebug() << "QDeclarativeEngine::addToImport(" << imports << uri << prefix << vmaj << '.' << vmin << (importType==QDeclarativeScriptParser::Import::Library? "Library" : "File"); - bool ok = imports->d->add(imports->d->base,uri,prefix,vmaj,vmin,importType,fileImportPath, engine); + bool ok = imports->d->add(imports->d->base,qmldircontentnetwork, uri,prefix,vmaj,vmin,importType,fileImportPath, engine); return ok; } diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h index 0f8b90a..c73a758 100644 --- a/src/declarative/qml/qdeclarativeengine_p.h +++ b/src/declarative/qml/qdeclarativeengine_p.h @@ -276,7 +276,7 @@ public: QString resolvePlugin(const QDir &dir, const QString &baseName); - bool addToImport(Imports*, const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType) const; + bool addToImport(Imports*, const QString& uri, const QString &qmldircontentnetwork, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType) const; bool resolveType(const Imports&, const QByteArray& type, QDeclarativeType** type_return, QUrl* url_return, int *version_major, int *version_minor, -- cgit v0.12 From 83fe3a8e1f12ddfb6fc8d42f007816c122bed94d Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Mon, 15 Mar 2010 15:30:53 +0100 Subject: Compile with user defined Qt namespace Protect the forward declaration of qstrtod with a QT_BEGIN/END namespace --- src/declarative/qml/parser/qdeclarativejslexer.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/declarative/qml/parser/qdeclarativejslexer.cpp b/src/declarative/qml/parser/qdeclarativejslexer.cpp index 34163a4..6404be3 100644 --- a/src/declarative/qml/parser/qdeclarativejslexer.cpp +++ b/src/declarative/qml/parser/qdeclarativejslexer.cpp @@ -56,9 +56,11 @@ #include #include -QT_QML_BEGIN_NAMESPACE - +QT_BEGIN_NAMESPACE extern double qstrtod(const char *s00, char const **se, bool *ok); +QT_END_NAMESPACE + +QT_QML_BEGIN_NAMESPACE #define shiftWindowsLineBreak() \ do { \ -- cgit v0.12 From ad70622193f8a34c28b6536521f8612e0b500fbf Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Tue, 16 Mar 2010 09:05:06 +1000 Subject: Optimize QRegion::intersects(QRect). Further optimize for the common case where numRects == 1. Benchmarks included. Reviewed-by: Samuel --- src/gui/painting/qregion.cpp | 36 ++++++++++--------- tests/benchmarks/gui/painting/qregion/main.cpp | 50 ++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 16 deletions(-) diff --git a/src/gui/painting/qregion.cpp b/src/gui/painting/qregion.cpp index bea2b6e..bfeef72 100644 --- a/src/gui/painting/qregion.cpp +++ b/src/gui/painting/qregion.cpp @@ -704,28 +704,13 @@ bool QRegion::intersects(const QRegion ®ion) const } /*! + \fn bool QRegion::intersects(const QRect &rect) const \since 4.2 Returns true if this region intersects with \a rect, otherwise returns false. */ -bool QRegion::intersects(const QRect &rect) const -{ - if (isEmpty() || rect.isNull()) - return false; - const QRect r = rect.normalized(); - if (!rect_intersects(boundingRect(), r)) - return false; - if (rectCount() == 1) - return true; - - const QVector myRects = rects(); - for (QVector::const_iterator it = myRects.constBegin(); it < myRects.constEnd(); ++it) - if (rect_intersects(r, *it)) - return true; - return false; -} #if !defined (Q_OS_UNIX) && !defined (Q_WS_WIN) /*! @@ -4349,5 +4334,24 @@ bool QRegion::operator==(const QRegion &r) const return EqualRegion(d->qt_rgn, r.d->qt_rgn); } +bool QRegion::intersects(const QRect &rect) const +{ + if (isEmptyHelper(d->qt_rgn) || rect.isNull()) + return false; + + const QRect r = rect.normalized(); + if (!rect_intersects(d->qt_rgn->extents, r)) + return false; + if (d->qt_rgn->numRects == 1) + return true; + + const QVector myRects = rects(); + for (QVector::const_iterator it = myRects.constBegin(); it < myRects.constEnd(); ++it) + if (rect_intersects(r, *it)) + return true; + return false; +} + + #endif QT_END_NAMESPACE diff --git a/tests/benchmarks/gui/painting/qregion/main.cpp b/tests/benchmarks/gui/painting/qregion/main.cpp index 3d16e41..1d19854 100644 --- a/tests/benchmarks/gui/painting/qregion/main.cpp +++ b/tests/benchmarks/gui/painting/qregion/main.cpp @@ -49,6 +49,9 @@ class tst_qregion : public QObject private slots: void map_data(); void map(); + + void intersects_data(); + void intersects(); }; @@ -84,6 +87,53 @@ void tst_qregion::map() } } +void tst_qregion::intersects_data() +{ + QTest::addColumn("region"); + QTest::addColumn("rect"); + + QRegion region(0, 0, 100, 100); + QRegion complexRegion; + complexRegion = complexRegion.united(QRect(0, 0, 100, 100)); + complexRegion = complexRegion.united(QRect(120, 20, 100, 100)); + + { + QRect rect(0, 0, 100, 100); + QTest::newRow("same -- simple") << region << rect; + } + { + QRect rect(10, 10, 10, 10); + QTest::newRow("inside -- simple") << region << rect; + } + { + QRect rect(110, 110, 10, 10); + QTest::newRow("outside -- simple") << region << rect; + } + + { + QRect rect(0, 0, 100, 100); + QTest::newRow("same -- complex") << complexRegion << rect; + } + { + QRect rect(10, 10, 10, 10); + QTest::newRow("inside -- complex") << complexRegion << rect; + } + { + QRect rect(110, 110, 10, 10); + QTest::newRow("outside -- complex") << complexRegion << rect; + } +} + +void tst_qregion::intersects() +{ + QFETCH(QRegion, region); + QFETCH(QRect, rect); + + QBENCHMARK { + region.intersects(rect); + } +} + QTEST_MAIN(tst_qregion) #include "main.moc" -- cgit v0.12 From a0f2c60dd9f6f44b7016f879b5b3ec32c665fdb9 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Tue, 16 Mar 2010 09:18:45 +1000 Subject: Optimize drawPixmapFragments for the GL2 paint engine. In this case, we don't need QGL2PEXVertexArray to keep track of min and max information. Reviewed-by: Samuel --- src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h | 5 +++++ .../gl2paintengineex/qpaintengineex_opengl2.cpp | 24 +++++++++++----------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h index d1e7615..adc69ee 100644 --- a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h +++ b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h @@ -132,6 +132,11 @@ public: } + inline void addVertex(const GLfloat x, const GLfloat y) + { + vertexArray.add(QGLPoint(x, y)); + } + void addPath(const QVectorPath &path, GLfloat curveInverseScale, bool outline = true); void clear(); diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index d68a268..1884138 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1696,23 +1696,23 @@ void QGL2PaintEngineExPrivate::drawPixmapFragments(const QPainter::PixmapFragmen QGLPoint bottomRight(right * c - bottom * s, right * s + bottom * c); QGLPoint bottomLeft(-right * c - bottom * s, -right * s + bottom * c); - vertexCoordinateArray.lineToArray(bottomRight.x + fragments[i].x, bottomRight.y + fragments[i].y); - vertexCoordinateArray.lineToArray(-bottomLeft.x + fragments[i].x, -bottomLeft.y + fragments[i].y); - vertexCoordinateArray.lineToArray(-bottomRight.x + fragments[i].x, -bottomRight.y + fragments[i].y); - vertexCoordinateArray.lineToArray(-bottomRight.x + fragments[i].x, -bottomRight.y + fragments[i].y); - vertexCoordinateArray.lineToArray(bottomLeft.x + fragments[i].x, bottomLeft.y + fragments[i].y); - vertexCoordinateArray.lineToArray(bottomRight.x + fragments[i].x, bottomRight.y + fragments[i].y); + vertexCoordinateArray.addVertex(bottomRight.x + fragments[i].x, bottomRight.y + fragments[i].y); + vertexCoordinateArray.addVertex(-bottomLeft.x + fragments[i].x, -bottomLeft.y + fragments[i].y); + vertexCoordinateArray.addVertex(-bottomRight.x + fragments[i].x, -bottomRight.y + fragments[i].y); + vertexCoordinateArray.addVertex(-bottomRight.x + fragments[i].x, -bottomRight.y + fragments[i].y); + vertexCoordinateArray.addVertex(bottomLeft.x + fragments[i].x, bottomLeft.y + fragments[i].y); + vertexCoordinateArray.addVertex(bottomRight.x + fragments[i].x, bottomRight.y + fragments[i].y); QGLRect src(fragments[i].sourceLeft * dx, fragments[i].sourceTop * dy, (fragments[i].sourceLeft + fragments[i].width) * dx, (fragments[i].sourceTop + fragments[i].height) * dy); - textureCoordinateArray.lineToArray(src.right, src.bottom); - textureCoordinateArray.lineToArray(src.right, src.top); - textureCoordinateArray.lineToArray(src.left, src.top); - textureCoordinateArray.lineToArray(src.left, src.top); - textureCoordinateArray.lineToArray(src.left, src.bottom); - textureCoordinateArray.lineToArray(src.right, src.bottom); + textureCoordinateArray.addVertex(src.right, src.bottom); + textureCoordinateArray.addVertex(src.right, src.top); + textureCoordinateArray.addVertex(src.left, src.top); + textureCoordinateArray.addVertex(src.left, src.top); + textureCoordinateArray.addVertex(src.left, src.bottom); + textureCoordinateArray.addVertex(src.right, src.bottom); qreal opacity = fragments[i].opacity * q->state()->opacity; opacityArray << opacity << opacity << opacity << opacity << opacity << opacity; -- cgit v0.12 From ee8375dd20823173fd8df03481f19db245af1a7f Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 16 Mar 2010 10:30:03 +1000 Subject: Split post alpha API changes into a separate section. --- src/declarative/QmlChanges.txt | 48 ++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt index 13b1eee..6d0f16f 100644 --- a/src/declarative/QmlChanges.txt +++ b/src/declarative/QmlChanges.txt @@ -1,26 +1,45 @@ ============================================================================= -The changes below are pre Qt 4.7.0 alpha +The changes below are pre Qt 4.7.0 beta PathView: offset property now uses range 0-1.0 rather than 0-100 ListView, GridView::positionViewAtIndex() gained a 'mode' parameter +Removed Qt.playSound (replaced by SoundEffect element) +Removed Qt.closestAngle (use RotationAnimation instead) +Removed NumberFormatter +Removed DateTimeFormatter (use Qt.formatDateTime() instead) +Using WebView now requires "import org.webkit 1.0" +Using Particles now requires "import Qt.labs.particles 1.0" +AnchorAnimation must now be used to animate anchor changes (and not NumberAnimation) + +C++ API +------- +QDeclarativeContext::addDefaultObject() has been replaced with +QDeclarativeContext::setContextObject() + +Behavior and Animation syntax +----------------------------- +Previously animations and behaviors could be "assigned" to properties like this: + Item { x: Behavior {}; y: NumberAnimation {} } +To make it more obvious that these are not regular value assignments a new "on" +syntax has been introduced: + Item { Behavior on x {}; NumberAnimation on y {} } +Only the syntax has changed, the behavior is identical. + + +============================================================================= +The changes below are pre Qt 4.7.0 alpha + Flickable: renamed viewportWidth -> contentWidth Flickable: renamed viewportHeight -> contentHeight Flickable: renamed viewportX -> contentX Flickable: renamed viewportY -> contentY Removed Flickable.reportedVelocitySmoothing -Removed Qt.playSound (replaced by SoundEffect element) -Removed Qt.closestAngle (use RotationAnimation instead) -Removed NumberFormatter -Removed DateTimeFormatter (use Qt.formatDateTime() instead) Renamed MouseRegion -> MouseArea Connection: syntax and rename: Connection { sender: a; signal: foo(); script: xxx } Connection { sender: a; signal: bar(); script: yyy } becomes: Connections { target: a; onFoo: xxx; onBar: yyy } -Using WebView now requires "import org.webkit 1.0" -Using Particles now requires "import Qt.labs.particles 1.0" -AnchorAnimation must now be used to animate anchor changes (and not NumberAnimation) QmlView ------- @@ -55,25 +74,12 @@ should also consider using the QmlExtensionPlugin (previously named QmlModulePlu as a cleaner mechanism for publishing libraries of QML types, or the upcoming application plugin features of the qmlviewer / qmlruntime / qml. -QDeclarativeContext::addDefaultObject() has been replaced with -QDeclarativeContext::setContextObject() - PropertyAnimation ------------------ matchProperties and matchTargets have been renamed back to properties and targets. The semantics are explained in the PropertyAnimation::properties documentation and the animation overview documentation. -Behavior and Animation syntax ------------------------------ - -Previously animations and behaviors could be "assigned" to properties like this: - Item { x: Behavior {}; y: NumberAnimation {} } -To make it more obvious that these are not regular value assignments a new "on" -syntax has been introduced: - Item { Behavior on x {}; NumberAnimation on y {} } -Only the syntax has changed, the behavior is identical. - ============================================================================= The changes below are pre-4.6.0 release. -- cgit v0.12 From 081fafe395d52ae42b57c36d1279e6ac05ae2cde Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Tue, 16 Mar 2010 11:16:13 +1000 Subject: Remove WorkerListModel and integrate its functionality into ListModel. Task-number: QT-2829 --- .../declarative/listmodel-threaded/dataloader.js | 14 + .../declarative/listmodel-threaded/timedisplay.qml | 33 + examples/declarative/workerlistmodel/dataloader.js | 14 - .../declarative/workerlistmodel/timedisplay.qml | 33 - src/declarative/qml/qdeclarativeengine.cpp | 1 - src/declarative/qml/qdeclarativeworkerscript.cpp | 647 +------------- src/declarative/qml/qdeclarativeworkerscript_p.h | 41 - src/declarative/util/qdeclarativelistmodel.cpp | 980 ++++++++++++++------- src/declarative/util/qdeclarativelistmodel_p.h | 21 +- src/declarative/util/qdeclarativelistmodel_p_p.h | 199 +++++ .../util/qdeclarativelistmodelworkeragent.cpp | 245 ++++++ .../util/qdeclarativelistmodelworkeragent_p.h | 155 ++++ src/declarative/util/util.pri | 7 +- .../qdeclarativelistmodel/data/model.qml | 24 + .../qdeclarativelistmodel/data/script.js | 12 + .../qdeclarativelistmodel.pro | 3 + .../tst_qdeclarativelistmodel.cpp | 238 ++++- .../qdeclarativeworkerlistmodel/data/model.qml | 14 - .../qdeclarativeworkerlistmodel/data/script.js | 6 - .../qdeclarativeworkerlistmodel.pro | 9 - .../tst_qdeclarativeworkerlistmodel.cpp | 193 ---- 21 files changed, 1610 insertions(+), 1279 deletions(-) create mode 100644 examples/declarative/listmodel-threaded/dataloader.js create mode 100644 examples/declarative/listmodel-threaded/timedisplay.qml delete mode 100644 examples/declarative/workerlistmodel/dataloader.js delete mode 100644 examples/declarative/workerlistmodel/timedisplay.qml create mode 100644 src/declarative/util/qdeclarativelistmodel_p_p.h create mode 100644 src/declarative/util/qdeclarativelistmodelworkeragent.cpp create mode 100644 src/declarative/util/qdeclarativelistmodelworkeragent_p.h create mode 100644 tests/auto/declarative/qdeclarativelistmodel/data/model.qml create mode 100644 tests/auto/declarative/qdeclarativelistmodel/data/script.js delete mode 100644 tests/auto/declarative/qdeclarativeworkerlistmodel/data/model.qml delete mode 100644 tests/auto/declarative/qdeclarativeworkerlistmodel/data/script.js delete mode 100644 tests/auto/declarative/qdeclarativeworkerlistmodel/qdeclarativeworkerlistmodel.pro delete mode 100644 tests/auto/declarative/qdeclarativeworkerlistmodel/tst_qdeclarativeworkerlistmodel.cpp diff --git a/examples/declarative/listmodel-threaded/dataloader.js b/examples/declarative/listmodel-threaded/dataloader.js new file mode 100644 index 0000000..eac7478 --- /dev/null +++ b/examples/declarative/listmodel-threaded/dataloader.js @@ -0,0 +1,14 @@ +// ![0] +WorkerScript.onMessage = function(msg) { + console.log("Worker told to", msg.action); + + if (msg.action == 'appendCurrentTime') { + var data = {'time': new Date().toTimeString()}; + msg.model.append(data); + msg.model.sync(); // updates the changes to the list + + var msgToSend = {'msg': 'Model updated!'}; + WorkerScript.sendMessage(msgToSend); + } +} +// ![0] diff --git a/examples/declarative/listmodel-threaded/timedisplay.qml b/examples/declarative/listmodel-threaded/timedisplay.qml new file mode 100644 index 0000000..e8d8fe2 --- /dev/null +++ b/examples/declarative/listmodel-threaded/timedisplay.qml @@ -0,0 +1,33 @@ +// ![0] +import Qt 4.6 + +ListView { + width: 200 + height: 300 + + model: listModel + delegate: Component { + Text { text: time } + } + + ListModel { id: listModel } + + WorkerScript { + id: worker + source: "dataloader.js" + onMessage: { + console.log("Worker said", messageObject.msg); + } + } + + Timer { + id: timer + interval: 2000; repeat: true; running: true; triggeredOnStart: true + + onTriggered: { + var msg = {'action': 'appendCurrentTime', 'model': listModel}; + worker.sendMessage(msg); + } + } +} +// ![0] diff --git a/examples/declarative/workerlistmodel/dataloader.js b/examples/declarative/workerlistmodel/dataloader.js deleted file mode 100644 index eac7478..0000000 --- a/examples/declarative/workerlistmodel/dataloader.js +++ /dev/null @@ -1,14 +0,0 @@ -// ![0] -WorkerScript.onMessage = function(msg) { - console.log("Worker told to", msg.action); - - if (msg.action == 'appendCurrentTime') { - var data = {'time': new Date().toTimeString()}; - msg.model.append(data); - msg.model.sync(); // updates the changes to the list - - var msgToSend = {'msg': 'Model updated!'}; - WorkerScript.sendMessage(msgToSend); - } -} -// ![0] diff --git a/examples/declarative/workerlistmodel/timedisplay.qml b/examples/declarative/workerlistmodel/timedisplay.qml deleted file mode 100644 index 3bf2630..0000000 --- a/examples/declarative/workerlistmodel/timedisplay.qml +++ /dev/null @@ -1,33 +0,0 @@ -// ![0] -import Qt 4.6 - -ListView { - width: 200 - height: 300 - - model: listModel - delegate: Component { - Text { text: time } - } - - WorkerListModel { id: listModel } - - WorkerScript { - id: worker - source: "dataloader.js" - onMessage: { - console.log("Worker said", messageObject.msg); - } - } - - Timer { - id: timer - interval: 2000; repeat: true; running: true; triggeredOnStart: true - - onTriggered: { - var msg = {'action': 'appendCurrentTime', 'model': listModel}; - worker.sendMessage(msg); - } - } -} -// ![0] diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 41d55d7..3b8d603 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -149,7 +149,6 @@ void QDeclarativeEnginePrivate::defineModule() QML_REGISTER_TYPE(Qt,4,6,Component,QDeclarativeComponent); QML_REGISTER_TYPE(Qt,4,6,QtObject,QObject); QML_REGISTER_TYPE(Qt,4,6,WorkerScript,QDeclarativeWorkerScript); - QML_REGISTER_TYPE(Qt,4,6,WorkerListModel,QDeclarativeWorkerListModel); QML_REGISTER_NOCREATE_TYPE(QDeclarativeBinding); } diff --git a/src/declarative/qml/qdeclarativeworkerscript.cpp b/src/declarative/qml/qdeclarativeworkerscript.cpp index 784353a..10c0b54 100644 --- a/src/declarative/qml/qdeclarativeworkerscript.cpp +++ b/src/declarative/qml/qdeclarativeworkerscript.cpp @@ -40,7 +40,8 @@ ****************************************************************************/ #include "qdeclarativeworkerscript_p.h" - +#include "qdeclarativelistmodel_p.h" +#include "qdeclarativelistmodelworkeragent_p.h" #include "qdeclarativeengine_p.h" #include @@ -104,6 +105,7 @@ private: class QDeclarativeWorkerScriptEnginePrivate : public QObject { + Q_OBJECT public: QDeclarativeWorkerScriptEnginePrivate(QDeclarativeEngine *eng); @@ -165,87 +167,6 @@ private: void processLoad(int, const QUrl &); }; -// Currently this will leak as no-one releases it in the worker thread -class QDeclarativeWorkerListModelAgent : public QObject -{ - Q_OBJECT - Q_PROPERTY(int count READ count) - -public: - QDeclarativeWorkerListModelAgent(QDeclarativeWorkerListModel *); - ~QDeclarativeWorkerListModelAgent(); - - void addref(); - void release(); - - int count() const; - - Q_INVOKABLE void clear(); - Q_INVOKABLE void remove(int index); - Q_INVOKABLE void append(const QScriptValue &); - Q_INVOKABLE void insert(int index, const QScriptValue&); - Q_INVOKABLE QScriptValue get(int index) const; - Q_INVOKABLE void set(int index, const QScriptValue &); - Q_INVOKABLE void sync(); - - struct VariantRef - { - VariantRef() : a(0) {} - VariantRef(const VariantRef &r) : a(r.a) { if (a) a->addref(); } - VariantRef(QDeclarativeWorkerListModelAgent *_a) : a(_a) { if (a) a->addref(); } - ~VariantRef() { if (a) a->release(); } - - VariantRef &operator=(const VariantRef &o) { - if (o.a) o.a->addref(); - if (a) a->release(); a = o.a; - return *this; - } - - QDeclarativeWorkerListModelAgent *a; - }; -protected: - virtual bool event(QEvent *); - -private: - friend class QDeclarativeWorkerScriptEnginePrivate; - friend class QDeclarativeWorkerListModel; - QScriptEngine *m_engine; - - struct Change { - enum { Inserted, Removed, Moved, Changed } type; - int index; // Inserted/Removed/Moved/Changed - int count; // Inserted/Removed/Moved/Changed - int to; // Moved - }; - - struct Data { - QHash roles; - QHash strings; - QList > values; - QList changes; - - void clearChange(); - void insertChange(int index, int count); - void removeChange(int index, int count); - void changedChange(int index, int count); - }; - Data data; - - struct Sync : public QEvent { - Sync() : QEvent(QEvent::User) {} - Data data; - }; - - QAtomicInt m_ref; - QDeclarativeWorkerListModel *m_model; -}; - -QT_END_NAMESPACE - -Q_DECLARE_METATYPE(QDeclarativeWorkerListModelAgent::VariantRef); - -QT_BEGIN_NAMESPACE - QDeclarativeWorkerScriptEnginePrivate::QDeclarativeWorkerScriptEnginePrivate(QDeclarativeEngine *engine) : workerEngine(0), qmlengine(engine), m_nextId(0) { @@ -390,10 +311,15 @@ QVariant QDeclarativeWorkerScriptEnginePrivate::scriptValueToVariant(const QScri return QVariant(list); } else if (value.isQObject()) { - QDeclarativeWorkerListModel *lm = qobject_cast(value.toQObject()); + QDeclarativeListModel *lm = qobject_cast(value.toQObject()); if (lm) { - QDeclarativeWorkerListModelAgent::VariantRef v(lm->agent()); - return qVariantFromValue(v); + QDeclarativeListModelWorkerAgent *agent = lm->agent(); + if (agent) { + QDeclarativeListModelWorkerAgent::VariantRef v(agent); + return qVariantFromValue(v); + } else { + return QVariant(); + } } else { // No other QObject's are allowed to be sent return QVariant(); @@ -423,11 +349,11 @@ QScriptValue QDeclarativeWorkerScriptEnginePrivate::variantToScriptValue(const Q return QScriptValue(value.toString()); } else if (value.userType() == QMetaType::QReal) { return QScriptValue(value.toReal()); - } else if (value.userType() == qMetaTypeId()) { - QDeclarativeWorkerListModelAgent::VariantRef vr = qvariant_cast(value); - if (vr.a->m_engine == 0) - vr.a->m_engine = engine; - else if (vr.a->m_engine != engine) + } else if (value.userType() == qMetaTypeId()) { + QDeclarativeListModelWorkerAgent::VariantRef vr = qvariant_cast(value); + if (vr.a->scriptEngine() == 0) + vr.a->setScriptEngine(engine); + else if (vr.a->scriptEngine() != engine) return engine->nullValue(); QScriptValue o = engine->newQObject(vr.a); o.setData(engine->newVariant(value)); // Keeps the agent ref so that it is cleaned up on gc @@ -619,8 +545,6 @@ void QDeclarativeWorkerScriptEngine::run() called, triggering the \tt WorkerScript.onMessage() handler in \tt source.js. This in turn sends a reply message that is then received by the \tt onMessage() handler of \tt myWorker. - - \sa WorkerListModel */ QDeclarativeWorkerScript::QDeclarativeWorkerScript(QObject *parent) : QObject(parent), m_engine(0), m_scriptId(-1) @@ -714,544 +638,7 @@ bool QDeclarativeWorkerScript::event(QEvent *event) } } -void QDeclarativeWorkerListModelAgent::Data::clearChange() -{ - changes.clear(); -} - -void QDeclarativeWorkerListModelAgent::Data::insertChange(int index, int count) -{ - Change c = { Change::Inserted, index, count, 0 }; - changes << c; -} - -void QDeclarativeWorkerListModelAgent::Data::removeChange(int index, int count) -{ - Change c = { Change::Removed, index, count, 0 }; - changes << c; -} - -void QDeclarativeWorkerListModelAgent::Data::changedChange(int index, int count) -{ - Change c = { Change::Changed, index, count, 0 }; - changes << c; -} - -QDeclarativeWorkerListModelAgent::QDeclarativeWorkerListModelAgent(QDeclarativeWorkerListModel *m) -: m_engine(0), m_ref(1), m_model(m) -{ - data.roles = m_model->m_roles; - data.strings = m_model->m_strings; - data.values = m_model->m_values; -} - -QDeclarativeWorkerListModelAgent::~QDeclarativeWorkerListModelAgent() -{ -} - -void QDeclarativeWorkerListModelAgent::addref() -{ - m_ref.ref(); -} - -void QDeclarativeWorkerListModelAgent::release() -{ - bool del = !m_ref.deref(); - - if (del) - delete this; -} - -int QDeclarativeWorkerListModelAgent::count() const -{ - return data.values.count(); -} - -void QDeclarativeWorkerListModelAgent::clear() -{ - data.clearChange(); - data.removeChange(0, data.values.count()); - data.values.clear(); -} - -void QDeclarativeWorkerListModelAgent::remove(int index) -{ - if (data.values.count() <= index) - return; - - data.values.removeAt(index); - data.removeChange(index, 1); -} - -void QDeclarativeWorkerListModelAgent::append(const QScriptValue &value) -{ - QHash row; - - QScriptValueIterator it(value); - while (it.hasNext()) { - it.next(); - QString name = it.name(); - QVariant v = it.value().toVariant(); - - QHash::Iterator iter = data.strings.find(name); - if (iter == data.strings.end()) { - int role = data.roles.count(); - data.roles.insert(role, name); - iter = data.strings.insert(name, role); - } - row.insert(*iter, v); - } - - data.values.append(row); - data.insertChange(data.values.count() - 1, 1); -} - -void QDeclarativeWorkerListModelAgent::insert(int index, const QScriptValue &value) -{ - if (index > data.values.count()) - return; - - QHash row; - - QScriptValueIterator it(value); - while (it.hasNext()) { - it.next(); - QString name = it.name(); - QVariant v = it.value().toVariant(); - - QHash::Iterator iter = data.strings.find(name); - if (iter == data.strings.end()) { - int role = data.roles.count(); - data.roles.insert(role, name); - iter = data.strings.insert(name, role); - } - row.insert(*iter, v); - } - - data.values.insert(index, row); - data.insertChange(index, 1); -} - -void QDeclarativeWorkerListModelAgent::set(int index, const QScriptValue &value) -{ - if (data.values.count() <= index) - return; - - QHash row; - - QScriptValueIterator it(value); - while (it.hasNext()) { - it.next(); - QString name = it.name(); - QVariant v = it.value().toVariant(); - - QHash::Iterator iter = data.strings.find(name); - if (iter == data.strings.end()) { - int role = data.roles.count(); - data.roles.insert(role, name); - iter = data.strings.insert(name, role); - } - row.insert(*iter, v); - } - - if (data.values.at(index) != row) { - data.values[index] = row; - data.changedChange(index, 1); - } -} - -QScriptValue QDeclarativeWorkerListModelAgent::get(int index) const -{ - if (data.values.count() <= index) - return m_engine->undefinedValue(); - - QScriptValue rv = m_engine->newObject(); - - QHash row = data.values.at(index); - for (QHash::ConstIterator iter = row.begin(); iter != row.end(); ++iter) - rv.setProperty(data.roles.value(iter.key()), qScriptValueFromValue(m_engine, iter.value())); - - return rv; -} - -void QDeclarativeWorkerListModelAgent::sync() -{ - Sync *s = new Sync; - s->data = data; - data.changes.clear(); - QCoreApplication::postEvent(this, s); -} - -bool QDeclarativeWorkerListModelAgent::event(QEvent *e) -{ - if (e->type() == QEvent::User) { - Sync *s = static_cast(e); - - const QList &changes = s->data.changes; - - if (m_model) { - bool cc = m_model->m_values.count() != s->data.values.count(); - - m_model->m_roles = s->data.roles; - m_model->m_strings = s->data.strings; - m_model->m_values = s->data.values; - - for (int ii = 0; ii < changes.count(); ++ii) { - const Change &change = changes.at(ii); - switch (change.type) { - case Change::Inserted: - emit m_model->itemsInserted(change.index, change.count); - break; - case Change::Removed: - emit m_model->itemsRemoved(change.index, change.count); - break; - case Change::Moved: - emit m_model->itemsMoved(change.index, change.to, change.count); - break; - case Change::Changed: - emit m_model->itemsMoved(change.index, change.to, change.count); - break; - } - } - - if (cc) - emit m_model->countChanged(); - } - } - - return QObject::event(e); -} - -/*! - \qmlclass WorkerListModel QDeclarativeWorkerListModel - \brief The WorkerListModel element provides a threaded list model. - - Use WorkerListModel together with WorkerScript to define a list model - that is controlled by a separate thread. This is useful if list modification - operations are synchronous and take some time: using WorkerListModel - moves these operations to a different thread and avoids blocking of the - main GUI thread. - - The thread that creates the WorkerListModel can modify the model for any - initial set-up requirements. However, once the model has been modified by - the associated WorkerScript, the model can only be modified by that worker - script and becomes read-only to all other threads. - - Here is an example application that uses WorkerScript to append the - current time to a WorkerListModel: - - \snippet examples/declarative/workerlistmodel/timedisplay.qml 0 - - The included file, \tt dataloader.js, looks like this: - - \snippet examples/declarative/workerlistmodel/dataloader.js 0 - - The application's \tt Timer object periodically sends a message to the - worker script by calling \tt WorkerScript::sendMessage(). When this message - is received, \tt WorkerScript.onMessage() is invoked in - \tt dataloader.js, which appends the current time to the worker list - model. - - Note that unlike ListModel, WorkerListModel does not have \tt move() and - \tt setProperty() methods. - - \sa WorkerScript, ListModel -*/ -QDeclarativeWorkerListModel::QDeclarativeWorkerListModel(QObject *parent) -: QListModelInterface(parent), m_agent(0) -{ -} - -QDeclarativeWorkerListModel::~QDeclarativeWorkerListModel() -{ - if (m_agent) { - m_agent->m_model = 0; - m_agent->release(); - } -} - -/*! - \qmlmethod WorkerListModel::clear() - - Deletes all content from the model. The properties are cleared such that - different properties may be set on subsequent additions. - - \sa append() remove() -*/ -void QDeclarativeWorkerListModel::clear() -{ - if (m_agent) { - qmlInfo(this) << "List can only be modified from a WorkerScript"; - return; - } - - int count = m_values.count(); - m_values.clear(); - if (count) { - emit itemsRemoved(0, count); - emit countChanged(); - } -} - -/*! - \qmlmethod WorkerListModel::remove(int index) - - Deletes the content at \a index from the model. - - \sa clear() -*/ -void QDeclarativeWorkerListModel::remove(int index) -{ - if (m_agent) { - qmlInfo(this) << "List can only be modified from a WorkerScript"; - return; - } - - if (m_values.count() <= index) - return; - - m_values.removeAt(index); - emit itemsRemoved(index, 1); - emit countChanged(); -} - -/*! - \qmlmethod WorkerListModel::append(jsobject dict) - - Adds a new item to the end of the list model, with the - values in \a dict. - - \code - FruitModel.append({"cost": 5.95, "name":"Pizza"}) - \endcode - - \sa set() remove() -*/ -void QDeclarativeWorkerListModel::append(const QScriptValue &value) -{ - if (m_agent) { - qmlInfo(this) << "List can only be modified from a WorkerScript"; - return; - } - - QHash data; - - QScriptValueIterator it(value); - while (it.hasNext()) { - it.next(); - QString name = it.name(); - QVariant v = it.value().toVariant(); - - QHash::Iterator iter = m_strings.find(name); - if (iter == m_strings.end()) { - int role = m_roles.count(); - m_roles.insert(role, name); - iter = m_strings.insert(name, role); - } - data.insert(*iter, v); - } - - m_values.append(data); - - emit itemsInserted(m_values.count() - 1, 1); - emit countChanged(); -} - -/*! - \qmlmethod WorkerListModel::insert(int index, jsobject dict) - - Adds a new item to the list model at position \a index, with the - values in \a dict. - - \code - FruitModel.insert(2, {"cost": 5.95, "name":"Pizza"}) - \endcode - - The \a index must be to an existing item in the list, or one past - the end of the list (equivalent to append). - - \sa set() append() -*/ -void QDeclarativeWorkerListModel::insert(int index, const QScriptValue &value) -{ - if (m_agent) { - qmlInfo(this) << "List can only be modified from a WorkerScript"; - return; - } - - if (index > m_values.count()) - return; - - QHash data; - - QScriptValueIterator it(value); - while (it.hasNext()) { - it.next(); - QString name = it.name(); - QVariant v = it.value().toVariant(); - - QHash::Iterator iter = m_strings.find(name); - if (iter == m_strings.end()) { - int role = m_roles.count(); - m_roles.insert(role, name); - iter = m_strings.insert(name, role); - } - data.insert(*iter, v); - } - - m_values.insert(index, data); - emit itemsInserted(index, 1); - emit countChanged(); -} - -/*! - \qmlmethod object ListModel::get(int index) - - Returns the item at \a index in the list model. - - \code - FruitModel.append({"cost": 5.95, "name":"Jackfruit"}) - FruitModel.get(0).cost - \endcode - - The \a index must be an element in the list. - - Note that properties of the returned object that are themselves objects - will also be models, and this get() method is used to access elements: - - \code - FruitModel.append(..., "attributes": - [{"name":"spikes","value":"7mm"}, - {"name":"color","value":"green"}]); - FruitModel.get(0).attributes.get(1).value; // == "green" - \endcode - - \sa append() -*/ -QScriptValue QDeclarativeWorkerListModel::get(int index) const -{ - QDeclarativeEngine *engine = qmlEngine(this); - if (!engine || m_values.count() <= index) - return QScriptValue(); - - QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); - QScriptValue rv = scriptEngine->newObject(); - - QHash data = m_values.at(index); - for (QHash::ConstIterator iter = data.begin(); iter != data.end(); ++iter) - rv.setProperty(m_roles.value(iter.key()), qScriptValueFromValue(scriptEngine, iter.value())); - - return rv; -} - -/*! - \qmlmethod WorkerListModel::set(int index, jsobject dict) - - Changes the item at \a index in the list model with the - values in \a dict. Properties not appearing in \a valuemap - are left unchanged. - - \code - FruitModel.set(3, {"cost": 5.95, "name":"Pizza"}) - \endcode - - The \a index must be an element in the list. - - \sa append() -*/ -void QDeclarativeWorkerListModel::set(int index, const QScriptValue &value) -{ - if (m_agent) { - qmlInfo(this) << "List can only be modified from a WorkerScript"; - return; - } - - if (m_values.count() <= index) - return; - - QHash data; - - QScriptValueIterator it(value); - while (it.hasNext()) { - it.next(); - QString name = it.name(); - QVariant v = it.value().toVariant(); - - QHash::Iterator iter = m_strings.find(name); - if (iter == m_strings.end()) { - int role = m_roles.count(); - m_roles.insert(role, name); - iter = m_strings.insert(name, role); - } - data.insert(*iter, v); - } - - if (m_values.at(index) != data) { - m_values[index] = data; - emit itemsChanged(index, 1, m_roles.keys()); - } -} - -/*! - \qmlmethod WorkerListModel::sync() - - Writes any unsaved changes to the list model. This must be called after - changes have been made to the list model in the worker script. - - Note that this method can only be called from the associated worker script. -*/ -void QDeclarativeWorkerListModel::sync() -{ - // This is really a dummy method to make it look like sync() exists in - // WorkerListModel (and not QDeclarativeWorkerListModelAgent) and to let - // us document sync(). - qmlInfo(this) << "sync() can only be called from a WorkerScript"; -} - -QDeclarativeWorkerListModelAgent *QDeclarativeWorkerListModel::agent() -{ - if (!m_agent) - m_agent = new QDeclarativeWorkerListModelAgent(this); - - return m_agent; -} - -QList QDeclarativeWorkerListModel::roles() const -{ - return m_roles.keys(); -} - -QString QDeclarativeWorkerListModel::toString(int role) const -{ - return m_roles.value(role); -} - -/*! - \qmlproperty int ListModel::count - The number of data entries in the model. -*/ -int QDeclarativeWorkerListModel::count() const -{ - return m_values.count(); -} - -QHash QDeclarativeWorkerListModel::data(int index, const QList &) const -{ - if (m_values.count() <= index) - return QHash(); - else - return m_values.at(index); -} - -QVariant QDeclarativeWorkerListModel::data(int index, int role) const -{ - if (m_values.count() <= index) - return QVariant(); - else - return m_values.at(index).value(role); -} - QT_END_NAMESPACE -#include "qdeclarativeworkerscript.moc" +#include diff --git a/src/declarative/qml/qdeclarativeworkerscript_p.h b/src/declarative/qml/qdeclarativeworkerscript_p.h index 912eac9..6cce799 100644 --- a/src/declarative/qml/qdeclarativeworkerscript_p.h +++ b/src/declarative/qml/qdeclarativeworkerscript_p.h @@ -55,7 +55,6 @@ #include "qdeclarative.h" #include "qdeclarativeparserstatus.h" -#include #include #include @@ -118,49 +117,9 @@ private: QUrl m_source; }; -class QDeclarativeWorkerListModelAgent; -class Q_DECLARATIVE_EXPORT QDeclarativeWorkerListModel : public QListModelInterface -{ - Q_OBJECT - Q_PROPERTY(int count READ count NOTIFY countChanged) - -public: - QDeclarativeWorkerListModel(QObject * = 0); - virtual ~QDeclarativeWorkerListModel(); - - Q_INVOKABLE void clear(); - Q_INVOKABLE void remove(int index); - Q_INVOKABLE void append(const QScriptValue &); - Q_INVOKABLE void insert(int index, const QScriptValue&); - Q_INVOKABLE QScriptValue get(int index) const; - Q_INVOKABLE void set(int index, const QScriptValue &); - Q_INVOKABLE void sync(); - - QDeclarativeWorkerListModelAgent *agent(); - - virtual QList roles() const; - virtual QString toString(int role) const; - virtual int count() const; - virtual QHash data(int index, const QList &roles = (QList())) const; - virtual QVariant data(int index, int role) const; - -Q_SIGNALS: - void countChanged(); - -private: - friend class QDeclarativeWorkerListModelAgent; - - QHash m_roles; - QHash m_strings; - QList > m_values; - - QDeclarativeWorkerListModelAgent *m_agent; -}; - QT_END_NAMESPACE QML_DECLARE_TYPE(QDeclarativeWorkerScript); -QML_DECLARE_TYPE(QDeclarativeWorkerListModel); QT_END_HEADER diff --git a/src/declarative/util/qdeclarativelistmodel.cpp b/src/declarative/util/qdeclarativelistmodel.cpp index e3f26d7..b290742 100644 --- a/src/declarative/util/qdeclarativelistmodel.cpp +++ b/src/declarative/util/qdeclarativelistmodel.cpp @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#include "qdeclarativelistmodel_p.h" - +#include "qdeclarativelistmodel_p_p.h" +#include "qdeclarativelistmodelworkeragent_p.h" #include "qdeclarativeopenmetaobject_p.h" #include @@ -66,8 +66,6 @@ QDeclarativeListModelParser::ListInstruction *QDeclarativeListModelParser::ListM return (QDeclarativeListModelParser::ListInstruction *)((char *)this + sizeof(ListModelData)); } -static void dump(ModelNode *node, int ind); - /*! \qmlclass ListModel QDeclarativeListModel \since 4.7 @@ -193,253 +191,146 @@ static void dump(ModelNode *node, int ind); except by first clearing the model - whatever properties are first added are then the only permitted properties in the model. - \sa {qmlmodels}{Data Models} -*/ - -class ModelObject : public QObject -{ - Q_OBJECT -public: - ModelObject(); - - void setValue(const QByteArray &name, const QVariant &val) - { - _mo->setValue(name, val); - } - -private: - QDeclarativeOpenMetaObject *_mo; -}; -struct ModelNode -{ - ModelNode(); - ~ModelNode(); - - QList values; - QHash properties; + \section2 Using threaded list models with WorkerScript - QDeclarativeListModel *model(const QDeclarativeListModel *parent) { - if (!modelCache) { - modelCache = new QDeclarativeListModel; - QDeclarativeEngine::setContextForObject(modelCache,QDeclarativeEngine::contextForObject(parent)); + ListModel can be used together with WorkerScript to define a list model + that is accessible from multiple threads. This is useful if list + modifications are synchronous and take some time: the list operations can + be moved to a different thread to avoid blocking of the main GUI thread. - modelCache->_root = this; - } - return modelCache; - } + Note that a list model is to be accessed from a WorkerScript, it \bold cannot + contain nested list data. So, this model cannot be used from a WorkerScript + because of the "attributes" value which contains a list: - ModelObject *object(const QDeclarativeListModel *parent) { - if (!objectCache) { - objectCache = new ModelObject(); - QHash::iterator it; - for (it = properties.begin(); it != properties.end(); ++it) { - objectCache->setValue(it.key().toUtf8(), parent->valueForNode(*it)); - } + \code + ListModel { + id: fruitModel + ListElement { + name: "Apple" + cost: 2.45 + attributes: [ + ListElement { description: "Core" }, + ListElement { description: "Deciduous" } + ] } - return objectCache; } + \endcode - void setObjectValue(const QScriptValue& valuemap); - void setListValue(const QScriptValue& valuelist); + In addition, the WorkerScript cannot add any nested list data to the model. - void setProperty(const QString& prop, const QVariant& val) { - QHash::const_iterator it = properties.find(prop); - if (it != properties.end()) { - (*it)->values[0] = val; - } else { - ModelNode *n = new ModelNode; - n->values << val; - properties.insert(prop,n); - } - if (objectCache) - objectCache->setValue(prop.toUtf8(), val); - } + \section3 Example - QDeclarativeListModel *modelCache; - ModelObject *objectCache; - bool isArray; -}; + To use a list model from a worker script, pass the model to the script + through the onMessage() handler, make the list modifications, and call + sync() to save the changes to the model data. -QT_END_NAMESPACE + Here is an example application that uses WorkerScript to append the + current time to a ListModel: -Q_DECLARE_METATYPE(ModelNode *) + \snippet examples/declarative/listmodel-threaded/timedisplay.qml 0 -QT_BEGIN_NAMESPACE + The included file, \tt dataloader.js, looks like this: -void ModelNode::setObjectValue(const QScriptValue& valuemap) { - QScriptValueIterator it(valuemap); - while (it.hasNext()) { - it.next(); - ModelNode *value = new ModelNode; - QScriptValue v = it.value(); - if (v.isArray()) { - value->isArray = true; - value->setListValue(v); - } else { - value->values << v.toVariant(); - } - properties.insert(it.name(),value); - } -} + \snippet examples/declarative/listmodel-threaded/dataloader.js 0 -void ModelNode::setListValue(const QScriptValue& valuelist) { - QScriptValueIterator it(valuelist); - values.clear(); - while (it.hasNext()) { - it.next(); - ModelNode *value = new ModelNode; - QScriptValue v = it.value(); - if (v.isArray()) { - value->isArray = true; - value->setListValue(v); - } else if (v.isObject()) { - value->setObjectValue(v); - } else { - value->values << v.toVariant(); - } - values.append(qVariantFromValue(value)); + The application's \tt Timer object periodically sends a message to the + worker script by calling \tt WorkerScript::sendMessage(). When this message + is received, \tt WorkerScript.onMessage() is invoked in + \tt dataloader.js, which appends the current time to the list model. - } -} + \sa {qmlmodels}{Data Models}, WorkerScript +*/ -ModelObject::ModelObject() -: _mo(new QDeclarativeOpenMetaObject(this)) +QDeclarativeListModel::QDeclarativeListModel(QObject *parent) +: QListModelInterface(parent), m_agent(0), m_nested(new NestedListModel(this)), m_flat(0), m_isWorkerCopy(false) { } -QDeclarativeListModel::QDeclarativeListModel(QObject *parent) -: QListModelInterface(parent), _rolesOk(false), _root(0) +QDeclarativeListModel::QDeclarativeListModel(bool workerCopy, QObject *parent) +: QListModelInterface(parent), m_agent(0), m_nested(0), m_flat(0), m_isWorkerCopy(workerCopy) { + if (workerCopy) + m_flat = new FlatListModel(this); + else + m_nested = new NestedListModel(this); } QDeclarativeListModel::~QDeclarativeListModel() { - delete _root; + delete m_nested; + delete m_flat; } -void QDeclarativeListModel::checkRoles() const +bool QDeclarativeListModel::flatten() { - if (_rolesOk || !_root) - return; + if (m_flat) + return true; - for (int ii = 0; ii < _root->values.count(); ++ii) { - ModelNode *node = qvariant_cast(_root->values.at(ii)); - if (node) { - foreach (const QString &role, node->properties.keys()) - addRole(role); - } + QList roles = m_nested->roles(); + + QList > values; + bool hasNested = false; + for (int i=0; icount(); i++) { + values.append(m_nested->data(i, roles, &hasNested)); + if (hasNested) + return false; } - _rolesOk = true; + FlatListModel *flat = new FlatListModel(this); + flat->m_values = values; + + for (int i=0; itoString(roles[i]); + flat->m_roles.insert(roles[i], s); + flat->m_strings.insert(s, roles[i]); + } + + m_flat = flat; + delete m_nested; + m_nested = 0; + return true; } -void QDeclarativeListModel::addRole(const QString &role) const +QDeclarativeListModelWorkerAgent *QDeclarativeListModel::agent() { - if (!roleStrings.contains(role)) - roleStrings << role; + if (m_agent) + return m_agent; + + if (!flatten()) { + qmlInfo(this) << "List contains nested list values and cannot be used from a worker script"; + return 0; + } + + m_agent = new QDeclarativeListModelWorkerAgent(this); + return m_agent; } QList QDeclarativeListModel::roles() const { - checkRoles(); - QList rv; - for (int ii = 0; ii < roleStrings.count(); ++ii) - rv << ii; - return rv; + return m_flat ? m_flat->roles() : m_nested->roles(); } QString QDeclarativeListModel::toString(int role) const { - checkRoles(); - if (role < roleStrings.count()) - return roleStrings.at(role); - else - return QString(); -} - -QVariant QDeclarativeListModel::valueForNode(ModelNode *node) const -{ - QObject *rv = 0; - - if (node->isArray) { - // List - rv = node->model(this); - } else { - if (!node->properties.isEmpty()) { - // Object - rv = node->object(this); - } else if (node->values.count() == 0) { - // Invalid - return QVariant(); - } else if (node->values.count() == 1) { - // Value - QVariant &var = node->values[0]; - ModelNode *valueNode = qvariant_cast(var); - if (valueNode) { - if (!valueNode->properties.isEmpty()) - rv = valueNode->object(this); - else - rv = valueNode->model(this); - } else { - return var; - } - } - } - - if (rv) - return QVariant::fromValue(rv); - else - return QVariant(); + return m_flat ? m_flat->toString(role) : m_nested->toString(role); } QHash QDeclarativeListModel::data(int index, const QList &roles) const { - checkRoles(); - QHash rv; if (index >= count() || index < 0) - return rv; - - ModelNode *node = qvariant_cast(_root->values.at(index)); - if (!node) - return rv; - - for (int ii = 0; ii < roles.count(); ++ii) { - const QString &roleString = roleStrings.at(roles.at(ii)); - - QHash::ConstIterator iter = - node->properties.find(roleString); - if (iter != node->properties.end()) { - ModelNode *row = *iter; - rv.insert(roles.at(ii), valueForNode(row)); - } - } + return QHash(); - return rv; + return m_flat ? m_flat->data(index, roles) : m_nested->data(index, roles); } QVariant QDeclarativeListModel::data(int index, int role) const { - checkRoles(); - QVariant rv; if (index >= count() || index < 0) - return rv; - - ModelNode *node = qvariant_cast(_root->values.at(index)); - if (!node) - return rv; - - const QString &roleString = roleStrings.at(role); - - QHash::ConstIterator iter = - node->properties.find(roleString); - if (iter != node->properties.end()) { - ModelNode *row = *iter; - rv = valueForNode(row); - } + return QVariant(); - return rv; + return m_flat ? m_flat->data(index, role) : m_nested->data(index, role); } /*! @@ -448,8 +339,7 @@ QVariant QDeclarativeListModel::data(int index, int role) const */ int QDeclarativeListModel::count() const { - if (!_root) return 0; - return _root->values.count(); + return m_flat ? m_flat->count() : m_nested->count(); } /*! @@ -463,12 +353,15 @@ int QDeclarativeListModel::count() const void QDeclarativeListModel::clear() { int cleared = count(); - _rolesOk = false; - delete _root; - _root = 0; - roleStrings.clear(); - emit itemsRemoved(0,cleared); - emit countChanged(0); + if (m_flat) + m_flat->clear(); + else + m_nested->clear(); + + if (!m_isWorkerCopy) { + emit itemsRemoved(0, cleared); + emit countChanged(0); + } } /*! @@ -480,17 +373,18 @@ void QDeclarativeListModel::clear() */ void QDeclarativeListModel::remove(int index) { - if (!_root || index < 0 || index >= _root->values.count()) { + if (index < 0 || index >= count()) { qmlInfo(this) << tr("remove: index %1 out of range").arg(index); return; } - ModelNode *node = qvariant_cast(_root->values.at(index)); - _root->values.removeAt(index); - if (node) - delete node; - emit itemsRemoved(index,1); - emit countChanged(_root->values.count()); + if (m_flat) + m_flat->remove(index); + else + m_nested->remove(index); + + if (!m_isWorkerCopy) + emit countChanged(this->count()); } /*! @@ -514,20 +408,17 @@ void QDeclarativeListModel::insert(int index, const QScriptValue& valuemap) qmlInfo(this) << tr("insert: value is not an object"); return; } - if (!_root) - _root = new ModelNode; - if (index >= _root->values.count() || index<0) { - if (index == _root->values.count()) - append(valuemap); - else - qmlInfo(this) << tr("insert: index %1 out of range").arg(index); + + if (index < 0 || index > count()) { + qmlInfo(this) << tr("insert: index %1 out of range").arg(index); return; } - ModelNode *mn = new ModelNode; - mn->setObjectValue(valuemap); - _root->values.insert(index,qVariantFromValue(mn)); - emit itemsInserted(index,1); - emit countChanged(_root->values.count()); + + bool ok = m_flat ? m_flat->insert(index, valuemap) : m_nested->insert(index, valuemap); + if (ok && !m_isWorkerCopy) { + emit itemsInserted(index, 1); + emit countChanged(this->count()); + } } /*! @@ -552,9 +443,10 @@ void QDeclarativeListModel::move(int from, int to, int n) qmlInfo(this) << tr("move: out of range"); return; } - int origfrom=from; // preserve actual move, so any animations are correct - int origto=to; - int orign=n; + + int origfrom = from; + int origto = to; + int orign = n; if (from > to) { // Only move forwards - flip if backwards moving int tfrom = from; @@ -563,24 +455,14 @@ void QDeclarativeListModel::move(int from, int to, int n) to = tto+n; n = tfrom-tto; } - if (n==1) { - _root->values.move(from,to); - } else { - QList replaced; - int i=0; - QVariantList::const_iterator it=_root->values.begin(); it += from+n; - for (; ivalues.begin(); it += from; - for (; ivalues.begin(); t += from; - for (; f != replaced.end(); ++f, ++t) - *t = *f; - } - emit itemsMoved(origfrom,origto,orign); + + if (m_flat) + m_flat->move(from, to, n); + else + m_nested->move(from, to, n); + + if (!m_isWorkerCopy) + emit itemsMoved(origfrom, origto, orign); } /*! @@ -601,13 +483,8 @@ void QDeclarativeListModel::append(const QScriptValue& valuemap) qmlInfo(this) << tr("append: value is not an object"); return; } - if (!_root) - _root = new ModelNode; - ModelNode *mn = new ModelNode; - mn->setObjectValue(valuemap); - _root->values << qVariantFromValue(mn); - emit itemsInserted(count()-1,1); - emit countChanged(_root->values.count()); + + insert(count(), valuemap); } /*! @@ -641,15 +518,7 @@ QScriptValue QDeclarativeListModel::get(int index) const return 0; } - ModelNode *node = qvariant_cast(_root->values.at(index)); - if (!node) - return 0; - QDeclarativeEngine *eng = qmlEngine(this); - if (!eng) { - qWarning("Cannot call QDeclarativeListModel::get() without a QDeclarativeEngine"); - return 0; - } - return QDeclarativeEnginePrivate::qmlScriptObject(node->object(this), eng); + return m_flat ? m_flat->get(index) : m_nested->get(index); } /*! @@ -673,27 +542,22 @@ void QDeclarativeListModel::set(int index, const QScriptValue& valuemap) qmlInfo(this) << tr("set: value is not an object"); return; } - if ( !_root || index > _root->values.count() || index < 0) { + if (count() == 0 || index > count() || index < 0) { qmlInfo(this) << tr("set: index %1 out of range").arg(index); return; } - if (index == _root->values.count()) + + if (index == count()) { append(valuemap); - else { - ModelNode *node = qvariant_cast(_root->values.at(index)); + } else { QList roles; - node->setObjectValue(valuemap); - QScriptValueIterator it(valuemap); - while (it.hasNext()) { - it.next(); - int r = roleStrings.indexOf(it.name()); - if (r<0) { - r = roleStrings.count(); - roleStrings << it.name(); - } - roles.append(r); - } - emit itemsChanged(index,1,roles); + if (m_flat) + m_flat->set(index, valuemap, &roles); + else + m_nested->set(index, valuemap, &roles); + + if (!m_isWorkerCopy) + emit itemsChanged(index, 1, roles); } } @@ -712,22 +576,33 @@ void QDeclarativeListModel::set(int index, const QScriptValue& valuemap) */ void QDeclarativeListModel::setProperty(int index, const QString& property, const QVariant& value) { - if ( !_root || index >= _root->values.count() || index < 0) { + if (count() == 0 || index >= count() || index < 0) { qmlInfo(this) << tr("set: index %1 out of range").arg(index); return; } - ModelNode *node = qvariant_cast(_root->values.at(index)); - int r = roleStrings.indexOf(property); - if (r<0) { - r = roleStrings.count(); - roleStrings << property; - } + QList roles; - roles.append(r); + if (m_flat) + m_flat->setProperty(index, property, value, &roles); + else + m_nested->setProperty(index, property, value, &roles); - if (node) - node->setProperty(property,value); - emit itemsChanged(index,1,roles); + if (!m_isWorkerCopy) + emit itemsChanged(index, 1, roles); +} + +/*! + \qmlmethod ListModel::sync() + + Writes any unsaved changes to the list model after it has been modified + from a worker script. +*/ +void QDeclarativeListModel::sync() +{ + // This is just a dummy method to make it look like sync() exists in + // ListModel (and not just QDeclarativeListModelWorkerAgent) and to let + // us document sync(). + qmlInfo(this) << "List sync() can only be called from a WorkerScript"; } bool QDeclarativeListModelParser::compileProperty(const QDeclarativeCustomParserProperty &prop, QList &instr, QByteArray &data) @@ -858,7 +733,7 @@ void QDeclarativeListModelParser::setCustomData(QObject *obj, const QByteArray & QDeclarativeListModel *rv = static_cast(obj); ModelNode *root = new ModelNode; - rv->_root = root; + rv->m_nested->_root = root; QStack nodes; nodes << root; @@ -943,43 +818,522 @@ bool QDeclarativeListModelParser::definesEmptyList(const QString &s) \sa ListModel */ -static void dump(ModelNode *node, int ind) +FlatListModel::FlatListModel(QDeclarativeListModel *base) + : m_scriptEngine(0), m_listModel(base) { - QByteArray indentBa(ind * 4, ' '); - const char *indent = indentBa.constData(); - - for (int ii = 0; ii < node->values.count(); ++ii) { - ModelNode *subNode = qvariant_cast(node->values.at(ii)); - if (subNode) { - qWarning().nospace() << indent << "Sub-node " << ii; - dump(subNode, ind + 1); - } else { - qWarning().nospace() << indent << "Sub-node " << ii << ": " << node->values.at(ii).toString(); - } - } - - for (QHash::ConstIterator iter = node->properties.begin(); iter != node->properties.end(); ++iter) { - qWarning().nospace() << indent << "Property " << iter.key() << ':'; - dump(iter.value(), ind + 1); - } } -ModelNode::ModelNode() -: modelCache(0), objectCache(0), isArray(false) +FlatListModel::~FlatListModel() +{ +} + +QHash FlatListModel::data(int index, const QList &roles) const +{ + Q_ASSERT(index >= 0 && index < m_values.count()); + + QHash row; + for (int i=0; i= 0 && index < m_values.count()); + if (m_values[index].contains(role)) + return m_values[index][role]; + return QVariant(); +} + +QList FlatListModel::roles() const +{ + return m_roles.keys(); +} + +QString FlatListModel::toString(int role) const +{ + if (m_roles.contains(role)) + return m_roles[role]; + return QString(); +} + +int FlatListModel::count() const +{ + return m_values.count(); +} + +void FlatListModel::clear() +{ + m_values.clear(); +} + +void FlatListModel::remove(int index) +{ + m_values.removeAt(index); +} + +bool FlatListModel::append(const QScriptValue &value) +{ + return insert(m_values.count(), value); +} + +bool FlatListModel::insert(int index, const QScriptValue &value) +{ + Q_ASSERT(index >= 0 && index <= m_values.count()); + + QHash row; + if (!addValue(value, &row, 0)) + return false; + + m_values.insert(index, row); + return true; +} + +QScriptValue FlatListModel::get(int index) const +{ + Q_ASSERT(index >= 0 && index < m_values.count()); + + QScriptEngine *scriptEngine = m_scriptEngine ? m_scriptEngine : QDeclarativeEnginePrivate::getScriptEngine(qmlEngine(m_listModel)); + + if (!scriptEngine) + return 0; + + QScriptValue rv = scriptEngine->newObject(); + + QHash row = m_values.at(index); + for (QHash::ConstIterator iter = row.begin(); iter != row.end(); ++iter) + rv.setProperty(m_roles.value(iter.key()), qScriptValueFromValue(scriptEngine, iter.value())); + + return rv; +} + +void FlatListModel::set(int index, const QScriptValue &value, QList *roles) +{ + Q_ASSERT(index >= 0 && index < m_values.count()); + + QHash row = m_values[index]; + if (addValue(value, &row, roles)) + m_values[index] = row; +} + +void FlatListModel::setProperty(int index, const QString& property, const QVariant& value, QList *roles) +{ + Q_ASSERT(index >= 0 && index < m_values.count()); + + QHash::Iterator iter = m_strings.find(property); + int role; + if (iter == m_strings.end()) { + role = m_roles.count(); + m_roles.insert(role, property); + m_strings.insert(property, role); + } else { + role = iter.value(); + } + roles->append(role); + + m_values[index][role] = value; +} + +void FlatListModel::move(int from, int to, int n) +{ + if (n == 1) { + m_values.move(from, to); + } else { + QList > replaced; + int i=0; + QList >::ConstIterator it=m_values.begin(); it += from+n; + for (; i >::ConstIterator f=replaced.begin(); + QList >::Iterator t=m_values.begin(); t += from; + for (; f != replaced.end(); ++f, ++t) + *t = *f; + } +} + +bool FlatListModel::addValue(const QScriptValue &value, QHash *row, QList *roles) +{ + QScriptValueIterator it(value); + while (it.hasNext()) { + it.next(); + if (it.value().isObject()) { + qmlInfo(m_listModel) << "Cannot add nested list values when modifying or after modification from a worker script"; + return false; + } + + QString name = it.name(); + QVariant v = it.value().toVariant(); + + QHash::Iterator iter = m_strings.find(name); + if (iter == m_strings.end()) { + int role = m_roles.count(); + m_roles.insert(role, name); + iter = m_strings.insert(name, role); + if (roles) + roles->append(role); + } + row->insert(*iter, v); + } + return true; +} + +NestedListModel::NestedListModel(QDeclarativeListModel *base) + : _root(0), m_listModel(base), _rolesOk(false) +{ +} + +NestedListModel::~NestedListModel() +{ + delete _root; +} + +QVariant NestedListModel::valueForNode(ModelNode *node, bool *hasNested) const +{ + QObject *rv = 0; + if (hasNested) + *hasNested = false; + + if (node->isArray) { + // List + rv = node->model(this); + if (hasNested) + *hasNested = true; + } else { + if (!node->properties.isEmpty()) { + // Object + rv = node->object(this); + } else if (node->values.count() == 0) { + // Invalid + return QVariant(); + } else if (node->values.count() == 1) { + // Value + QVariant &var = node->values[0]; + ModelNode *valueNode = qvariant_cast(var); + if (valueNode) { + if (!valueNode->properties.isEmpty()) + rv = valueNode->object(this); + else + rv = valueNode->model(this); + } else { + return var; + } + } + } + + if (rv) { + return QVariant::fromValue(rv); + } else { + return QVariant(); + } +} + +QHash NestedListModel::data(int index, const QList &roles, bool *hasNested) const +{ + Q_ASSERT(_root && index >= 0 && index < _root->values.count()); + checkRoles(); + QHash rv; + + ModelNode *node = qvariant_cast(_root->values.at(index)); + if (!node) + return rv; + + for (int ii = 0; ii < roles.count(); ++ii) { + const QString &roleString = roleStrings.at(roles.at(ii)); + + QHash::ConstIterator iter = node->properties.find(roleString); + if (iter != node->properties.end()) { + ModelNode *row = *iter; + rv.insert(roles.at(ii), valueForNode(row, hasNested)); + } + } + + return rv; +} + +QVariant NestedListModel::data(int index, int role) const +{ + Q_ASSERT(_root && index >= 0 && index < _root->values.count()); + checkRoles(); + QVariant rv; + + ModelNode *node = qvariant_cast(_root->values.at(index)); + if (!node) + return rv; + + const QString &roleString = roleStrings.at(role); + + QHash::ConstIterator iter = node->properties.find(roleString); + if (iter != node->properties.end()) { + ModelNode *row = *iter; + rv = valueForNode(row); + } + + return rv; +} + +int NestedListModel::count() const +{ + if (!_root) return 0; + return _root->values.count(); +} + +void NestedListModel::clear() +{ + _rolesOk = false; + roleStrings.clear(); + + delete _root; + _root = 0; +} + +void NestedListModel::remove(int index) +{ + if (!_root) + return; + ModelNode *node = qvariant_cast(_root->values.at(index)); + _root->values.removeAt(index); + if (node) + delete node; +} + +bool NestedListModel::insert(int index, const QScriptValue& valuemap) +{ + if (!_root) + _root = new ModelNode; + + ModelNode *mn = new ModelNode; + mn->setObjectValue(valuemap); + _root->values.insert(index,qVariantFromValue(mn)); + return true; +} + +void NestedListModel::move(int from, int to, int n) +{ + if (n==1) { + _root->values.move(from,to); + } else { + QList replaced; + int i=0; + QVariantList::const_iterator it=_root->values.begin(); it += from+n; + for (; ivalues.begin(); it += from; + for (; ivalues.begin(); t += from; + for (; f != replaced.end(); ++f, ++t) + *t = *f; + } +} + +bool NestedListModel::append(const QScriptValue& valuemap) +{ + if (!_root) + _root = new ModelNode; + ModelNode *mn = new ModelNode; + mn->setObjectValue(valuemap); + _root->values << qVariantFromValue(mn); + return true; +} + +QScriptValue NestedListModel::get(int index) const +{ + ModelNode *node = qvariant_cast(_root->values.at(index)); + if (!node) + return 0; + QDeclarativeEngine *eng = qmlEngine(m_listModel); + if (!eng) { + qWarning("Cannot call QDeclarativeListModel::get() without a QDeclarativeEngine"); + return 0; + } + return QDeclarativeEnginePrivate::qmlScriptObject(node->object(this), eng); +} + +void NestedListModel::set(int index, const QScriptValue& valuemap, QList *roles) +{ + Q_ASSERT(index >=0 && index < count()); + + ModelNode *node = qvariant_cast(_root->values.at(index)); + node->setObjectValue(valuemap); + + QScriptValueIterator it(valuemap); + while (it.hasNext()) { + it.next(); + int r = roleStrings.indexOf(it.name()); + if (r < 0) { + r = roleStrings.count(); + roleStrings << it.name(); + } + roles->append(r); + } +} + +void NestedListModel::setProperty(int index, const QString& property, const QVariant& value, QList *roles) +{ + Q_ASSERT(index >=0 && index < count()); + + ModelNode *node = qvariant_cast(_root->values.at(index)); + node->setProperty(property, value); + + int r = roleStrings.indexOf(property); + if (r < 0) { + r = roleStrings.count(); + roleStrings << property; + } + roles->append(r); +} + +void NestedListModel::checkRoles() const +{ + if (_rolesOk || !_root) + return; + + for (int i = 0; i<_root->values.count(); ++i) { + ModelNode *node = qvariant_cast(_root->values.at(i)); + if (node) { + foreach (const QString &role, node->properties.keys()) { + if (!roleStrings.contains(role)) + roleStrings.append(role); + } + } + } + + _rolesOk = true; +} + +QList NestedListModel::roles() const +{ + checkRoles(); + QList rv; + for (int ii = 0; ii < roleStrings.count(); ++ii) + rv << ii; + return rv; +} + +QString NestedListModel::toString(int role) const +{ + checkRoles(); + if (role < roleStrings.count()) + return roleStrings.at(role); + else + return QString(); +} + + +ModelNode::ModelNode() +: modelCache(0), objectCache(0), isArray(false) { } ModelNode::~ModelNode() { - qDeleteAll(properties); + ModelNode *node; + + QList nodeValues = properties.values(); + for (int ii = 0; ii < nodeValues.count(); ++ii) { + node = nodeValues[ii]; + if (node) { delete node; node = 0; } + } + for (int ii = 0; ii < values.count(); ++ii) { - ModelNode *node = qvariant_cast(values.at(ii)); + node = qvariant_cast(values.at(ii)); if (node) { delete node; node = 0; } } - if (modelCache) { modelCache->_root = 0/* ==this */; delete modelCache; modelCache = 0; } - if (objectCache) { delete objectCache; } + + if (modelCache) { modelCache->m_nested->_root = 0/* ==this */; delete modelCache; modelCache = 0; } + if (objectCache) { delete objectCache; objectCache = 0; } +} + +void ModelNode::setObjectValue(const QScriptValue& valuemap) { + QScriptValueIterator it(valuemap); + while (it.hasNext()) { + it.next(); + ModelNode *value = new ModelNode; + QScriptValue v = it.value(); + if (v.isArray()) { + value->isArray = true; + value->setListValue(v); + } else { + value->values << v.toVariant(); + } + properties.insert(it.name(),value); + } +} + +void ModelNode::setListValue(const QScriptValue& valuelist) { + QScriptValueIterator it(valuelist); + values.clear(); + while (it.hasNext()) { + it.next(); + ModelNode *value = new ModelNode; + QScriptValue v = it.value(); + if (v.isArray()) { + value->isArray = true; + value->setListValue(v); + } else if (v.isObject()) { + value->setObjectValue(v); + } else { + value->values << v.toVariant(); + } + values.append(qVariantFromValue(value)); + + } +} + +void ModelNode::setProperty(const QString& prop, const QVariant& val) { + QHash::const_iterator it = properties.find(prop); + if (it != properties.end()) { + (*it)->values[0] = val; + } else { + ModelNode *n = new ModelNode; + n->values << val; + properties.insert(prop,n); + } + if (objectCache) + objectCache->setValue(prop.toUtf8(), val); +} + +void ModelNode::dump(ModelNode *node, int ind) +{ + QByteArray indentBa(ind * 4, ' '); + const char *indent = indentBa.constData(); + + for (int ii = 0; ii < node->values.count(); ++ii) { + ModelNode *subNode = qvariant_cast(node->values.at(ii)); + if (subNode) { + qWarning().nospace() << indent << "Sub-node " << ii; + dump(subNode, ind + 1); + } else { + qWarning().nospace() << indent << "Sub-node " << ii << ": " << node->values.at(ii).toString(); + } + } + + for (QHash::ConstIterator iter = node->properties.begin(); iter != node->properties.end(); ++iter) { + qWarning().nospace() << indent << "Property " << iter.key() << ':'; + dump(iter.value(), ind + 1); + } } +ModelObject::ModelObject() +: _mo(new QDeclarativeOpenMetaObject(this)) +{ +} + +void ModelObject::setValue(const QByteArray &name, const QVariant &val) +{ + _mo->setValue(name, val); +} + + QT_END_NAMESPACE #include diff --git a/src/declarative/util/qdeclarativelistmodel_p.h b/src/declarative/util/qdeclarativelistmodel_p.h index 8eb6583..6a0426b 100644 --- a/src/declarative/util/qdeclarativelistmodel_p.h +++ b/src/declarative/util/qdeclarativelistmodel_p.h @@ -59,6 +59,9 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) +class FlatListModel; +class NestedListModel; +class QDeclarativeListModelWorkerAgent; struct ModelNode; class Q_DECLARATIVE_EXPORT QDeclarativeListModel : public QListModelInterface { @@ -83,20 +86,26 @@ public: Q_INVOKABLE void set(int index, const QScriptValue&); Q_INVOKABLE void setProperty(int index, const QString& property, const QVariant& value); Q_INVOKABLE void move(int from, int to, int count); + Q_INVOKABLE void sync(); + + QDeclarativeListModelWorkerAgent *agent(); Q_SIGNALS: void countChanged(int); private: - QVariant valueForNode(ModelNode *) const; - mutable QStringList roleStrings; friend class QDeclarativeListModelParser; + friend class QDeclarativeListModelWorkerAgent; friend struct ModelNode; - void checkRoles() const; - void addRole(const QString &) const; - mutable bool _rolesOk; - ModelNode *_root; + QDeclarativeListModel(bool workerCopy, QObject *parent=0); + bool flatten(); + bool modifyCheck(); + + QDeclarativeListModelWorkerAgent *m_agent; + NestedListModel *m_nested; + FlatListModel *m_flat; + bool m_isWorkerCopy; }; // ### FIXME diff --git a/src/declarative/util/qdeclarativelistmodel_p_p.h b/src/declarative/util/qdeclarativelistmodel_p_p.h new file mode 100644 index 0000000..8041561 --- /dev/null +++ b/src/declarative/util/qdeclarativelistmodel_p_p.h @@ -0,0 +1,199 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDECLARATIVELISTMODEL_P_P_H +#define QDECLARATIVELISTMODEL_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qdeclarativelistmodel_p.h" + +#include "qdeclarative.h" +#include "qdeclarativeengine_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QDeclarativeOpenMetaObject; +class QScriptEngine; +class QDeclarativeListModelWorkerAgent; +struct ModelNode; + +class FlatListModel +{ +public: + FlatListModel(QDeclarativeListModel *base); + ~FlatListModel(); + + QHash data(int index, const QList &roles) const; + QVariant data(int index, int role) const; + + QList roles() const; + QString toString(int role) const; + + int count() const; + void clear(); + void remove(int index); + bool append(const QScriptValue&); + bool insert(int index, const QScriptValue&); + QScriptValue get(int index) const; + void set(int index, const QScriptValue&, QList *roles); + void setProperty(int index, const QString& property, const QVariant& value, QList *roles); + void move(int from, int to, int count); + +private: + friend class QDeclarativeListModelWorkerAgent; + friend class QDeclarativeListModel; + + bool addValue(const QScriptValue &value, QHash *row, QList *roles); + + QScriptEngine *m_scriptEngine; + QHash m_roles; + QHash m_strings; + QList > m_values; + QDeclarativeListModel *m_listModel; +}; + +class NestedListModel +{ +public: + NestedListModel(QDeclarativeListModel *base); + ~NestedListModel(); + + QHash data(int index, const QList &roles, bool *hasNested = 0) const; + QVariant data(int index, int role) const; + + QList roles() const; + QString toString(int role) const; + + int count() const; + void clear(); + void remove(int index); + bool append(const QScriptValue&); + bool insert(int index, const QScriptValue&); + QScriptValue get(int index) const; + void set(int index, const QScriptValue&, QList *roles); + void setProperty(int index, const QString& property, const QVariant& value, QList *role); + void move(int from, int to, int count); + + QVariant valueForNode(ModelNode *, bool *hasNested = 0) const; + void checkRoles() const; + + ModelNode *_root; + QDeclarativeListModel *m_listModel; + +private: + mutable QStringList roleStrings; + mutable bool _rolesOk; +}; + + +class ModelObject : public QObject +{ + Q_OBJECT +public: + ModelObject(); + void setValue(const QByteArray &name, const QVariant &val); + +private: + QDeclarativeOpenMetaObject *_mo; +}; + +struct ModelNode +{ + ModelNode(); + ~ModelNode(); + + QList values; + QHash properties; + + QDeclarativeListModel *model(const NestedListModel *model) { + if (!modelCache) { + modelCache = new QDeclarativeListModel; + QDeclarativeEngine::setContextForObject(modelCache,QDeclarativeEngine::contextForObject(model->m_listModel)); + modelCache->m_nested->_root = this; // ListModel defaults to nestable model + } + return modelCache; + } + + ModelObject *object(const NestedListModel *model) { + if (!objectCache) { + objectCache = new ModelObject(); + QHash::iterator it; + for (it = properties.begin(); it != properties.end(); ++it) { + objectCache->setValue(it.key().toUtf8(), model->valueForNode(*it)); + } + } + return objectCache; + } + + + void setObjectValue(const QScriptValue& valuemap); + void setListValue(const QScriptValue& valuelist); + void setProperty(const QString& prop, const QVariant& val); + static void dump(ModelNode *node, int ind); + + QDeclarativeListModel *modelCache; + ModelObject *objectCache; + bool isArray; +}; + + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(ModelNode *) + +QT_END_HEADER + +#endif // QDECLARATIVELISTMODEL_P_P_H + diff --git a/src/declarative/util/qdeclarativelistmodelworkeragent.cpp b/src/declarative/util/qdeclarativelistmodelworkeragent.cpp new file mode 100644 index 0000000..ee43447 --- /dev/null +++ b/src/declarative/util/qdeclarativelistmodelworkeragent.cpp @@ -0,0 +1,245 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdeclarativelistmodelworkeragent_p.h" +#include "qdeclarativelistmodel_p_p.h" +#include "qdeclarativedeclarativedata_p.h" +#include "qdeclarativeengine_p.h" +#include "qdeclarativeinfo.h" + +#include +#include +#include + + +QT_BEGIN_NAMESPACE + + +void QDeclarativeListModelWorkerAgent::Data::clearChange() +{ + changes.clear(); +} + +void QDeclarativeListModelWorkerAgent::Data::insertChange(int index, int count) +{ + Change c = { Change::Inserted, index, count, 0 }; + changes << c; +} + +void QDeclarativeListModelWorkerAgent::Data::removeChange(int index, int count) +{ + Change c = { Change::Removed, index, count, 0 }; + changes << c; +} + +void QDeclarativeListModelWorkerAgent::Data::moveChange(int index, int count, int to) +{ + Change c = { Change::Moved, index, count, to }; + changes << c; +} + +void QDeclarativeListModelWorkerAgent::Data::changedChange(int index, int count) +{ + Change c = { Change::Changed, index, count, 0 }; + changes << c; +} + +QDeclarativeListModelWorkerAgent::QDeclarativeListModelWorkerAgent(QDeclarativeListModel *model) +: m_engine(0), m_ref(1), m_orig(model), m_copy(new QDeclarativeListModel(true, this)) +{ + m_copy->m_flat->m_roles = m_orig->m_flat->m_roles; + m_copy->m_flat->m_strings = m_orig->m_flat->m_strings; + m_copy->m_flat->m_values = m_orig->m_flat->m_values; +} + +QDeclarativeListModelWorkerAgent::~QDeclarativeListModelWorkerAgent() +{ +} + +void QDeclarativeListModelWorkerAgent::setScriptEngine(QScriptEngine *eng) +{ + m_engine = eng; + if (m_copy->m_flat) + m_copy->m_flat->m_scriptEngine = eng; +} + +QScriptEngine *QDeclarativeListModelWorkerAgent::scriptEngine() const +{ + return m_engine; +} + +void QDeclarativeListModelWorkerAgent::addref() +{ + m_ref.ref(); +} + +void QDeclarativeListModelWorkerAgent::release() +{ + bool del = !m_ref.deref(); + + if (del) + delete this; +} + +int QDeclarativeListModelWorkerAgent::count() const +{ + return m_copy->count(); +} + +void QDeclarativeListModelWorkerAgent::clear() +{ + data.clearChange(); + data.removeChange(0, m_copy->count()); + m_copy->clear(); +} + +void QDeclarativeListModelWorkerAgent::remove(int index) +{ + int count = m_copy->count(); + m_copy->remove(index); + + if (m_copy->count() != count) + data.removeChange(index, 1); +} + +void QDeclarativeListModelWorkerAgent::append(const QScriptValue &value) +{ + int count = m_copy->count(); + m_copy->append(value); + + if (m_copy->count() != count) + data.insertChange(m_copy->count() - 1, 1); +} + +void QDeclarativeListModelWorkerAgent::insert(int index, const QScriptValue &value) +{ + int count = m_copy->count(); + m_copy->insert(index, value); + + if (m_copy->count() != count) + data.insertChange(index, 1); +} + +QScriptValue QDeclarativeListModelWorkerAgent::get(int index) const +{ + if (index < 0 || index >= count()) + return m_engine->undefinedValue(); + + return m_copy->get(index); +} + +void QDeclarativeListModelWorkerAgent::set(int index, const QScriptValue &value) +{ + m_copy->set(index, value); + data.changedChange(index, 1); +} + +void QDeclarativeListModelWorkerAgent::setProperty(int index, const QString& property, const QVariant& value) +{ + m_copy->setProperty(index, property, value); + data.changedChange(index, 1); +} + +void QDeclarativeListModelWorkerAgent::move(int from, int to, int count) +{ + m_copy->move(from, to, count); + data.moveChange(from, to, count); +} + +void QDeclarativeListModelWorkerAgent::sync() +{ + Sync *s = new Sync; + s->data = data; + s->list = m_copy; + data.changes.clear(); + QCoreApplication::postEvent(this, s); +} + +bool QDeclarativeListModelWorkerAgent::event(QEvent *e) +{ + if (e->type() == QEvent::User) { + Sync *s = static_cast(e); + + const QList &changes = s->data.changes; + + if (m_copy) { + bool cc = m_copy->count() != s->list->count(); + + FlatListModel *orig = m_orig->m_flat; + FlatListModel *copy = s->list->m_flat; + if (!orig || !copy) { + qWarning("QML List worker: cannot synchronize lists"); + return QObject::event(e); + } + orig->m_roles = copy->m_roles; + orig->m_strings = copy->m_strings; + orig->m_values = copy->m_values; + + for (int ii = 0; ii < changes.count(); ++ii) { + const Change &change = changes.at(ii); + switch (change.type) { + case Change::Inserted: + emit m_orig->itemsInserted(change.index, change.count); + break; + case Change::Removed: + emit m_orig->itemsRemoved(change.index, change.count); + break; + case Change::Moved: + emit m_orig->itemsMoved(change.index, change.to, change.count); + break; + case Change::Changed: + emit m_orig->itemsMoved(change.index, change.to, change.count); + break; + } + } + + if (cc) + emit m_orig->countChanged(m_copy->count()); + + //qDebug() << "------sync():" << m_copy->count() << s->list->count() << m_orig->count(); + } + } + + return QObject::event(e); +} + +QT_END_NAMESPACE + diff --git a/src/declarative/util/qdeclarativelistmodelworkeragent_p.h b/src/declarative/util/qdeclarativelistmodelworkeragent_p.h new file mode 100644 index 0000000..b6a643b --- /dev/null +++ b/src/declarative/util/qdeclarativelistmodelworkeragent_p.h @@ -0,0 +1,155 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDECLARATIVELISTMODELWORKERAGENT_P_H +#define QDECLARATIVELISTMODELWORKERAGENT_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qdeclarative.h" + +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QDeclarativeListModel; + +// Currently this will leak as no-one releases it in the worker thread +class QDeclarativeListModelWorkerAgent : public QObject +{ + Q_OBJECT + Q_PROPERTY(int count READ count) + +public: + QDeclarativeListModelWorkerAgent(QDeclarativeListModel *); + ~QDeclarativeListModelWorkerAgent(); + + void setScriptEngine(QScriptEngine *eng); + QScriptEngine *scriptEngine() const; + + void addref(); + void release(); + + int count() const; + + Q_INVOKABLE void clear(); + Q_INVOKABLE void remove(int index); + Q_INVOKABLE void append(const QScriptValue &); + Q_INVOKABLE void insert(int index, const QScriptValue&); + Q_INVOKABLE QScriptValue get(int index) const; + Q_INVOKABLE void set(int index, const QScriptValue &); + Q_INVOKABLE void setProperty(int index, const QString& property, const QVariant& value); + Q_INVOKABLE void move(int from, int to, int count); + Q_INVOKABLE void sync(); + + struct VariantRef + { + VariantRef() : a(0) {} + VariantRef(const VariantRef &r) : a(r.a) { if (a) a->addref(); } + VariantRef(QDeclarativeListModelWorkerAgent *_a) : a(_a) { if (a) a->addref(); } + ~VariantRef() { if (a) a->release(); } + + VariantRef &operator=(const VariantRef &o) { + if (o.a) o.a->addref(); + if (a) a->release(); a = o.a; + return *this; + } + + QDeclarativeListModelWorkerAgent *a; + }; +protected: + virtual bool event(QEvent *); + +private: + friend class QDeclarativeWorkerScriptEnginePrivate; + QScriptEngine *m_engine; + + struct Change { + enum { Inserted, Removed, Moved, Changed } type; + int index; // Inserted/Removed/Moved/Changed + int count; // Inserted/Removed/Moved/Changed + int to; // Moved + }; + + struct Data { + QList changes; + + void clearChange(); + void insertChange(int index, int count); + void removeChange(int index, int count); + void moveChange(int index, int count, int to); + void changedChange(int index, int count); + }; + Data data; + + struct Sync : public QEvent { + Sync() : QEvent(QEvent::User) {} + Data data; + QDeclarativeListModel *list; + }; + + QAtomicInt m_ref; + QDeclarativeListModel *m_orig; + QDeclarativeListModel *m_copy; +}; + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QDeclarativeListModelWorkerAgent::VariantRef); + +QT_END_HEADER + +#endif // QDECLARATIVEWORKERSCRIPT_P_H + diff --git a/src/declarative/util/util.pri b/src/declarative/util/util.pri index 26edecc..041aa13 100644 --- a/src/declarative/util/util.pri +++ b/src/declarative/util/util.pri @@ -27,7 +27,8 @@ SOURCES += \ $$PWD/qdeclarativepixmapcache.cpp \ $$PWD/qdeclarativebehavior.cpp \ $$PWD/qdeclarativefontloader.cpp \ - $$PWD/qdeclarativestyledtext.cpp + $$PWD/qdeclarativestyledtext.cpp \ + $$PWD/qdeclarativelistmodelworkeragent.cpp HEADERS += \ $$PWD/qdeclarativeutilmodule_p.h\ @@ -59,7 +60,9 @@ HEADERS += \ $$PWD/qdeclarativepixmapcache_p.h \ $$PWD/qdeclarativebehavior_p.h \ $$PWD/qdeclarativefontloader_p.h \ - $$PWD/qdeclarativestyledtext_p.h + $$PWD/qdeclarativestyledtext_p.h \ + $$PWD/qdeclarativelistmodelworkeragent_p.h \ + $$PWD/qdeclarativelistmodelworkeragent_p_p.h contains(QT_CONFIG, xmlpatterns) { QT+=xmlpatterns diff --git a/tests/auto/declarative/qdeclarativelistmodel/data/model.qml b/tests/auto/declarative/qdeclarativelistmodel/data/model.qml new file mode 100644 index 0000000..97e3030 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelistmodel/data/model.qml @@ -0,0 +1,24 @@ +import Qt 4.6 + +Item { + id: item + property var model + property bool done: false + + function evalExpressionViaWorker(expr) { + done = false + if (expr[expr.length-1] == ';') + expr = expr.substring(0, expr.length-1) + var cmds = expr.split(';') + + worker.sendMessage({'commands': cmds, 'model': model}) + } + + WorkerScript { + id: worker + source: "script.js" + onMessage: { + item.done = true + } + } +} diff --git a/tests/auto/declarative/qdeclarativelistmodel/data/script.js b/tests/auto/declarative/qdeclarativelistmodel/data/script.js new file mode 100644 index 0000000..bfeeb8b --- /dev/null +++ b/tests/auto/declarative/qdeclarativelistmodel/data/script.js @@ -0,0 +1,12 @@ +WorkerScript.onMessage = function(msg) { + try { + for (var i=0; i +#include #include #include #include -#include + +#include +#include + +#include "../../../shared/util.h" class tst_QDeclarativeListModel : public QObject { @@ -50,6 +55,11 @@ class tst_QDeclarativeListModel : public QObject public: tst_QDeclarativeListModel() {} +private: + QScriptValue nestedListValue(QScriptEngine *eng) const; + QDeclarativeItem *createWorkerTest(QDeclarativeEngine *eng, QDeclarativeComponent *component, QDeclarativeListModel *model); + void waitForWorker(QDeclarativeItem *item); + private slots: void static_types(); void static_types_data(); @@ -58,10 +68,50 @@ private slots: void static_nestedElements_data(); void dynamic_data(); void dynamic(); + void dynamic_worker_data(); + void dynamic_worker(); + void convertNestedToFlat_fail(); + void convertNestedToFlat_fail_data(); + void convertNestedToFlat_ok(); + void convertNestedToFlat_ok_data(); void error_data(); void error(); }; +QScriptValue tst_QDeclarativeListModel::nestedListValue(QScriptEngine *eng) const +{ + QScriptValue list = eng->newArray(); + list.setProperty(0, eng->newObject()); + list.setProperty(1, eng->newObject()); + QScriptValue sv = eng->newObject(); + sv.setProperty("foo", list); + return sv; +} + +QDeclarativeItem *tst_QDeclarativeListModel::createWorkerTest(QDeclarativeEngine *eng, QDeclarativeComponent *component, QDeclarativeListModel *model) +{ + QDeclarativeItem *item = qobject_cast(component->create()); + QDeclarativeEngine::setContextForObject(model, eng->rootContext()); + if (item) + item->setProperty("model", qVariantFromValue(model)); + return item; +} + +void tst_QDeclarativeListModel::waitForWorker(QDeclarativeItem *item) +{ + QEventLoop loop; + QTimer timer; + timer.setSingleShot(true); + connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); + + QDeclarativeProperty prop(item, "done"); + QVERIFY(prop.isValid()); + QVERIFY(prop.connectNotifySignal(&loop, SLOT(quit()))); + timer.start(10000); + loop.exec(); + QVERIFY(timer.isActive()); +} + void tst_QDeclarativeListModel::static_i18n() { QString expect = QString::fromUtf8("na\303\257ve"); @@ -149,10 +199,10 @@ void tst_QDeclarativeListModel::dynamic_data() QTest::newRow("remove2b") << "{append({'foo':123});append({'foo':456});remove(0);get(0).foo}" << 456 << ""; QTest::newRow("remove2c") << "{append({'foo':123});append({'foo':456});remove(1);get(0).foo}" << 123 << ""; QTest::newRow("remove3") << "{append({'foo':123});remove(0);get(0).foo}" << 0 << "QML ListModel (unknown location) get: index 0 out of range"; - QTest::newRow("remove3a") << "{append({'foo':123});remove(-1)}" << 0 << "QML ListModel (unknown location) remove: index -1 out of range"; + QTest::newRow("remove3a") << "{append({'foo':123});remove(-1);count}" << 1 << "QML ListModel (unknown location) remove: index -1 out of range"; QTest::newRow("remove4a") << "{remove(0)}" << 0 << "QML ListModel (unknown location) remove: index 0 out of range"; - QTest::newRow("remove4b") << "{append({'foo':123});remove(0);remove(0)}" << 0 << "QML ListModel (unknown location) remove: index 0 out of range"; - QTest::newRow("remove4c") << "{append({'foo':123});remove(1)}" << 0 << "QML ListModel (unknown location) remove: index 1 out of range"; + QTest::newRow("remove4b") << "{append({'foo':123});remove(0);remove(0);count}" << 0 << "QML ListModel (unknown location) remove: index 0 out of range"; + QTest::newRow("remove4c") << "{append({'foo':123});remove(1);count}" << 1 << "QML ListModel (unknown location) remove: index 1 out of range"; QTest::newRow("insert1") << "{insert(0,{'foo':123});count}" << 1 << ""; QTest::newRow("insert2") << "{insert(1,{'foo':123});count}" << 0 << "QML ListModel (unknown location) insert: index 1 out of range"; @@ -161,7 +211,7 @@ void tst_QDeclarativeListModel::dynamic_data() QTest::newRow("insert3c") << "{append({'foo':123});insert(1,{'foo':456});get(1).foo}" << 456 << ""; QTest::newRow("insert3d") << "{append({'foo':123});insert(0,{'foo':456});get(0).foo}" << 456 << ""; QTest::newRow("insert3e") << "{append({'foo':123});insert(0,{'foo':456});get(1).foo}" << 123 << ""; - QTest::newRow("insert4") << "{append({'foo':123});insert(-1,{'foo':456})}" << 0 << "QML ListModel (unknown location) insert: index -1 out of range"; + QTest::newRow("insert4") << "{append({'foo':123});insert(-1,{'foo':456});count}" << 1 << "QML ListModel (unknown location) insert: index -1 out of range"; QTest::newRow("insert5a") << "{insert(0,123)}" << 0 << "QML ListModel (unknown location) insert: value is not an object"; QTest::newRow("insert5b") << "{insert(0,[1,2,3])}" << 0 << "QML ListModel (unknown location) insert: value is not an object"; @@ -171,8 +221,8 @@ void tst_QDeclarativeListModel::dynamic_data() QTest::newRow("set3b") << "{append({'foo':123,'bar':456});set(0,{'foo':999});get(0).bar}" << 456 << ""; QTest::newRow("set4a") << "{set(0,{'foo':456})}" << 0 << "QML ListModel (unknown location) set: index 0 out of range"; QTest::newRow("set4c") << "{set(-1,{'foo':456})}" << 0 << "QML ListModel (unknown location) set: index -1 out of range"; - QTest::newRow("set5a") << "{append({'foo':123,'bar':456});set(0,123)}" << 0 << "QML ListModel (unknown location) set: value is not an object"; - QTest::newRow("set5b") << "{append({'foo':123,'bar':456});set(0,[1,2,3])}" << 0 << "QML ListModel (unknown location) set: value is not an object"; + QTest::newRow("set5a") << "{append({'foo':123,'bar':456});set(0,123);count}" << 1 << "QML ListModel (unknown location) set: value is not an object"; + QTest::newRow("set5b") << "{append({'foo':123,'bar':456});set(0,[1,2,3]);count}" << 1 << "QML ListModel (unknown location) set: value is not an object"; QTest::newRow("set6") << "{append({'foo':123});set(1,{'foo':456});count}" << 2 << ""; QTest::newRow("setprop1") << "{append({'foo':123});setProperty(0,'foo',456);count}" << 1 << ""; @@ -181,7 +231,7 @@ void tst_QDeclarativeListModel::dynamic_data() QTest::newRow("setprop3b") << "{append({'foo':123,'bar':456});setProperty(0,'foo',999);get(0).bar}" << 456 << ""; QTest::newRow("setprop4a") << "{setProperty(0,'foo',456)}" << 0 << "QML ListModel (unknown location) set: index 0 out of range"; QTest::newRow("setprop4b") << "{setProperty(-1,'foo',456)}" << 0 << "QML ListModel (unknown location) set: index -1 out of range"; - QTest::newRow("setprop4c") << "{append({'foo':123,'bar':456});setProperty(1,'foo',456)}" << 0 << "QML ListModel (unknown location) set: index 1 out of range"; + QTest::newRow("setprop4c") << "{append({'foo':123,'bar':456});setProperty(1,'foo',456);count}" << 1 << "QML ListModel (unknown location) set: index 1 out of range"; QTest::newRow("setprop5") << "{append({'foo':123,'bar':456});append({'foo':111});setProperty(1,'bar',222);get(1).bar}" << 222 << ""; QTest::newRow("move1a") << "{append({'foo':123});append({'foo':456});move(0,1,1);count}" << 2 << ""; @@ -193,16 +243,22 @@ void tst_QDeclarativeListModel::dynamic_data() QTest::newRow("move2b") << "{append({'foo':123});append({'foo':456});append({'foo':789});move(0,1,2);get(0).foo}" << 789 << ""; QTest::newRow("move2c") << "{append({'foo':123});append({'foo':456});append({'foo':789});move(0,1,2);get(1).foo}" << 123 << ""; QTest::newRow("move2d") << "{append({'foo':123});append({'foo':456});append({'foo':789});move(0,1,2);get(2).foo}" << 456 << ""; - QTest::newRow("move3a") << "{append({'foo':123});append({'foo':456});append({'foo':789});move(1,0,3)}" << 0 << "QML ListModel (unknown location) move: out of range"; - QTest::newRow("move3b") << "{append({'foo':123});append({'foo':456});append({'foo':789});move(1,-1,1)}" << 0 << "QML ListModel (unknown location) move: out of range"; - QTest::newRow("move3c") << "{append({'foo':123});append({'foo':456});append({'foo':789});move(1,0,-1)}" << 0 << "QML ListModel (unknown location) move: out of range"; - QTest::newRow("move3d") << "{append({'foo':123});append({'foo':456});append({'foo':789});move(0,3,1)}" << 0 << "QML ListModel (unknown location) move: out of range"; + QTest::newRow("move3a") << "{append({'foo':123});append({'foo':456});append({'foo':789});move(1,0,3);count}" << 3 << "QML ListModel (unknown location) move: out of range"; + QTest::newRow("move3b") << "{append({'foo':123});append({'foo':456});append({'foo':789});move(1,-1,1);count}" << 3 << "QML ListModel (unknown location) move: out of range"; + QTest::newRow("move3c") << "{append({'foo':123});append({'foo':456});append({'foo':789});move(1,0,-1);count}" << 3 << "QML ListModel (unknown location) move: out of range"; + QTest::newRow("move3d") << "{append({'foo':123});append({'foo':456});append({'foo':789});move(0,3,1);count}" << 3 << "QML ListModel (unknown location) move: out of range"; + + // Nested models - // Structured model + QTest::newRow("nested-append1") << "{append({'foo':123,'bars':[{'a':1},{'a':2},{'a':3}]});count}" << 1 << ""; + QTest::newRow("nested-append2") << "{append({'foo':123,'bars':[{'a':1},{'a':2},{'a':3}]});get(0).bars.get(1).a}" << 2 << ""; + QTest::newRow("nested-append3") << "{append({'foo':123,'bars':[{'a':1},{'a':2},{'a':3}]});get(0).bars.append({'a':4});get(0).bars.get(3).a}" << 4 << ""; - QTest::newRow("listprop1a") << "{append({'foo':123,'bars':[{'a':1},{'a':2},{'a':3}]});count}" << 1 << ""; - QTest::newRow("listprop1b") << "{append({'foo':123,'bars':[{'a':1},{'a':2},{'a':3}]});get(0).bars.get(1).a}" << 2 << ""; - QTest::newRow("listprop2a") << "{append({'foo':123,'bars':[{'a':1},{'a':2},{'a':3}]});get(0).bars.append({'a':4});get(0).bars.get(3).a}" << 4 << ""; + QTest::newRow("nested-insert") << "{append({'foo':123});insert(0,{'bars':[{'a':1},{'b':2},{'c':3}]});get(0).bars.get(0).a}" << 1 << ""; + QTest::newRow("nested-set") << "{append({'foo':123});set(0,{'foo':[{'x':123}]});get(0).foo.get(0).x}" << 123 << ""; + + // XXX + //QTest::newRow("nested-setprop") << "{append({'foo':123});setProperty(0,'foo',[{'x':123}]);get(0).foo.get(0).x}" << 123 << ""; } void tst_QDeclarativeListModel::dynamic() @@ -213,11 +269,13 @@ void tst_QDeclarativeListModel::dynamic() QDeclarativeEngine engine; QDeclarativeListModel model; - QDeclarativeEngine::setContextForObject(&model,engine.rootContext()); + QDeclarativeEngine::setContextForObject(&model, engine.rootContext()); engine.rootContext()->addDefaultObject(&model); + QDeclarativeExpression e(engine.rootContext(), script, &model); if (!warning.isEmpty()) QTest::ignoreMessage(QtWarningMsg, warning.toLatin1()); + int actual = e.value().toInt(); if (e.hasError()) qDebug() << e.error(); // errors not expected @@ -225,6 +283,152 @@ void tst_QDeclarativeListModel::dynamic() QCOMPARE(actual,result); } +void tst_QDeclarativeListModel::dynamic_worker_data() +{ + dynamic_data(); +} + +void tst_QDeclarativeListModel::dynamic_worker() +{ + QFETCH(QString, script); + QFETCH(int, result); + QFETCH(QString, warning); + + QDeclarativeListModel model; + QDeclarativeEngine eng; + QDeclarativeComponent component(&eng, QUrl::fromLocalFile(SRCDIR "/data/model.qml")); + QDeclarativeItem *item = createWorkerTest(&eng, &component, &model); + QVERIFY(item != 0); + + if (script[0] == QLatin1Char('{') && script[script.length()-1] == QLatin1Char('}')) + script = script.mid(1, script.length() - 2); + QString finalTest = script.split(';').last(); + QString scriptWithoutFinalTest = script.mid(0, script.indexOf(finalTest)); + + if (!warning.isEmpty()) + QTest::ignoreMessage(QtWarningMsg, warning.toLatin1()); + + if (!scriptWithoutFinalTest.isEmpty()) { + if (QByteArray(QTest::currentDataTag()).startsWith("nested")) + QTest::ignoreMessage(QtWarningMsg, "QML ListModel (unknown location) Cannot add nested list values when modifying or after modification from a worker script"); + QVERIFY(QMetaObject::invokeMethod(item, "evalExpressionViaWorker", Q_ARG(QVariant, scriptWithoutFinalTest))); + waitForWorker(item); + } + + QDeclarativeExpression e(eng.rootContext(), finalTest, &model); + if (QByteArray(QTest::currentDataTag()).startsWith("nested")) + QVERIFY(e.value().toInt() != result); + else + QCOMPARE(e.value().toInt(), result); + + QEventLoop loop; + QTimer timer; + timer.setSingleShot(true); + connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); + connect(item, SIGNAL(destroyed(QObject*)), &loop, SLOT(quit())); + timer.start(10000); + item->deleteLater(); + loop.exec(); + + QTest::ignoreMessage(QtWarningMsg, "QThread: Destroyed while thread is still running"); + qApp->processEvents(); +} + +void tst_QDeclarativeListModel::convertNestedToFlat_fail() +{ + // If a model has nested data, it cannot be used at all from a worker script + + QFETCH(QString, script); + + QDeclarativeListModel model; + QDeclarativeEngine eng; + QDeclarativeComponent component(&eng, QUrl::fromLocalFile(SRCDIR "/data/model.qml")); + QDeclarativeItem *item = createWorkerTest(&eng, &component, &model); + QVERIFY(item != 0); + + QScriptEngine s_eng; + QScriptValue plainData = s_eng.newObject(); + plainData.setProperty("foo", QScriptValue(123)); + model.append(plainData); + model.append(nestedListValue(&s_eng)); + QCOMPARE(model.count(), 2); + + QTest::ignoreMessage(QtWarningMsg, "QML ListModel (unknown location) List contains nested list values and cannot be used from a worker script"); + QVERIFY(QMetaObject::invokeMethod(item, "evalExpressionViaWorker", Q_ARG(QVariant, script))); + waitForWorker(item); + + QCOMPARE(model.count(), 2); + + delete item; + QTest::ignoreMessage(QtWarningMsg, "QThread: Destroyed while thread is still running"); + qApp->processEvents(); +} + +void tst_QDeclarativeListModel::convertNestedToFlat_fail_data() +{ + QTest::addColumn("script"); + + QTest::newRow("clear") << "clear()"; + QTest::newRow("remove") << "remove(0)"; + QTest::newRow("append") << "append({'x':1})"; + QTest::newRow("insert") << "insert(0, {'x':1})"; + QTest::newRow("set") << "set(0, {'foo':1})"; + QTest::newRow("setProperty") << "setProperty(0, 'foo', 1})"; + QTest::newRow("move") << "move(0, 1, 1})"; + QTest::newRow("get") << "get(0)"; +} + +void tst_QDeclarativeListModel::convertNestedToFlat_ok() +{ + // If a model only has plain data, it can be modified from a worker script. However, + // once the model is used from a worker script, it no longer accepts nested data + + QFETCH(QString, script); + + QDeclarativeListModel model; + QDeclarativeEngine eng; + QDeclarativeComponent component(&eng, QUrl::fromLocalFile(SRCDIR "/data/model.qml")); + QDeclarativeItem *item = createWorkerTest(&eng, &component, &model); + QVERIFY(item != 0); + + QScriptEngine s_eng; + QScriptValue plainData = s_eng.newObject(); + plainData.setProperty("foo", QScriptValue(123)); + model.append(plainData); + QCOMPARE(model.count(), 1); + + QVERIFY(QMetaObject::invokeMethod(item, "evalExpressionViaWorker", Q_ARG(QVariant, script))); + waitForWorker(item); + + // can still add plain data + int count = model.count(); + model.append(plainData); + QCOMPARE(model.count(), count+1); + + QScriptValue nested = nestedListValue(&s_eng); + const char *warning = "QML ListModel (unknown location) Cannot add nested list values when modifying or after modification from a worker script"; + + QTest::ignoreMessage(QtWarningMsg, warning); + model.append(nested); + + QTest::ignoreMessage(QtWarningMsg, warning); + model.insert(0, nested); + + QTest::ignoreMessage(QtWarningMsg, warning); + model.set(0, nested); + + QCOMPARE(model.count(), count+1); + + delete item; + QTest::ignoreMessage(QtWarningMsg, "QThread: Destroyed while thread is still running"); + qApp->processEvents(); +} + +void tst_QDeclarativeListModel::convertNestedToFlat_ok_data() +{ + convertNestedToFlat_fail_data(); +} + void tst_QDeclarativeListModel::static_types_data() { QTest::addColumn("qml"); diff --git a/tests/auto/declarative/qdeclarativeworkerlistmodel/data/model.qml b/tests/auto/declarative/qdeclarativeworkerlistmodel/data/model.qml deleted file mode 100644 index be94e00..0000000 --- a/tests/auto/declarative/qdeclarativeworkerlistmodel/data/model.qml +++ /dev/null @@ -1,14 +0,0 @@ -import Qt 4.6 - -Item { - property alias model: model - - WorkerListModel { id: model } - - function workerModifyModel(cmd) { worker.sendMessage({'command': cmd, 'model': model}) } - - WorkerScript { - id: worker - source: "script.js" - } -} diff --git a/tests/auto/declarative/qdeclarativeworkerlistmodel/data/script.js b/tests/auto/declarative/qdeclarativeworkerlistmodel/data/script.js deleted file mode 100644 index 8ee62b4..0000000 --- a/tests/auto/declarative/qdeclarativeworkerlistmodel/data/script.js +++ /dev/null @@ -1,6 +0,0 @@ -WorkerScript.onMessage = function(msg) { - eval("msg.model." + msg.command) - msg.model.sync() -} - - diff --git a/tests/auto/declarative/qdeclarativeworkerlistmodel/qdeclarativeworkerlistmodel.pro b/tests/auto/declarative/qdeclarativeworkerlistmodel/qdeclarativeworkerlistmodel.pro deleted file mode 100644 index 960dbe1..0000000 --- a/tests/auto/declarative/qdeclarativeworkerlistmodel/qdeclarativeworkerlistmodel.pro +++ /dev/null @@ -1,9 +0,0 @@ -load(qttest_p4) -contains(QT_CONFIG,declarative): QT += declarative -QT += script -macx:CONFIG -= app_bundle - -SOURCES += tst_qdeclarativeworkerlistmodel.cpp - -# Define SRCDIR equal to test's source directory -DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/declarative/qdeclarativeworkerlistmodel/tst_qdeclarativeworkerlistmodel.cpp b/tests/auto/declarative/qdeclarativeworkerlistmodel/tst_qdeclarativeworkerlistmodel.cpp deleted file mode 100644 index 11a7447..0000000 --- a/tests/auto/declarative/qdeclarativeworkerlistmodel/tst_qdeclarativeworkerlistmodel.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include - -#include -#include -#include - -#include -#include -#include "../../../shared/util.h" - - - -class tst_QDeclarativeWorkerListModel : public QObject -{ - Q_OBJECT -public: - tst_QDeclarativeWorkerListModel() {} -private slots: - void clear(); - void remove(); - void append(); - void insert(); - void get(); - void set(); - -private: - QByteArray modificationWarning() const { - QString file = QUrl::fromLocalFile(SRCDIR "/data/model.qml").toString(); - return QString("QML WorkerListModel (" + file + ":6:5) List can only be modified from a WorkerScript").toUtf8(); - } - - QDeclarativeEngine m_engine; -}; - -void tst_QDeclarativeWorkerListModel::clear() -{ - QDeclarativeComponent component(&m_engine, SRCDIR "/data/model.qml"); - QDeclarativeItem *item = qobject_cast(component.create()); - QVERIFY(item != 0); - QDeclarativeWorkerListModel *model = item->property("model").value(); - QVERIFY(model != 0); - - QCOMPARE(model->count(), 0); - QVERIFY(QMetaObject::invokeMethod(item, "workerModifyModel", Q_ARG(QVariant, "append({'name': 'A'})"))); - QTRY_COMPARE(model->count(), 1); - - QTest::ignoreMessage(QtWarningMsg, modificationWarning().constData()); - model->clear(); - QCOMPARE(model->count(), 1); - - QVERIFY(QMetaObject::invokeMethod(item, "workerModifyModel", Q_ARG(QVariant, "clear()"))); - QTRY_COMPARE(model->count(), 0); - - qApp->processEvents(); -} - -void tst_QDeclarativeWorkerListModel::remove() -{ - QDeclarativeComponent component(&m_engine, SRCDIR "/data/model.qml"); - QDeclarativeItem *item = qobject_cast(component.create()); - QVERIFY(item != 0); - QDeclarativeWorkerListModel *model = item->property("model").value(); - QVERIFY(model != 0); - - QVERIFY(QMetaObject::invokeMethod(item, "workerModifyModel", Q_ARG(QVariant, "append({'name': 'A'})"))); - QTRY_COMPARE(model->count(), 1); - - QTest::ignoreMessage(QtWarningMsg, modificationWarning().constData()); - model->remove(0); - QCOMPARE(model->count(), 1); - - QVERIFY(QMetaObject::invokeMethod(item, "workerModifyModel", Q_ARG(QVariant, "remove(0)"))); - QTRY_COMPARE(model->count(), 0); - - qApp->processEvents(); -} - -void tst_QDeclarativeWorkerListModel::append() -{ - QDeclarativeComponent component(&m_engine, SRCDIR "/data/model.qml"); - QDeclarativeItem *item = qobject_cast(component.create()); - QVERIFY(item != 0); - QDeclarativeWorkerListModel *model = item->property("model").value(); - QVERIFY(model != 0); - - QVERIFY(QMetaObject::invokeMethod(item, "workerModifyModel", Q_ARG(QVariant, "append({'name': 'A'})"))); - QTRY_COMPARE(model->count(), 1); - - QTest::ignoreMessage(QtWarningMsg, modificationWarning().constData()); - model->append(QScriptValue(1)); - QCOMPARE(model->count(), 1); - - qApp->processEvents(); -} - -void tst_QDeclarativeWorkerListModel::insert() -{ - QDeclarativeComponent component(&m_engine, SRCDIR "/data/model.qml"); - QDeclarativeItem *item = qobject_cast(component.create()); - QVERIFY(item != 0); - QDeclarativeWorkerListModel *model = item->property("model").value(); - QVERIFY(model != 0); - - QVERIFY(QMetaObject::invokeMethod(item, "workerModifyModel", Q_ARG(QVariant, "insert(0, {'name': 'A'})"))); - QTRY_COMPARE(model->count(), 1); - - QTest::ignoreMessage(QtWarningMsg, modificationWarning().constData()); - model->insert(0, QScriptValue(1)); - QCOMPARE(model->count(), 1); - - qApp->processEvents(); -} - -void tst_QDeclarativeWorkerListModel::get() -{ - QDeclarativeComponent component(&m_engine, SRCDIR "/data/model.qml"); - QDeclarativeItem *item = qobject_cast(component.create()); - QVERIFY(item != 0); - QDeclarativeWorkerListModel *model = item->property("model").value(); - QVERIFY(model != 0); - - QVERIFY(QMetaObject::invokeMethod(item, "workerModifyModel", Q_ARG(QVariant, "append({'name': 'A'})"))); - QTRY_COMPARE(model->count(), 1); - QCOMPARE(model->get(0).property("name").toString(), QString("A")); - - qApp->processEvents(); -} - -void tst_QDeclarativeWorkerListModel::set() -{ - QDeclarativeComponent component(&m_engine, SRCDIR "/data/model.qml"); - QDeclarativeItem *item = qobject_cast(component.create()); - QVERIFY(item != 0); - QDeclarativeWorkerListModel *model = item->property("model").value(); - QVERIFY(model != 0); - - QVERIFY(QMetaObject::invokeMethod(item, "workerModifyModel", Q_ARG(QVariant, "append({'name': 'A'})"))); - QTRY_COMPARE(model->count(), 1); - - QTest::ignoreMessage(QtWarningMsg, modificationWarning().constData()); - model->set(0, QScriptValue(1)); - - QVERIFY(QMetaObject::invokeMethod(item, "workerModifyModel", Q_ARG(QVariant, "set(0, {'name': 'Z'})"))); - QTRY_COMPARE(model->get(0).property("name").toString(), QString("Z")); - - qApp->processEvents(); -} - -QTEST_MAIN(tst_QDeclarativeWorkerListModel) - -#include "tst_qdeclarativeworkerlistmodel.moc" - -- cgit v0.12 From 31e06818aaf65150f61107f112b305cfd8585710 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 16 Mar 2010 11:37:48 +1000 Subject: QmlChanges.txt cleanup. --- src/declarative/QmlChanges.txt | 49 ++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt index 6d0f16f..e9325b7 100644 --- a/src/declarative/QmlChanges.txt +++ b/src/declarative/QmlChanges.txt @@ -41,6 +41,31 @@ Connection: syntax and rename: becomes: Connections { target: a; onFoo: xxx; onBar: yyy } +ListView::sectionExpression has been replaced by section.property, section.criteria + +ListModel +--------- +- types are strictly checked (previously, everything was a string) + - foo: "bar" continues to work as before + - foo: bar is now invalid, use foo: "bar" + - foo: true is now a bool (not string "true") + - foo: false is now a bool (not string "false" == true!) + +PropertyAnimation +------------------ +matchProperties and matchTargets have been renamed back to properties and targets. +The semantics are explained in the PropertyAnimation::properties documentation +and the animation overview documentation. + +C++ API +------- +QML_DEFINE_... definition macros, previously global macros, are replaced by +qmlRegisterType registration functions, which must be called explicitly. +C++ API users should also consider using the QmlExtensionPlugin (previously +named QmlModulePlugin) as a cleaner mechanism for publishing libraries of QML +types, or the upcoming application plugin features of the qmlviewer / +qmlruntime / qml. + QmlView ------- The API of QmlView has been narrowed and its role as a convenience class @@ -55,30 +80,8 @@ reinforced. - remove quit() signal -> use quit() signal of engine() - initialSize() signal removed - Added status() to determine status of the internal QmlComponent +- removed execute() - setSource() will also execute the QML. -sectionExpression has been replaced by section.property, section.criteria - -ListModel ---------- -- types are strictly checked (previously, everything was a string) - - foo: "bar" continues to work as before - - foo: bar is now invalid, use foo: "bar" - - foo: true is now a bool (not string "true") - - foo: false is now a bool (not string "false" == true!) - -C++ API -------- -QML_DEFINE_... definition macros, previously global macros, are replaced by -QML_REGISTER_... registration macros, which must be called explicitly. C++ API users -should also consider using the QmlExtensionPlugin (previously named QmlModulePlugin) -as a cleaner mechanism for publishing libraries of QML types, or the upcoming -application plugin features of the qmlviewer / qmlruntime / qml. - -PropertyAnimation ------------------- -matchProperties and matchTargets have been renamed back to properties and targets. -The semantics are explained in the PropertyAnimation::properties documentation -and the animation overview documentation. ============================================================================= The changes below are pre-4.6.0 release. -- cgit v0.12 From fcfc3a68a525c32d4550068d7cf47bb3a5816da6 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Tue, 16 Mar 2010 14:04:38 +1000 Subject: Doc fixes. --- doc/src/declarative/elements.qdoc | 1 - src/declarative/util/qdeclarativelistmodel.cpp | 54 +++++++++++++------------- 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/doc/src/declarative/elements.qdoc b/doc/src/declarative/elements.qdoc index 0d7fe3b..75f8b97 100644 --- a/doc/src/declarative/elements.qdoc +++ b/doc/src/declarative/elements.qdoc @@ -94,7 +94,6 @@ The following table lists the QML elements provided by the Qt Declarative module \o \l VisualDataModel \o \l Package \o \l XmlListModel and XmlRole -\o \l WorkerListModel \endlist \o diff --git a/src/declarative/util/qdeclarativelistmodel.cpp b/src/declarative/util/qdeclarativelistmodel.cpp index b290742..d612ba8 100644 --- a/src/declarative/util/qdeclarativelistmodel.cpp +++ b/src/declarative/util/qdeclarativelistmodel.cpp @@ -194,14 +194,34 @@ QDeclarativeListModelParser::ListInstruction *QDeclarativeListModelParser::ListM \section2 Using threaded list models with WorkerScript - ListModel can be used together with WorkerScript to define a list model - that is accessible from multiple threads. This is useful if list - modifications are synchronous and take some time: the list operations can - be moved to a different thread to avoid blocking of the main GUI thread. + ListModel can be used together with WorkerScript access a list model + from multiple threads. This is useful if list modifications are + synchronous and take some time: the list operations can be moved to a + different thread to avoid blocking of the main GUI thread. - Note that a list model is to be accessed from a WorkerScript, it \bold cannot - contain nested list data. So, this model cannot be used from a WorkerScript - because of the "attributes" value which contains a list: + Here is an example that uses WorkerScript to periodically append the + current time to a list model: + + \snippet examples/declarative/listmodel-threaded/timedisplay.qml 0 + + The included file, \tt dataloader.js, looks like this: + + \snippet examples/declarative/listmodel-threaded/dataloader.js 0 + + The application's \tt Timer object periodically sends a message to the + worker script by calling \tt WorkerScript::sendMessage(). When this message + is received, \tt WorkerScript.onMessage() is invoked in + \tt dataloader.js, which appends the current time to the list model. + + Note the call to sync() from the \c WorkerScript.onMessage() handler. + Without this call, the changes made to the list are not reflected in the + list model in the main thread. + + \section3 Limitations + + If a list model is to be accessed from a WorkerScript, it \bold cannot + contain nested list data. So, the following model cannot be used from a WorkerScript + because of the list contained in the "attributes" property: \code ListModel { @@ -219,26 +239,6 @@ QDeclarativeListModelParser::ListInstruction *QDeclarativeListModelParser::ListM In addition, the WorkerScript cannot add any nested list data to the model. - \section3 Example - - To use a list model from a worker script, pass the model to the script - through the onMessage() handler, make the list modifications, and call - sync() to save the changes to the model data. - - Here is an example application that uses WorkerScript to append the - current time to a ListModel: - - \snippet examples/declarative/listmodel-threaded/timedisplay.qml 0 - - The included file, \tt dataloader.js, looks like this: - - \snippet examples/declarative/listmodel-threaded/dataloader.js 0 - - The application's \tt Timer object periodically sends a message to the - worker script by calling \tt WorkerScript::sendMessage(). When this message - is received, \tt WorkerScript.onMessage() is invoked in - \tt dataloader.js, which appends the current time to the list model. - \sa {qmlmodels}{Data Models}, WorkerScript */ -- cgit v0.12 From a32cd00668076674b6968b821d4b7377c95ddee9 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 16 Mar 2010 15:49:27 +1000 Subject: Update more animation on property value source docs. --- doc/src/declarative/animation.qdoc | 9 +++++---- doc/src/declarative/dynamicobjects.qdoc | 25 +++++++++++++------------ src/declarative/util/qdeclarativeanimation.cpp | 2 +- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/doc/src/declarative/animation.qdoc b/doc/src/declarative/animation.qdoc index 2b75211..7e0a787 100644 --- a/doc/src/declarative/animation.qdoc +++ b/doc/src/declarative/animation.qdoc @@ -58,7 +58,8 @@ types listed above. If the property you are animating is a number or color, you NumberAnimation or ColorAnimation. These elements don't add any additional functionality, but will help enforce type correctness and are slightly more efficient. -A property animation can be specified as a value source. This is especially useful for repeating animations. +A property animation can be specified as a value source using the \e Animation \bold on \e property syntax. This is especially useful +for repeating animations. The following example creates a bouncing effect: \qml @@ -70,7 +71,7 @@ Rectangle { source: "qt-logo.png" x: 60-img.width/2 y: 0 - y: SequentialAnimation { + SequentialAnimation on y { repeat: true NumberAnimation { to: 200-img.height; easing.type: "OutBounce"; duration: 2000 } PauseAnimation { duration: 1000 } @@ -93,7 +94,7 @@ Rectangle { Rectangle { color: "red" width: 50; height: 50 - x: NumberAnimation { to: 50; } + NumberAnimation on x { to: 50; } } } \endqml @@ -226,7 +227,7 @@ Rectangle { id: redRect color: "red" width: 100; height: 100 - x: Behavior { NumberAnimation { duration: 300; easing.type: "InOutQuad" } } + Behavior on x { NumberAnimation { duration: 300; easing.type: "InOutQuad" } } } \endqml diff --git a/doc/src/declarative/dynamicobjects.qdoc b/doc/src/declarative/dynamicobjects.qdoc index 033c0d1..b2e3f90 100644 --- a/doc/src/declarative/dynamicobjects.qdoc +++ b/doc/src/declarative/dynamicobjects.qdoc @@ -76,25 +76,25 @@ the component. Example QML script is below. Remember that QML files that might b \code var component; var sprite; - function finishCreation(){ - if(component.isReady()){ + function finishCreation() { + if(component.isReady()) { sprite = component.createObject(); - if(sprite == 0){ + if(sprite == 0) { // Error Handling - }else{ + } else { sprite.parent = page; sprite.x = 200; //... } - }else if(component.isError()){ + } else if(component.isError()) { // Error Handling } } component = createComponent("Sprite.qml"); - if(component.isReady()){ + if(component.isReady()) { finishCreation(); - }else{ + } else { component.statusChanged.connect(finishCreation); } \endcode @@ -104,10 +104,10 @@ the component. Example QML script is below. Remember that QML files that might b \code component = createComponent("Sprite.qml"); sprite = component.createObject(); - if(sprite == 0){ + if(sprite == 0) { // Error Handling console.log(component.errorsString()); - }else{ + } else { sprite.parent = page; sprite.x = 200; //... @@ -122,7 +122,7 @@ If the QML does not exist until runtime, you can create a QML item from a string of QML using the createQmlObject function, as in the following example: \code - newObject = createQmlObject('import Qt 4.6; Rectangle {color: "red"; width: 20; height: 20}', + newObject = createQmlObject('import Qt 4.6; Rectangle { color: "red"; width: 20; height: 20 }', targetItem, "dynamicSnippet1"); \endcode The first argument is the string of QML to create. Just like in a new file, you will need to @@ -158,11 +158,12 @@ argument, which is an approximate delay in ms and which defaults to zero. This allows you to wait until the completion of an animation or transition. An example: \code - Component{ id:fadesOut + Component { + id: fadesOut Rectangle{ id: rect width: 40; height: 40; - opacity: NumberAnimation{from:1; to:0; duration: 1000;} + NumberAnimation on opacity { from:1; to:0; duration: 1000 } Component.onCompleted: rect.destroy(1000); } } diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index 009e07f..49206b7 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -132,7 +132,7 @@ QDeclarativeAbstractAnimation::QDeclarativeAbstractAnimation(QDeclarativeAbstrac using the \c start() and \c stop() methods. By default, animations are not running. Though, when the animations are assigned to properties, - as property value sources, they are set to running by default. + as property value sources using the \e on syntax, they are set to running by default. */ bool QDeclarativeAbstractAnimation::isRunning() const { -- cgit v0.12 From 99d756aca86fb9c7a92d50bda05a9911af3229b6 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 16 Mar 2010 18:02:55 +1000 Subject: Add easing changes to QmlChanges.txt --- src/declarative/QmlChanges.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt index e9325b7..7c584b4d 100644 --- a/src/declarative/QmlChanges.txt +++ b/src/declarative/QmlChanges.txt @@ -57,6 +57,14 @@ matchProperties and matchTargets have been renamed back to properties and target The semantics are explained in the PropertyAnimation::properties documentation and the animation overview documentation. +Easing curves and their parameters are now specified via dot properties: +* easing.type : enum +* easing.amplitude : real +* easing.overshoot : real +* easing.period : real +For example: +PropertyAnimation { properties: "y"; easing.type: "InOutElastic"; easing.amplitude: 2.0; easing.period: 1.5 } + C++ API ------- QML_DEFINE_... definition macros, previously global macros, are replaced by -- cgit v0.12 From 972d984b1c38daec3a75c2040f91ce59b8224472 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 16 Mar 2010 18:10:33 +1000 Subject: Remove unneeded #include and add needed header to .pri --- src/declarative/util/qdeclarativelistmodel.cpp | 2 -- src/declarative/util/util.pri | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/declarative/util/qdeclarativelistmodel.cpp b/src/declarative/util/qdeclarativelistmodel.cpp index d612ba8..61e49ce 100644 --- a/src/declarative/util/qdeclarativelistmodel.cpp +++ b/src/declarative/util/qdeclarativelistmodel.cpp @@ -1335,5 +1335,3 @@ void ModelObject::setValue(const QByteArray &name, const QVariant &val) QT_END_NAMESPACE - -#include diff --git a/src/declarative/util/util.pri b/src/declarative/util/util.pri index 041aa13..ddf00ea 100644 --- a/src/declarative/util/util.pri +++ b/src/declarative/util/util.pri @@ -50,6 +50,7 @@ HEADERS += \ $$PWD/qdeclarativestategroup_p.h \ $$PWD/qdeclarativetransition_p.h \ $$PWD/qdeclarativelistmodel_p.h\ + $$PWD/qdeclarativelistmodel_p_p.h\ $$PWD/qdeclarativelistaccessor_p.h \ $$PWD/qdeclarativeopenmetaobject_p.h \ $$PWD/qdeclarativenullablevalue_p_p.h \ -- cgit v0.12 From d5e7356a16e51c544b7c5d148af7dcc70a7d6532 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Tue, 16 Mar 2010 12:23:41 +0100 Subject: Remove test in .pro file also --- tests/auto/declarative/declarative.pro | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/auto/declarative/declarative.pro b/tests/auto/declarative/declarative.pro index 143fbad..36eade8 100644 --- a/tests/auto/declarative/declarative.pro +++ b/tests/auto/declarative/declarative.pro @@ -55,7 +55,6 @@ SUBDIRS += \ qpacketprotocol \ # Cover qdeclarativerepeater \ # Cover qdeclarativeworkerscript \ # Cover - qdeclarativeworkerlistmodel \ # Cover qdeclarativevaluetypes \ # Cover qdeclarativexmlhttprequest \ # Cover qdeclarativeimageprovider \ # Cover -- cgit v0.12 From 55a55426f24685400b7ab062b221f248ac159821 Mon Sep 17 00:00:00 2001 From: mae Date: Tue, 16 Mar 2010 15:24:03 +0100 Subject: add alan's tic-tac-toe AI --- .../declarative/tic-tac-toe/content/Button.qml | 35 ++++++ .../declarative/tic-tac-toe/content/pics/board.png | Bin 5524 -> 11208 bytes examples/declarative/tic-tac-toe/tic-tac-toe.qml | 123 +++++++++++++++++++-- 3 files changed, 151 insertions(+), 7 deletions(-) create mode 100644 examples/declarative/tic-tac-toe/content/Button.qml diff --git a/examples/declarative/tic-tac-toe/content/Button.qml b/examples/declarative/tic-tac-toe/content/Button.qml new file mode 100644 index 0000000..cfc2f04 --- /dev/null +++ b/examples/declarative/tic-tac-toe/content/Button.qml @@ -0,0 +1,35 @@ +import Qt 4.6 + +Rectangle { + id: container + + signal clicked + property string text: "Button" + property bool down: false + property string mainCol: "lightgray" + property string darkCol: "darkgray" + property string lightCol: "white" + + color: mainCol; smooth: true + width: txtItem.width + 20; height: txtItem.height + 6 + border.width: 1; border.color: Qt.darker(mainCol); radius: 8; + + gradient: Gradient { + GradientStop { + id: topGrad; position: 0.0 + color: if (container.down) { darkCol } else { lightCol } } + GradientStop { position: 1.0; color: mainCol } + } + + MouseArea { id: mr; anchors.fill: parent; onClicked: container.clicked() } + + Text { + id: txtItem; text: container.text; + anchors.centerIn: container + color: "blue" + styleColor: "white" + style: Text.Outline + font.pixelSize: 14 + font.bold: true + } +} diff --git a/examples/declarative/tic-tac-toe/content/pics/board.png b/examples/declarative/tic-tac-toe/content/pics/board.png index cd85971..e7a7324 100644 Binary files a/examples/declarative/tic-tac-toe/content/pics/board.png and b/examples/declarative/tic-tac-toe/content/pics/board.png differ diff --git a/examples/declarative/tic-tac-toe/tic-tac-toe.qml b/examples/declarative/tic-tac-toe/tic-tac-toe.qml index 63ee483..ae187d2 100644 --- a/examples/declarative/tic-tac-toe/tic-tac-toe.qml +++ b/examples/declarative/tic-tac-toe/tic-tac-toe.qml @@ -2,11 +2,17 @@ import Qt 4.6 import "content" Item { - width: boardimage.width - height: boardimage.height + id: game + property bool show: false; + width: 440 + height: 480 + anchors.fill: parent + property real difficulty: 1.0; //chance it will actually think Image { id: boardimage + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter source: "content/pics/board.png" } @@ -31,7 +37,7 @@ Item { } Script { - function winner() + function winner(board) { for (var i=0; i<3; ++i) { if (board.children[i].state!="" @@ -68,7 +74,7 @@ Item { function makeMove(pos,player) { board.children[pos].state = player - if (winner()) { + if (winner(board)) { win(player + " wins") return true } else { @@ -78,13 +84,95 @@ Item { function computerTurn() { - // world's dumbest player - for (var i=0; i<9; ++i) + var r = Math.random(); + if(r < game.difficulty){ + smartAI(); + }else{ + randAI(); + } + } + + function smartAI() + { + function boardCopy(a){ + var ret = new Object; + ret.children = new Array(9); + for(var i = 0; i<9; i++){ + ret.children[i] = new Object; + ret.children[i].state = a.children[i].state; + } + return ret; + } + for(var i=0; i<9; i++){ + var simpleBoard = boardCopy(board); + if (board.children[i].state == "") { + simpleBoard.children[i].state = "O"; + if(winner(simpleBoard)){ + makeMove(i,"O") + return + } + } + } + for(var i=0; i<9; i++){ + var simpleBoard = boardCopy(board); + if (board.children[i].state == "") { + simpleBoard.children[i].state = "X"; + if(winner(simpleBoard)){ + makeMove(i,"O") + return + } + } + } + function thwart(a,b,c){//If they are at a, try b or c + if (board.children[a].state == "X") { + if (board.children[b].state == "") { + makeMove(b,"O") + return true + }else if (board.children[c].state == "") { + makeMove(c,"O") + return true + } + } + return false; + } + if(thwart(4,0,2)) return; + if(thwart(0,4,3)) return; + if(thwart(2,4,1)) return; + if(thwart(6,4,7)) return; + if(thwart(8,4,5)) return; + if(thwart(1,4,2)) return; + if(thwart(3,4,0)) return; + if(thwart(5,4,8)) return; + if(thwart(7,4,6)) return; + for(var i =0; i<9; i++){//Backup if (board.children[i].state == "") { makeMove(i,"O") return } - restart() + } + restart(); + } + + function randAI() + { + var open = 0; + for (var i=0; i<9; ++i) + if (board.children[i].state == "") { + open += 1; + } + if(open == 0){ + restart(); + return; + } + var openA = new Array(open);//JS doesn't have lists I can append to (i think) + var acc = 0; + for (var i=0; i<9; ++i) + if (board.children[i].state == "") { + openA[acc] = i; + acc += 1; + } + var choice = openA[Math.floor(Math.random() * open)]; + makeMove(choice, "O"); } function win(s) @@ -102,6 +190,27 @@ Item { } } + Row { + spacing: 4 + anchors.top: board.bottom + anchors.horizontalCenter: board.horizontalCenter + Button { + text: "Hard" + onClicked: game.difficulty=1.0; + down: game.difficulty == 1.0 + } + Button { + text: "Moderate" + onClicked: game.difficulty=0.8; + down: game.difficulty == 0.8 + } + Button { + text: "Easy" + onClicked: game.difficulty=0.2; + down: game.difficulty == 0.2 + } + } + Text { id: msg opacity: 0 -- cgit v0.12 From 3dd972ec56da468ab340afe02f04fa4216c53d63 Mon Sep 17 00:00:00 2001 From: mae Date: Tue, 16 Mar 2010 16:15:17 +0100 Subject: Fix documentation --- examples/declarative/plugins/README | 4 ++-- examples/declarative/plugins/plugins.qml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/declarative/plugins/README b/examples/declarative/plugins/README index 621f570..3ae256d 100644 --- a/examples/declarative/plugins/README +++ b/examples/declarative/plugins/README @@ -1,9 +1,9 @@ -This example shows a module "com.nokia.TimeExample" that is implelement +This example shows a module "com.nokia.TimeExample" that is implemented by a C++ plugin (providing the "Time" type), and by QML files (providing the "Clock" type). To run: make install - qmlviewer plugins.qml + qml plugins.qml diff --git a/examples/declarative/plugins/plugins.qml b/examples/declarative/plugins/plugins.qml index 44b552b..449cd9a 100644 --- a/examples/declarative/plugins/plugins.qml +++ b/examples/declarative/plugins/plugins.qml @@ -1,8 +1,8 @@ import com.nokia.TimeExample 1.0 // import types from the plugin -Clock { // this class is defined in QML (files/Clock.qml) +Clock { // this class is defined in QML (com/nokia/TimeExample/Clock.qml) - Time { // this class is defined in C++ (plugins.cpp) + Time { // this class is defined in C++ (plugin.cpp) id: time } -- cgit v0.12 From dc829ac31694f382bf7b8a0702f73409762e36f0 Mon Sep 17 00:00:00 2001 From: mae Date: Tue, 16 Mar 2010 16:15:33 +0100 Subject: Fixes for the module import The change makes import "url" also load plugins. We know must decide on the preferred coding style. Since native types must be registered with a unique uri, we now generate a stable uri from the plugin path and the import paths. This way we do not have to call registerTypes() multiple times. --- src/declarative/qml/qdeclarativeengine.cpp | 148 +++++++++++++++++++++-------- src/declarative/util/qdeclarativeview.cpp | 1 + 2 files changed, 111 insertions(+), 38 deletions(-) diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index e84e267..0d8c7e9 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1429,9 +1429,89 @@ public: QSet qmlDirFilesForWhichPluginsHaveBeenLoaded; - bool add(const QUrl& base, const QString &qmldircontentnetwork, const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType, const QStringList& importPath, QDeclarativeEngine *engine) + QString importExtension(const QString &absoluteFilePath, const QString &uri, QDeclarativeEngine *engine) { + QFile file(absoluteFilePath); + QString dir = QFileInfo(file).path(); + QString qmldircontent; + if (file.open(QFile::ReadOnly)) { + qmldircontent = QString::fromUtf8(file.readAll()); + if (qmlImportTrace()) + qDebug() << "QDeclarativeEngine::add: loaded" << absoluteFilePath; + } + + if (! qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(absoluteFilePath)) { + qmlDirFilesForWhichPluginsHaveBeenLoaded.insert(absoluteFilePath); + + QDeclarativeDirParser qmldirParser; + qmldirParser.setSource(qmldircontent); + qmldirParser.parse(); + + foreach (const QDeclarativeDirParser::Plugin &plugin, qmldirParser.plugins()) { + QDir pluginDir(dir + QDir::separator() + plugin.path); + if (dir.startsWith(QLatin1Char(':'))) + pluginDir = QDir(QCoreApplication::applicationDirPath()); + QString resolvedFilePath = + QDeclarativeEnginePrivate::get(engine) + ->resolvePlugin(pluginDir, + plugin.name); + + if (!resolvedFilePath.isEmpty()) { + engine->importExtension(resolvedFilePath, uri); + } + } + } + return qmldircontent; + } + + QString resolvedUri(const QString &dir_arg, QDeclarativeEngine *engine) + { + QString dir = dir_arg; + if (dir.endsWith(QLatin1Char('/')) || dir.endsWith(QLatin1Char('\\'))) + dir.chop(1); + + QStringList paths; + + QUrl baseUrl = QDeclarativeEnginePrivate::get(engine)->baseUrl; + if (!baseUrl.isEmpty()) { + QString baseDir = QFileInfo(toLocalFileOrQrc(baseUrl)).path(); + paths += baseDir; + } + + QString applicationDirPath = QCoreApplication::applicationDirPath(); + if (!applicationDirPath.isEmpty()) + paths += applicationDirPath; + + paths += QDeclarativeEnginePrivate::get(engine)->environmentImportPath; +#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) + QString builtinPath = QLibraryInfo::location(QLibraryInfo::ImportsPath); +#else + QString builtinPath; +#endif + if (!builtinPath.isEmpty()) + paths += builtinPath; + + // add fileImportPath last, this is *not* search order. + paths += QDeclarativeEnginePrivate::get(engine)->fileImportPath; + + QString stableRelativePath = dir; + foreach( QString path, paths) { + if (dir.startsWith(path)) { + stableRelativePath = dir.mid(path.length()+1); + break; + } + } + stableRelativePath.replace(QLatin1Char('/'), QLatin1Char('.')); + stableRelativePath.replace(QLatin1Char('\\'), QLatin1Char('.')); + return stableRelativePath; + } + + + + + bool add(const QUrl& base, const QString &qmldircontentnetwork, const QString& uri_arg, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType, QDeclarativeEngine *engine) { QString qmldircontent = qmldircontentnetwork; + QString uri = uri_arg; QDeclarativeEnginePrivate::ImportedNamespace *s; if (prefix.isEmpty()) { s = &unqualifiedset; @@ -1440,31 +1520,34 @@ public: if (!s) set.insert(prefix,(s=new QDeclarativeEnginePrivate::ImportedNamespace)); } + + + QString url = uri; if (importType == QDeclarativeScriptParser::Import::Library) { url.replace(QLatin1Char('.'), QLatin1Char('/')); bool found = false; QString dir; + // user import paths QStringList paths; - // base.. QString localFileOrQrc = toLocalFileOrQrc(base); QString localFileOrQrcPath = QFileInfo(localFileOrQrc).path(); paths += localFileOrQrcPath; - paths += importPath; + paths += QDeclarativeEnginePrivate::get(engine)->fileImportPath; QString applicationDirPath = QCoreApplication::applicationDirPath(); if (!applicationDirPath.isEmpty()) paths += applicationDirPath; paths += QDeclarativeEnginePrivate::get(engine)->environmentImportPath; -#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) + #if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) QString builtinPath = QLibraryInfo::location(QLibraryInfo::ImportsPath); -#else + #else QString builtinPath; -#endif + #endif if (!builtinPath.isEmpty()) paths += builtinPath; @@ -1478,41 +1561,28 @@ public: found = true; url = QUrl::fromLocalFile(fi.absolutePath()).toString(); - - QFile file(absoluteFilePath); - if (file.open(QFile::ReadOnly)) { - qmldircontent = QString::fromUtf8(file.readAll()); - if (qmlImportTrace()) - qDebug() << "QDeclarativeEngine::add: loaded" << absoluteFilePath; - } - - if (! qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(absoluteFilePath)) { - qmlDirFilesForWhichPluginsHaveBeenLoaded.insert(absoluteFilePath); - - QDeclarativeDirParser qmldirParser; - qmldirParser.setSource(qmldircontent); - qmldirParser.parse(); - - foreach (const QDeclarativeDirParser::Plugin &plugin, qmldirParser.plugins()) { - QDir pluginDir(dir + QDir::separator() + plugin.path); - if (p.startsWith(QLatin1Char(':'))) - pluginDir = QDir(QCoreApplication::applicationDirPath()); - QString resolvedFilePath = - QDeclarativeEnginePrivate::get(engine) - ->resolvePlugin(pluginDir, - plugin.name); - - if (!resolvedFilePath.isEmpty()) { - engine->importExtension(resolvedFilePath, uri); - } - } - } - + uri = resolvedUri(dir, engine); + qmldircontent = importExtension(absoluteFilePath, uri, engine); break; } } } else { + + if (importType == QDeclarativeScriptParser::Import::File && qmldircontent.isEmpty()) { + QUrl importUrl = base.resolved(QUrl(uri + QLatin1String("/qmldir"))); + QString localFileOrQrc = toLocalFileOrQrc(importUrl); + if (!localFileOrQrc.isEmpty()) { + uri = resolvedUri(toLocalFileOrQrc(base.resolved(QUrl(uri))), engine); + qmldircontent = importExtension(localFileOrQrc, + uri, + engine); + + if (uri.endsWith(QLatin1Char('/'))) + uri.chop(1); + } + } + url = base.resolved(QUrl(url)).toString(); } @@ -1797,6 +1867,8 @@ QString QDeclarativeEnginePrivate::resolvePlugin(const QDir &dir, const QString return fileInfo.absoluteFilePath(); } + if (qmlImportTrace()) + qDebug() << "QDeclarativeEngine::resolvePlugin: Could not resolve plugin" << baseName << "in" << dir.absolutePath(); return QString(); } @@ -1890,8 +1962,8 @@ bool QDeclarativeEnginePrivate::addToImport(Imports* imports, const QString &qml { QDeclarativeEngine *engine = QDeclarativeEnginePrivate::get(const_cast(this)); if (qmlImportTrace()) - qDebug() << "QDeclarativeEngine::addToImport(" << imports << uri << prefix << vmaj << '.' << vmin << (importType==QDeclarativeScriptParser::Import::Library? "Library" : "File"); - bool ok = imports->d->add(imports->d->base,qmldircontentnetwork, uri,prefix,vmaj,vmin,importType,fileImportPath, engine); + qDebug().nospace() << "QDeclarativeEngine::addToImport " << imports << " " << uri << " " << vmaj << '.' << vmin << " " << (importType==QDeclarativeScriptParser::Import::Library? "Library" : "File") << " as " << prefix; + bool ok = imports->d->add(imports->d->base,qmldircontentnetwork, uri,prefix,vmaj,vmin,importType, engine); return ok; } diff --git a/src/declarative/util/qdeclarativeview.cpp b/src/declarative/util/qdeclarativeview.cpp index 486553a..59a062a 100644 --- a/src/declarative/util/qdeclarativeview.cpp +++ b/src/declarative/util/qdeclarativeview.cpp @@ -298,6 +298,7 @@ QDeclarativeView::~QDeclarativeView() void QDeclarativeView::setSource(const QUrl& url) { d->source = url; + d->engine.setBaseUrl(url); d->execute(); } -- cgit v0.12 From a88c755e511d3aea726bd0e096621054af18ce01 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Fri, 12 Mar 2010 17:07:12 +1000 Subject: Optimization: Combine QDeclarativeDeclarativeData and QObject allocations --- src/declarative/qml/qdeclarativecompileddata.cpp | 12 +++++++++--- src/declarative/qml/qdeclarativedeclarativedata_p.h | 3 ++- src/declarative/qml/qdeclarativeengine.cpp | 5 ++++- src/declarative/qml/qdeclarativemetatype.cpp | 14 ++++++++++++++ src/declarative/qml/qdeclarativemetatype_p.h | 1 + 5 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/declarative/qml/qdeclarativecompileddata.cpp b/src/declarative/qml/qdeclarativecompileddata.cpp index bdf16a3..30f9510 100644 --- a/src/declarative/qml/qdeclarativecompileddata.cpp +++ b/src/declarative/qml/qdeclarativecompileddata.cpp @@ -203,9 +203,15 @@ void QDeclarativeCompiledData::clear() QObject *QDeclarativeCompiledData::TypeReference::createInstance(QDeclarativeContext *ctxt, const QBitField &bindings) const { if (type) { - QObject *rv = type->create(); - if (rv) - QDeclarativeEngine::setContextForObject(rv, ctxt); + QObject *rv = 0; + void *memory = 0; + + type->create(&rv, &memory, sizeof(QDeclarativeDeclarativeData)); + QDeclarativeDeclarativeData *ddata = new (memory) QDeclarativeDeclarativeData; + ddata->ownMemory = false; + QObjectPrivate::get(rv)->declarativeData = ddata; + QDeclarativeEngine::setContextForObject(rv, ctxt); + return rv; } else { Q_ASSERT(component); diff --git a/src/declarative/qml/qdeclarativedeclarativedata_p.h b/src/declarative/qml/qdeclarativedeclarativedata_p.h index ffce9c9..f962986 100644 --- a/src/declarative/qml/qdeclarativedeclarativedata_p.h +++ b/src/declarative/qml/qdeclarativedeclarativedata_p.h @@ -67,7 +67,7 @@ class Q_AUTOTEST_EXPORT QDeclarativeDeclarativeData : public QDeclarativeData { public: QDeclarativeDeclarativeData(QDeclarativeContext *ctxt = 0) - : indestructible(true), explicitIndestructibleSet(false), context(ctxt), + : ownMemory(true), 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) {} @@ -79,6 +79,7 @@ public: if (!explicitIndestructibleSet) indestructible = false; } + quint32 ownMemory:1; quint32 indestructible:1; quint32 explicitIndestructibleSet:1; quint32 dummy:29; diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 0d8c7e9..2a26626 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -828,7 +828,10 @@ void QDeclarativeDeclarativeData::destroyed(QObject *object) g->objectDestroyed(object); } - delete this; + if (ownMemory) + delete this; + else + this->~QDeclarativeDeclarativeData(); } void QDeclarativeDeclarativeData::parentChanged(QObject *, QObject *parent) diff --git a/src/declarative/qml/qdeclarativemetatype.cpp b/src/declarative/qml/qdeclarativemetatype.cpp index 55c7413..b32e575 100644 --- a/src/declarative/qml/qdeclarativemetatype.cpp +++ b/src/declarative/qml/qdeclarativemetatype.cpp @@ -287,6 +287,20 @@ QObject *QDeclarativeType::create() const return rv; } +void QDeclarativeType::create(QObject **out, void **memory, size_t additionalMemory) const +{ + d->init(); + + QObject *rv = (QObject *)operator new(d->m_allocationSize + additionalMemory); + d->m_newFunc(rv); + + if (rv && !d->m_metaObjects.isEmpty()) + (void *)new QDeclarativeProxyMetaObject(rv, &d->m_metaObjects); + + *out = rv; + *memory = ((char *)rv) + d->m_allocationSize; +} + QDeclarativeCustomParser *QDeclarativeType::customParser() const { return d->m_customParser; diff --git a/src/declarative/qml/qdeclarativemetatype_p.h b/src/declarative/qml/qdeclarativemetatype_p.h index cf8946d..1a36f10 100644 --- a/src/declarative/qml/qdeclarativemetatype_p.h +++ b/src/declarative/qml/qdeclarativemetatype_p.h @@ -111,6 +111,7 @@ public: bool availableInVersion(int vmajor, int vminor) const; QObject *create() const; + void create(QObject **, void **, size_t) const; QDeclarativeCustomParser *customParser() const; -- cgit v0.12 From 4613955f735837d8007f5558db6a07ec5efb9ab5 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Fri, 12 Mar 2010 17:33:06 +1000 Subject: Optimization: Use id notifier for QtScript bindings --- .../qml/qdeclarativecontextscriptclass.cpp | 9 +++++--- src/declarative/qml/qdeclarativeengine_p.h | 5 ++++- src/declarative/qml/qdeclarativeexpression.cpp | 24 +++++++++++++++++++++- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/declarative/qml/qdeclarativecontextscriptclass.cpp b/src/declarative/qml/qdeclarativecontextscriptclass.cpp index 874eeac..0e5066e 100644 --- a/src/declarative/qml/qdeclarativecontextscriptclass.cpp +++ b/src/declarative/qml/qdeclarativecontextscriptclass.cpp @@ -252,6 +252,9 @@ QDeclarativeContextScriptClass::property(Object *object, const Identifier &name) QScriptValue rv; if (lastPropertyIndex < cp->idValueCount) { rv = ep->objectClass->newQObject(cp->idValues[lastPropertyIndex].data()); + + if (ep->captureProperties) + ep->capturedProperties << QDeclarativeEnginePrivate::CapturedProperty(&cp->idValues[lastPropertyIndex].bindings); } else { const QVariant &value = cp->propertyValues.at(lastPropertyIndex); if (value.userType() == qMetaTypeId >()) { @@ -259,10 +262,10 @@ QDeclarativeContextScriptClass::property(Object *object, const Identifier &name) } else { rv = ep->scriptValueFromVariant(value); } - } - if (ep->captureProperties) - ep->capturedProperties << QDeclarativeEnginePrivate::CapturedProperty(bindContext, -1, lastPropertyIndex + cp->notifyIndex); + if (ep->captureProperties) + ep->capturedProperties << QDeclarativeEnginePrivate::CapturedProperty(bindContext, -1, lastPropertyIndex + cp->notifyIndex); + } return Value(scriptEngine, rv); diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h index c73a758..fb8c5e7 100644 --- a/src/declarative/qml/qdeclarativeengine_p.h +++ b/src/declarative/qml/qdeclarativeengine_p.h @@ -144,10 +144,13 @@ public: struct CapturedProperty { CapturedProperty(QObject *o, int c, int n) - : object(o), coreIndex(c), notifyIndex(n) {} + : object(o), coreIndex(c), notifier(0), notifyIndex(n) {} + CapturedProperty(QDeclarativeNotifier *n) + : object(0), coreIndex(-1), notifier(n), notifyIndex(-1) {} QObject *object; int coreIndex; + QDeclarativeNotifier *notifier; int notifyIndex; }; bool captureProperties; diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp index 5ff22f7..f3299ba 100644 --- a/src/declarative/qml/qdeclarativeexpression.cpp +++ b/src/declarative/qml/qdeclarativeexpression.cpp @@ -656,7 +656,29 @@ void QDeclarativeExpressionPrivate::updateGuards(const QPODVectorguardList[jj].isConnected(property.notifier)) + existing = true; + + if (existing) { + // duplicate + guard.disconnect(); + } else { + guard.connect(property.notifier); + } + } + + + } else if (property.notifyIndex != -1) { if (!noChanges && guard.isConnected(property.object, property.notifyIndex)) { // Nothing to do -- cgit v0.12 From 3799ecd97312ab0f5a8dc5e6aef4227cef36813a Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Fri, 12 Mar 2010 18:03:57 +1000 Subject: Simplify QDeclarativeComponent::creationContext() logic --- src/declarative/qml/qdeclarativecomponent.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp index d3608c4..07cdd6d 100644 --- a/src/declarative/qml/qdeclarativecomponent.cpp +++ b/src/declarative/qml/qdeclarativecomponent.cpp @@ -405,11 +405,8 @@ QDeclarativeContext *QDeclarativeComponent::creationContext() const Q_D(const QDeclarativeComponent); if(d->creationContext) return d->creationContext; - QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(this); - if (ddata) - return ddata->context; - else - return 0; + + return qmlContext(this); } /*! -- cgit v0.12 From 06766918436dc6c5de2e605e7ed3421c548c6782 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Fri, 12 Mar 2010 18:09:46 +1000 Subject: Reset QDeclarativeDeclarativeData::outerContext when the context is removed --- src/declarative/qml/qdeclarativecontext.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp index 237cb7e..06637d8 100644 --- a/src/declarative/qml/qdeclarativecontext.cpp +++ b/src/declarative/qml/qdeclarativecontext.cpp @@ -312,6 +312,7 @@ QDeclarativeContext::~QDeclarativeContext() d->contextObjects = d->contextObjects->nextContextObject; co->context = 0; + co->outerContext = 0; co->nextContextObject = 0; co->prevContextObject = 0; } -- cgit v0.12 From 26cd94ef47ffc969dc835e98b58eded14e669964 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Mon, 15 Mar 2010 15:58:35 +1000 Subject: Optimization: Reduce unnecessary QObject allocations --- src/declarative/qml/qdeclarativebinding.cpp | 19 +- src/declarative/qml/qdeclarativebinding_p.h | 5 +- .../qml/qdeclarativecompiledbindings.cpp | 68 +-- .../qml/qdeclarativecompiledbindings_p.h | 2 +- src/declarative/qml/qdeclarativecompileddata.cpp | 20 - src/declarative/qml/qdeclarativecompiler_p.h | 3 +- src/declarative/qml/qdeclarativecomponent.cpp | 61 +-- src/declarative/qml/qdeclarativecomponent.h | 1 - src/declarative/qml/qdeclarativecomponent_p.h | 10 +- src/declarative/qml/qdeclarativecontext.cpp | 504 +++++++++++---------- src/declarative/qml/qdeclarativecontext.h | 4 +- src/declarative/qml/qdeclarativecontext_p.h | 170 +++++-- .../qml/qdeclarativecontextscriptclass.cpp | 62 ++- .../qml/qdeclarativecontextscriptclass_p.h | 9 +- .../qml/qdeclarativedeclarativedata_p.h | 17 +- src/declarative/qml/qdeclarativeengine.cpp | 33 +- src/declarative/qml/qdeclarativeengine_p.h | 6 +- src/declarative/qml/qdeclarativeenginedebug.cpp | 35 +- src/declarative/qml/qdeclarativeexpression.cpp | 68 +-- src/declarative/qml/qdeclarativeexpression.h | 12 +- src/declarative/qml/qdeclarativeexpression_p.h | 15 +- src/declarative/qml/qdeclarativeinfo.cpp | 3 +- .../qml/qdeclarativeobjectscriptclass.cpp | 18 +- .../qml/qdeclarativeobjectscriptclass_p.h | 6 +- src/declarative/qml/qdeclarativeproperty.cpp | 12 +- src/declarative/qml/qdeclarativeproperty_p.h | 6 +- src/declarative/qml/qdeclarativevme.cpp | 80 +++- src/declarative/qml/qdeclarativevme_p.h | 10 +- src/declarative/qml/qdeclarativevmemetaobject.cpp | 25 +- src/declarative/qml/qdeclarativevmemetaobject_p.h | 3 +- .../util/qdeclarativepropertychanges.cpp | 3 +- 31 files changed, 740 insertions(+), 550 deletions(-) diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp index bc78b5b..090bd5b 100644 --- a/src/declarative/qml/qdeclarativebinding.cpp +++ b/src/declarative/qml/qdeclarativebinding.cpp @@ -79,14 +79,25 @@ QDeclarativeBindingPrivate::QDeclarativeBindingPrivate() { } -QDeclarativeBinding::QDeclarativeBinding(void *data, QDeclarativeRefCount *rc, QObject *obj, QDeclarativeContext *ctxt, const QString &url, int lineNumber, QObject *parent) +QDeclarativeBinding::QDeclarativeBinding(void *data, QDeclarativeRefCount *rc, QObject *obj, + QDeclarativeContextData *ctxt, const QString &url, int lineNumber, + QObject *parent) : QDeclarativeExpression(ctxt, data, rc, obj, url, lineNumber, *new QDeclarativeBindingPrivate) { setParent(parent); setNotifyOnValueChanged(true); } -QDeclarativeBinding::QDeclarativeBinding(const QString &str, QObject *obj, QDeclarativeContext *ctxt, QObject *parent) +QDeclarativeBinding::QDeclarativeBinding(const QString &str, QObject *obj, QDeclarativeContext *ctxt, + QObject *parent) +: QDeclarativeExpression(QDeclarativeContextData::get(ctxt), str, obj, *new QDeclarativeBindingPrivate) +{ + setParent(parent); + setNotifyOnValueChanged(true); +} + +QDeclarativeBinding::QDeclarativeBinding(const QString &str, QObject *obj, QDeclarativeContextData *ctxt, + QObject *parent) : QDeclarativeExpression(ctxt, str, obj, *new QDeclarativeBindingPrivate) { setParent(parent); @@ -181,8 +192,8 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags) } if (data->error.isValid()) { - QDeclarativeEnginePrivate *p = (data->context() && data->context()->engine())? - QDeclarativeEnginePrivate::get(data->context()->engine()):0; + QDeclarativeEnginePrivate *p = (data->context() && data->context()->engine)? + QDeclarativeEnginePrivate::get(data->context()->engine):0; if (!data->addError(p)) qWarning().nospace() << qPrintable(this->error().toString()); } else { diff --git a/src/declarative/qml/qdeclarativebinding_p.h b/src/declarative/qml/qdeclarativebinding_p.h index 21e3248..533b6d4 100644 --- a/src/declarative/qml/qdeclarativebinding_p.h +++ b/src/declarative/qml/qdeclarativebinding_p.h @@ -134,8 +134,9 @@ class Q_DECLARATIVE_EXPORT QDeclarativeBinding : public QDeclarativeExpression, Q_OBJECT public: QDeclarativeBinding(const QString &, QObject *, QDeclarativeContext *, QObject *parent=0); - QDeclarativeBinding(void *, QDeclarativeRefCount *, QObject *, QDeclarativeContext *, const QString &, int, - QObject *parent); + QDeclarativeBinding(const QString &, QObject *, QDeclarativeContextData *, QObject *parent=0); + QDeclarativeBinding(void *, QDeclarativeRefCount *, QObject *, QDeclarativeContextData *, + const QString &, int, QObject *parent); ~QDeclarativeBinding(); void setTarget(const QDeclarativeProperty &); diff --git a/src/declarative/qml/qdeclarativecompiledbindings.cpp b/src/declarative/qml/qdeclarativecompiledbindings.cpp index aa549a9..c8bff17 100644 --- a/src/declarative/qml/qdeclarativecompiledbindings.cpp +++ b/src/declarative/qml/qdeclarativecompiledbindings.cpp @@ -142,18 +142,18 @@ public: static int methodCount; void init(); - void run(int instr, QDeclarativeContextPrivate *context, + void run(int instr, QDeclarativeContextData *context, QDeclarativeDelayedError *error, QObject *scope, QObject *output); inline void unsubscribe(int subIndex); - inline void subscribeId(QDeclarativeContextPrivate *p, int idIndex, int subIndex); + inline void subscribeId(QDeclarativeContextData *p, int idIndex, int subIndex); inline void subscribe(QObject *o, int notifyIndex, int subIndex); QDeclarativePropertyCache::Data *findproperty(QObject *obj, - const QScriptDeclarativeClass::Identifier &name, - QDeclarativeEnginePrivate *enginePriv, - QDeclarativePropertyCache::Data &local); + const QScriptDeclarativeClass::Identifier &name, + QDeclarativeEnginePrivate *enginePriv, + QDeclarativePropertyCache::Data &local); bool findproperty(QObject *obj, Register *output, QDeclarativeEnginePrivate *enginePriv, @@ -162,7 +162,7 @@ public: bool isTerminal); void findgeneric(Register *output, // value output int subIdx, // Subscription index in config - QDeclarativeContextPrivate *context, // Context to search in + QDeclarativeContextData *context, // Context to search in const QScriptDeclarativeClass::Identifier &name, bool isTerminal); }; @@ -180,7 +180,7 @@ QDeclarativeCompiledBindingsPrivate::~QDeclarativeCompiledBindingsPrivate() int QDeclarativeCompiledBindingsPrivate::methodCount = -1; -QDeclarativeCompiledBindings::QDeclarativeCompiledBindings(const char *program, QDeclarativeContext *context) +QDeclarativeCompiledBindings::QDeclarativeCompiledBindings(const char *program, QDeclarativeContextData *context) : QObject(*(new QDeclarativeCompiledBindingsPrivate)) { Q_D(QDeclarativeCompiledBindings); @@ -279,17 +279,19 @@ void QDeclarativeCompiledBindingsPrivate::run(Binding *binding) if (!binding->enabled) return; - QDeclarativeContext *context = q->QDeclarativeAbstractExpression::context(); + QDeclarativeContextData *context = q->QDeclarativeAbstractExpression::context(); if (!context) { qWarning("QDeclarativeCompiledBindings: Attempted to evaluate an expression in an invalid context"); return; } - QDeclarativeContextPrivate *cp = QDeclarativeContextPrivate::get(context); + + if (!context->engine) + return; if (binding->updating) { QString name; if (binding->property & 0xFFFF0000) { - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(cp->engine); + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine); QDeclarativeValueType *vt = ep->valueTypes[(binding->property >> 16) & 0xFF]; Q_ASSERT(vt); @@ -298,7 +300,7 @@ void QDeclarativeCompiledBindingsPrivate::run(Binding *binding) name.append(QLatin1String(".")); name.append(QLatin1String(vt->metaObject()->property(binding->property >> 24).name())); } else { - name = binding->target->metaObject()->property(binding->property).name(); + name = QLatin1String(binding->target->metaObject()->property(binding->property).name()); } qmlInfo(binding->target) << QCoreApplication::translate("QDeclarativeCompiledBindings", "Binding loop detected for property \"%1\"").arg(name); return; @@ -306,19 +308,19 @@ void QDeclarativeCompiledBindingsPrivate::run(Binding *binding) binding->updating = true; if (binding->property & 0xFFFF0000) { - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(cp->engine); + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine); QDeclarativeValueType *vt = ep->valueTypes[(binding->property >> 16) & 0xFF]; Q_ASSERT(vt); vt->read(binding->target, binding->property & 0xFFFF); QObject *target = vt; - run(binding->index, cp, binding, binding->scope, target); + run(binding->index, context, binding, binding->scope, target); vt->write(binding->target, binding->property & 0xFFFF, QDeclarativePropertyPrivate::DontRemoveBinding); } else { - run(binding->index, cp, binding, binding->scope, binding->target); + run(binding->index, context, binding, binding->scope, binding->target); } binding->updating = false; } @@ -630,13 +632,11 @@ struct QDeclarativeBindingCompilerPrivate void QDeclarativeCompiledBindingsPrivate::unsubscribe(int subIndex) { - Q_Q(QDeclarativeCompiledBindings); - QDeclarativeCompiledBindingsPrivate::Subscription *sub = (subscriptions + subIndex); sub->disconnect(); } -void QDeclarativeCompiledBindingsPrivate::subscribeId(QDeclarativeContextPrivate *p, int idIndex, int subIndex) +void QDeclarativeCompiledBindingsPrivate::subscribeId(QDeclarativeContextData *p, int idIndex, int subIndex) { Q_Q(QDeclarativeCompiledBindings); @@ -710,7 +710,7 @@ inline static bool toBool(Register *reg, int type, bool *ok = 0) } } -inline static QUrl toUrl(Register *reg, int type, QDeclarativeContextPrivate *context, bool *ok = 0) +inline static QUrl toUrl(Register *reg, int type, QDeclarativeContextData *context, bool *ok = 0) { if (ok) *ok = true; @@ -828,7 +828,7 @@ bool QDeclarativeCompiledBindingsPrivate::findproperty(QObject *obj, Register *o void QDeclarativeCompiledBindingsPrivate::findgeneric(Register *output, int subIdx, - QDeclarativeContextPrivate *context, + QDeclarativeContextData *context, const QScriptDeclarativeClass::Identifier &name, bool isTerminal) { @@ -841,14 +841,17 @@ void QDeclarativeCompiledBindingsPrivate::findgeneric(Register *output, if (contextPropertyIndex != -1) { - if (subIdx != -1) - subscribe(QDeclarativeContextPrivate::get(context), contextPropertyIndex + context->notifyIndex, subIdx); - if (contextPropertyIndex < context->idValueCount) { output->setQObject(context->idValues[contextPropertyIndex]); output->settype(QMetaType::QObjectStar); + + if (subIdx != -1) + subscribeId(context, contextPropertyIndex, subIdx); + } else { - const QVariant &value = context->propertyValues.at(contextPropertyIndex); + QDeclarativeContextPrivate *cp = context->asQDeclarativeContextPrivate(); + const QVariant &value = cp->propertyValues.at(contextPropertyIndex); + if (isTerminal) { new (output->typeDataPtr()) QVariant(value); output->settype(qMetaTypeId()); @@ -859,6 +862,11 @@ void QDeclarativeCompiledBindingsPrivate::findgeneric(Register *output, else { output->settype(QMetaType::QObjectStar); } return; } + + if (subIdx != -1) + subscribe(context->asQDeclarativeContext(), contextPropertyIndex + cp->notifyIndex, subIdx); + + } return; @@ -878,11 +886,7 @@ void QDeclarativeCompiledBindingsPrivate::findgeneric(Register *output, } - if (context->parent) { - context = QDeclarativeContextPrivate::get(context->parent); - } else { - context = 0; - } + context = context->parent; } output->setUndefined(); @@ -901,7 +905,7 @@ void QDeclarativeCompiledBindingsPrivate::init() } static void throwException(int id, QDeclarativeDelayedError *error, - Program *program, QDeclarativeContextPrivate *context, + Program *program, QDeclarativeContextData *context, const QString &description = QString()) { error->error.setUrl(context->url); @@ -1063,8 +1067,8 @@ static void dumpInstruction(const Instr *instr) } void QDeclarativeCompiledBindingsPrivate::run(int instrIndex, - QDeclarativeContextPrivate *context, QDeclarativeDelayedError *error, - QObject *scope, QObject *output) + QDeclarativeContextData *context, QDeclarativeDelayedError *error, + QObject *scope, QObject *output) { error->removeError(); @@ -1398,7 +1402,7 @@ void QDeclarativeCompiledBindingsPrivate::run(int instrIndex, // name is not present in the current context or it would have been // found during the static compile findgeneric(registers + instr->find.reg, instr->find.subscribeIndex, - QDeclarativeContextPrivate::get(context->parent), + context->parent, identifiers[instr->find.name].identifier, instr->common.type == Instr::FindGenericTerminal); break; diff --git a/src/declarative/qml/qdeclarativecompiledbindings_p.h b/src/declarative/qml/qdeclarativecompiledbindings_p.h index 2e24371..84a5df9 100644 --- a/src/declarative/qml/qdeclarativecompiledbindings_p.h +++ b/src/declarative/qml/qdeclarativecompiledbindings_p.h @@ -95,7 +95,7 @@ class QDeclarativeCompiledBindingsPrivate; class QDeclarativeCompiledBindings : public QObject, public QDeclarativeAbstractExpression, public QDeclarativeRefCount { public: - QDeclarativeCompiledBindings(const char *program, QDeclarativeContext *context); + QDeclarativeCompiledBindings(const char *program, QDeclarativeContextData *context); virtual ~QDeclarativeCompiledBindings(); QDeclarativeAbstractBinding *configBinding(int index, QObject *target, QObject *scope, int property); diff --git a/src/declarative/qml/qdeclarativecompileddata.cpp b/src/declarative/qml/qdeclarativecompileddata.cpp index 30f9510..dfbf453 100644 --- a/src/declarative/qml/qdeclarativecompileddata.cpp +++ b/src/declarative/qml/qdeclarativecompileddata.cpp @@ -199,26 +199,6 @@ void QDeclarativeCompiledData::clear() cachedPrograms[ii] = 0; } - -QObject *QDeclarativeCompiledData::TypeReference::createInstance(QDeclarativeContext *ctxt, const QBitField &bindings) const -{ - if (type) { - QObject *rv = 0; - void *memory = 0; - - type->create(&rv, &memory, sizeof(QDeclarativeDeclarativeData)); - QDeclarativeDeclarativeData *ddata = new (memory) QDeclarativeDeclarativeData; - ddata->ownMemory = false; - QObjectPrivate::get(rv)->declarativeData = ddata; - QDeclarativeEngine::setContextForObject(rv, ctxt); - - return rv; - } else { - Q_ASSERT(component); - return QDeclarativeComponentPrivate::get(component)->create(ctxt, bindings); - } -} - const QMetaObject *QDeclarativeCompiledData::TypeReference::metaObject() const { if (type) { diff --git a/src/declarative/qml/qdeclarativecompiler_p.h b/src/declarative/qml/qdeclarativecompiler_p.h index cca42e2..05b556e 100644 --- a/src/declarative/qml/qdeclarativecompiler_p.h +++ b/src/declarative/qml/qdeclarativecompiler_p.h @@ -72,6 +72,7 @@ QT_BEGIN_NAMESPACE class QDeclarativeEngine; class QDeclarativeComponent; class QDeclarativeContext; +class QDeclarativeContextData; class QScriptProgram; class Q_AUTOTEST_EXPORT QDeclarativeCompiledData : public QDeclarativeRefCount, public QDeclarativeCleanup @@ -95,7 +96,7 @@ public: QDeclarativeComponent *component; QDeclarativeRefCount *ref; - QObject *createInstance(QDeclarativeContext *, const QBitField &) const; + QObject *createInstance(QDeclarativeContextData *, const QBitField &) const; const QMetaObject *metaObject() const; }; QList types; diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp index 07cdd6d..ffbd0fa 100644 --- a/src/declarative/qml/qdeclarativecomponent.cpp +++ b/src/declarative/qml/qdeclarativecomponent.cpp @@ -404,23 +404,12 @@ QDeclarativeContext *QDeclarativeComponent::creationContext() const { Q_D(const QDeclarativeComponent); if(d->creationContext) - return d->creationContext; + return d->creationContext->asQDeclarativeContext(); return qmlContext(this); } /*! - \internal - Sets the QDeclarativeContext the component was created in. This is only - desirable for components created in QML script. -*/ -void QDeclarativeComponent::setCreationContext(QDeclarativeContext* c) -{ - Q_D(QDeclarativeComponent); - d->creationContext = c; -} - -/*! Load the QDeclarativeComponent from the provided \a url. */ void QDeclarativeComponent::loadUrl(const QUrl &url) @@ -547,16 +536,11 @@ QObject *QDeclarativeComponent::create(QDeclarativeContext *context) return rv; } -QObject *QDeclarativeComponentPrivate::create(QDeclarativeContext *context, - const QBitField &bindings) +QObject *QDeclarativeComponentPrivate::create(QDeclarativeContextData *context, + const QBitField &bindings) { if (!context) - context = engine->rootContext(); - - if (context->engine() != engine) { - qWarning("QDeclarativeComponent::create(): Must create component in context from the same QDeclarativeEngine"); - return 0; - } + context = QDeclarativeContextData::get(engine->rootContext()); QObject *rv = beginCreate(context, bindings); completeCreate(); @@ -589,7 +573,7 @@ QObject *QDeclarativeComponentPrivate::create(QDeclarativeContext *context, QObject *QDeclarativeComponent::beginCreate(QDeclarativeContext *context) { Q_D(QDeclarativeComponent); - QObject *rv = d->beginCreate(context, QBitField()); + QObject *rv = d->beginCreate(context?QDeclarativeContextData::get(context):0, QBitField()); if (rv) { QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(rv); Q_ASSERT(ddata); @@ -599,7 +583,7 @@ QObject *QDeclarativeComponent::beginCreate(QDeclarativeContext *context) } QObject * -QDeclarativeComponentPrivate::beginCreate(QDeclarativeContext *context, const QBitField &bindings) +QDeclarativeComponentPrivate::beginCreate(QDeclarativeContextData *context, const QBitField &bindings) { Q_Q(QDeclarativeComponent); if (!context) { @@ -607,7 +591,7 @@ QDeclarativeComponentPrivate::beginCreate(QDeclarativeContext *context, const QB return 0; } - if (context->engine() != engine) { + if (context->engine != engine) { qWarning("QDeclarativeComponent::beginCreate(): Must create component in context from the same QDeclarativeEngine"); return 0; } @@ -624,29 +608,26 @@ QDeclarativeComponentPrivate::beginCreate(QDeclarativeContext *context, const QB QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); - QDeclarativeContextPrivate *contextPriv = - static_cast(QObjectPrivate::get(context)); - QDeclarativeContext *ctxt = new QDeclarativeContext(context, 0, true); - static_cast(ctxt->d_func())->url = cc->url; - static_cast(ctxt->d_func())->imports = cc->importCache; + QDeclarativeContextData *ctxt = new QDeclarativeContextData; + ctxt->isInternal = true; + ctxt->url = cc->url; + ctxt->imports = cc->importCache; cc->importCache->addref(); + ctxt->setParent(context); QObject *rv = begin(ctxt, ep, cc, start, count, &state, bindings); - if (rv) { - QDeclarative_setParent_noEvent(ctxt, rv); - } else { - delete ctxt; - } + if (!rv) ctxt->destroy(); + + if (rv && !context->isInternal && ep->isDebugging) + context->asQDeclarativeContextPrivate()->instances.append(rv); - if (rv && !contextPriv->isInternal && ep->isDebugging) - contextPriv->instances.append(rv); return rv; } -QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContext *ctxt, QDeclarativeEnginePrivate *enginePriv, - QDeclarativeCompiledData *component, int start, int count, - ConstructionState *state, const QBitField &bindings) +QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContextData *ctxt, QDeclarativeEnginePrivate *enginePriv, + QDeclarativeCompiledData *component, int start, int count, + ConstructionState *state, const QBitField &bindings) { bool isRoot = !enginePriv->inBeginCreate; enginePriv->inBeginCreate = true; @@ -676,8 +657,8 @@ QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContext *ctxt, QDeclar return rv; } -void QDeclarativeComponentPrivate::beginDeferred(QDeclarativeContext *, QDeclarativeEnginePrivate *enginePriv, - QObject *object, ConstructionState *state) +void QDeclarativeComponentPrivate::beginDeferred(QDeclarativeContextData *, QDeclarativeEnginePrivate *enginePriv, + QObject *object, ConstructionState *state) { bool isRoot = !enginePriv->inBeginCreate; enginePriv->inBeginCreate = true; diff --git a/src/declarative/qml/qdeclarativecomponent.h b/src/declarative/qml/qdeclarativecomponent.h index aec0480..13a243e 100644 --- a/src/declarative/qml/qdeclarativecomponent.h +++ b/src/declarative/qml/qdeclarativecomponent.h @@ -104,7 +104,6 @@ public: void loadUrl(const QUrl &url); void setData(const QByteArray &, const QUrl &baseUrl); - void setCreationContext(QDeclarativeContext*); QDeclarativeContext *creationContext() const; static QDeclarativeComponentAttached *qmlAttachedProperties(QObject *); diff --git a/src/declarative/qml/qdeclarativecomponent_p.h b/src/declarative/qml/qdeclarativecomponent_p.h index 3155813..649fce5 100644 --- a/src/declarative/qml/qdeclarativecomponent_p.h +++ b/src/declarative/qml/qdeclarativecomponent_p.h @@ -81,8 +81,8 @@ class QDeclarativeComponentPrivate : public QObjectPrivate public: QDeclarativeComponentPrivate() : typeData(0), progress(0.), start(-1), count(-1), cc(0), engine(0), creationContext(0) {} - QObject *create(QDeclarativeContext *context, const QBitField &); - QObject *beginCreate(QDeclarativeContext *, const QBitField &); + QObject *create(QDeclarativeContextData *, const QBitField &); + QObject *beginCreate(QDeclarativeContextData *, const QBitField &); void completeCreate(); QDeclarativeCompositeTypeData *typeData; @@ -108,15 +108,15 @@ public: }; ConstructionState state; - static QObject *begin(QDeclarativeContext *ctxt, QDeclarativeEnginePrivate *enginePriv, + static QObject *begin(QDeclarativeContextData *ctxt, QDeclarativeEnginePrivate *enginePriv, QDeclarativeCompiledData *component, int start, int count, ConstructionState *state, const QBitField &bindings = QBitField()); - static void beginDeferred(QDeclarativeContext *ctxt, QDeclarativeEnginePrivate *enginePriv, + static void beginDeferred(QDeclarativeContextData *ctxt, QDeclarativeEnginePrivate *enginePriv, QObject *object, ConstructionState *state); static void complete(QDeclarativeEnginePrivate *enginePriv, ConstructionState *state); QDeclarativeEngine *engine; - QDeclarativeContext *creationContext; + QDeclarativeContextData *creationContext; void clear(); diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp index 06637d8..f1c961d 100644 --- a/src/declarative/qml/qdeclarativecontext.cpp +++ b/src/declarative/qml/qdeclarativecontext.cpp @@ -58,85 +58,13 @@ QT_BEGIN_NAMESPACE QDeclarativeContextPrivate::QDeclarativeContextPrivate() -: parent(0), engine(0), isInternal(false), propertyNames(0), - notifyIndex(-1), contextObject(0), imports(0), childContexts(0), - nextChild(0), prevChild(0), expressions(0), contextObjects(0), - idValues(0), idValueCount(0), optimizedBindings(0) +: data(0), notifyIndex(-1) { } -void QDeclarativeContextPrivate::addScript(const QDeclarativeParser::Object::ScriptBlock &script, - QObject *scopeObject) -{ - Q_Q(QDeclarativeContext); - - if (!engine) - return; - - QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine); - QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); - - QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine); - - scriptContext->pushScope(enginePriv->contextClass->newContext(q, scopeObject)); - scriptContext->pushScope(enginePriv->globalClass->globalObject()); - - QScriptValue scope = scriptEngine->newObject(); - scriptContext->setActivationObject(scope); - scriptContext->pushScope(scope); - - for (int ii = 0; ii < script.codes.count(); ++ii) { - scriptEngine->evaluate(script.codes.at(ii), script.files.at(ii), script.lineNumbers.at(ii)); - - if (scriptEngine->hasUncaughtException()) { - QDeclarativeError error; - QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error); - qWarning().nospace() << qPrintable(error.toString()); - } - } - - scriptEngine->popContext(); - - scripts.append(scope); -} - -void QDeclarativeContextPrivate::destroyed(ContextGuard *guard) -{ - Q_Q(QDeclarativeContext); - - // process of being deleted (which is *probably* why obj has been destroyed - // anyway), as we're about to get deleted which will invalidate all the - // expressions that could depend on us - QObject *parent = q->parent(); - if (parent && QObjectPrivate::get(parent)->wasDeleted) - return; - - guard->bindings.notify(); - - for (int ii = 0; ii < idValueCount; ++ii) { - if (&idValues[ii] == guard) { - QMetaObject::activate(q, ii + notifyIndex, 0); - return; - } - } -} - -void QDeclarativeContextPrivate::init() -{ - Q_Q(QDeclarativeContext); - - if (parent) { - QDeclarativeContextPrivate *ppriv = parent->d_func(); - nextChild = ppriv->childContexts; - if (nextChild) nextChild->d_func()->prevChild = &nextChild; - prevChild = &ppriv->childContexts; - ppriv->childContexts = q; - } -} - /*! \class QDeclarativeContext - \since 4.7 + \since 4.7 \brief The QDeclarativeContext class defines a context within a QML engine. \mainclass @@ -223,8 +151,9 @@ QDeclarativeContext::QDeclarativeContext(QDeclarativeEngine *e, bool) : QObject(*(new QDeclarativeContextPrivate)) { Q_D(QDeclarativeContext); - d->engine = e; - d->init(); + d->data = new QDeclarativeContextData(this); + + d->data->engine = e; } /*! @@ -235,10 +164,9 @@ QDeclarativeContext::QDeclarativeContext(QDeclarativeEngine *engine, QObject *pa : QObject(*(new QDeclarativeContextPrivate), parent) { Q_D(QDeclarativeContext); - QDeclarativeContext *parentContext = engine?engine->rootContext():0; - d->parent = parentContext; - d->engine = parentContext->engine(); - d->init(); + d->data = new QDeclarativeContextData(this); + + d->data->setParent(engine?QDeclarativeContextData::get(engine->rootContext()):0); } /*! @@ -249,22 +177,19 @@ QDeclarativeContext::QDeclarativeContext(QDeclarativeContext *parentContext, QOb : QObject(*(new QDeclarativeContextPrivate), parent) { Q_D(QDeclarativeContext); - d->parent = parentContext; - d->engine = parentContext->engine(); - d->init(); + d->data = new QDeclarativeContextData(this); + + d->data->setParent(parentContext?QDeclarativeContextData::get(parentContext):0); } /*! \internal */ -QDeclarativeContext::QDeclarativeContext(QDeclarativeContext *parentContext, QObject *parent, bool) -: QObject(*(new QDeclarativeContextPrivate), parent) +QDeclarativeContext::QDeclarativeContext(QDeclarativeContextData *data) +: QObject(*(new QDeclarativeContextPrivate), 0) { Q_D(QDeclarativeContext); - d->parent = parentContext; - d->engine = parentContext->engine(); - d->isInternal = true; - d->init(); + d->data = data; } /*! @@ -278,90 +203,8 @@ QDeclarativeContext::~QDeclarativeContext() { Q_D(QDeclarativeContext); - if (d->prevChild) { - *d->prevChild = d->nextChild; - if (d->nextChild) d->nextChild->d_func()->prevChild = d->prevChild; - d->nextChild = 0; - d->prevChild = 0; - } - - QDeclarativeContext *child = d->childContexts; - while (child) { - QDeclarativeContextPrivate *childpriv = child->d_func(); - childpriv->invalidateEngines(); - childpriv->parent = 0; - child = childpriv->nextChild; - childpriv->nextChild = 0; - childpriv->prevChild = 0; - } - d->childContexts = 0; - - QDeclarativeAbstractExpression *expression = d->expressions; - while (expression) { - QDeclarativeAbstractExpression *nextExpression = expression->m_nextExpression; - - expression->m_context = 0; - expression->m_prevExpression = 0; - expression->m_nextExpression = 0; - - expression = nextExpression; - } - - while (d->contextObjects) { - QDeclarativeDeclarativeData *co = d->contextObjects; - d->contextObjects = d->contextObjects->nextContextObject; - - co->context = 0; - co->outerContext = 0; - co->nextContextObject = 0; - co->prevContextObject = 0; - } - - if (d->propertyNames) - d->propertyNames->release(); - - if (d->imports) - d->imports->release(); - - if (d->optimizedBindings) - d->optimizedBindings->release(); - - delete [] d->idValues; -} - -void QDeclarativeContextPrivate::invalidateEngines() -{ - if (!engine) - return; - engine = 0; - - QDeclarativeContext *child = childContexts; - while (child) { - QDeclarativeContextPrivate *childpriv = child->d_func(); - childpriv->invalidateEngines(); - child = childpriv->nextChild; - } -} - -/* -Refreshes all expressions that could possibly depend on this context. -Refreshing flushes all context-tree dependent caches in the expressions, and should occur every -time the context tree *structure* (not values) changes. -*/ -void QDeclarativeContextPrivate::refreshExpressions() -{ - QDeclarativeContext *child = childContexts; - while (child) { - QDeclarativeContextPrivate *childpriv = child->d_func(); - childpriv->refreshExpressions(); - child = childpriv->nextChild; - } - - QDeclarativeAbstractExpression *expression = expressions; - while (expression) { - expression->refresh(); - expression = expression->m_nextExpression; - } + if (!d->data->isInternal) + d->data->destroy(); } /*! @@ -371,7 +214,7 @@ void QDeclarativeContextPrivate::refreshExpressions() QDeclarativeEngine *QDeclarativeContext::engine() const { Q_D(const QDeclarativeContext); - return d->engine; + return d->data->engine; } /*! @@ -381,7 +224,7 @@ QDeclarativeEngine *QDeclarativeContext::engine() const QDeclarativeContext *QDeclarativeContext::parentContext() const { Q_D(const QDeclarativeContext); - return d->parent; + return d->data->parent?d->data->parent->asQDeclarativeContext():0; } /*! @@ -390,7 +233,7 @@ QDeclarativeContext *QDeclarativeContext::parentContext() const QObject *QDeclarativeContext::contextObject() const { Q_D(const QDeclarativeContext); - return d->contextObject; + return d->data->contextObject; } /*! @@ -399,7 +242,7 @@ QObject *QDeclarativeContext::contextObject() const void QDeclarativeContext::setContextObject(QObject *object) { Q_D(QDeclarativeContext); - d->contextObject = object; + d->data->contextObject = object; } /*! @@ -411,50 +254,31 @@ void QDeclarativeContext::setContextProperty(const QString &name, const QVariant if (d->notifyIndex == -1) d->notifyIndex = this->metaObject()->methodCount(); - if (d->engine) { + QDeclarativeContextData *data = d->data; + + if (data->engine) { bool ok; - QObject *o = QDeclarativeEnginePrivate::get(d->engine)->toQObject(value, &ok); + QObject *o = QDeclarativeEnginePrivate::get(data->engine)->toQObject(value, &ok); if (ok) { setContextProperty(name, o); return; } } - if (!d->propertyNames) d->propertyNames = new QDeclarativeIntegerCache(d->engine); + if (!data->propertyNames) data->propertyNames = new QDeclarativeIntegerCache(data->engine); - int idx = d->propertyNames->value(name); + int idx = data->propertyNames->value(name); if (idx == -1) { - d->propertyNames->add(name, d->idValueCount + d->propertyValues.count()); + data->propertyNames->add(name, data->idValueCount + d->propertyValues.count()); d->propertyValues.append(value); - d->refreshExpressions(); + data->refreshExpressions(); } else { d->propertyValues[idx] = value; QMetaObject::activate(this, idx + d->notifyIndex, 0); } } -void QDeclarativeContextPrivate::setIdProperty(int idx, QObject *obj) -{ - if (notifyIndex == -1) { - Q_Q(QDeclarativeContext); - notifyIndex = q->metaObject()->methodCount(); - } - - idValues[idx].priv = this; - idValues[idx] = obj; -} - -void QDeclarativeContextPrivate::setIdPropertyData(QDeclarativeIntegerCache *data) -{ - Q_ASSERT(!propertyNames); - propertyNames = data; - propertyNames->addref(); - - idValueCount = data->count(); - idValues = new ContextGuard[idValueCount]; -} - /*! Set the \a value of the \a name property on this context. @@ -466,14 +290,16 @@ void QDeclarativeContext::setContextProperty(const QString &name, QObject *value if (d->notifyIndex == -1) d->notifyIndex = this->metaObject()->methodCount(); - if (!d->propertyNames) d->propertyNames = new QDeclarativeIntegerCache(d->engine); - int idx = d->propertyNames->value(name); + QDeclarativeContextData *data = d->data; + + if (!data->propertyNames) data->propertyNames = new QDeclarativeIntegerCache(data->engine); + int idx = data->propertyNames->value(name); if (idx == -1) { - d->propertyNames->add(name, d->idValueCount + d->propertyValues.count()); + data->propertyNames->add(name, data->idValueCount + d->propertyValues.count()); d->propertyValues.append(QVariant::fromValue(value)); - d->refreshExpressions(); + data->refreshExpressions(); } else { d->propertyValues[idx] = QVariant::fromValue(value); QMetaObject::activate(this, idx + d->notifyIndex, 0); @@ -489,15 +315,19 @@ QVariant QDeclarativeContext::contextProperty(const QString &name) const Q_D(const QDeclarativeContext); QVariant value; int idx = -1; - if (d->propertyNames) - idx = d->propertyNames->value(name); + + QDeclarativeContextData *data = d->data; + + if (data->propertyNames) + idx = data->propertyNames->value(name); if (idx == -1) { QByteArray utf8Name = name.toUtf8(); - if (d->contextObject) { - QObject *obj = d->contextObject; + if (data->contextObject) { + QObject *obj = data->contextObject; QDeclarativePropertyCache::Data local; - QDeclarativePropertyCache::Data *property = QDeclarativePropertyCache::property(d->engine, obj, name, local); + QDeclarativePropertyCache::Data *property = + QDeclarativePropertyCache::property(data->engine, obj, name, local); if (property) value = obj->metaObject()->property(property->coreIndex).read(obj); } @@ -505,7 +335,7 @@ QVariant QDeclarativeContext::contextProperty(const QString &name) const value = parentContext()->contextProperty(name); } else { if (idx >= d->propertyValues.count()) - value = QVariant::fromValue(d->idValues[idx - d->propertyValues.count()].data()); + value = QVariant::fromValue(data->idValues[idx - d->propertyValues.count()].data()); else value = d->propertyValues[idx]; } @@ -522,20 +352,26 @@ QVariant QDeclarativeContext::contextProperty(const QString &name) const QUrl QDeclarativeContext::resolvedUrl(const QUrl &src) { Q_D(QDeclarativeContext); - QDeclarativeContext *ctxt = this; + return d->data->resolvedUrl(src); +} + +QUrl QDeclarativeContextData::resolvedUrl(const QUrl &src) +{ + QDeclarativeContextData *ctxt = this; + if (src.isRelative() && !src.isEmpty()) { if (ctxt) { while(ctxt) { - if(ctxt->d_func()->url.isValid()) + if(ctxt->url.isValid()) break; else - ctxt = ctxt->parentContext(); + ctxt = ctxt->parent; } if (ctxt) - return ctxt->d_func()->url.resolved(src); - else if (d->engine) - return d->engine->baseUrl().resolved(src); + return ctxt->url.resolved(src); + else if (engine) + return engine->baseUrl().resolved(src); } return QUrl(); } else { @@ -543,6 +379,7 @@ QUrl QDeclarativeContext::resolvedUrl(const QUrl &src) } } + /*! Explicitly sets the url resolvedUrl() will use for relative references to \a baseUrl. @@ -553,7 +390,9 @@ QUrl QDeclarativeContext::resolvedUrl(const QUrl &src) */ void QDeclarativeContext::setBaseUrl(const QUrl &baseUrl) { - d_func()->url = baseUrl; + Q_D(QDeclarativeContext); + + d->data->url = baseUrl; } /*! @@ -562,12 +401,13 @@ void QDeclarativeContext::setBaseUrl(const QUrl &baseUrl) */ QUrl QDeclarativeContext::baseUrl() const { - const QDeclarativeContext* p = this; - while (p && p->d_func()->url.isEmpty()) { - p = p->parentContext(); - } - if (p) - return p->d_func()->url; + Q_D(const QDeclarativeContext); + const QDeclarativeContextData* data = d->data; + while (data && data->url.isEmpty()) + data = data->parent; + + if (data) + return data->url; else return QUrl(); } @@ -598,4 +438,214 @@ QObject *QDeclarativeContextPrivate::context_at(QDeclarativeListPropertydestroy(); + + if (prevChild) { + *prevChild = nextChild; + if (nextChild) nextChild->prevChild = prevChild; + nextChild = 0; + prevChild = 0; + } + + QDeclarativeContextData *child = childContexts; + while (child) { + QDeclarativeContextData *next = child->nextChild; + + child->invalidateEngines(); + child->parent = 0; + child->nextChild = 0; + child->prevChild = 0; + + child = next; + } + childContexts = 0; + + QDeclarativeAbstractExpression *expression = expressions; + while (expression) { + QDeclarativeAbstractExpression *nextExpression = expression->m_nextExpression; + + expression->m_context = 0; + expression->m_prevExpression = 0; + expression->m_nextExpression = 0; + + expression = nextExpression; + } + expressions = 0; + + while (contextObjects) { + QDeclarativeDeclarativeData *co = contextObjects; + contextObjects = contextObjects->nextContextObject; + + co->context = 0; + co->outerContext = 0; + co->nextContextObject = 0; + co->prevContextObject = 0; + } + + QDeclarativeGuardedContextData *contextGuard = contextGuards; + while (contextGuard) { + QDeclarativeGuardedContextData *next = contextGuard->m_next; + contextGuard->m_next = 0; + contextGuard->m_prev = 0; + contextGuard->m_contextData = 0; + contextGuard = next; + } + contextGuards = 0; + + if (propertyNames) + propertyNames->release(); + + if (imports) + imports->release(); + + if (optimizedBindings) + optimizedBindings->release(); + + delete [] idValues; + + if (isInternal) + delete publicContext; + + delete this; +} + +void QDeclarativeContextData::setParent(QDeclarativeContextData *p) +{ + if (p) { + parent = p; + engine = p->engine; + nextChild = p->childContexts; + if (nextChild) nextChild->prevChild = &nextChild; + prevChild = &p->childContexts; + p->childContexts = this; + } +} + +void QDeclarativeContextData::invalidateEngines() +{ + if (!engine) + return; + engine = 0; + + QDeclarativeContextData *child = childContexts; + while (child) { + child->invalidateEngines(); + child = child->nextChild; + } +} + +/* +Refreshes all expressions that could possibly depend on this context. Refreshing flushes all +context-tree dependent caches in the expressions, and should occur every time the context tree + *structure* (not values) changes. +*/ +void QDeclarativeContextData::refreshExpressions() +{ + QDeclarativeContextData *child = childContexts; + while (child) { + child->refreshExpressions(); + child = child->nextChild; + } + + QDeclarativeAbstractExpression *expression = expressions; + while (expression) { + expression->refresh(); + expression = expression->m_nextExpression; + } +} + +void QDeclarativeContextData::addObject(QObject *o) +{ + QDeclarativeDeclarativeData *data = QDeclarativeDeclarativeData::get(o, true); + + Q_ASSERT(data->context == 0); + + data->context = this; + data->outerContext = this; + + data->nextContextObject = contextObjects; + if (data->nextContextObject) + data->nextContextObject->prevContextObject = &data->nextContextObject; + data->prevContextObject = &contextObjects; + contextObjects = data; +} + +void QDeclarativeContextData::addScript(const QDeclarativeParser::Object::ScriptBlock &script, + QObject *scopeObject) +{ + if (!engine) + return; + + QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine); + QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); + + QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine); + + scriptContext->pushScope(enginePriv->contextClass->newContext(this, scopeObject)); + scriptContext->pushScope(enginePriv->globalClass->globalObject()); + + QScriptValue scope = scriptEngine->newObject(); + scriptContext->setActivationObject(scope); + scriptContext->pushScope(scope); + + for (int ii = 0; ii < script.codes.count(); ++ii) { + scriptEngine->evaluate(script.codes.at(ii), script.files.at(ii), script.lineNumbers.at(ii)); + + if (scriptEngine->hasUncaughtException()) { + QDeclarativeError error; + QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error); + qWarning().nospace() << qPrintable(error.toString()); + } + } + + scriptEngine->popContext(); + + scripts.append(scope); +} + +void QDeclarativeContextData::setIdProperty(int idx, QObject *obj) +{ + idValues[idx] = obj; +} + +void QDeclarativeContextData::setIdPropertyData(QDeclarativeIntegerCache *data) +{ + Q_ASSERT(!propertyNames); + propertyNames = data; + propertyNames->addref(); + + idValueCount = data->count(); + idValues = new ContextGuard[idValueCount]; +} + +QDeclarativeContext *QDeclarativeContextData::asQDeclarativeContext() +{ + if (!publicContext) + publicContext = new QDeclarativeContext(this); + return publicContext; +} + +QDeclarativeContextPrivate *QDeclarativeContextData::asQDeclarativeContextPrivate() +{ + return QDeclarativeContextPrivate::get(asQDeclarativeContext()); +} + QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativecontext.h b/src/declarative/qml/qdeclarativecontext.h index 3ad9863..a349628 100644 --- a/src/declarative/qml/qdeclarativecontext.h +++ b/src/declarative/qml/qdeclarativecontext.h @@ -58,6 +58,7 @@ class QDeclarativeEngine; class QDeclarativeRefCount; class QDeclarativeContextPrivate; class QDeclarativeCompositeTypeData; +class QDeclarativeContextData; class Q_DECLARATIVE_EXPORT QDeclarativeContext : public QObject { @@ -96,7 +97,8 @@ private: friend class QDeclarativeComponentPrivate; friend class QDeclarativeScriptPrivate; friend class QDeclarativeBoundSignalProxy; - QDeclarativeContext(QDeclarativeContext *parent, QObject *objParent, bool); + friend class QDeclarativeContextData; + QDeclarativeContext(QDeclarativeContextData *); QDeclarativeContext(QDeclarativeEngine *, bool); }; QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h index a1056b1..59b848f 100644 --- a/src/declarative/qml/qdeclarativecontext_p.h +++ b/src/declarative/qml/qdeclarativecontext_p.h @@ -56,10 +56,11 @@ #include "qdeclarativecontext.h" #include "qdeclarativedeclarativedata_p.h" -#include "qdeclarativeengine_p.h" #include "qdeclarativeintegercache_p.h" #include "qdeclarativetypenamecache_p.h" #include "qdeclarativenotifier_p.h" +#include "qdeclarativelist.h" +#include "qdeclarativeparser_p.h" #include #include @@ -78,6 +79,7 @@ class QDeclarativeExpressionPrivate; class QDeclarativeAbstractExpression; class QDeclarativeBinding_Id; class QDeclarativeCompiledBindings; +class QDeclarativeContextData; class Q_DECLARATIVE_EXPORT QDeclarativeContextPrivate : public QObjectPrivate { @@ -85,82 +87,178 @@ class Q_DECLARATIVE_EXPORT QDeclarativeContextPrivate : public QObjectPrivate public: QDeclarativeContextPrivate(); - QDeclarativeContext *parent; + QDeclarativeContextData *data; + + QList propertyValues; + int notifyIndex; + + static QDeclarativeContextPrivate *get(QDeclarativeContext *context) { + return static_cast(QObjectPrivate::get(context)); + } + static QDeclarativeContext *get(QDeclarativeContextPrivate *context) { + return static_cast(context->q_func()); + } + + // Only used for debugging + QList > instances; + + static int context_count(QDeclarativeListProperty *); + static QObject *context_at(QDeclarativeListProperty *, int); +}; + +class QDeclarativeGuardedContextData; +class QDeclarativeContextData +{ +public: + QDeclarativeContextData(); + QDeclarativeContextData(QDeclarativeContext *); + void destroy(); + + // My parent context and engine + QDeclarativeContextData *parent; QDeclarativeEngine *engine; + void setParent(QDeclarativeContextData *); + void invalidateEngines(); + void refreshExpressions(); + + void addObject(QObject *); + + QUrl resolvedUrl(const QUrl &); + + // My containing QDeclarativeContext. If isInternal is true this owns publicContext. + // If internal is false publicContext owns this. + QDeclarativeContext *asQDeclarativeContext(); + QDeclarativeContextPrivate *asQDeclarativeContextPrivate(); bool isInternal; + QDeclarativeContext *publicContext; + // Property name cache QDeclarativeIntegerCache *propertyNames; - QList propertyValues; - int notifyIndex; + // Context object QObject *contextObject; + // Any script blocks that exist on this context QList scripts; - void addScript(const QDeclarativeParser::Object::ScriptBlock &, QObject *); + void addScript(const QDeclarativeParser::Object::ScriptBlock &script, QObject *scopeObject); + // Context base url QUrl url; + // List of imports that apply to this context QDeclarativeTypeNameCache *imports; - void init(); - - void invalidateEngines(); - void refreshExpressions(); - - QDeclarativeContext *childContexts; + // My children + QDeclarativeContextData *childContexts; - QDeclarativeContext *nextChild; - QDeclarativeContext **prevChild; + // My peers in parent's childContexts list + QDeclarativeContextData *nextChild; + QDeclarativeContextData **prevChild; + // Expressions that use this context QDeclarativeAbstractExpression *expressions; + // Doubly-linked list of objects that are owned by this context QDeclarativeDeclarativeData *contextObjects; + // Doubly-linked list of context guards (XXX merge with contextObjects) + QDeclarativeGuardedContextData *contextGuards; + + // id guards struct ContextGuard : public QDeclarativeGuard { - inline ContextGuard(); - inline ContextGuard &operator=(QObject *obj); - inline virtual void objectDestroyed(QObject *); - - QDeclarativeContextPrivate *priv; + inline ContextGuard &operator=(QObject *obj) + { QDeclarativeGuard::operator=(obj); return *this; } + virtual void objectDestroyed(QObject *) { bindings.notify(); } QDeclarativeNotifier bindings; }; ContextGuard *idValues; int idValueCount; void setIdProperty(int, QObject *); void setIdPropertyData(QDeclarativeIntegerCache *); - void destroyed(ContextGuard *); - static QDeclarativeContextPrivate *get(QDeclarativeContext *context) { - return static_cast(QObjectPrivate::get(context)); - } - static QDeclarativeContext *get(QDeclarativeContextPrivate *context) { - return static_cast(context->q_func()); + // Optimized binding pointer + QDeclarativeCompiledBindings *optimizedBindings; + + // Linked contexts. this owns linkedContext. + QDeclarativeContextData *linkedContext; + + static QDeclarativeContextData *get(QDeclarativeContext *context) { + return QDeclarativeContextPrivate::get(context)->data; } - QDeclarativeCompiledBindings *optimizedBindings; +private: + ~QDeclarativeContextData() {} +}; - // Only used for debugging - QList > instances; +class QDeclarativeGuardedContextData +{ +public: + inline QDeclarativeGuardedContextData(); + inline QDeclarativeGuardedContextData(QDeclarativeContextData *); + inline ~QDeclarativeGuardedContextData(); - static int context_count(QDeclarativeListProperty *); - static QObject *context_at(QDeclarativeListProperty *, int); + inline void setContextData(QDeclarativeContextData *); + + inline QDeclarativeContextData *contextData(); + + inline operator QDeclarativeContextData*() const { return m_contextData; } + inline QDeclarativeContextData* operator->() const { return m_contextData; } + +private: + friend class QDeclarativeContextData; + + inline void clear(); + + QDeclarativeContextData *m_contextData; + QDeclarativeGuardedContextData *m_next; + QDeclarativeGuardedContextData **m_prev; }; -QDeclarativeContextPrivate::ContextGuard::ContextGuard() -: priv(0) +QDeclarativeGuardedContextData::QDeclarativeGuardedContextData() +: m_contextData(0), m_next(0), m_prev(0) +{ +} + +QDeclarativeGuardedContextData::QDeclarativeGuardedContextData(QDeclarativeContextData *data) +: m_contextData(0), m_next(0), m_prev(0) +{ + setContextData(data); +} + +QDeclarativeGuardedContextData::~QDeclarativeGuardedContextData() +{ + clear(); +} + +void QDeclarativeGuardedContextData::setContextData(QDeclarativeContextData *contextData) { + clear(); + + if (contextData) { + m_contextData = contextData; + m_next = contextData->contextGuards; + if (m_next) m_next->m_prev = &m_next; + m_prev = &contextData->contextGuards; + contextData->contextGuards = this; + } } -QDeclarativeContextPrivate::ContextGuard &QDeclarativeContextPrivate::ContextGuard::operator=(QObject *obj) +QDeclarativeContextData *QDeclarativeGuardedContextData::contextData() { - (QDeclarativeGuard&)*this = obj; return *this; + return m_contextData; } -void QDeclarativeContextPrivate::ContextGuard::objectDestroyed(QObject *) -{ - priv->destroyed(this); +void QDeclarativeGuardedContextData::clear() +{ + if (m_prev) { + *m_prev = m_next; + if (m_next) m_next->m_prev = m_prev; + m_contextData = 0; + m_next = 0; + m_prev = 0; + } } QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativecontextscriptclass.cpp b/src/declarative/qml/qdeclarativecontextscriptclass.cpp index 0e5066e..847d632 100644 --- a/src/declarative/qml/qdeclarativecontextscriptclass.cpp +++ b/src/declarative/qml/qdeclarativecontextscriptclass.cpp @@ -51,17 +51,17 @@ QT_BEGIN_NAMESPACE struct ContextData : public QScriptDeclarativeClass::Object { ContextData() : overrideObject(0), isSharedContext(true) {} - ContextData(QDeclarativeContext *c, QObject *o) : context(c), scopeObject(o), overrideObject(0), isSharedContext(false) {} - QDeclarativeGuard context; + ContextData(QDeclarativeContextData *c, QObject *o) : context(c), scopeObject(o), overrideObject(0), isSharedContext(false) {} + QDeclarativeGuardedContextData context; QDeclarativeGuard scopeObject; QObject *overrideObject; bool isSharedContext; - QDeclarativeContext *getContext(QDeclarativeEngine *engine) { + QDeclarativeContextData *getContext(QDeclarativeEngine *engine) { if (isSharedContext) { return QDeclarativeEnginePrivate::get(engine)->sharedContext; } else { - return context.data(); + return context.contextData(); } } @@ -88,7 +88,7 @@ QDeclarativeContextScriptClass::~QDeclarativeContextScriptClass() { } -QScriptValue QDeclarativeContextScriptClass::newContext(QDeclarativeContext *context, QObject *scopeObject) +QScriptValue QDeclarativeContextScriptClass::newContext(QDeclarativeContextData *context, QObject *scopeObject) { QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); @@ -102,7 +102,7 @@ QScriptValue QDeclarativeContextScriptClass::newSharedContext() return newObject(scriptEngine, this, new ContextData()); } -QDeclarativeContext *QDeclarativeContextScriptClass::contextFromValue(const QScriptValue &v) +QDeclarativeContextData *QDeclarativeContextScriptClass::contextFromValue(const QScriptValue &v) { if (scriptClass(v) != this) return 0; @@ -133,7 +133,7 @@ QDeclarativeContextScriptClass::queryProperty(Object *object, const Identifier & lastData = 0; lastPropertyIndex = -1; - QDeclarativeContext *bindContext = ((ContextData *)object)->getContext(engine); + QDeclarativeContextData *bindContext = ((ContextData *)object)->getContext(engine); QObject *scopeObject = ((ContextData *)object)->getScope(engine); if (!bindContext) return 0; @@ -159,29 +159,28 @@ QDeclarativeContextScriptClass::queryProperty(Object *object, const Identifier & scopeObject = 0; // Only applies to the first context includeTypes = false; // Only applies to the first context if (rv) return rv; - bindContext = bindContext->parentContext(); + bindContext = bindContext->parent; } return 0; } QScriptClass::QueryFlags -QDeclarativeContextScriptClass::queryProperty(QDeclarativeContext *bindContext, QObject *scopeObject, - const Identifier &name, - QScriptClass::QueryFlags flags, - bool includeTypes) +QDeclarativeContextScriptClass::queryProperty(QDeclarativeContextData *bindContext, QObject *scopeObject, + const Identifier &name, + QScriptClass::QueryFlags flags, + bool includeTypes) { QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); - QDeclarativeContextPrivate *cp = QDeclarativeContextPrivate::get(bindContext); - lastPropertyIndex = cp->propertyNames?cp->propertyNames->value(name):-1; + lastPropertyIndex = bindContext->propertyNames?bindContext->propertyNames->value(name):-1; if (lastPropertyIndex != -1) { lastContext = bindContext; return QScriptClass::HandlesReadAccess; } - if (includeTypes && cp->imports) { - QDeclarativeTypeNameCache::Data *data = cp->imports->data(name); + if (includeTypes && bindContext->imports) { + QDeclarativeTypeNameCache::Data *data = bindContext->imports->data(name); if (data) { lastData = data; @@ -190,8 +189,8 @@ QDeclarativeContextScriptClass::queryProperty(QDeclarativeContext *bindContext, } } - for (int ii = 0; ii < cp->scripts.count(); ++ii) { - lastFunction = QScriptDeclarativeClass::function(cp->scripts.at(ii), name); + for (int ii = 0; ii < bindContext->scripts.count(); ++ii) { + lastFunction = QScriptDeclarativeClass::function(bindContext->scripts.at(ii), name); if (lastFunction.isValid()) { lastContext = bindContext; return QScriptClass::HandlesReadAccess; @@ -209,13 +208,13 @@ QDeclarativeContextScriptClass::queryProperty(QDeclarativeContext *bindContext, } } - if (cp->contextObject) { + if (bindContext->contextObject) { QScriptClass::QueryFlags rv = - ep->objectClass->queryProperty(cp->contextObject, name, flags, bindContext, + ep->objectClass->queryProperty(bindContext->contextObject, name, flags, bindContext, QDeclarativeObjectScriptClass::ImplicitObject | QDeclarativeObjectScriptClass::SkipAttachedProperties); if (rv) { - lastScopeObject = cp->contextObject; + lastScopeObject = bindContext->contextObject; lastContext = bindContext; return rv; } @@ -229,11 +228,10 @@ QDeclarativeContextScriptClass::property(Object *object, const Identifier &name) { Q_UNUSED(object); - QDeclarativeContext *bindContext = lastContext; + QDeclarativeContextData *bindContext = lastContext; Q_ASSERT(bindContext); QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); - QDeclarativeContextPrivate *cp = QDeclarativeContextPrivate::get(bindContext); QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); if (lastScopeObject) { @@ -243,28 +241,29 @@ QDeclarativeContextScriptClass::property(Object *object, const Identifier &name) } else if (lastData) { if (lastData->type) - return Value(scriptEngine, ep->typeNameClass->newObject(cp->contextObject, lastData->type)); + return Value(scriptEngine, ep->typeNameClass->newObject(bindContext->contextObject, lastData->type)); else - return Value(scriptEngine, ep->typeNameClass->newObject(cp->contextObject, lastData->typeNamespace)); + return Value(scriptEngine, ep->typeNameClass->newObject(bindContext->contextObject, lastData->typeNamespace)); } else if (lastPropertyIndex != -1) { QScriptValue rv; - if (lastPropertyIndex < cp->idValueCount) { - rv = ep->objectClass->newQObject(cp->idValues[lastPropertyIndex].data()); + if (lastPropertyIndex < bindContext->idValueCount) { + rv = ep->objectClass->newQObject(bindContext->idValues[lastPropertyIndex].data()); if (ep->captureProperties) - ep->capturedProperties << QDeclarativeEnginePrivate::CapturedProperty(&cp->idValues[lastPropertyIndex].bindings); + ep->capturedProperties << QDeclarativeEnginePrivate::CapturedProperty(&bindContext->idValues[lastPropertyIndex].bindings); } else { + QDeclarativeContextPrivate *cp = bindContext->asQDeclarativeContextPrivate(); const QVariant &value = cp->propertyValues.at(lastPropertyIndex); if (value.userType() == qMetaTypeId >()) { - rv = ep->listClass->newList(QDeclarativeListProperty(bindContext, (void*)lastPropertyIndex, 0, QDeclarativeContextPrivate::context_count, QDeclarativeContextPrivate::context_at), qMetaTypeId >()); + rv = ep->listClass->newList(QDeclarativeListProperty(bindContext->asQDeclarativeContext(), (void*)lastPropertyIndex, 0, QDeclarativeContextPrivate::context_count, QDeclarativeContextPrivate::context_at), qMetaTypeId >()); } else { rv = ep->scriptValueFromVariant(value); } if (ep->captureProperties) - ep->capturedProperties << QDeclarativeEnginePrivate::CapturedProperty(bindContext, -1, lastPropertyIndex + cp->notifyIndex); + ep->capturedProperties << QDeclarativeEnginePrivate::CapturedProperty(bindContext->asQDeclarativeContext(), -1, lastPropertyIndex + cp->notifyIndex); } @@ -283,11 +282,10 @@ void QDeclarativeContextScriptClass::setProperty(Object *object, const Identifie Q_UNUSED(object); Q_ASSERT(lastScopeObject); - QDeclarativeContext *bindContext = lastContext; + QDeclarativeContextData *bindContext = lastContext; Q_ASSERT(bindContext); QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); - QDeclarativeContextPrivate *cp = QDeclarativeContextPrivate::get(bindContext); ep->objectClass->setProperty(lastScopeObject, name, value, bindContext); } diff --git a/src/declarative/qml/qdeclarativecontextscriptclass_p.h b/src/declarative/qml/qdeclarativecontextscriptclass_p.h index 32c117c..93e4b20 100644 --- a/src/declarative/qml/qdeclarativecontextscriptclass_p.h +++ b/src/declarative/qml/qdeclarativecontextscriptclass_p.h @@ -60,16 +60,17 @@ QT_BEGIN_NAMESPACE class QDeclarativeEngine; class QDeclarativeContext; +class QDeclarativeContextData; class QDeclarativeContextScriptClass : public QDeclarativeScriptClass { public: QDeclarativeContextScriptClass(QDeclarativeEngine *); ~QDeclarativeContextScriptClass(); - QScriptValue newContext(QDeclarativeContext *, QObject * = 0); + QScriptValue newContext(QDeclarativeContextData *, QObject * = 0); QScriptValue newSharedContext(); - QDeclarativeContext *contextFromValue(const QScriptValue &); + QDeclarativeContextData *contextFromValue(const QScriptValue &); QObject *setOverrideObject(QScriptValue &, QObject *); protected: @@ -79,7 +80,7 @@ protected: virtual void setProperty(Object *, const Identifier &name, const QScriptValue &); private: - QScriptClass::QueryFlags queryProperty(QDeclarativeContext *, QObject *scopeObject, + QScriptClass::QueryFlags queryProperty(QDeclarativeContextData *, QObject *scopeObject, const Identifier &, QScriptClass::QueryFlags flags, bool includeTypes); @@ -87,7 +88,7 @@ private: QDeclarativeEngine *engine; QObject *lastScopeObject; - QDeclarativeContext *lastContext; + QDeclarativeContextData *lastContext; QDeclarativeTypeNameCache::Data *lastData; int lastPropertyIndex; QScriptValue lastFunction; diff --git a/src/declarative/qml/qdeclarativedeclarativedata_p.h b/src/declarative/qml/qdeclarativedeclarativedata_p.h index f962986..d1d063a 100644 --- a/src/declarative/qml/qdeclarativedeclarativedata_p.h +++ b/src/declarative/qml/qdeclarativedeclarativedata_p.h @@ -63,13 +63,14 @@ class QDeclarativeCompiledData; class QDeclarativeAbstractBinding; class QDeclarativeContext; class QDeclarativePropertyCache; +class QDeclarativeContextData; class Q_AUTOTEST_EXPORT QDeclarativeDeclarativeData : public QDeclarativeData { public: - QDeclarativeDeclarativeData(QDeclarativeContext *ctxt = 0) - : ownMemory(true), 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), + QDeclarativeDeclarativeData() + : ownMemory(true), ownContext(false), indestructible(true), explicitIndestructibleSet(false), + context(0), outerContext(0), bindings(0), nextContextObject(0), prevContextObject(0), bindingBitsSize(0), + bindingBits(0), lineNumber(0), columnNumber(0), deferredComponent(0), deferredIdx(0), attachedProperties(0), propertyCache(0), guards(0) {} virtual void destroyed(QObject *); @@ -80,11 +81,14 @@ public: } quint32 ownMemory:1; + quint32 ownContext:1; quint32 indestructible:1; quint32 explicitIndestructibleSet:1; - quint32 dummy:29; + quint32 dummy:28; + + QDeclarativeContextData *context; + QDeclarativeContextData *outerContext; - QDeclarativeContext *context; QDeclarativeAbstractBinding *bindings; // Linked list for QDeclarativeContext::contextObjects @@ -97,7 +101,6 @@ public: void clearBindingBit(int); void setBindingBit(QObject *obj, int); - QDeclarativeContext *outerContext; // Can't this be found from context? ushort lineNumber; ushort columnNumber; diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 2a26626..e19e53f 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -189,7 +189,7 @@ QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e) QUrl QDeclarativeScriptEngine::resolvedUrl(QScriptContext *context, const QUrl& url) { if (p) { - QDeclarativeContext *ctxt = QDeclarativeEnginePrivate::get(this)->getContext(context); + QDeclarativeContextData *ctxt = QDeclarativeEnginePrivate::get(this)->getContext(context); Q_ASSERT(ctxt); return ctxt->resolvedUrl(url); } @@ -635,9 +635,9 @@ QDeclarativeContext *QDeclarativeEngine::contextForObject(const QObject *object) if (!data) return 0; else if (data->outerContext) - return data->outerContext; + return data->outerContext->asQDeclarativeContext(); else - return data->context; + return 0; } /*! @@ -658,12 +658,8 @@ void QDeclarativeEngine::setContextForObject(QObject *object, QDeclarativeContex return; } - data->context = context; - data->nextContextObject = context->d_func()->contextObjects; - if (data->nextContextObject) - data->nextContextObject->prevContextObject = &data->nextContextObject; - data->prevContextObject = &context->d_func()->contextObjects; - context->d_func()->contextObjects = data; + QDeclarativeContextData *contextData = QDeclarativeContextData::get(context); + contextData->addObject(object); } /*! @@ -727,7 +723,7 @@ void qmlExecuteDeferred(QObject *object) if (data && data->deferredComponent) { - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(data->context->engine()); + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(data->context->engine); QDeclarativeComponentPrivate::ConstructionState state; QDeclarativeComponentPrivate::beginDeferred(data->context, ep, object, &state); @@ -828,6 +824,9 @@ void QDeclarativeDeclarativeData::destroyed(QObject *object) g->objectDestroyed(object); } + if (ownContext) + context->destroy(); + if (ownMemory) delete this; else @@ -893,7 +892,7 @@ QScriptValue QDeclarativeEnginePrivate::qmlScriptObject(QObject* object, /*! Returns the QDeclarativeContext for the executing QScript \a ctxt. */ -QDeclarativeContext *QDeclarativeEnginePrivate::getContext(QScriptContext *ctxt) +QDeclarativeContextData *QDeclarativeEnginePrivate::getContext(QScriptContext *ctxt) { QScriptValue scopeNode = QScriptDeclarativeClass::scopeChainValue(ctxt, -3); Q_ASSERT(scopeNode.isValid()); @@ -901,15 +900,15 @@ QDeclarativeContext *QDeclarativeEnginePrivate::getContext(QScriptContext *ctxt) return contextClass->contextFromValue(scopeNode); } -QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt, - QScriptEngine *engine) +QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt, QScriptEngine *engine) { QDeclarativeEnginePrivate *activeEnginePriv = static_cast(engine)->p; QDeclarativeEngine* activeEngine = activeEnginePriv->q_func(); - QDeclarativeContext* context = activeEnginePriv->getContext(ctxt); + QDeclarativeContextData* context = activeEnginePriv->getContext(ctxt); Q_ASSERT(context); + if(ctxt->argumentCount() != 1) { return engine->nullValue(); }else{ @@ -918,7 +917,7 @@ QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt, return engine->nullValue(); QUrl url = QUrl(context->resolvedUrl(QUrl(arg))); QDeclarativeComponent *c = new QDeclarativeComponent(activeEngine, url, activeEngine); - c->setCreationContext(context); + QDeclarativeComponentPrivate::get(c)->creationContext = context; QDeclarativeDeclarativeData::get(c, true)->setImplicitDestructible(); return activeEnginePriv->objectClass->newQObject(c, qMetaTypeId()); } @@ -933,7 +932,7 @@ QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QS if(ctxt->argumentCount() < 2 || ctxt->argumentCount() > 3) return engine->nullValue(); - QDeclarativeContext* context = activeEnginePriv->getContext(ctxt); + QDeclarativeContextData* context = activeEnginePriv->getContext(ctxt); Q_ASSERT(context); QString qml = ctxt->argument(0).toString(); @@ -971,7 +970,7 @@ QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QS return engine->nullValue(); } - QObject *obj = component.create(context); + QObject *obj = component.create(context->asQDeclarativeContext()); if(component.isError()) { QList errors = component.errors(); diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h index fb8c5e7..f1b7b0e 100644 --- a/src/declarative/qml/qdeclarativeengine_p.h +++ b/src/declarative/qml/qdeclarativeengine_p.h @@ -61,6 +61,7 @@ #include "qdeclarative.h" #include "qdeclarativevaluetype_p.h" #include "qdeclarativecontext.h" +#include "qdeclarativecontext_p.h" #include "qdeclarativeexpression.h" #include "qdeclarativeproperty_p.h" #include "qdeclarativepropertycache_p.h" @@ -162,7 +163,7 @@ public: struct ImportedNamespace; QDeclarativeContextScriptClass *contextClass; - QDeclarativeContext *sharedContext; + QDeclarativeContextData *sharedContext; QObject *sharedScope; QDeclarativeObjectScriptClass *objectClass; QDeclarativeValueTypeScriptClass *valueTypeClass; @@ -336,9 +337,10 @@ public: static QDeclarativeEngine *getEngine(QScriptEngine *e) { return static_cast(e)->p->q_func(); } static QDeclarativeEnginePrivate *get(QDeclarativeEngine *e) { return e->d_func(); } static QDeclarativeEnginePrivate *get(QDeclarativeContext *c) { return (c && c->engine()) ? QDeclarativeEnginePrivate::get(c->engine()) : 0; } + static QDeclarativeEnginePrivate *get(QDeclarativeContextData *c) { return (c && c->engine) ? QDeclarativeEnginePrivate::get(c->engine) : 0; } static QDeclarativeEnginePrivate *get(QScriptEngine *e) { return static_cast(e)->p; } static QDeclarativeEngine *get(QDeclarativeEnginePrivate *p) { return p->q_func(); } - QDeclarativeContext *getContext(QScriptContext *); + QDeclarativeContextData *getContext(QScriptContext *); static void defineModule(); }; diff --git a/src/declarative/qml/qdeclarativeenginedebug.cpp b/src/declarative/qml/qdeclarativeenginedebug.cpp index 933683c..da73178 100644 --- a/src/declarative/qml/qdeclarativeenginedebug.cpp +++ b/src/declarative/qml/qdeclarativeenginedebug.cpp @@ -49,6 +49,7 @@ #include "qdeclarativebinding_p.h" #include "qdeclarativecontext_p.h" #include "qdeclarativewatcher_p.h" +#include "qdeclarativevaluetype_p.h" #include #include @@ -218,10 +219,9 @@ void QDeclarativeEngineDebugServer::buildObjectDump(QDataStream &message, message << fakeProperties[ii]; } -void QDeclarativeEngineDebugServer::buildObjectList(QDataStream &message, - QDeclarativeContext *ctxt) +void QDeclarativeEngineDebugServer::buildObjectList(QDataStream &message, QDeclarativeContext *ctxt) { - QDeclarativeContextPrivate *p = (QDeclarativeContextPrivate *)QObjectPrivate::get(ctxt); + QDeclarativeContextData *p = QDeclarativeContextData::get(ctxt); QString ctxtName = ctxt->objectName(); int ctxtId = QDeclarativeDebugService::idForObject(ctxt); @@ -230,35 +230,34 @@ void QDeclarativeEngineDebugServer::buildObjectList(QDataStream &message, int count = 0; - QDeclarativeContext *child = p->childContexts; + QDeclarativeContextData *child = p->childContexts; while (child) { - QDeclarativeContextPrivate *p = QDeclarativeContextPrivate::get(child); - if (!p->isInternal) + if (!child->isInternal) ++count; - child = p->nextChild; + child = child->nextChild; } message << count; child = p->childContexts; while (child) { - QDeclarativeContextPrivate *p = QDeclarativeContextPrivate::get(child); - if (!p->isInternal) - buildObjectList(message, child); - child = p->nextChild; + if (!child->isInternal) + buildObjectList(message, child->asQDeclarativeContext()); + child = child->nextChild; } // Clean deleted objects - for (int ii = 0; ii < p->instances.count(); ++ii) { - if (!p->instances.at(ii)) { - p->instances.removeAt(ii); + QDeclarativeContextPrivate *ctxtPriv = QDeclarativeContextPrivate::get(ctxt); + for (int ii = 0; ii < ctxtPriv->instances.count(); ++ii) { + if (!ctxtPriv->instances.at(ii)) { + ctxtPriv->instances.removeAt(ii); --ii; } } - message << p->instances.count(); - for (int ii = 0; ii < p->instances.count(); ++ii) { - message << objectData(p->instances.at(ii)); + message << ctxtPriv->instances.count(); + for (int ii = 0; ii < ctxtPriv->instances.count(); ++ii) { + message << objectData(ctxtPriv->instances.at(ii)); } } @@ -268,7 +267,7 @@ QDeclarativeEngineDebugServer::objectData(QObject *object) QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(object); QDeclarativeObjectData rv; if (ddata) { - rv.url = ddata->outerContext->baseUrl(); + rv.url = ddata->outerContext->url; rv.lineNumber = ddata->lineNumber; rv.columnNumber = ddata->columnNumber; } else { diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp index f3299ba..609eb39 100644 --- a/src/declarative/qml/qdeclarativeexpression.cpp +++ b/src/declarative/qml/qdeclarativeexpression.cpp @@ -98,8 +98,8 @@ QDeclarativeExpressionPrivate::~QDeclarativeExpressionPrivate() if (data) { data->q = 0; data->release(); data = 0; } } -void QDeclarativeExpressionPrivate::init(QDeclarativeContext *ctxt, const QString &expr, - QObject *me) +void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, const QString &expr, + QObject *me) { data->expression = expr; @@ -107,8 +107,8 @@ void QDeclarativeExpressionPrivate::init(QDeclarativeContext *ctxt, const QStrin data->me = me; } -void QDeclarativeExpressionPrivate::init(QDeclarativeContext *ctxt, void *expr, QDeclarativeRefCount *rc, - QObject *me, const QString &url, int lineNumber) +void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, void *expr, QDeclarativeRefCount *rc, + QObject *me, const QString &url, int lineNumber) { data->url = url; data->line = lineNumber; @@ -127,7 +127,7 @@ void QDeclarativeExpressionPrivate::init(QDeclarativeContext *ctxt, void *expr, bool isShared = progIdx & 0x80000000; progIdx &= 0x7FFFFFFF; - QDeclarativeEngine *engine = ctxt->engine(); + QDeclarativeEngine *engine = ctxt->engine; QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); @@ -167,10 +167,10 @@ void QDeclarativeExpressionPrivate::init(QDeclarativeContext *ctxt, void *expr, data->me = me; } -QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContext *context, QObject *object, +QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContextData *context, QObject *object, const QString &program, QScriptValue *contextObject) { - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine()); + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine); QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(&ep->scriptEngine); if (contextObject) { *contextObject = ep->contextClass->newContext(context, object); @@ -184,10 +184,11 @@ QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContex return rv; } -QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContext *context, QObject *object, - const QScriptProgram &program, QScriptValue *contextObject) +QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContextData *context, QObject *object, + const QScriptProgram &program, + QScriptValue *contextObject) { - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine()); + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine); QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(&ep->scriptEngine); if (contextObject) { *contextObject = ep->contextClass->newContext(context, object); @@ -219,10 +220,10 @@ QDeclarativeExpression::QDeclarativeExpression() } /*! \internal */ -QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContext *ctxt, void *expr, - QDeclarativeRefCount *rc, QObject *me, - const QString &url, int lineNumber, - QDeclarativeExpressionPrivate &dd) +QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, void *expr, + QDeclarativeRefCount *rc, QObject *me, + const QString &url, int lineNumber, + QDeclarativeExpressionPrivate &dd) : QObject(dd, 0) { Q_D(QDeclarativeExpression); @@ -237,7 +238,18 @@ QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContext *ctxt, void * the expression's execution. */ QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContext *ctxt, const QString &expression, - QObject *scope) + QObject *scope) +: QObject(*new QDeclarativeExpressionPrivate, 0) +{ + Q_D(QDeclarativeExpression); + d->init(QDeclarativeContextData::get(ctxt), expression, scope); +} + +/*! + \internal +*/ +QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, const QString &expression, + QObject *scope) : QObject(*new QDeclarativeExpressionPrivate, 0) { Q_D(QDeclarativeExpression); @@ -245,8 +257,8 @@ QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContext *ctxt, const } /*! \internal */ -QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContext *ctxt, const QString &expression, - QObject *scope, QDeclarativeExpressionPrivate &dd) +QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, const QString &expression, + QObject *scope, QDeclarativeExpressionPrivate &dd) : QObject(dd, 0) { Q_D(QDeclarativeExpression); @@ -267,7 +279,7 @@ QDeclarativeExpression::~QDeclarativeExpression() QDeclarativeEngine *QDeclarativeExpression::engine() const { Q_D(const QDeclarativeExpression); - return d->data->context()?d->data->context()->engine():0; + return d->data->context()?d->data->context()->engine:0; } /*! @@ -277,7 +289,8 @@ QDeclarativeEngine *QDeclarativeExpression::engine() const QDeclarativeContext *QDeclarativeExpression::context() const { Q_D(const QDeclarativeExpression); - return d->data->context(); + QDeclarativeContextData *data = d->data->context(); + return data?data->asQDeclarativeContext():0; } /*! @@ -338,8 +351,7 @@ QVariant QDeclarativeExpressionPrivate::evalQtScript(QObject *secondaryScope, bo #endif QDeclarativeExpressionData *data = this->data; - QDeclarativeContextPrivate *ctxtPriv = data->context()->d_func(); - QDeclarativeEngine *engine = data->context()->engine(); + QDeclarativeEngine *engine = data->context()->engine; QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); @@ -370,7 +382,7 @@ QVariant QDeclarativeExpressionPrivate::evalQtScript(QObject *secondaryScope, bo data->expressionFunctionValid = true; } - QDeclarativeContext *oldSharedContext = 0; + QDeclarativeContextData *oldSharedContext = 0; QObject *oldSharedScope = 0; QObject *oldOverride = 0; if (data->isShared) { @@ -743,12 +755,12 @@ QDeclarativeAbstractExpression::~QDeclarativeAbstractExpression() } } -QDeclarativeContext *QDeclarativeAbstractExpression::context() const +QDeclarativeContextData *QDeclarativeAbstractExpression::context() const { return m_context; } -void QDeclarativeAbstractExpression::setContext(QDeclarativeContext *context) +void QDeclarativeAbstractExpression::setContext(QDeclarativeContextData *context) { if (m_prevExpression) { *m_prevExpression = m_nextExpression; @@ -761,13 +773,11 @@ void QDeclarativeAbstractExpression::setContext(QDeclarativeContext *context) m_context = context; if (m_context) { - QDeclarativeContextPrivate *cp = - static_cast(QObjectPrivate::get(m_context)); - m_nextExpression = cp->expressions; + m_nextExpression = m_context->expressions; if (m_nextExpression) m_nextExpression->m_prevExpression = &m_nextExpression; - m_prevExpression = &cp->expressions; - cp->expressions = this; + m_prevExpression = &context->expressions; + m_context->expressions = this; } } diff --git a/src/declarative/qml/qdeclarativeexpression.h b/src/declarative/qml/qdeclarativeexpression.h index 911d328..73a5793 100644 --- a/src/declarative/qml/qdeclarativeexpression.h +++ b/src/declarative/qml/qdeclarativeexpression.h @@ -58,6 +58,7 @@ class QDeclarativeRefCount; class QDeclarativeEngine; class QDeclarativeContext; class QDeclarativeExpressionPrivate; +class QDeclarativeContextData; class Q_DECLARATIVE_EXPORT QDeclarativeExpression : public QObject { Q_OBJECT @@ -91,18 +92,21 @@ Q_SIGNALS: void valueChanged(); protected: - QDeclarativeExpression(QDeclarativeContext *, const QString &, QObject *, - QDeclarativeExpressionPrivate &dd); - QDeclarativeExpression(QDeclarativeContext *, void *, QDeclarativeRefCount *rc, QObject *me, const QString &, - int, QDeclarativeExpressionPrivate &dd); + QDeclarativeExpression(QDeclarativeContextData *, const QString &, QObject *, + QDeclarativeExpressionPrivate &dd); + QDeclarativeExpression(QDeclarativeContextData *, void *, QDeclarativeRefCount *rc, + QObject *me, const QString &, int, QDeclarativeExpressionPrivate &dd); private Q_SLOTS: void __q_notify(); private: + QDeclarativeExpression(QDeclarativeContextData *, const QString &, QObject *); + Q_DECLARE_PRIVATE(QDeclarativeExpression) friend class QDeclarativeDebugger; friend class QDeclarativeContext; + friend class QDeclarativeVME; }; QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativeexpression_p.h b/src/declarative/qml/qdeclarativeexpression_p.h index d170559..5adaa89 100644 --- a/src/declarative/qml/qdeclarativeexpression_p.h +++ b/src/declarative/qml/qdeclarativeexpression_p.h @@ -70,15 +70,16 @@ public: bool isValid() const; - QDeclarativeContext *context() const; - void setContext(QDeclarativeContext *); + QDeclarativeContextData *context() const; + void setContext(QDeclarativeContextData *); virtual void refresh(); private: friend class QDeclarativeContext; + friend class QDeclarativeContextData; friend class QDeclarativeContextPrivate; - QDeclarativeContext *m_context; + QDeclarativeContextData *m_context; QDeclarativeAbstractExpression **m_prevExpression; QDeclarativeAbstractExpression *m_nextExpression; }; @@ -143,8 +144,8 @@ public: QDeclarativeExpressionPrivate(QDeclarativeExpressionData *); ~QDeclarativeExpressionPrivate(); - void init(QDeclarativeContext *, const QString &, QObject *); - void init(QDeclarativeContext *, void *, QDeclarativeRefCount *, QObject *, const QString &, int); + void init(QDeclarativeContextData *, const QString &, QObject *); + void init(QDeclarativeContextData *, void *, QDeclarativeRefCount *, QObject *, const QString &, int); QDeclarativeExpressionData *data; @@ -164,8 +165,8 @@ public: virtual void emitValueChanged(); static void exceptionToError(QScriptEngine *, QDeclarativeError &); - static QScriptValue evalInObjectScope(QDeclarativeContext *, QObject *, const QString &, QScriptValue * = 0); - static QScriptValue evalInObjectScope(QDeclarativeContext *, QObject *, const QScriptProgram &, QScriptValue * = 0); + static QScriptValue evalInObjectScope(QDeclarativeContextData *, QObject *, const QString &, QScriptValue * = 0); + static QScriptValue evalInObjectScope(QDeclarativeContextData *, QObject *, const QScriptProgram &, QScriptValue * = 0); }; QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativeinfo.cpp b/src/declarative/qml/qdeclarativeinfo.cpp index 7dc61fd..87a9254 100644 --- a/src/declarative/qml/qdeclarativeinfo.cpp +++ b/src/declarative/qml/qdeclarativeinfo.cpp @@ -43,6 +43,7 @@ #include "qdeclarativedeclarativedata_p.h" #include "qdeclarativecontext.h" +#include "qdeclarativecontext_p.h" #include "qdeclarativemetatype_p.h" #include @@ -103,7 +104,7 @@ QDeclarativeInfo::QDeclarativeInfo(const QObject *object) pos += QLatin1String(" ("); if (ddata) { if (ddata->outerContext) { - pos += ddata->outerContext->baseUrl().toString(); + pos += ddata->outerContext->url.toString(); pos += QLatin1Char(':'); pos += QString::number(ddata->lineNumber); pos += QLatin1Char(':'); diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp index 32a28fe..027166a 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp @@ -142,7 +142,7 @@ QDeclarativeObjectScriptClass::queryProperty(Object *object, const Identifier &n QScriptClass::QueryFlags QDeclarativeObjectScriptClass::queryProperty(QObject *obj, const Identifier &name, - QScriptClass::QueryFlags flags, QDeclarativeContext *evalContext, + QScriptClass::QueryFlags flags, QDeclarativeContextData *evalContext, QueryHints hints) { Q_UNUSED(flags); @@ -173,15 +173,11 @@ QDeclarativeObjectScriptClass::queryProperty(QObject *obj, const Identifier &nam } } - if (evalContext) { - QDeclarativeContextPrivate *cp = QDeclarativeContextPrivate::get(evalContext); - - if (cp->imports) { - QDeclarativeTypeNameCache::Data *data = cp->imports->data(name); - if (data) { - lastTNData = data; - return QScriptClass::HandlesReadAccess; - } + if (evalContext && evalContext->imports) { + QDeclarativeTypeNameCache::Data *data = evalContext->imports->data(name); + if (data) { + lastTNData = data; + return QScriptClass::HandlesReadAccess; } } } @@ -316,7 +312,7 @@ void QDeclarativeObjectScriptClass::setProperty(Object *object, void QDeclarativeObjectScriptClass::setProperty(QObject *obj, const Identifier &name, const QScriptValue &value, - QDeclarativeContext *evalContext) + QDeclarativeContextData *evalContext) { Q_UNUSED(name); diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass_p.h b/src/declarative/qml/qdeclarativeobjectscriptclass_p.h index 1f7d1c9..396b782 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass_p.h +++ b/src/declarative/qml/qdeclarativeobjectscriptclass_p.h @@ -64,7 +64,7 @@ QT_BEGIN_NAMESPACE class QDeclarativeEngine; class QScriptContext; class QScriptEngine; -class QDeclarativeContext; +class QDeclarativeContextData; #if (QT_VERSION > QT_VERSION_CHECK(4, 6, 2)) || defined(QT_HAVE_QSCRIPTDECLARATIVECLASS_VALUE) class Q_AUTOTEST_EXPORT QDeclarativeObjectMethodScriptClass : public QScriptDeclarativeClass @@ -112,13 +112,13 @@ public: QScriptClass::QueryFlags queryProperty(QObject *, const Identifier &, QScriptClass::QueryFlags flags, - QDeclarativeContext *evalContext, + QDeclarativeContextData *evalContext, QueryHints hints = 0); ScriptValue property(QObject *, const Identifier &); void setProperty(QObject *, const Identifier &name, const QScriptValue &, - QDeclarativeContext *evalContext = 0); + QDeclarativeContextData *evalContext = 0); virtual QStringList propertyNames(Object *); virtual bool compare(Object *, Object *); diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp index c55c22f..caa1acf 100644 --- a/src/declarative/qml/qdeclarativeproperty.cpp +++ b/src/declarative/qml/qdeclarativeproperty.cpp @@ -124,7 +124,7 @@ QDeclarativeProperty::QDeclarativeProperty(QObject *obj, QDeclarativeContext *ct : d(new QDeclarativePropertyPrivate) { d->q = this; - d->context = ctxt; + d->context = ctxt?QDeclarativeContextData::get(ctxt):0; d->engine = ctxt?ctxt->engine():0; d->initDefault(obj); } @@ -177,7 +177,7 @@ QDeclarativeProperty::QDeclarativeProperty(QObject *obj, const QString &name, QD : d(new QDeclarativePropertyPrivate) { d->q = this; - d->context = ctxt; + d->context = ctxt?QDeclarativeContextData::get(ctxt):0; d->engine = ctxt?ctxt->engine():0; d->initProperty(obj, name); if (!isValid()) { d->object = 0; d->context = 0; d->engine = 0; } @@ -204,7 +204,7 @@ void QDeclarativePropertyPrivate::initProperty(QObject *obj, const QString &name { if (!obj) return; - QDeclarativeTypeNameCache *typeNameCache = context?QDeclarativeContextPrivate::get(context)->imports:0; + QDeclarativeTypeNameCache *typeNameCache = context?context->imports:0; QStringList path = name.split(QLatin1Char('.')); if (path.isEmpty()) return; @@ -924,7 +924,7 @@ bool QDeclarativePropertyPrivate::writeValueProperty(const QVariant &value, Writ } bool QDeclarativePropertyPrivate::write(QObject *object, const QDeclarativePropertyCache::Data &property, - const QVariant &value, QDeclarativeContext *context, + const QVariant &value, QDeclarativeContextData *context, WriteFlags flags) { int coreIdx = property.coreIndex; @@ -1305,7 +1305,7 @@ QByteArray QDeclarativePropertyPrivate::saveProperty(const QMetaObject *metaObje } QDeclarativeProperty -QDeclarativePropertyPrivate::restore(const QByteArray &data, QObject *object, QDeclarativeContext *ctxt) +QDeclarativePropertyPrivate::restore(const QByteArray &data, QObject *object, QDeclarativeContextData *ctxt) { QDeclarativeProperty prop; @@ -1314,7 +1314,7 @@ QDeclarativePropertyPrivate::restore(const QByteArray &data, QObject *object, QD prop.d->object = object; prop.d->context = ctxt; - prop.d->engine = ctxt?ctxt->engine():0; + prop.d->engine = ctxt->engine; const SerializedData *sd = (const SerializedData *)data.constData(); if (sd->isValueType) { diff --git a/src/declarative/qml/qdeclarativeproperty_p.h b/src/declarative/qml/qdeclarativeproperty_p.h index 26b85b8..1bbee64 100644 --- a/src/declarative/qml/qdeclarativeproperty_p.h +++ b/src/declarative/qml/qdeclarativeproperty_p.h @@ -82,7 +82,7 @@ public: valueType(other.valueType) {} QDeclarativeProperty *q; - QDeclarativeContext *context; + QDeclarativeContextData *context; QDeclarativeEngine *engine; QDeclarativeGuard object; @@ -109,7 +109,7 @@ public: static bool writeEnumProperty(const QMetaProperty &prop, int idx, QObject *object, const QVariant &value, int flags); static bool write(QObject *, const QDeclarativePropertyCache::Data &, const QVariant &, - QDeclarativeContext *, WriteFlags flags = 0); + QDeclarativeContextData *, WriteFlags flags = 0); static QDeclarativeAbstractBinding *setBinding(QObject *, int coreIndex, int valueTypeIndex /* -1 */, QDeclarativeAbstractBinding *, WriteFlags flags = DontRemoveBinding); @@ -117,7 +117,7 @@ public: static QByteArray saveValueType(const QMetaObject *, int, const QMetaObject *, int); static QByteArray saveProperty(const QMetaObject *, int); - static QDeclarativeProperty restore(const QByteArray &, QObject *, QDeclarativeContext *); + static QDeclarativeProperty restore(const QByteArray &, QObject *, QDeclarativeContextData *); static bool equal(const QMetaObject *, const QMetaObject *); static bool canConvert(const QMetaObject *from, const QMetaObject *to); diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp index 05553fd..b3c07f5 100644 --- a/src/declarative/qml/qdeclarativevme.cpp +++ b/src/declarative/qml/qdeclarativevme.cpp @@ -100,9 +100,8 @@ struct ListInstance QDeclarativeListProperty qListProperty; }; -QObject *QDeclarativeVME::run(QDeclarativeContext *ctxt, QDeclarativeCompiledData *comp, - int start, int count, - const QBitField &bindingSkipList) +QObject *QDeclarativeVME::run(QDeclarativeContextData *ctxt, QDeclarativeCompiledData *comp, + int start, int count, const QBitField &bindingSkipList) { QDeclarativeVMEStack stack; @@ -119,7 +118,7 @@ void QDeclarativeVME::runDeferred(QObject *object) if (!data || !data->context || !data->deferredComponent) return; - QDeclarativeContext *ctxt = data->context; + QDeclarativeContextData *ctxt = data->context; QDeclarativeCompiledData *comp = data->deferredComponent; int start = data->deferredIdx + 1; int count = data->deferredComponent->bytecode.at(data->deferredIdx).defer.deferCount; @@ -129,7 +128,8 @@ void QDeclarativeVME::runDeferred(QObject *object) run(stack, ctxt, comp, start, count, QBitField()); } -QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, QDeclarativeContext *ctxt, +QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, + QDeclarativeContextData *ctxt, QDeclarativeCompiledData *comp, int start, int count, const QBitField &bindingSkipList) @@ -152,8 +152,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, QDeclarati QDeclarativeVMEStack qliststack; vmeErrors.clear(); - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine()); - QDeclarativeContextPrivate *cp = (QDeclarativeContextPrivate *)QObjectPrivate::get(ctxt); + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine); int status = -1; //for dbus QDeclarativePropertyPrivate::WriteFlags flags = QDeclarativePropertyPrivate::BypassInterceptor; @@ -169,9 +168,9 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, QDeclarati if (instr.init.parserStatusSize) parserStatus = QDeclarativeEnginePrivate::SimpleList(instr.init.parserStatusSize); if (instr.init.contextCache != -1) - cp->setIdPropertyData(comp->contextCaches.at(instr.init.contextCache)); + ctxt->setIdPropertyData(comp->contextCaches.at(instr.init.contextCache)); if (instr.init.compiledBinding != -1) - cp->optimizedBindings = new QDeclarativeCompiledBindings(datas.at(instr.init.compiledBinding).constData(), ctxt); + ctxt->optimizedBindings = new QDeclarativeCompiledBindings(datas.at(instr.init.compiledBinding).constData(), ctxt); } break; @@ -188,6 +187,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, QDeclarati QObject *o = types.at(instr.create.type).createInstance(ctxt, bindings); + if (!o) { if(types.at(instr.create.type).component) vmeErrors << types.at(instr.create.type).component->errors(); @@ -197,6 +197,24 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, QDeclarati QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(o); Q_ASSERT(ddata); + + if (stack.isEmpty()) { + if (ddata->context) { + Q_ASSERT(ddata->context != ctxt); + Q_ASSERT(ddata->outerContext); + Q_ASSERT(ddata->outerContext != ctxt); + QDeclarativeContextData *c = ddata->context; + while (c->linkedContext) c = c->linkedContext; + c->linkedContext = ctxt; + } else { + ctxt->addObject(o); + } + + ddata->ownContext = true; + } else if (!ddata->context) { + ctxt->addObject(o); + } + ddata->setImplicitDestructible(); ddata->outerContext = ctxt; ddata->lineNumber = instr.line; @@ -229,25 +247,30 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, QDeclarati case QDeclarativeInstruction::SetId: { QObject *target = stack.top(); - cp->setIdProperty(instr.setId.index, target); + ctxt->setIdProperty(instr.setId.index, target); } break; case QDeclarativeInstruction::SetDefault: { - QObject *target = stack.top(); - ctxt->setContextObject(target); + ctxt->contextObject = stack.top(); } break; case QDeclarativeInstruction::CreateComponent: { - QObject *qcomp = new QDeclarativeComponent(ctxt->engine(), comp, ii + 1, instr.createComponent.count, stack.isEmpty() ? 0 : stack.top()); + QObject *qcomp = new QDeclarativeComponent(ctxt->engine, comp, ii + 1, instr.createComponent.count, + stack.isEmpty() ? 0 : stack.top()); - QDeclarativeEngine::setContextForObject(qcomp, ctxt); - QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(qcomp); + QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(qcomp, true); Q_ASSERT(ddata); + + ctxt->addObject(qcomp); + + if (stack.isEmpty()) + ddata->ownContext = true; + ddata->setImplicitDestructible(); ddata->outerContext = ctxt; ddata->lineNumber = instr.line; @@ -555,7 +578,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, QDeclarati case QDeclarativeInstruction::StoreScript: { QObject *target = stack.top(); - cp->addScript(scripts.at(instr.storeScript.value), target); + ctxt->addScript(scripts.at(instr.storeScript.value), target); } break; @@ -564,7 +587,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, QDeclarati QObject *target = stack.top(); QObject *scope = stack.at(stack.count() - 1 - instr.storeScriptString.scope); QDeclarativeScriptString ss; - ss.setContext(ctxt); + ss.setContext(ctxt->asQDeclarativeContext()); ss.setScopeObject(scope); ss.setScript(primitives.at(instr.storeScriptString.value)); @@ -620,7 +643,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, QDeclarati break; QDeclarativeAbstractBinding *binding = - cp->optimizedBindings->configBinding(instr.assignBinding.value, target, scope, property); + ctxt->optimizedBindings->configBinding(instr.assignBinding.value, target, scope, property); bindValues.append(binding); binding->m_mePtr = &bindValues.values[bindValues.count - 1]; binding->addToObject(target); @@ -848,4 +871,25 @@ QList QDeclarativeVME::errors() const return vmeErrors; } +QObject * +QDeclarativeCompiledData::TypeReference::createInstance(QDeclarativeContextData *ctxt, + const QBitField &bindings) const +{ + if (type) { + QObject *rv = 0; + void *memory = 0; + + type->create(&rv, &memory, sizeof(QDeclarativeDeclarativeData)); + QDeclarativeDeclarativeData *ddata = new (memory) QDeclarativeDeclarativeData; + ddata->ownMemory = false; + QObjectPrivate::get(rv)->declarativeData = ddata; + + return rv; + } else { + Q_ASSERT(component); + return QDeclarativeComponentPrivate::get(component)->create(ctxt, bindings); + } +} + + QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativevme_p.h b/src/declarative/qml/qdeclarativevme_p.h index bcd3ac9..3f8aa15 100644 --- a/src/declarative/qml/qdeclarativevme_p.h +++ b/src/declarative/qml/qdeclarativevme_p.h @@ -65,7 +65,7 @@ class QObject; class QDeclarativeInstruction; class QDeclarativeCompiledData; class QDeclarativeCompiledData; -class QDeclarativeContext; +class QDeclarativeContextData; template class QDeclarativeVMEStack { @@ -100,7 +100,7 @@ class QDeclarativeVME public: QDeclarativeVME(); - QObject *run(QDeclarativeContext *, QDeclarativeCompiledData *, + QObject *run(QDeclarativeContextData *, QDeclarativeCompiledData *, int start = -1, int count = -1, const QBitField & = QBitField()); void runDeferred(QObject *); @@ -109,8 +109,10 @@ public: QList errors() const; private: - QObject *run(QDeclarativeVMEStack &, QDeclarativeContext *, QDeclarativeCompiledData *, - int start, int count, const QBitField &); + QObject *run(QDeclarativeVMEStack &, + QDeclarativeContextData *, QDeclarativeCompiledData *, + int start, int count, + const QBitField &); QList vmeErrors; }; diff --git a/src/declarative/qml/qdeclarativevmemetaobject.cpp b/src/declarative/qml/qdeclarativevmemetaobject.cpp index d67c834..f9c99ee 100644 --- a/src/declarative/qml/qdeclarativevmemetaobject.cpp +++ b/src/declarative/qml/qdeclarativevmemetaobject.cpp @@ -55,11 +55,11 @@ QT_BEGIN_NAMESPACE QDeclarativeVMEMetaObject::QDeclarativeVMEMetaObject(QObject *obj, - const QMetaObject *other, - const QDeclarativeVMEMetaData *meta, - QDeclarativeCompiledData *cdata) -: object(obj), compiledData(cdata), ctxt(qmlContext(obj)), metaData(meta), methods(0), - parent(0) + const QMetaObject *other, + const QDeclarativeVMEMetaData *meta, + QDeclarativeCompiledData *cdata) +: object(obj), compiledData(cdata), ctxt(QDeclarativeDeclarativeData::get(obj)->outerContext), + metaData(meta), methods(0), parent(0) { compiledData->addref(); @@ -115,7 +115,7 @@ int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) if (type != QVariant::Invalid) { if (valueIndex != -1) { - QDeclarativeEnginePrivate *ep = ctxt?QDeclarativeEnginePrivate::get(ctxt->engine()):0; + QDeclarativeEnginePrivate *ep = ctxt?QDeclarativeEnginePrivate::get(ctxt->engine):0; QDeclarativeValueType *valueType = 0; if (ep) valueType = ep->valueTypes[type]; else valueType = QDeclarativeValueTypeFactory::valueType(type); @@ -214,16 +214,17 @@ int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) *reinterpret_cast(a[0]) = 0; if (!ctxt) return -1; - QDeclarativeContextPrivate *ctxtPriv = - (QDeclarativeContextPrivate *)QObjectPrivate::get(ctxt); - QObject *target = ctxtPriv->idValues[d->contextIdx].data(); + QDeclarativeContext *context = ctxt->asQDeclarativeContext(); + QDeclarativeContextPrivate *ctxtPriv = QDeclarativeContextPrivate::get(context); + + QObject *target = ctxtPriv->data->idValues[d->contextIdx].data(); if (!target) return -1; if (c == QMetaObject::ReadProperty && !aConnected.testBit(id)) { int sigIdx = methodOffset + id + metaData->propertyCount; - QMetaObject::connect(ctxt, d->contextIdx + ctxtPriv->notifyIndex, object, sigIdx); + QMetaObject::connect(context, d->contextIdx + ctxtPriv->notifyIndex, object, sigIdx); if (d->propertyIdx != -1) { QMetaProperty prop = @@ -262,10 +263,10 @@ int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) id -= plainSignals; if (id < metaData->methodCount) { - if (!ctxt->engine()) + if (!ctxt->engine) return -1; // We can't run the method - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine()); + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine); QScriptValue function = method(id); diff --git a/src/declarative/qml/qdeclarativevmemetaobject_p.h b/src/declarative/qml/qdeclarativevmemetaobject_p.h index 37c0b7a..e11f6fa 100644 --- a/src/declarative/qml/qdeclarativevmemetaobject_p.h +++ b/src/declarative/qml/qdeclarativevmemetaobject_p.h @@ -63,6 +63,7 @@ #include "qdeclarativeguard_p.h" #include "qdeclarativecompiler_p.h" +#include "qdeclarativecontext_p.h" QT_BEGIN_NAMESPACE @@ -121,7 +122,7 @@ protected: private: QObject *object; QDeclarativeCompiledData *compiledData; - QDeclarativeGuard ctxt; + QDeclarativeGuardedContextData ctxt; const QDeclarativeVMEMetaData *metaData; int propOffset; diff --git a/src/declarative/util/qdeclarativepropertychanges.cpp b/src/declarative/util/qdeclarativepropertychanges.cpp index 9c2b1e6..8865e04 100644 --- a/src/declarative/util/qdeclarativepropertychanges.cpp +++ b/src/declarative/util/qdeclarativepropertychanges.cpp @@ -439,7 +439,8 @@ QDeclarativePropertyChanges::ActionList QDeclarativePropertyChanges::actions() if (d->isExplicit) { a.toValue = d->expressions.at(ii).second->value(); } else { - QDeclarativeBinding *newBinding = new QDeclarativeBinding(d->expressions.at(ii).second->expression(), object(), qmlContext(this)); + QDeclarativeBinding *newBinding = + new QDeclarativeBinding(d->expressions.at(ii).second->expression(), object(), qmlContext(this)); newBinding->setTarget(prop); a.toBinding = newBinding; a.deletableToBinding = true; -- cgit v0.12 From 48f89845732b2bf6b9e7a6dbe98efd6dfd5e3cff Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Mon, 15 Mar 2010 17:02:23 +1000 Subject: Optimization: Don't unnecessarily run VMEStack element constructors --- src/declarative/qml/qdeclarativevme_p.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/declarative/qml/qdeclarativevme_p.h b/src/declarative/qml/qdeclarativevme_p.h index 3f8aa15..1c6fd3c 100644 --- a/src/declarative/qml/qdeclarativevme_p.h +++ b/src/declarative/qml/qdeclarativevme_p.h @@ -70,8 +70,8 @@ class QDeclarativeContextData; template class QDeclarativeVMEStack { public: - QDeclarativeVMEStack() : index(-1), maxSize(N), data(fixedData) {} - ~QDeclarativeVMEStack() { if (data != fixedData) qFree(data); } + QDeclarativeVMEStack() : index(-1), maxSize(N), data((T *)fixedData) {} + ~QDeclarativeVMEStack() { if (data != (T *)fixedData) qFree(data); } bool isEmpty() const { return index == -1; } const T &top() const { return data[index]; } @@ -83,7 +83,7 @@ public: private: void realloc() { maxSize += N; - if (data != fixedData) { + if (data != (T *)fixedData) { data = (T*)qRealloc(data, maxSize * sizeof(T)); } else { data = (T*)qMalloc(maxSize * sizeof(T)); @@ -92,7 +92,7 @@ private: int index; int maxSize; T *data; - T fixedData[N]; + char fixedData[N * sizeof(T)]; }; class QDeclarativeVME -- cgit v0.12 From 34f0d9de68963499bfbc245639d0a099433734b1 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Mon, 15 Mar 2010 18:01:04 +1000 Subject: Fix test failures --- src/declarative/qml/qdeclarativecomponent.cpp | 2 -- src/declarative/qml/qdeclarativecontext.cpp | 1 + src/declarative/qml/qdeclarativecontext_p.h | 6 +++++- src/declarative/qml/qdeclarativeenginedebug.cpp | 2 +- src/declarative/qml/qdeclarativeinfo.cpp | 2 +- src/declarative/qml/qdeclarativevme.cpp | 4 +++- 6 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp index ffbd0fa..a280d7e 100644 --- a/src/declarative/qml/qdeclarativecomponent.cpp +++ b/src/declarative/qml/qdeclarativecomponent.cpp @@ -617,8 +617,6 @@ QDeclarativeComponentPrivate::beginCreate(QDeclarativeContextData *context, cons QObject *rv = begin(ctxt, ep, cc, start, count, &state, bindings); - if (!rv) ctxt->destroy(); - if (rv && !context->isInternal && ep->isDebugging) context->asQDeclarativeContextPrivate()->instances.append(rv); diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp index f1c961d..60fc1d1 100644 --- a/src/declarative/qml/qdeclarativecontext.cpp +++ b/src/declarative/qml/qdeclarativecontext.cpp @@ -624,6 +624,7 @@ void QDeclarativeContextData::addScript(const QDeclarativeParser::Object::Script void QDeclarativeContextData::setIdProperty(int idx, QObject *obj) { idValues[idx] = obj; + idValues[idx].context = this; } void QDeclarativeContextData::setIdPropertyData(QDeclarativeIntegerCache *data) diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h index 59b848f..d74aa33 100644 --- a/src/declarative/qml/qdeclarativecontext_p.h +++ b/src/declarative/qml/qdeclarativecontext_p.h @@ -168,9 +168,13 @@ public: // id guards struct ContextGuard : public QDeclarativeGuard { + ContextGuard() : context(0) {} inline ContextGuard &operator=(QObject *obj) { QDeclarativeGuard::operator=(obj); return *this; } - virtual void objectDestroyed(QObject *) { bindings.notify(); } + virtual void objectDestroyed(QObject *) { + if (!QObjectPrivate::get(context->contextObject)->wasDeleted) bindings.notify(); + } + QDeclarativeContextData *context; QDeclarativeNotifier bindings; }; ContextGuard *idValues; diff --git a/src/declarative/qml/qdeclarativeenginedebug.cpp b/src/declarative/qml/qdeclarativeenginedebug.cpp index da73178..a377b35 100644 --- a/src/declarative/qml/qdeclarativeenginedebug.cpp +++ b/src/declarative/qml/qdeclarativeenginedebug.cpp @@ -266,7 +266,7 @@ QDeclarativeEngineDebugServer::objectData(QObject *object) { QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(object); QDeclarativeObjectData rv; - if (ddata) { + if (ddata && ddata->outerContext) { rv.url = ddata->outerContext->url; rv.lineNumber = ddata->lineNumber; rv.columnNumber = ddata->columnNumber; diff --git a/src/declarative/qml/qdeclarativeinfo.cpp b/src/declarative/qml/qdeclarativeinfo.cpp index 87a9254..5146bb6 100644 --- a/src/declarative/qml/qdeclarativeinfo.cpp +++ b/src/declarative/qml/qdeclarativeinfo.cpp @@ -103,7 +103,7 @@ QDeclarativeInfo::QDeclarativeInfo(const QObject *object) QDeclarativeDeclarativeData *ddata = object?QDeclarativeDeclarativeData::get(object):0; pos += QLatin1String(" ("); if (ddata) { - if (ddata->outerContext) { + if (ddata->outerContext && !ddata->outerContext->url.isEmpty()) { pos += ddata->outerContext->url.toString(); pos += QLatin1Char(':'); pos += QString::number(ddata->lineNumber); diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp index b3c07f5..4457404 100644 --- a/src/declarative/qml/qdeclarativevme.cpp +++ b/src/declarative/qml/qdeclarativevme.cpp @@ -844,7 +844,9 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, if (isError()) { if (!stack.isEmpty()) { - delete stack.at(0); + delete stack.at(0); // ### What about failures in deferred creation? + } else { + ctxt->destroy(); } QDeclarativeEnginePrivate::clear(bindValues); -- cgit v0.12 From 83000e5def6787df01be6b8b423cb4aeadc2d9d1 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Tue, 16 Mar 2010 09:21:45 +1000 Subject: One url for an *unqualilfied* import is not special. Stops tst_qdeclarativelanguage passing when network transparency breaks. --- src/declarative/qml/qdeclarativeengine.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index e19e53f..7c21ab8 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1615,7 +1615,8 @@ public: if (s) { if (s->find(unqualifiedtype,vmajor,vminor,type_return,url_return)) return true; - if (s->urls.count() == 1 && !s->isLibrary[0] && url_return) { + if (s->urls.count() == 1 && !s->isLibrary[0] && url_return && s != &unqualifiedset) { + // qualified, and only 1 url *url_return = QUrl(s->urls[0]+QLatin1Char('/')).resolved(QUrl(QString::fromUtf8(unqualifiedtype) + QLatin1String(".qml"))); return true; } -- cgit v0.12 From d8aaf0f1823e1bcbfb687ac964187332b5c90259 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Wed, 17 Mar 2010 12:19:34 +1000 Subject: Verbose unexpected errors. --- tests/auto/declarative/qdeclarativewebview/tst_qdeclarativewebview.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/auto/declarative/qdeclarativewebview/tst_qdeclarativewebview.cpp b/tests/auto/declarative/qdeclarativewebview/tst_qdeclarativewebview.cpp index b63e14b..91115e4 100644 --- a/tests/auto/declarative/qdeclarativewebview/tst_qdeclarativewebview.cpp +++ b/tests/auto/declarative/qdeclarativewebview/tst_qdeclarativewebview.cpp @@ -122,8 +122,7 @@ void tst_qdeclarativewebview::cleanupTestCase() void tst_qdeclarativewebview::checkNoErrors(const QDeclarativeComponent& component) { // Wait until the component is ready - QTRY_VERIFY(component.isReady()); - + QTRY_VERIFY(component.isReady() || component.isError()); if (component.isError()) { QList errors = component.errors(); -- cgit v0.12 From 20470e30d11733ada5443ff993d8518aa14737ca Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Wed, 17 Mar 2010 12:56:52 +1000 Subject: Tests for default count(), get() values should be run on the worker list model instead of being ignored. Also do some cleaning up in the list model. --- src/declarative/util/qdeclarativelistmodel.cpp | 2 +- .../util/qdeclarativelistmodelworkeragent.cpp | 7 +--- .../qdeclarativelistmodel/data/model.qml | 10 ++--- .../qdeclarativelistmodel/data/script.js | 5 ++- .../tst_qdeclarativelistmodel.cpp | 44 ++++++++++++---------- 5 files changed, 33 insertions(+), 35 deletions(-) diff --git a/src/declarative/util/qdeclarativelistmodel.cpp b/src/declarative/util/qdeclarativelistmodel.cpp index 61e49ce..824e1b5 100644 --- a/src/declarative/util/qdeclarativelistmodel.cpp +++ b/src/declarative/util/qdeclarativelistmodel.cpp @@ -483,7 +483,7 @@ void QDeclarativeListModel::append(const QScriptValue& valuemap) qmlInfo(this) << tr("append: value is not an object"); return; } - + insert(count(), valuemap); } diff --git a/src/declarative/util/qdeclarativelistmodelworkeragent.cpp b/src/declarative/util/qdeclarativelistmodelworkeragent.cpp index ee43447..2951262 100644 --- a/src/declarative/util/qdeclarativelistmodelworkeragent.cpp +++ b/src/declarative/util/qdeclarativelistmodelworkeragent.cpp @@ -160,9 +160,6 @@ void QDeclarativeListModelWorkerAgent::insert(int index, const QScriptValue &val QScriptValue QDeclarativeListModelWorkerAgent::get(int index) const { - if (index < 0 || index >= count()) - return m_engine->undefinedValue(); - return m_copy->get(index); } @@ -206,7 +203,7 @@ bool QDeclarativeListModelWorkerAgent::event(QEvent *e) FlatListModel *orig = m_orig->m_flat; FlatListModel *copy = s->list->m_flat; if (!orig || !copy) { - qWarning("QML List worker: cannot synchronize lists"); + qWarning("QML ListModel worker: sync() failed"); return QObject::event(e); } orig->m_roles = copy->m_roles; @@ -233,8 +230,6 @@ bool QDeclarativeListModelWorkerAgent::event(QEvent *e) if (cc) emit m_orig->countChanged(m_copy->count()); - - //qDebug() << "------sync():" << m_copy->count() << s->list->count() << m_orig->count(); } } diff --git a/tests/auto/declarative/qdeclarativelistmodel/data/model.qml b/tests/auto/declarative/qdeclarativelistmodel/data/model.qml index 97e3030..ebd4ebf 100644 --- a/tests/auto/declarative/qdeclarativelistmodel/data/model.qml +++ b/tests/auto/declarative/qdeclarativelistmodel/data/model.qml @@ -4,20 +4,18 @@ Item { id: item property var model property bool done: false + property var result - function evalExpressionViaWorker(expr) { + function evalExpressionViaWorker(commands) { done = false - if (expr[expr.length-1] == ';') - expr = expr.substring(0, expr.length-1) - var cmds = expr.split(';') - - worker.sendMessage({'commands': cmds, 'model': model}) + worker.sendMessage({'commands': commands, 'model': model}) } WorkerScript { id: worker source: "script.js" onMessage: { + item.result = messageObject.result item.done = true } } diff --git a/tests/auto/declarative/qdeclarativelistmodel/data/script.js b/tests/auto/declarative/qdeclarativelistmodel/data/script.js index bfeeb8b..66a4acb 100644 --- a/tests/auto/declarative/qdeclarativelistmodel/data/script.js +++ b/tests/auto/declarative/qdeclarativelistmodel/data/script.js @@ -1,12 +1,13 @@ WorkerScript.onMessage = function(msg) { + var result = null try { for (var i=0; ideleteLater(); - loop.exec(); + QDeclarativeExpression e(eng.rootContext(), operations.last().toString(), &model); + if (QByteArray(QTest::currentDataTag()).startsWith("nested")) + QVERIFY(e.value().toInt() != result); + else + QCOMPARE(e.value().toInt(), result); + } + delete item; QTest::ignoreMessage(QtWarningMsg, "QThread: Destroyed while thread is still running"); qApp->processEvents(); } @@ -354,7 +358,7 @@ void tst_QDeclarativeListModel::convertNestedToFlat_fail() QTest::ignoreMessage(QtWarningMsg, "QML ListModel (unknown location) List contains nested list values and cannot be used from a worker script"); QVERIFY(QMetaObject::invokeMethod(item, "evalExpressionViaWorker", Q_ARG(QVariant, script))); - waitForWorker(item); + waitForWorker(item); QCOMPARE(model.count(), 2); -- cgit v0.12 From 9bf133d66f91e29b77ecff16b595280565ab0837 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 17 Mar 2010 13:14:24 +1000 Subject: Add ListView and GridView.indexAt() methods to get the index at a point. --- .../graphicsitems/qdeclarativegridview.cpp | 40 +++++++++++++++++----- .../graphicsitems/qdeclarativegridview_p.h | 4 ++- .../graphicsitems/qdeclarativelistview.cpp | 30 ++++++++++++++-- .../graphicsitems/qdeclarativelistview_p.h | 4 ++- 4 files changed, 65 insertions(+), 13 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index b1391f9..93f8d06 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -81,6 +81,10 @@ public: item->setPos(QPointF(row, col)); } } + bool contains(int x, int y) const { + return (x >= item->x() && x < item->x() + view->cellWidth() && + y >= item->y() && y < item->y() + view->cellHeight()); + } QDeclarativeItem *item; QDeclarativeGridView *view; @@ -115,7 +119,7 @@ public: void updateGrid(); void scheduleLayout(); - void layout(bool removed=false); + void layout(); void updateUnrequestedIndexes(); void updateUnrequestedPositions(); void updateTrackedItem(); @@ -274,7 +278,7 @@ public: || newGeometry.width() != oldGeometry.width()) { if (q->isComponentComplete()) { updateGrid(); - layout(); + scheduleLayout(); } } } @@ -538,7 +542,7 @@ void QDeclarativeGridViewPrivate::scheduleLayout() } } -void QDeclarativeGridViewPrivate::layout(bool removed) +void QDeclarativeGridViewPrivate::layout() { Q_Q(QDeclarativeGridView); layoutScheduled = false; @@ -547,8 +551,6 @@ void QDeclarativeGridViewPrivate::layout(bool removed) qreal colPos = visibleItems.first()->colPos(); int col = visibleIndex % columns; if (colPos != col * colSize()) { - if (removed) - rowPos -= rowSize(); colPos = col * colSize(); visibleItems.first()->setPosition(colPos, rowPos); } @@ -1503,7 +1505,7 @@ qreal QDeclarativeGridView::maxYExtent() const return QDeclarativeFlickable::maxYExtent(); qreal extent; if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) - extent = -(d->rowPosAt(count()-1) - d->highlightRangeEnd); + extent = -(d->endPosition() - d->highlightRangeEnd); else extent = -(d->endPosition() - height()); const qreal minY = minYExtent(); @@ -1530,7 +1532,7 @@ qreal QDeclarativeGridView::maxXExtent() const return QDeclarativeFlickable::maxXExtent(); qreal extent; if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) - extent = -(d->rowPosAt(count()-1) - d->highlightRangeEnd); + extent = -(d->endPosition() - d->highlightRangeEnd); else extent = -(d->endPosition() - height()); const qreal minX = minXExtent(); @@ -1744,6 +1746,28 @@ void QDeclarativeGridView::positionViewAtIndex(int index, int mode) d->fixupPosition(); } +/*! + \qmlmethod int GridView::indexAt(int x, int y) + + Returns the index of the visible item containing the point \a x, \a y in content + coordinates. If there is no item at the point specified, or the item is + not visible -1 is returned. + + If the item is outside the visible area, -1 is returned, regardless of + whether an item will exist at that point when scrolled into view. +*/ +int QDeclarativeGridView::indexAt(int x, int y) const +{ + Q_D(const QDeclarativeGridView); + for (int i = 0; i < d->visibleItems.count(); ++i) { + const FxGridItem *listItem = d->visibleItems.at(i); + if(listItem->contains(x, y)) + return listItem->index; + } + + return -1; +} + void QDeclarativeGridView::componentComplete() { Q_D(QDeclarativeGridView); @@ -2120,7 +2144,7 @@ void QDeclarativeGridView::itemsMoved(int from, int to, int count) d->releaseItem(item); } - d->layout(removedBeforeVisible); + d->layout(); } void QDeclarativeGridView::modelReset() diff --git a/src/declarative/graphicsitems/qdeclarativegridview_p.h b/src/declarative/graphicsitems/qdeclarativegridview_p.h index f14ec14..f032240 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview_p.h +++ b/src/declarative/graphicsitems/qdeclarativegridview_p.h @@ -140,6 +140,9 @@ public: enum PositionMode { Beginning, Center, End, Visible, Contain }; Q_ENUMS(PositionMode) + Q_INVOKABLE void positionViewAtIndex(int index, int mode); + Q_INVOKABLE int indexAt(int x, int y) const; + static QDeclarativeGridViewAttached *qmlAttachedProperties(QObject *); public Q_SLOTS: @@ -147,7 +150,6 @@ public Q_SLOTS: void moveCurrentIndexDown(); void moveCurrentIndexLeft(); void moveCurrentIndexRight(); - void positionViewAtIndex(int index, int mode); Q_SIGNALS: void countChanged(); diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index e5013a9..84281c8 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -129,6 +129,10 @@ public: item->setX(pos); } } + bool contains(int x, int y) const { + return (x >= item->x() && x < item->x() + item->width() && + y >= item->y() && y < item->y() + item->height()); + } QDeclarativeItem *item; QDeclarativeItem *section; @@ -393,9 +397,8 @@ public: QDeclarativeFlickablePrivate::itemGeometryChanged(item, newGeometry, oldGeometry); if (item != viewport) { if ((orient == QDeclarativeListView::Vertical && newGeometry.height() != oldGeometry.height()) - || newGeometry.width() != oldGeometry.width()) { - layout(); - fixupPosition(); + || (orient == QDeclarativeListView::Horizontal && newGeometry.width() != oldGeometry.width())) { + scheduleLayout(); } } } @@ -2260,6 +2263,27 @@ void QDeclarativeListView::positionViewAtIndex(int index, int mode) d->fixupPosition(); } +/*! + \qmlmethod int ListView::indexAt(int x, int y) + + Returns the index of the visible item containing the point \a x, \a y in content + coordinates. If there is no item at the point specified, or the item is + not visible -1 is returned. + + If the item is outside the visible area, -1 is returned, regardless of + whether an item will exist at that point when scrolled into view. +*/ +int QDeclarativeListView::indexAt(int x, int y) const +{ + Q_D(const QDeclarativeListView); + for (int i = 0; i < d->visibleItems.count(); ++i) { + const FxListItem *listItem = d->visibleItems.at(i); + if(listItem->contains(x, y)) + return listItem->index; + } + + return -1; +} void QDeclarativeListView::componentComplete() { diff --git a/src/declarative/graphicsitems/qdeclarativelistview_p.h b/src/declarative/graphicsitems/qdeclarativelistview_p.h index 0c2677c..1ea0080 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview_p.h +++ b/src/declarative/graphicsitems/qdeclarativelistview_p.h @@ -194,10 +194,12 @@ public: enum PositionMode { Beginning, Center, End, Visible, Contain }; Q_ENUMS(PositionMode) + Q_INVOKABLE void positionViewAtIndex(int index, int mode); + Q_INVOKABLE int indexAt(int x, int y) const; + public Q_SLOTS: void incrementCurrentIndex(); void decrementCurrentIndex(); - void positionViewAtIndex(int index, int mode); Q_SIGNALS: void countChanged(); -- cgit v0.12 From 7a8ed0580665e0240fc3539f29300606cfe7ccbc Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 17 Mar 2010 02:44:06 +0100 Subject: Register QGraphicsWidget type. Reviewed-by:TrustMe --- src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp index 2ac55a4..1a48cbd 100644 --- a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp @@ -138,6 +138,7 @@ void QDeclarativeItemModule::defineModule() qmlRegisterType(); qmlRegisterType(); qmlRegisterType(); + qmlRegisterType(); qmlRegisterType(); qmlRegisterType(); qmlRegisterType(); -- cgit v0.12 From 36dcc2be63375da1f73d87565397fd11bf445bf8 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 17 Mar 2010 14:02:17 +1000 Subject: Make states test work with smaller font size. --- tests/auto/declarative/qdeclarativestates/data/reset.qml | 4 ++-- tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/auto/declarative/qdeclarativestates/data/reset.qml b/tests/auto/declarative/qdeclarativestates/data/reset.qml index a0a2b8c..8e9b13a 100644 --- a/tests/auto/declarative/qdeclarativestates/data/reset.qml +++ b/tests/auto/declarative/qdeclarativestates/data/reset.qml @@ -5,9 +5,9 @@ Rectangle { height: 480 Text { id: theText - width: 50 + width: 40 wrap: true - text: "a text string that is longer than 50 pixels" + text: "a text string that is longer than 40 pixels" } states: State { diff --git a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp index eb0e2bd..c16a870 100644 --- a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp +++ b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp @@ -955,12 +955,12 @@ void tst_qdeclarativestates::reset() QDeclarativeText *text = rect->findChild(); QVERIFY(text != 0); - QCOMPARE(text->width(), qreal(50.)); + QCOMPARE(text->width(), qreal(40.)); QVERIFY(text->width() < text->height()); rect->setState("state1"); - QVERIFY(text->width() > 51); + QVERIFY(text->width() > 41); QVERIFY(text->width() > text->height()); } -- cgit v0.12 From 0830464f4a139234ba424b25590fc5d7bb5f4785 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 17 Mar 2010 05:14:46 +0100 Subject: MouseArea works now with any QGraphicsObject Easy, you just need to change the property. Reviewed-by:Martin Jones --- src/declarative/graphicsitems/qdeclarativemousearea.cpp | 4 ++-- src/declarative/graphicsitems/qdeclarativemousearea_p.h | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativemousearea.cpp b/src/declarative/graphicsitems/qdeclarativemousearea.cpp index 13195af..26242bc 100644 --- a/src/declarative/graphicsitems/qdeclarativemousearea.cpp +++ b/src/declarative/graphicsitems/qdeclarativemousearea.cpp @@ -58,12 +58,12 @@ QDeclarativeDrag::~QDeclarativeDrag() { } -QDeclarativeItem *QDeclarativeDrag::target() const +QGraphicsObject *QDeclarativeDrag::target() const { return _target; } -void QDeclarativeDrag::setTarget(QDeclarativeItem *t) +void QDeclarativeDrag::setTarget(QGraphicsObject *t) { if (_target == t) return; diff --git a/src/declarative/graphicsitems/qdeclarativemousearea_p.h b/src/declarative/graphicsitems/qdeclarativemousearea_p.h index 33422e2..db49b57 100644 --- a/src/declarative/graphicsitems/qdeclarativemousearea_p.h +++ b/src/declarative/graphicsitems/qdeclarativemousearea_p.h @@ -55,7 +55,7 @@ class Q_DECLARATIVE_EXPORT QDeclarativeDrag : public QObject Q_OBJECT Q_ENUMS(Axis) - Q_PROPERTY(QDeclarativeItem *target READ target WRITE setTarget NOTIFY targetChanged) + Q_PROPERTY(QGraphicsObject *target READ target WRITE setTarget NOTIFY targetChanged) Q_PROPERTY(Axis axis READ axis WRITE setAxis NOTIFY axisChanged) Q_PROPERTY(qreal minimumX READ xmin WRITE setXmin NOTIFY minimumXChanged) Q_PROPERTY(qreal maximumX READ xmax WRITE setXmax NOTIFY maximumXChanged) @@ -67,8 +67,8 @@ public: QDeclarativeDrag(QObject *parent=0); ~QDeclarativeDrag(); - QDeclarativeItem *target() const; - void setTarget(QDeclarativeItem *); + QGraphicsObject *target() const; + void setTarget(QGraphicsObject *); enum Axis { XAxis=0x01, YAxis=0x02, XandYAxis=0x03 }; Axis axis() const; @@ -92,7 +92,7 @@ Q_SIGNALS: void maximumYChanged(); private: - QDeclarativeItem *_target; + QGraphicsObject *_target; Axis _axis; qreal _xmin; qreal _xmax; -- cgit v0.12 From 13be084a5295a0406e6a0893e9fb1eeda5444940 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 17 Mar 2010 14:49:53 +1000 Subject: Fix warnings. --- src/declarative/graphicsitems/qdeclarativeanchors_p.h | 2 +- src/declarative/graphicsitems/qdeclarativeitem.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativeanchors_p.h b/src/declarative/graphicsitems/qdeclarativeanchors_p.h index 0b97e8c..f37fd6c 100644 --- a/src/declarative/graphicsitems/qdeclarativeanchors_p.h +++ b/src/declarative/graphicsitems/qdeclarativeanchors_p.h @@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) -class QDeclarativeAnchorsPrivate; +struct QDeclarativeAnchorsPrivate; class QDeclarativeAnchorLine; class Q_DECLARATIVE_EXPORT QDeclarativeAnchors : public QObject { diff --git a/src/declarative/graphicsitems/qdeclarativeitem.h b/src/declarative/graphicsitems/qdeclarativeitem.h index 9b85ba3..c88b1db 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.h +++ b/src/declarative/graphicsitems/qdeclarativeitem.h @@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) class QDeclarativeState; -class QDeclarativeAnchorLine; +struct QDeclarativeAnchorLine; class QDeclarativeTransition; class QDeclarativeKeyEvent; class QDeclarativeAnchors; -- cgit v0.12 From 2fc57473958c566b25be0f8715e72fa3e4811717 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 17 Mar 2010 14:54:19 +1000 Subject: Really fix warning. --- src/declarative/graphicsitems/qdeclarativeanchors_p.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativeanchors_p.h b/src/declarative/graphicsitems/qdeclarativeanchors_p.h index f37fd6c..1961fdd 100644 --- a/src/declarative/graphicsitems/qdeclarativeanchors_p.h +++ b/src/declarative/graphicsitems/qdeclarativeanchors_p.h @@ -54,8 +54,8 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) -struct QDeclarativeAnchorsPrivate; -class QDeclarativeAnchorLine; +class QDeclarativeAnchorsPrivate; +struct QDeclarativeAnchorLine; class Q_DECLARATIVE_EXPORT QDeclarativeAnchors : public QObject { Q_OBJECT -- cgit v0.12 From fab7cd962bc108a0f1f38ba0276aeae4f7f0399d Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 17 Mar 2010 15:51:35 +1000 Subject: Cleanup benchmark a little --- .../declarative/creation/tst_creation.cpp | 328 ++++++--------------- 1 file changed, 96 insertions(+), 232 deletions(-) diff --git a/tests/benchmarks/declarative/creation/tst_creation.cpp b/tests/benchmarks/declarative/creation/tst_creation.cpp index cd69cfe..743caa4 100644 --- a/tests/benchmarks/declarative/creation/tst_creation.cpp +++ b/tests/benchmarks/declarative/creation/tst_creation.cpp @@ -60,7 +60,7 @@ class tst_creation : public QObject { Q_OBJECT public: - tst_creation() {} + tst_creation(); private slots: void qobject_cpp(); @@ -68,27 +68,42 @@ private slots: void qobject_qmltype(); void qobject_alloc(); - void qdeclarativecontext(); + void qobject_10flat_qml(); + void qobject_10flat_cpp(); - void objects_qmltype_data(); - void objects_qmltype(); + void qobject_10tree_qml(); + void qobject_10tree_cpp(); - void qgraphicsitem(); - void qgraphicsobject(); - void qgraphicsitem14(); - void qgraphicsitem_tree14(); - - void itemtree_notree_cpp(); - void itemtree_objtree_cpp(); - void itemtree_cpp(); - void itemtree_data_cpp(); - void itemtree_qml(); - void itemtree_scene_cpp(); + void elements_data(); + void elements(); private: QDeclarativeEngine engine; }; +class TestType : public QObject +{ +Q_OBJECT +Q_PROPERTY(QDeclarativeListProperty resources READ resources); +Q_CLASSINFO("DefaultProperty", "resources"); +public: + TestType(QObject *parent = 0) + : QObject(parent) {} + + QDeclarativeListProperty resources() { + return QDeclarativeListProperty(this, 0, resources_append); + } + + static void resources_append(QDeclarativeListProperty *p, QObject *o) { + o->setParent(p->object); + } +}; + +tst_creation::tst_creation() +{ + qmlRegisterType("Qt.test", 1, 0, "TestType"); +} + inline QUrl TEST_FILE(const QString &filename) { return QUrl::fromLocalFile(QLatin1String(SRCDIR) + QLatin1String("/data/") + filename); @@ -115,6 +130,70 @@ void tst_creation::qobject_qml() } } +void tst_creation::qobject_10flat_qml() +{ + QDeclarativeComponent component(&engine); + component.setData("import Qt.test 1.0\nTestType { resources: [ TestType{},TestType{},TestType{},TestType{},TestType{},TestType{},TestType{},TestType{},TestType{},TestType{} ] }", QUrl()); + QObject *obj = component.create(); + delete obj; + + QBENCHMARK { + QObject *obj = component.create(); + delete obj; + } +} + +void tst_creation::qobject_10flat_cpp() +{ + QBENCHMARK { + QObject *item = new TestType; + new TestType(item); + new TestType(item); + new TestType(item); + new TestType(item); + new TestType(item); + new TestType(item); + new TestType(item); + new TestType(item); + new TestType(item); + new TestType(item); + delete item; + } +} + +void tst_creation::qobject_10tree_qml() +{ + QDeclarativeComponent component(&engine); + component.setData("import Qt.test 1.0\nTestType { TestType{ TestType { TestType{ TestType{ TestType{ TestType{ TestType{ TestType{ TestType{ TestType{ } } } } } } } } } } }", QUrl()); + + QObject *obj = component.create(); + delete obj; + + QBENCHMARK { + QObject *obj = component.create(); + delete obj; + } +} + +void tst_creation::qobject_10tree_cpp() +{ + QBENCHMARK { + QObject *item = new TestType; + QObject *root = item; + item = new TestType(item); + item = new TestType(item); + item = new TestType(item); + item = new TestType(item); + item = new TestType(item); + item = new TestType(item); + item = new TestType(item); + item = new TestType(item); + item = new TestType(item); + item = new TestType(item); + delete root; + } +} + void tst_creation::qobject_qmltype() { QDeclarativeType *t = QDeclarativeMetaType::qmlType("Qt/QtObject", 4, 6); @@ -154,15 +233,7 @@ void tst_creation::qobject_alloc() } } -void tst_creation::qdeclarativecontext() -{ - QBENCHMARK { - QDeclarativeContext *ctxt = new QDeclarativeContext(&engine); - delete ctxt; - } -} - -void tst_creation::objects_qmltype_data() +void tst_creation::elements_data() { QTest::addColumn("type"); @@ -171,7 +242,7 @@ void tst_creation::objects_qmltype_data() QTest::newRow(type.constData()) << type; } -void tst_creation::objects_qmltype() +void tst_creation::elements() { QFETCH(QByteArray, type); QDeclarativeType *t = QDeclarativeMetaType::qmlType(type, 4, 6); @@ -184,213 +255,6 @@ void tst_creation::objects_qmltype() } } -class QGraphicsItemDummy : public QGraphicsItem -{ -public: - virtual QRectF boundingRect() const { return QRectF(); } - virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) {} -}; - -class QGraphicsObjectDummy : public QGraphicsObject -{ -public: - virtual QRectF boundingRect() const { return QRectF(); } - virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) {} -}; - -void tst_creation::qgraphicsitem() -{ - QBENCHMARK { - QGraphicsItemDummy *i = new QGraphicsItemDummy(); - delete i; - } -} - -void tst_creation::qgraphicsobject() -{ - QBENCHMARK { - QGraphicsObjectDummy *i = new QGraphicsObjectDummy(); - delete i; - } -} - -void tst_creation::qgraphicsitem14() -{ - QBENCHMARK { - QGraphicsItemDummy *i1 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i2 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i3 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i4 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i5 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i6 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i7 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i8 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i9 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i10 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i11 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i12 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i13 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i14 = new QGraphicsItemDummy(); - - delete i1; - delete i2; - delete i3; - delete i4; - delete i5; - delete i6; - delete i7; - delete i8; - delete i9; - delete i10; - delete i11; - delete i12; - delete i13; - delete i14; - } -} - -void tst_creation::qgraphicsitem_tree14() -{ - QBENCHMARK { - // i1 - // +-------------------------+ - // i2 i3 - // +-----------+ +-----+-----+ - // i4 i5 i6 i7 - // +----+ +--+ +--+--+ +----+ - // i8 i9 i10 i11 i12 i13 i14 - - QGraphicsItemDummy *i1 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i2 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i3 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i4 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i5 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i6 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i7 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i8 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i9 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i10 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i11 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i12 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i13 = new QGraphicsItemDummy(); - QGraphicsItemDummy *i14 = new QGraphicsItemDummy(); - - i14->setParentItem(i7); - i13->setParentItem(i7); - i12->setParentItem(i6); - i11->setParentItem(i6); - i10->setParentItem(i5); - i9->setParentItem(i4); - i8->setParentItem(i4); - - i7->setParentItem(i3); - i6->setParentItem(i3); - i5->setParentItem(i2); - i4->setParentItem(i2); - - i3->setParentItem(i1); - i2->setParentItem(i1); - - delete i1; - } -} - -struct QDeclarativeGraphics_DerivedObject : public QObject -{ - void setParent_noEvent(QObject *parent) { - bool sce = d_ptr->sendChildEvents; - d_ptr->sendChildEvents = false; - setParent(parent); - d_ptr->sendChildEvents = sce; - } -}; - -inline void QDeclarativeGraphics_setParent_noEvent(QObject *object, QObject *parent) -{ - static_cast(object)->setParent_noEvent(parent); -} - -void tst_creation::itemtree_notree_cpp() -{ - QBENCHMARK { - QDeclarativeItem *item = new QDeclarativeItem; - for (int i = 0; i < 30; ++i) { - QDeclarativeItem *child = new QDeclarativeItem; - } - delete item; - } -} - -void tst_creation::itemtree_objtree_cpp() -{ - QBENCHMARK { - QDeclarativeItem *item = new QDeclarativeItem; - for (int i = 0; i < 30; ++i) { - QDeclarativeItem *child = new QDeclarativeItem; - QDeclarativeGraphics_setParent_noEvent(child,item); - } - delete item; - } -} - -void tst_creation::itemtree_cpp() -{ - QBENCHMARK { - QDeclarativeItem *item = new QDeclarativeItem; - for (int i = 0; i < 30; ++i) { - QDeclarativeItem *child = new QDeclarativeItem; - QDeclarativeGraphics_setParent_noEvent(child,item); - child->setParentItem(item); - } - delete item; - } -} - -void tst_creation::itemtree_data_cpp() -{ - QBENCHMARK { - QDeclarativeItem *item = new QDeclarativeItem; - for (int i = 0; i < 30; ++i) { - QDeclarativeItem *child = new QDeclarativeItem; - QDeclarativeGraphics_setParent_noEvent(child,item); - QDeclarativeListReference ref(item, "data"); - ref.append(child); - } - delete item; - } -} - -void tst_creation::itemtree_qml() -{ - QDeclarativeComponent component(&engine, TEST_FILE("item.qml")); - QObject *obj = component.create(); - delete obj; - - QBENCHMARK { - QObject *obj = component.create(); - delete obj; - } -} - -void tst_creation::itemtree_scene_cpp() -{ - QGraphicsScene scene; - QDeclarativeItem *root = new QDeclarativeItem; - scene.addItem(root); - QBENCHMARK { - QDeclarativeItem *item = new QDeclarativeItem; - for (int i = 0; i < 30; ++i) { - QDeclarativeItem *child = new QDeclarativeItem; - QDeclarativeGraphics_setParent_noEvent(child,item); - child->setParentItem(item); - } - item->setParentItem(root); - delete item; - } - delete root; -} - - QTEST_MAIN(tst_creation) #include "tst_creation.moc" -- cgit v0.12 From 0a52765f1c7fbd7d5286bcaab32cff35feb89a95 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 17 Mar 2010 15:59:46 +1000 Subject: Compile --- tests/benchmarks/declarative/binding/testtypes.cpp | 2 +- tests/benchmarks/declarative/declarative.pro | 3 ++- tests/benchmarks/declarative/painting/paintbenchmark.pro | 13 ------------- tests/benchmarks/declarative/painting/painting.pro | 13 +++++++++++++ .../declarative/qdeclarativecomponent/testtypes.cpp | 2 +- .../declarative/qdeclarativetime/qdeclarativetime.cpp | 2 +- tests/benchmarks/declarative/script/tst_script.cpp | 2 +- 7 files changed, 19 insertions(+), 18 deletions(-) delete mode 100644 tests/benchmarks/declarative/painting/paintbenchmark.pro create mode 100644 tests/benchmarks/declarative/painting/painting.pro diff --git a/tests/benchmarks/declarative/binding/testtypes.cpp b/tests/benchmarks/declarative/binding/testtypes.cpp index 043c8ab..1fc9ccd 100644 --- a/tests/benchmarks/declarative/binding/testtypes.cpp +++ b/tests/benchmarks/declarative/binding/testtypes.cpp @@ -42,5 +42,5 @@ void registerTypes() { - QML_REGISTER_TYPE(Test, 1, 0, MyQmlObject, MyQmlObject); + qmlRegisterType("Test", 1, 0, "MyQmlObject"); } diff --git a/tests/benchmarks/declarative/declarative.pro b/tests/benchmarks/declarative/declarative.pro index 8c0ed42..38ea6c4 100644 --- a/tests/benchmarks/declarative/declarative.pro +++ b/tests/benchmarks/declarative/declarative.pro @@ -2,9 +2,10 @@ TEMPLATE = subdirs SUBDIRS += \ binding \ creation \ + painting \ pointers \ qdeclarativecomponent \ qdeclarativeimage \ qdeclarativemetaproperty \ script \ -# qdeclarativetime + qdeclarativetime diff --git a/tests/benchmarks/declarative/painting/paintbenchmark.pro b/tests/benchmarks/declarative/painting/paintbenchmark.pro deleted file mode 100644 index 2f98e8b..0000000 --- a/tests/benchmarks/declarative/painting/paintbenchmark.pro +++ /dev/null @@ -1,13 +0,0 @@ -###################################################################### -# Automatically generated by qmake (2.01a) fr 29. jan 13:57:52 2010 -###################################################################### - -TEMPLATE = app -TARGET = -DEPENDPATH += . -INCLUDEPATH += . - -# Input -SOURCES += paintbenchmark.cpp -QT += opengl -CONFIG += console diff --git a/tests/benchmarks/declarative/painting/painting.pro b/tests/benchmarks/declarative/painting/painting.pro new file mode 100644 index 0000000..2f98e8b --- /dev/null +++ b/tests/benchmarks/declarative/painting/painting.pro @@ -0,0 +1,13 @@ +###################################################################### +# Automatically generated by qmake (2.01a) fr 29. jan 13:57:52 2010 +###################################################################### + +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +# Input +SOURCES += paintbenchmark.cpp +QT += opengl +CONFIG += console diff --git a/tests/benchmarks/declarative/qdeclarativecomponent/testtypes.cpp b/tests/benchmarks/declarative/qdeclarativecomponent/testtypes.cpp index acdc395..7bc6ca2 100644 --- a/tests/benchmarks/declarative/qdeclarativecomponent/testtypes.cpp +++ b/tests/benchmarks/declarative/qdeclarativecomponent/testtypes.cpp @@ -42,5 +42,5 @@ void registerTypes() { - QML_REGISTER_TYPE(Qt.test, 4, 6, MyQmlObject, MyQmlObject); + qmlRegisterType("Qt.test", 4, 6, "MyQmlObject"); } diff --git a/tests/benchmarks/declarative/qdeclarativetime/qdeclarativetime.cpp b/tests/benchmarks/declarative/qdeclarativetime/qdeclarativetime.cpp index a924337..20f0d93d 100644 --- a/tests/benchmarks/declarative/qdeclarativetime/qdeclarativetime.cpp +++ b/tests/benchmarks/declarative/qdeclarativetime/qdeclarativetime.cpp @@ -156,7 +156,7 @@ int main(int argc, char ** argv) { QApplication app(argc, argv); - QML_REGISTER_TYPE(QDeclarativeTime, 1, 0, Timer, Timer); + qmlRegisterType("QDeclarativeTime", 1, 0, "Timer"); uint iterations = 1024; QString filename; diff --git a/tests/benchmarks/declarative/script/tst_script.cpp b/tests/benchmarks/declarative/script/tst_script.cpp index 9dd4076..8ea6dcd 100644 --- a/tests/benchmarks/declarative/script/tst_script.cpp +++ b/tests/benchmarks/declarative/script/tst_script.cpp @@ -144,7 +144,7 @@ int TestObject::x() void tst_script::initTestCase() { - QML_REGISTER_TYPE(Qt.test, 1, 0, TestObject, TestObject); + qmlRegisterType("Qt.test", 1, 0, "TestObject"); } -- cgit v0.12 From 1c4bb7a951ae50983a38acaf633eab272d3603b9 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Wed, 17 Mar 2010 16:26:20 +1000 Subject: Allow enum constants as list element properties. Task-number: QTBUG-5974 --- src/declarative/qml/qdeclarativecompiler.cpp | 23 ++++++++++++++++++++++ src/declarative/qml/qdeclarativecompiler_p.h | 2 ++ src/declarative/qml/qdeclarativecustomparser.cpp | 12 +++++++++++ src/declarative/qml/qdeclarativecustomparser_p.h | 7 +++++++ src/declarative/util/qdeclarativelistmodel.cpp | 20 +++++++++++++++---- .../tst_qdeclarativelistmodel.cpp | 5 +++-- 6 files changed, 63 insertions(+), 6 deletions(-) diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index 06ff47c..5dc3858 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -825,7 +825,9 @@ bool QDeclarativeCompiler::buildObject(Object *obj, const BindingContext &ctxt) if (isCustomParser && !customProps.isEmpty()) { QDeclarativeCustomParser *cp = output->types.at(obj->type).type->customParser(); cp->clearErrors(); + cp->compiler = this; obj->custom = cp->compile(customProps); + cp->compiler = 0; foreach (QDeclarativeError err, cp->errors()) { err.setUrl(output->url); exceptions << err; @@ -2184,6 +2186,27 @@ bool QDeclarativeCompiler::testQualifiedEnumAssignment(const QMetaProperty &prop return true; } +// Similar logic to above, but not knowing target property. +int QDeclarativeCompiler::evaluateEnum(const QByteArray& script) const +{ + int dot = script.find('.'); + if (dot > 0) { + QDeclarativeType *type = 0; + QDeclarativeEnginePrivate::get(engine)->resolveType(unit->imports, script.left(dot), &type, 0, 0, 0, 0); + if (!type) + return -1; + const QMetaObject *mo = type->metaObject(); + const char *key = script.constData() + dot+1; + int i = mo->enumeratorCount(); + while (i--) { + int v = mo->enumerator(i).keyToValue(key); + if (v >= 0) + return v; + } + } + return -1; +} + // Ensures that the dynamic meta specification on obj is valid bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeParser::Object *obj) { diff --git a/src/declarative/qml/qdeclarativecompiler_p.h b/src/declarative/qml/qdeclarativecompiler_p.h index 05b556e..a81259b 100644 --- a/src/declarative/qml/qdeclarativecompiler_p.h +++ b/src/declarative/qml/qdeclarativecompiler_p.h @@ -161,6 +161,8 @@ public: static QMetaMethod findSignalByName(const QMetaObject *, const QByteArray &name); + int evaluateEnum(const QByteArray& script) const; // for QDeclarativeCustomParser::evaluateEnum + private: static void reset(QDeclarativeCompiledData *); diff --git a/src/declarative/qml/qdeclarativecustomparser.cpp b/src/declarative/qml/qdeclarativecustomparser.cpp index 67f0963..a3a511c 100644 --- a/src/declarative/qml/qdeclarativecustomparser.cpp +++ b/src/declarative/qml/qdeclarativecustomparser.cpp @@ -43,6 +43,7 @@ #include "qdeclarativecustomparser_p_p.h" #include "qdeclarativeparser_p.h" +#include "qdeclarativecompiler_p.h" #include @@ -260,4 +261,15 @@ void QDeclarativeCustomParser::error(const QDeclarativeCustomParserNode& node, c exceptions << error; } +/*! + If \a script is a simply enum expression (eg. Text.AlignLeft), + returns the integer equivalent (eg. 1). + + Otherwise, returns -1. +*/ +int QDeclarativeCustomParser::evaluateEnum(const QByteArray& script) const +{ + return compiler->evaluateEnum(script); +} + QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativecustomparser_p.h b/src/declarative/qml/qdeclarativecustomparser_p.h index 39bd43c..f9bf513 100644 --- a/src/declarative/qml/qdeclarativecustomparser_p.h +++ b/src/declarative/qml/qdeclarativecustomparser_p.h @@ -66,6 +66,8 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) +class QDeclarativeCompiler; + class QDeclarativeCustomParserPropertyPrivate; class Q_DECLARATIVE_EXPORT QDeclarativeCustomParserProperty { @@ -111,6 +113,7 @@ private: class Q_DECLARATIVE_EXPORT QDeclarativeCustomParser { public: + QDeclarativeCustomParser() : compiler(0) {} virtual ~QDeclarativeCustomParser() {} void clearErrors(); @@ -124,8 +127,12 @@ protected: void error(const QDeclarativeCustomParserProperty&, const QString& description); void error(const QDeclarativeCustomParserNode&, const QString& description); + int evaluateEnum(const QByteArray&) const; + private: QList exceptions; + QDeclarativeCompiler *compiler; + friend class QDeclarativeCompiler; }; #if 0 diff --git a/src/declarative/util/qdeclarativelistmodel.cpp b/src/declarative/util/qdeclarativelistmodel.cpp index 824e1b5..32a996d 100644 --- a/src/declarative/util/qdeclarativelistmodel.cpp +++ b/src/declarative/util/qdeclarativelistmodel.cpp @@ -94,9 +94,12 @@ QDeclarativeListModelParser::ListInstruction *QDeclarativeListModelParser::ListM } \endcode - Roles (properties) must begin with a lower-case letter. The above example defines a + Roles (properties) must begin with a lower-case letter.The above example defines a ListModel containing three elements, with the roles "name" and "cost". + Values must be simple constants - either strings (quoted), bools (true, false), numbers, + or enum values (like Text.AlignHCenter). + The defined model can be used in views such as ListView: \code Component { @@ -167,6 +170,8 @@ QDeclarativeListModelParser::ListInstruction *QDeclarativeListModelParser::ListM } \endcode + \section2 Modifying list models + The content of a ListModel may be created and modified using the clear(), append(), and set() methods. For example: @@ -674,10 +679,17 @@ bool QDeclarativeListModelParser::compileProperty(const QDeclarativeCustomParser d += char(variant.asBoolean()); } else if (variant.isScript()) { if (definesEmptyList(variant.asScript())) { - d[0] = 0; // QDeclarativeParser::Variant::Invalid - marks empty list + d[0] = char(QDeclarativeParser::Variant::Invalid); // marks empty list } else { - error(prop, QDeclarativeListModel::tr("ListElement: cannot use script for property value")); - return false; + QByteArray script = variant.asScript().toUtf8(); + int v = evaluateEnum(script); + if (v<0) { + error(prop, QDeclarativeListModel::tr("ListElement: cannot use script for property value")); + return false; + } else { + d[0] = char(QDeclarativeParser::Variant::Number); + d += QByteArray::number(v); + } } } d.append('\0'); diff --git a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp index 78e5912..576fe21 100644 --- a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp +++ b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include #include +#include #include #include #include @@ -459,7 +460,7 @@ void tst_QDeclarativeListModel::static_types_data() QTest::newRow("enum") << "ListElement { foo: Text.AlignHCenter }" - << QVariant("QTBUG-5974:ListElement: constant script support for property value"); + << QVariant(double(QDeclarativeText::AlignHCenter)); } void tst_QDeclarativeListModel::static_types() @@ -516,7 +517,7 @@ void tst_QDeclarativeListModel::error_data() QTest::newRow("bindings not allowed in ListElement") << "import Qt 4.6\nRectangle { id: rect; ListModel { ListElement { foo: rect.color } } }" - << "ListElement: cannot use script for property value"; // but note QTBUG-5974 + << "ListElement: cannot use script for property value"; QTest::newRow("random object list properties allowed in ListElement") << "import Qt 4.6\nListModel { ListElement { foo: [ ListElement { bar: 123 } ] } }" -- cgit v0.12 From caea4098b275eaecdf0c5c4019b897e47d8d9c13 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 17 Mar 2010 16:49:13 +1000 Subject: Readd the itemtree benchmarks for comparison purposes. --- .../declarative/creation/tst_creation.cpp | 102 +++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/tests/benchmarks/declarative/creation/tst_creation.cpp b/tests/benchmarks/declarative/creation/tst_creation.cpp index 743caa4..7aec32a 100644 --- a/tests/benchmarks/declarative/creation/tst_creation.cpp +++ b/tests/benchmarks/declarative/creation/tst_creation.cpp @@ -74,6 +74,13 @@ private slots: void qobject_10tree_qml(); void qobject_10tree_cpp(); + void itemtree_notree_cpp(); + void itemtree_objtree_cpp(); + void itemtree_cpp(); + void itemtree_data_cpp(); + void itemtree_qml(); + void itemtree_scene_cpp(); + void elements_data(); void elements(); @@ -233,6 +240,101 @@ void tst_creation::qobject_alloc() } } +struct QDeclarativeGraphics_DerivedObject : public QObject +{ + void setParent_noEvent(QObject *parent) { + bool sce = d_ptr->sendChildEvents; + d_ptr->sendChildEvents = false; + setParent(parent); + d_ptr->sendChildEvents = sce; + } +}; + +inline void QDeclarativeGraphics_setParent_noEvent(QObject *object, QObject *parent) +{ + static_cast(object)->setParent_noEvent(parent); +} + +void tst_creation::itemtree_notree_cpp() +{ + QBENCHMARK { + QDeclarativeItem *item = new QDeclarativeItem; + for (int i = 0; i < 30; ++i) { + QDeclarativeItem *child = new QDeclarativeItem; + } + delete item; + } +} + +void tst_creation::itemtree_objtree_cpp() +{ + QBENCHMARK { + QDeclarativeItem *item = new QDeclarativeItem; + for (int i = 0; i < 30; ++i) { + QDeclarativeItem *child = new QDeclarativeItem; + QDeclarativeGraphics_setParent_noEvent(child,item); + } + delete item; + } +} + +void tst_creation::itemtree_cpp() +{ + QBENCHMARK { + QDeclarativeItem *item = new QDeclarativeItem; + for (int i = 0; i < 30; ++i) { + QDeclarativeItem *child = new QDeclarativeItem; + QDeclarativeGraphics_setParent_noEvent(child,item); + child->setParentItem(item); + } + delete item; + } +} + +void tst_creation::itemtree_data_cpp() +{ + QBENCHMARK { + QDeclarativeItem *item = new QDeclarativeItem; + for (int i = 0; i < 30; ++i) { + QDeclarativeItem *child = new QDeclarativeItem; + QDeclarativeGraphics_setParent_noEvent(child,item); + QDeclarativeListReference ref(item, "data"); + ref.append(child); + } + delete item; + } +} + +void tst_creation::itemtree_qml() +{ + QDeclarativeComponent component(&engine, TEST_FILE("item.qml")); + QObject *obj = component.create(); + delete obj; + + QBENCHMARK { + QObject *obj = component.create(); + delete obj; + } +} + +void tst_creation::itemtree_scene_cpp() +{ + QGraphicsScene scene; + QDeclarativeItem *root = new QDeclarativeItem; + scene.addItem(root); + QBENCHMARK { + QDeclarativeItem *item = new QDeclarativeItem; + for (int i = 0; i < 30; ++i) { + QDeclarativeItem *child = new QDeclarativeItem; + QDeclarativeGraphics_setParent_noEvent(child,item); + child->setParentItem(item); + } + item->setParentItem(root); + delete item; + } + delete root; +} + void tst_creation::elements_data() { QTest::addColumn("type"); -- cgit v0.12 From c3302ae058fd1cfed9b95d098fd88ff695c95460 Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Wed, 17 Mar 2010 17:14:42 +1000 Subject: Emits itemsRemoved() in QDeclarativeListModel::remove. --- src/declarative/util/qdeclarativelistmodel.cpp | 30 ++++++++++++++------------ 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/declarative/util/qdeclarativelistmodel.cpp b/src/declarative/util/qdeclarativelistmodel.cpp index 824e1b5..45a3cf7 100644 --- a/src/declarative/util/qdeclarativelistmodel.cpp +++ b/src/declarative/util/qdeclarativelistmodel.cpp @@ -303,7 +303,7 @@ QDeclarativeListModelWorkerAgent *QDeclarativeListModel::agent() return 0; } - m_agent = new QDeclarativeListModelWorkerAgent(this); + m_agent = new QDeclarativeListModelWorkerAgent(this); return m_agent; } @@ -383,8 +383,10 @@ void QDeclarativeListModel::remove(int index) else m_nested->remove(index); - if (!m_isWorkerCopy) + if (!m_isWorkerCopy) { + emit itemsRemoved(index, 1); emit countChanged(this->count()); + } } /*! @@ -612,7 +614,7 @@ bool QDeclarativeListModelParser::compileProperty(const QDeclarativeCustomParser const QVariant &value = values.at(ii); if(value.userType() == qMetaTypeId()) { - QDeclarativeCustomParserNode node = + QDeclarativeCustomParserNode node = qvariant_cast(value); { @@ -659,7 +661,7 @@ bool QDeclarativeListModelParser::compileProperty(const QDeclarativeCustomParser } else { - QDeclarativeParser::Variant variant = + QDeclarativeParser::Variant variant = qvariant_cast(value); int ref = data.count(); @@ -710,15 +712,15 @@ QByteArray QDeclarativeListModelParser::compile(const QListdataOffset = sizeof(ListModelData) + + lmd->dataOffset = sizeof(ListModelData) + instr.count() * sizeof(ListInstruction); lmd->instrCount = instr.count(); for (int ii = 0; ii < instr.count(); ++ii) @@ -904,7 +906,7 @@ QScriptValue FlatListModel::get(int index) const QScriptValue rv = scriptEngine->newObject(); QHash row = m_values.at(index); - for (QHash::ConstIterator iter = row.begin(); iter != row.end(); ++iter) + for (QHash::ConstIterator iter = row.begin(); iter != row.end(); ++iter) rv.setProperty(m_roles.value(iter.key()), qScriptValueFromValue(scriptEngine, iter.value())); return rv; @@ -930,7 +932,7 @@ void FlatListModel::setProperty(int index, const QString& property, const QVaria m_roles.insert(role, property); m_strings.insert(property, role); } else { - role = iter.value(); + role = iter.value(); } roles->append(role); @@ -977,7 +979,7 @@ bool FlatListModel::addValue(const QScriptValue &value, QHash *ro m_roles.insert(role, name); iter = m_strings.insert(name, role); if (roles) - roles->append(role); + roles->append(role); } row->insert(*iter, v); } @@ -1031,7 +1033,7 @@ QVariant NestedListModel::valueForNode(ModelNode *node, bool *hasNested) const return QVariant::fromValue(rv); } else { return QVariant(); - } + } } QHash NestedListModel::data(int index, const QList &roles, bool *hasNested) const @@ -1041,7 +1043,7 @@ QHash NestedListModel::data(int index, const QList &roles, bo QHash rv; ModelNode *node = qvariant_cast(_root->values.at(index)); - if (!node) + if (!node) return rv; for (int ii = 0; ii < roles.count(); ++ii) { @@ -1148,7 +1150,7 @@ bool NestedListModel::append(const QScriptValue& valuemap) QScriptValue NestedListModel::get(int index) const { ModelNode *node = qvariant_cast(_root->values.at(index)); - if (!node) + if (!node) return 0; QDeclarativeEngine *eng = qmlEngine(m_listModel); if (!eng) { @@ -1204,7 +1206,7 @@ void NestedListModel::checkRoles() const if (!roleStrings.contains(role)) roleStrings.append(role); } - } + } } _rolesOk = true; -- cgit v0.12 From 2637e50d25d6b025b687760c90aed36529b8c918 Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Wed, 17 Mar 2010 17:21:42 +1000 Subject: Add/delete albums in photoviewer. --- .../photoviewer/PhotoViewerCore/AlbumDelegate.qml | 23 +++++++--- .../photoviewer/PhotoViewerCore/Button.qml | 25 +++++++++++ .../photoviewer/PhotoViewerCore/Tag.qml | 51 ++++++++++++++++------ .../declarative/photoviewer/PhotoViewerCore/qmldir | 1 + demos/declarative/photoviewer/photoviewer.qml | 19 ++++++-- 5 files changed, 95 insertions(+), 24 deletions(-) create mode 100644 demos/declarative/photoviewer/PhotoViewerCore/Button.qml diff --git a/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml b/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml index d71834e..fca7232 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml +++ b/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml @@ -39,9 +39,8 @@ Component { } PathView { - id: photosPathView; model: visualModel.parts.stack + id: photosPathView; model: visualModel.parts.stack; pathItemCount: 5 anchors.centerIn: parent; anchors.verticalCenterOffset: -20 - pathItemCount: 5 path: Path { PathAttribute { name: 'z'; value: 9999.0 } PathLine { x: 1; y: 1 } @@ -51,24 +50,34 @@ Component { Tag { anchors.horizontalCenter: parent.horizontalCenter; anchors.bottom: parent.bottom - label: tag; rotation: Math.random() * (2 * 6 + 1) - 6 + frontLabel: tag; backLabel: "Delete"; rotation: Math.random() * (2 * 6 + 1) - 6 + flipped: mainWindow.editMode } - MouseArea { anchors.fill: parent; onClicked: albumWrapper.state = 'inGrid' } + MouseArea { + anchors.fill: parent + onClicked: { + if (mainWindow.editMode) { + photosModel.remove(index) + } else { + albumWrapper.state = 'inGrid' + } + } + } states: [ State { name: 'inGrid' PropertyChanges { target: photosGridView; interactive: true } PropertyChanges { target: albumsShade; opacity: 1 } - PropertyChanges{ target: backTag; onClicked: albumWrapper.state = ''; y: 6 } + PropertyChanges { target: backButton; onClicked: albumWrapper.state = ''; y: 6 } }, State { name: 'fullscreen'; extend: 'inGrid' PropertyChanges { target: photosGridView; interactive: false } PropertyChanges { target: photosListView; interactive: true } PropertyChanges { target: photosShade; opacity: 1 } - PropertyChanges{ target: backTag; y: -backTag.height - 8 } + PropertyChanges { target: backButton; y: -backTag.height - 8 } } ] @@ -78,7 +87,7 @@ Component { SequentialAnimation { NumberAnimation { properties: 'opacity'; duration: 250 } PauseAnimation { duration: 350 } - NumberAnimation { target: backTag; properties: "y"; duration: 200; easing.type: "OutQuad" } + NumberAnimation { target: backButton; properties: "y"; duration: 200; easing.type: "OutQuad" } } }, Transition { diff --git a/demos/declarative/photoviewer/PhotoViewerCore/Button.qml b/demos/declarative/photoviewer/PhotoViewerCore/Button.qml new file mode 100644 index 0000000..fb28314 --- /dev/null +++ b/demos/declarative/photoviewer/PhotoViewerCore/Button.qml @@ -0,0 +1,25 @@ +import Qt 4.6 + +Item { + id: container + + property alias label: labelText.text + signal clicked + + width: labelText.width + 70 ; height: labelText.height + 18 + + BorderImage { + anchors { fill: container; leftMargin: -6; topMargin: -6; rightMargin: -8; bottomMargin: -8 } + source: 'images/box-shadow.png'; smooth: true + border.left: 10; border.top: 10; border.right: 10; border.bottom: 10 + } + + Image { anchors.fill: parent; source: "images/cardboard.png"; smooth: true } + + Text { id: labelText; font.pixelSize: 15; anchors.centerIn: parent; smooth: true } + + MouseArea { + anchors { fill: parent; leftMargin: -20; topMargin: -20; rightMargin: -20; bottomMargin: -20 } + onClicked: container.clicked() + } +} diff --git a/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml b/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml index ee11d05..d32fcd0 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml +++ b/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml @@ -1,22 +1,45 @@ import Qt 4.6 -Item { - id: container +Flipable { + id: flipable - property alias label: labelText.text - signal clicked + property alias frontLabel: frontButton.label + property alias backLabel: backButton.label - width: labelText.width + 70 ; height: labelText.height + 18 + property int angle: 0 + property bool flipped: false - BorderImage { - anchors { fill: container; leftMargin: -6; topMargin: -6; rightMargin: -8; bottomMargin: -8 } - source: 'images/box-shadow.png'; smooth: true - border.left: 10; border.top: 10; border.right: 10; border.bottom: 10 + signal frontClicked + signal backClicked + + front: Button { + id: frontButton; anchors.centerIn: parent; anchors.verticalCenterOffset: -20 + onClicked: flipable.frontClicked() + } + + back: Button { + id: backButton; anchors.centerIn: parent; anchors.verticalCenterOffset: -20 + onClicked: flipable.backClicked() + } + + transform: Rotation { + origin.x: flipable.width / 2; origin.y: flipable.height / 2 + axis.x: 0; axis.y: 1; axis.z: 0 + angle: flipable.angle + } + + states: State { + name: "back"; when: flipable.flipped + PropertyChanges { target: flipable; angle: 180 } } - Image { anchors.fill: parent; source: "images/cardboard.png"; smooth: true } - Text { id: labelText; font.pixelSize: 15; anchors.centerIn: parent; smooth: true } - MouseArea { - anchors { fill: parent; leftMargin: -20; topMargin: -20; rightMargin: -20; bottomMargin: -20 } - onClicked: container.clicked() + + transitions: Transition { + ParallelAnimation { + NumberAnimation { properties: "angle"; duration: 400 } + SequentialAnimation { + NumberAnimation { target: flipable; property: "scale"; to: 0.8; duration: 200 } + NumberAnimation { target: flipable; property: "scale"; to: 1.0; duration: 200 } + } + } } } diff --git a/demos/declarative/photoviewer/PhotoViewerCore/qmldir b/demos/declarative/photoviewer/PhotoViewerCore/qmldir index 4821faa..f94a560 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/qmldir +++ b/demos/declarative/photoviewer/PhotoViewerCore/qmldir @@ -2,5 +2,6 @@ AlbumDelegate AlbumDelegate.qml PhotoDelegate PhotoDelegate.qml ProgressBar ProgressBar.qml RssModel RssModel.qml +Button Button.qml Tag Tag.qml BusyIndicator BusyIndicator.qml diff --git a/demos/declarative/photoviewer/photoviewer.qml b/demos/declarative/photoviewer/photoviewer.qml index 5ce02f3..02134ac 100644 --- a/demos/declarative/photoviewer/photoviewer.qml +++ b/demos/declarative/photoviewer/photoviewer.qml @@ -6,6 +6,7 @@ Rectangle { property real downloadProgress: 0 property bool imageLoading: false + property bool editMode: false width: 800; height: 480; color: "#d5d6d8" @@ -21,8 +22,20 @@ Rectangle { VisualDataModel { id: albumVisualModel; model: photosModel; delegate: AlbumDelegate {} } GridView { - width: parent.width; height: parent.height; cellWidth: 210; cellHeight: 220; model: albumVisualModel.parts.album - visible: albumsShade.opacity != 1.0 + id: albumView; width: parent.width; height: parent.height; cellWidth: 210; cellHeight: 220 + model: albumVisualModel.parts.album; visible: albumsShade.opacity != 1.0 + } + + Column { + spacing: 20; anchors { bottom: parent.bottom; right: parent.right; rightMargin: 20; bottomMargin: 20 } + Button { id: deleteButton; label: "Edit"; rotation: -2; onClicked: mainWindow.editMode = !mainWindow.editMode } + Button { + id: newButton; label: "New"; rotation: 3 + onClicked: { + photosModel.append( { tag: "" } ) + albumView.positionViewAtIndex(albumView.count - 1, GridView.Contain) + } + } } Rectangle { @@ -32,7 +45,7 @@ Rectangle { ListView { anchors.fill: parent; model: albumVisualModel.parts.browser; interactive: false } - Tag { id: backTag; label: "Back"; rotation: 3; x: parent.width - backTag.width - 6; y: -backTag.height - 8 } + Button { id: backButton; label: "Back"; rotation: 3; x: parent.width - backButton.width - 6; y: -backButton.height - 8 } Rectangle { id: photosShade; color: 'black'; width: parent.width; height: parent.height; opacity: 0; visible: opacity != 0.0 } -- cgit v0.12 From 8b6f892ae48d296875a295381d4f67a8a5968a30 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 17 Mar 2010 17:23:44 +1000 Subject: Crash --- src/declarative/qml/qdeclarativeexpression.cpp | 8 +++++++- src/declarative/qml/qdeclarativenotifier_p.h | 20 ++++++++++++-------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp index 609eb39..20863c7 100644 --- a/src/declarative/qml/qdeclarativeexpression.cpp +++ b/src/declarative/qml/qdeclarativeexpression.cpp @@ -95,7 +95,13 @@ QDeclarativeExpressionPrivate::QDeclarativeExpressionPrivate(QDeclarativeExpress QDeclarativeExpressionPrivate::~QDeclarativeExpressionPrivate() { - if (data) { data->q = 0; data->release(); data = 0; } + if (data) { + delete [] data->guardList; + data->guardList = 0; + data->q = 0; + data->release(); + data = 0; + } } void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, const QString &expr, diff --git a/src/declarative/qml/qdeclarativenotifier_p.h b/src/declarative/qml/qdeclarativenotifier_p.h index a0e6b43..2a8087e 100644 --- a/src/declarative/qml/qdeclarativenotifier_p.h +++ b/src/declarative/qml/qdeclarativenotifier_p.h @@ -112,18 +112,22 @@ private: QDeclarativeNotifier::QDeclarativeNotifier() : endpoints(0) { - QDeclarativeNotifierEndpoint *endpoint = endpoints; - while (endpoint) { - QDeclarativeNotifierEndpoint *next = endpoint->asNotifier()->next; - endpoint->asNotifier()->next = 0; - endpoint->asNotifier()->prev = 0; - endpoint->asNotifier()->notifier = 0; - endpoint = next; - } } QDeclarativeNotifier::~QDeclarativeNotifier() { + QDeclarativeNotifierEndpoint *endpoint = endpoints; + while (endpoint) { + QDeclarativeNotifierEndpoint::Notifier *n = endpoint->asNotifier(); + endpoint = n->next; + + n->next = 0; + n->prev = 0; + n->notifier = 0; + if (n->disconnected) *n->disconnected = 0; + n->disconnected = 0; + } + endpoints = 0; } void QDeclarativeNotifier::notify() -- cgit v0.12 From 77d7ed2ca248bfcf6942e6795def38546a91b89b Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 17 Mar 2010 17:26:26 +1000 Subject: Don't use Qt3 support methods. --- src/declarative/qml/qdeclarativecompiler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index 5dc3858..c085556 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -2189,7 +2189,7 @@ bool QDeclarativeCompiler::testQualifiedEnumAssignment(const QMetaProperty &prop // Similar logic to above, but not knowing target property. int QDeclarativeCompiler::evaluateEnum(const QByteArray& script) const { - int dot = script.find('.'); + int dot = script.indexOf('.'); if (dot > 0) { QDeclarativeType *type = 0; QDeclarativeEnginePrivate::get(engine)->resolveType(unit->imports, script.left(dot), &type, 0, 0, 0, 0); -- cgit v0.12 From d54b11fef6403693de09277a645c9666f8eea6a2 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 17 Mar 2010 19:07:38 +1000 Subject: Fix crash If the notifier gets swapped out during emitting, the endpoint is also invalidated. Thus the "disconnected" writeback must track the endpoint not just the Notifier. --- src/declarative/qml/qdeclarativeexpression.cpp | 1 + src/declarative/qml/qdeclarativenotifier.cpp | 14 +++++++------- src/declarative/qml/qdeclarativenotifier_p.h | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp index 20863c7..9eed345 100644 --- a/src/declarative/qml/qdeclarativeexpression.cpp +++ b/src/declarative/qml/qdeclarativeexpression.cpp @@ -98,6 +98,7 @@ QDeclarativeExpressionPrivate::~QDeclarativeExpressionPrivate() if (data) { delete [] data->guardList; data->guardList = 0; + data->guardListLength = 0; data->q = 0; data->release(); data = 0; diff --git a/src/declarative/qml/qdeclarativenotifier.cpp b/src/declarative/qml/qdeclarativenotifier.cpp index 8e5904c..b12bf77 100644 --- a/src/declarative/qml/qdeclarativenotifier.cpp +++ b/src/declarative/qml/qdeclarativenotifier.cpp @@ -47,23 +47,23 @@ void QDeclarativeNotifier::emitNotify(QDeclarativeNotifierEndpoint *endpoint) { QDeclarativeNotifierEndpoint::Notifier *n = endpoint->asNotifier(); - QDeclarativeNotifierEndpoint::Notifier **oldDisconnected = n->disconnected; - n->disconnected = &n; + QDeclarativeNotifierEndpoint **oldDisconnected = n->disconnected; + n->disconnected = &endpoint; if (n->next) emitNotify(n->next); - if (n) { + if (endpoint) { void *args[] = { 0 }; QMetaObject::metacall(endpoint->target, QMetaObject::InvokeMetaMethod, endpoint->targetMethod, args); - if (n) - n->disconnected = oldDisconnected; + if (endpoint) + endpoint->asNotifier()->disconnected = oldDisconnected; } - if (oldDisconnected) *oldDisconnected = n; + if (oldDisconnected) *oldDisconnected = endpoint; } void QDeclarativeNotifierEndpoint::copyAndClear(QDeclarativeNotifierEndpoint &other) @@ -89,7 +89,7 @@ void QDeclarativeNotifierEndpoint::copyAndClear(QDeclarativeNotifierEndpoint &ot other_n->notifier = n->notifier; other_n->disconnected = n->disconnected; - if (other_n->disconnected) *other_n->disconnected = other_n; + if (other_n->disconnected) *other_n->disconnected = &other; if (n->next) { other_n->next = n->next; diff --git a/src/declarative/qml/qdeclarativenotifier_p.h b/src/declarative/qml/qdeclarativenotifier_p.h index 2a8087e..2a9660d 100644 --- a/src/declarative/qml/qdeclarativenotifier_p.h +++ b/src/declarative/qml/qdeclarativenotifier_p.h @@ -91,7 +91,7 @@ private: struct Notifier { QDeclarativeNotifier *notifier; - Notifier **disconnected; + QDeclarativeNotifierEndpoint **disconnected; QDeclarativeNotifierEndpoint *next; QDeclarativeNotifierEndpoint **prev; -- cgit v0.12 From 144e450292b4d33e72223626e4146f8e9efb8c9b Mon Sep 17 00:00:00 2001 From: mae Date: Wed, 17 Mar 2010 12:39:47 +0100 Subject: Add an implicit import "." to types loaded from a local url This triggers the loading of the qmldir and the import of native types from available plugins. The change puts native types on par with types defined in qml files. --- .../qml/qdeclarativecompositetypemanager.cpp | 31 +++++++++++++++++++--- src/declarative/qml/qdeclarativeengine.cpp | 1 + 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/declarative/qml/qdeclarativecompositetypemanager.cpp b/src/declarative/qml/qdeclarativecompositetypemanager.cpp index e2a6e0c..5f80000 100644 --- a/src/declarative/qml/qdeclarativecompositetypemanager.cpp +++ b/src/declarative/qml/qdeclarativecompositetypemanager.cpp @@ -315,12 +315,17 @@ void QDeclarativeCompositeTypeManager::resourceReplyFinished() reply->deleteLater(); } +// XXX this beyonds in QUrl::toLocalFile() +// WARNING, there is a copy of this function in qdeclarativeengine.cpp static QString toLocalFileOrQrc(const QUrl& url) { - QString r = url.toLocalFile(); - if (r.isEmpty() && url.scheme() == QLatin1String("qrc")) - r = QLatin1Char(':') + url.path(); - return r; + if (url.scheme() == QLatin1String("qrc")) { + if (url.authority().isEmpty()) + return QLatin1Char(':') + url.path(); + qWarning() << "Invalid url:" << url.toString() << "authority" << url.authority() << "not known."; + return QString(); + } + return url.toLocalFile(); } void QDeclarativeCompositeTypeManager::loadResource(QDeclarativeCompositeTypeResource *resource) @@ -505,6 +510,24 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData int waiting = 0; + + /* + For local urls, add an implicit import "." to the beginning of a file. This will trigger + the loading of the qmldir and the import of any native types from available plugins. + */ + QUrl baseUrl = unit->imports.baseUrl(); + if (!toLocalFileOrQrc(baseUrl).isEmpty()) { + QDeclarativeEnginePrivate::get(engine)-> + addToImport(&unit->imports, + QString(), + QLatin1String("."), + QString(), + -1, -1, + QDeclarativeScriptParser::Import::File); + + } + + foreach (QDeclarativeScriptParser::Import imp, unit->data.imports()) { QString qmldircontentnetwork; if (imp.type == QDeclarativeScriptParser::Import::File && imp.qualifier.isEmpty()) { diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 7c21ab8..f4eeff4 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1342,6 +1342,7 @@ QVariant QDeclarativeScriptClass::toVariant(QDeclarativeEngine *engine, const QS } // XXX this beyonds in QUrl::toLocalFile() +// WARNING, there is a copy of this function in qdeclarativecompositetypemanager.cpp static QString toLocalFileOrQrc(const QUrl& url) { if (url.scheme() == QLatin1String("qrc")) { -- cgit v0.12 From 8a5cd17c49888e5b6cb230516e1722af9adba251 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 17 Mar 2010 12:59:36 +0100 Subject: Fix default values on Textinput Task-number: BAUHAUS-389 --- src/declarative/graphicsitems/qdeclarativetextinput.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp index 6df3533..01167dc 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp @@ -834,6 +834,9 @@ void QDeclarativeTextInputPrivate::init() oldValidity = control->hasAcceptableInput(); lastSelectionStart = 0; lastSelectionEnd = 0; + QPalette p = control->palette(); + selectedTextColor = p.color(QPalette::HighlightedText); + selectionColor = p.color(QPalette::Highlight); } void QDeclarativeTextInput::cursorPosChanged() -- cgit v0.12 From 8c724518e2d2f68442cedbfd09cb84c545438cba Mon Sep 17 00:00:00 2001 From: mae Date: Wed, 17 Mar 2010 13:49:44 +0100 Subject: Fix type lookup with url The existence of a non-empty qmldir file (e.g. for defining a plugin) should not change the lookup rules for qml files via url --- src/declarative/qml/qdeclarativeengine.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index f4eeff4..f655151 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1404,14 +1404,14 @@ struct QDeclarativeEnginePrivate::ImportedNamespace { } } - } else { - // XXX search non-files too! (eg. zip files, see QT-524) - QFileInfo f(toLocalFileOrQrc(url)); - if (f.exists()) { - if (url_return) - *url_return = url; - return true; - } + } + + // XXX search non-files too! (eg. zip files, see QT-524) + QFileInfo f(toLocalFileOrQrc(url)); + if (f.exists()) { + if (url_return) + *url_return = url; + return true; } } return false; -- cgit v0.12 From ca8231566ac3804e479502d082871ab8ca28b8bb Mon Sep 17 00:00:00 2001 From: mae Date: Wed, 17 Mar 2010 14:21:21 +0100 Subject: Fix auto test This repairs 9727cb35b30e07d1f72100a39c8d23e438e2746c. The lookup can only happen if we have a file import (and not a library import) --- src/declarative/qml/qdeclarativeengine.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index f655151..4449404 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1386,7 +1386,6 @@ struct QDeclarativeEnginePrivate::ImportedNamespace { QString qmldircontent = qmlDirContent.at(i); if (!qmldircontent.isEmpty()) { - const QString typeName = QString::fromUtf8(type); QDeclarativeDirParser qmldirParser; @@ -1403,15 +1402,16 @@ struct QDeclarativeEnginePrivate::ImportedNamespace { } } } - } - // XXX search non-files too! (eg. zip files, see QT-524) - QFileInfo f(toLocalFileOrQrc(url)); - if (f.exists()) { - if (url_return) - *url_return = url; - return true; + if (!isLibrary.at(i)) { + // XXX search non-files too! (eg. zip files, see QT-524) + QFileInfo f(toLocalFileOrQrc(url)); + if (f.exists()) { + if (url_return) + *url_return = url; + return true; + } } } return false; -- cgit v0.12 From 47fb07c9fdf47584ae55f3412102bbeef5576b04 Mon Sep 17 00:00:00 2001 From: mae Date: Wed, 17 Mar 2010 17:13:00 +0100 Subject: Improve implicit "." import The change moves the implicit "." import to the very end, i.e. the first lookup. It also gets the content of a remote qmldir from the resources. --- .../qml/qdeclarativecompositetypemanager.cpp | 37 ++++++++++++---------- src/declarative/qml/qdeclarativeengine.cpp | 7 ++++ 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/declarative/qml/qdeclarativecompositetypemanager.cpp b/src/declarative/qml/qdeclarativecompositetypemanager.cpp index 5f80000..5014323 100644 --- a/src/declarative/qml/qdeclarativecompositetypemanager.cpp +++ b/src/declarative/qml/qdeclarativecompositetypemanager.cpp @@ -511,22 +511,6 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData int waiting = 0; - /* - For local urls, add an implicit import "." to the beginning of a file. This will trigger - the loading of the qmldir and the import of any native types from available plugins. - */ - QUrl baseUrl = unit->imports.baseUrl(); - if (!toLocalFileOrQrc(baseUrl).isEmpty()) { - QDeclarativeEnginePrivate::get(engine)-> - addToImport(&unit->imports, - QString(), - QLatin1String("."), - QString(), - -1, -1, - QDeclarativeScriptParser::Import::File); - - } - foreach (QDeclarativeScriptParser::Import imp, unit->data.imports()) { QString qmldircontentnetwork; @@ -568,6 +552,27 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData } } + /* + For local urls, add an implicit import "." as first lookup. This will also trigger + the loading of the qmldir and the import of any native types from available plugins. + */ + { + + QString qmldircontentnetwork; + if (QDeclarativeCompositeTypeResource *resource + = resources.value(unit->imports.baseUrl().resolved(QUrl(QLatin1String("./qmldir"))))) + qmldircontentnetwork = QString::fromUtf8(resource->data); + + QDeclarativeEnginePrivate::get(engine)-> + addToImport(&unit->imports, + qmldircontentnetwork, + QLatin1String("."), + QString(), + -1, -1, + QDeclarativeScriptParser::Import::File); + } + + QList types = unit->data.referencedTypes(); for (int ii = 0; ii < types.count(); ++ii) { diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 4449404..ce4a9f1 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1587,6 +1587,8 @@ public: } url = base.resolved(QUrl(url)).toString(); + if (url.endsWith(QLatin1Char('/'))) + url.chop(1); } s->uris.prepend(uri); @@ -1623,6 +1625,11 @@ public: } } + + + /* now comes really nasty code. It makes "private" types load in the remote case, but + it does this by breaking the import order. This must go. Instead private types must + be marked private in the qmldir. */ if (url_return) { *url_return = base.resolved(QUrl(QString::fromUtf8(type + ".qml"))); return true; -- cgit v0.12 From 4b4e9be3ea5a267c8fc05d6ff5aca972d64eb705 Mon Sep 17 00:00:00 2001 From: mae Date: Wed, 17 Mar 2010 17:38:02 +0100 Subject: Another fix to find Do not try to instantiate types that are explicitely forbidden in the qmldir (because the version does not match). --- src/declarative/qml/qdeclarativeengine.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index ce4a9f1..a097b02 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1385,6 +1385,7 @@ struct QDeclarativeEnginePrivate::ImportedNamespace { QUrl url = QUrl(urls.at(i) + QLatin1Char('/') + QString::fromUtf8(type) + QLatin1String(".qml")); QString qmldircontent = qmlDirContent.at(i); + bool typeWasDeclaredInQmldir = false; if (!qmldircontent.isEmpty()) { const QString typeName = QString::fromUtf8(type); @@ -1394,8 +1395,9 @@ struct QDeclarativeEnginePrivate::ImportedNamespace { qmldirParser.parse(); foreach (const QDeclarativeDirParser::Component &c, qmldirParser.components()) { // ### TODO: cache the components - if (c.majorVersion < vmaj || (c.majorVersion == vmaj && vmin >= c.minorVersion)) { - if (c.typeName == typeName) { + if (c.typeName == typeName) { + typeWasDeclaredInQmldir = true; + if (c.majorVersion < vmaj || (c.majorVersion == vmaj && vmin >= c.minorVersion)) { if (url_return) *url_return = url.resolved(QUrl(c.fileName)); return true; @@ -1404,7 +1406,7 @@ struct QDeclarativeEnginePrivate::ImportedNamespace { } } - if (!isLibrary.at(i)) { + if (!typeWasDeclaredInQmldir && !isLibrary.at(i)) { // XXX search non-files too! (eg. zip files, see QT-524) QFileInfo f(toLocalFileOrQrc(url)); if (f.exists()) { -- cgit v0.12 From 19988e1a2b81ae4a54edb6fec1f489326ae39089 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Thu, 18 Mar 2010 11:10:05 +1000 Subject: Fix tests after 47fb07c9fdf47584ae55f3412102bbeef5576b04. The import order has changed, so test files that mirror element names needed to be renamed (or they would resolve as the type). --- .../qdeclarativegridview/data/gridview.qml | 56 ---------- .../qdeclarativegridview/data/gridview1.qml | 56 ++++++++++ .../qdeclarativegridview/data/propertychanges.qml | 69 ------------ .../data/propertychangestest.qml | 69 ++++++++++++ .../tst_qdeclarativegridview.cpp | 20 ++-- .../qdeclarativeitem/data/keynavigation.qml | 47 -------- .../qdeclarativeitem/data/keynavigationtest.qml | 47 ++++++++ .../declarative/qdeclarativeitem/data/keys.qml | 20 ---- .../declarative/qdeclarativeitem/data/keystest.qml | 20 ++++ .../qdeclarativeitem/tst_qdeclarativeitem.cpp | 4 +- .../qdeclarativelistview/data/listview.qml | 119 --------------------- .../qdeclarativelistview/data/listviewtest.qml | 119 +++++++++++++++++++++ .../qdeclarativelistview/data/propertychanges.qml | 71 ------------ .../data/propertychangestest.qml | 71 ++++++++++++ .../tst_qdeclarativelistview.cpp | 24 ++--- .../qdeclarativeparticles/data/particlemotion.qml | 35 ------ .../data/particlemotiontest.qml | 35 ++++++ .../qdeclarativeparticles/data/particles.qml | 17 --- .../qdeclarativeparticles/data/particlestest.qml | 17 +++ .../tst_qdeclarativeparticles.cpp | 8 +- .../declarative/qdeclarativepathview/data/path.qml | 14 --- .../qdeclarativepathview/data/pathtest.qml | 14 +++ .../qdeclarativepathview/data/pathview.qml | 75 ------------- .../qdeclarativepathview/data/pathview0.qml | 75 +++++++++++++ .../tst_qdeclarativepathview.cpp | 8 +- .../qdeclarativepositioners/data/grid.qml | 39 ------- .../qdeclarativepositioners/data/gridtest.qml | 39 +++++++ .../data/propertychanges.qml | 39 ------- .../data/propertychangestest.qml | 39 +++++++ .../qdeclarativepositioners/data/repeater.qml | 20 ---- .../qdeclarativepositioners/data/repeatertest.qml | 20 ++++ .../tst_qdeclarativepositioners.cpp | 7 +- .../qdeclarativerepeater/data/repeater.qml | 28 ----- .../qdeclarativerepeater/data/repeater1.qml | 28 +++++ .../tst_qdeclarativerepeater.cpp | 2 +- .../qdeclarativestates/data/anchorChanges.qml | 23 ---- .../qdeclarativestates/data/anchorChanges1.qml | 23 ++++ .../qdeclarativestates/data/parentChange.qml | 37 ------- .../qdeclarativestates/data/parentChange1.qml | 37 +++++++ .../qdeclarativestates/tst_qdeclarativestates.cpp | 4 +- 40 files changed, 748 insertions(+), 747 deletions(-) delete mode 100644 tests/auto/declarative/qdeclarativegridview/data/gridview.qml create mode 100644 tests/auto/declarative/qdeclarativegridview/data/gridview1.qml delete mode 100644 tests/auto/declarative/qdeclarativegridview/data/propertychanges.qml create mode 100644 tests/auto/declarative/qdeclarativegridview/data/propertychangestest.qml delete mode 100644 tests/auto/declarative/qdeclarativeitem/data/keynavigation.qml create mode 100644 tests/auto/declarative/qdeclarativeitem/data/keynavigationtest.qml delete mode 100644 tests/auto/declarative/qdeclarativeitem/data/keys.qml create mode 100644 tests/auto/declarative/qdeclarativeitem/data/keystest.qml delete mode 100644 tests/auto/declarative/qdeclarativelistview/data/listview.qml create mode 100644 tests/auto/declarative/qdeclarativelistview/data/listviewtest.qml delete mode 100644 tests/auto/declarative/qdeclarativelistview/data/propertychanges.qml create mode 100644 tests/auto/declarative/qdeclarativelistview/data/propertychangestest.qml delete mode 100644 tests/auto/declarative/qdeclarativeparticles/data/particlemotion.qml create mode 100644 tests/auto/declarative/qdeclarativeparticles/data/particlemotiontest.qml delete mode 100644 tests/auto/declarative/qdeclarativeparticles/data/particles.qml create mode 100644 tests/auto/declarative/qdeclarativeparticles/data/particlestest.qml delete mode 100644 tests/auto/declarative/qdeclarativepathview/data/path.qml create mode 100644 tests/auto/declarative/qdeclarativepathview/data/pathtest.qml delete mode 100644 tests/auto/declarative/qdeclarativepathview/data/pathview.qml create mode 100644 tests/auto/declarative/qdeclarativepathview/data/pathview0.qml delete mode 100644 tests/auto/declarative/qdeclarativepositioners/data/grid.qml create mode 100644 tests/auto/declarative/qdeclarativepositioners/data/gridtest.qml delete mode 100644 tests/auto/declarative/qdeclarativepositioners/data/propertychanges.qml create mode 100644 tests/auto/declarative/qdeclarativepositioners/data/propertychangestest.qml delete mode 100644 tests/auto/declarative/qdeclarativepositioners/data/repeater.qml create mode 100644 tests/auto/declarative/qdeclarativepositioners/data/repeatertest.qml delete mode 100644 tests/auto/declarative/qdeclarativerepeater/data/repeater.qml create mode 100644 tests/auto/declarative/qdeclarativerepeater/data/repeater1.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/anchorChanges.qml create mode 100644 tests/auto/declarative/qdeclarativestates/data/anchorChanges1.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/parentChange.qml create mode 100644 tests/auto/declarative/qdeclarativestates/data/parentChange1.qml diff --git a/tests/auto/declarative/qdeclarativegridview/data/gridview.qml b/tests/auto/declarative/qdeclarativegridview/data/gridview.qml deleted file mode 100644 index ba6b807..0000000 --- a/tests/auto/declarative/qdeclarativegridview/data/gridview.qml +++ /dev/null @@ -1,56 +0,0 @@ -import Qt 4.6 - -Rectangle { - id: root - property int added: -1 - property var removed - - width: 240 - height: 320 - color: "#ffffff" - resources: [ - Component { - id: myDelegate - Rectangle { - id: wrapper - objectName: "wrapper" - width: 80 - height: 60 - border.color: "blue" - Text { - text: index - } - Text { - x: 40 - text: wrapper.x + ", " + wrapper.y - } - Text { - y: 20 - id: textName - objectName: "textName" - text: name - } - Text { - y: 40 - id: textNumber - objectName: "textNumber" - text: number - } - color: GridView.isCurrentItem ? "lightsteelblue" : "white" - GridView.onAdd: root.added = index - GridView.onRemove: root.removed = name - } - } - ] - GridView { - id: grid - objectName: "grid" - width: 240 - height: 320 - cellWidth: 80 - cellHeight: 60 - flow: (testTopToBottom == false) ? "LeftToRight" : "TopToBottom" - model: testModel - delegate: myDelegate - } -} diff --git a/tests/auto/declarative/qdeclarativegridview/data/gridview1.qml b/tests/auto/declarative/qdeclarativegridview/data/gridview1.qml new file mode 100644 index 0000000..ba6b807 --- /dev/null +++ b/tests/auto/declarative/qdeclarativegridview/data/gridview1.qml @@ -0,0 +1,56 @@ +import Qt 4.6 + +Rectangle { + id: root + property int added: -1 + property var removed + + width: 240 + height: 320 + color: "#ffffff" + resources: [ + Component { + id: myDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + width: 80 + height: 60 + border.color: "blue" + Text { + text: index + } + Text { + x: 40 + text: wrapper.x + ", " + wrapper.y + } + Text { + y: 20 + id: textName + objectName: "textName" + text: name + } + Text { + y: 40 + id: textNumber + objectName: "textNumber" + text: number + } + color: GridView.isCurrentItem ? "lightsteelblue" : "white" + GridView.onAdd: root.added = index + GridView.onRemove: root.removed = name + } + } + ] + GridView { + id: grid + objectName: "grid" + width: 240 + height: 320 + cellWidth: 80 + cellHeight: 60 + flow: (testTopToBottom == false) ? "LeftToRight" : "TopToBottom" + model: testModel + delegate: myDelegate + } +} diff --git a/tests/auto/declarative/qdeclarativegridview/data/propertychanges.qml b/tests/auto/declarative/qdeclarativegridview/data/propertychanges.qml deleted file mode 100644 index da2e8d0..0000000 --- a/tests/auto/declarative/qdeclarativegridview/data/propertychanges.qml +++ /dev/null @@ -1,69 +0,0 @@ -import Qt 4.6 - -Rectangle { - width: 360; height: 120; color: "white" - Component { - id: delegate - Item { - id: wrapper - width: 180; height: 40; - Column { - x: 5; y: 5 - Text { text: 'Name: ' + name } - Text { text: 'Number: ' + number } - } - } - } - Component { - id: highlightRed - Rectangle { - color: "red" - radius: 10 - opacity: 0.5 - } - } - GridView { - cellWidth:180 - cellHeight:40 - objectName: "gridView" - anchors.fill: parent - model: listModel - delegate: delegate - highlight: highlightRed - focus: true - keyNavigationWraps: true - cacheBuffer: 10 - flow: GridView.LeftToRight - } - - data:[ - ListModel { - id: listModel - ListElement { - name: "Bill Smith" - number: "555 3264" - } - ListElement { - name: "John Brown" - number: "555 8426" - } - ListElement { - name: "Sam Wise" - number: "555 0473" - } - }, - ListModel { - objectName: "alternateModel" - ListElement { - name: "Jack" - number: "555 8426" - } - ListElement { - name: "Mary" - number: "555 3264" - } - } - ] -} - - \ No newline at end of file diff --git a/tests/auto/declarative/qdeclarativegridview/data/propertychangestest.qml b/tests/auto/declarative/qdeclarativegridview/data/propertychangestest.qml new file mode 100644 index 0000000..da2e8d0 --- /dev/null +++ b/tests/auto/declarative/qdeclarativegridview/data/propertychangestest.qml @@ -0,0 +1,69 @@ +import Qt 4.6 + +Rectangle { + width: 360; height: 120; color: "white" + Component { + id: delegate + Item { + id: wrapper + width: 180; height: 40; + Column { + x: 5; y: 5 + Text { text: 'Name: ' + name } + Text { text: 'Number: ' + number } + } + } + } + Component { + id: highlightRed + Rectangle { + color: "red" + radius: 10 + opacity: 0.5 + } + } + GridView { + cellWidth:180 + cellHeight:40 + objectName: "gridView" + anchors.fill: parent + model: listModel + delegate: delegate + highlight: highlightRed + focus: true + keyNavigationWraps: true + cacheBuffer: 10 + flow: GridView.LeftToRight + } + + data:[ + ListModel { + id: listModel + ListElement { + name: "Bill Smith" + number: "555 3264" + } + ListElement { + name: "John Brown" + number: "555 8426" + } + ListElement { + name: "Sam Wise" + number: "555 0473" + } + }, + ListModel { + objectName: "alternateModel" + ListElement { + name: "Jack" + number: "555 8426" + } + ListElement { + name: "Mary" + number: "555 3264" + } + } + ] +} + + \ No newline at end of file diff --git a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp index 385d6f5..dd594774 100644 --- a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp +++ b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp @@ -165,7 +165,7 @@ void tst_QDeclarativeGridView::items() ctxt->setContextProperty("testModel", &model); ctxt->setContextProperty("testTopToBottom", QVariant(false)); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml")); qApp->processEvents(); QDeclarativeGridView *gridview = findItem(canvas->rootObject(), "grid"); @@ -213,7 +213,7 @@ void tst_QDeclarativeGridView::changed() ctxt->setContextProperty("testModel", &model); ctxt->setContextProperty("testTopToBottom", QVariant(false)); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml")); qApp->processEvents(); QDeclarativeFlickable *gridview = findItem(canvas->rootObject(), "grid"); @@ -246,7 +246,7 @@ void tst_QDeclarativeGridView::inserted() ctxt->setContextProperty("testModel", &model); ctxt->setContextProperty("testTopToBottom", QVariant(false)); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml")); qApp->processEvents(); QDeclarativeGridView *gridview = findItem(canvas->rootObject(), "grid"); @@ -331,7 +331,7 @@ void tst_QDeclarativeGridView::removed() ctxt->setContextProperty("testModel", &model); ctxt->setContextProperty("testTopToBottom", QVariant(false)); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml")); qApp->processEvents(); QDeclarativeGridView *gridview = findItem(canvas->rootObject(), "grid"); @@ -495,7 +495,7 @@ void tst_QDeclarativeGridView::moved() ctxt->setContextProperty("testModel", &model); ctxt->setContextProperty("testTopToBottom", QVariant(false)); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml")); qApp->processEvents(); QDeclarativeGridView *gridview = findItem(canvas->rootObject(), "grid"); @@ -723,7 +723,7 @@ void tst_QDeclarativeGridView::changeFlow() ctxt->setContextProperty("testModel", &model); ctxt->setContextProperty("testTopToBottom", QVariant(false)); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml")); qApp->processEvents(); QDeclarativeGridView *gridview = findItem(canvas->rootObject(), "grid"); @@ -820,7 +820,7 @@ void tst_QDeclarativeGridView::propertyChanges() { QDeclarativeView *canvas = createView(); QVERIFY(canvas); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml")); QDeclarativeGridView *gridView = canvas->rootObject()->findChild("gridView"); QVERIFY(gridView); @@ -860,7 +860,7 @@ void tst_QDeclarativeGridView::componentChanges() { QDeclarativeView *canvas = createView(); QVERIFY(canvas); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml")); QDeclarativeGridView *gridView = canvas->rootObject()->findChild("gridView"); QVERIFY(gridView); @@ -895,7 +895,7 @@ void tst_QDeclarativeGridView::modelChanges() { QDeclarativeView *canvas = createView(); QVERIFY(canvas); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml")); QDeclarativeGridView *gridView = canvas->rootObject()->findChild("gridView"); QVERIFY(gridView); @@ -929,7 +929,7 @@ void tst_QDeclarativeGridView::positionViewAtIndex() ctxt->setContextProperty("testModel", &model); ctxt->setContextProperty("testTopToBottom", QVariant(false)); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml")); qApp->processEvents(); QDeclarativeGridView *gridview = findItem(canvas->rootObject(), "grid"); diff --git a/tests/auto/declarative/qdeclarativeitem/data/keynavigation.qml b/tests/auto/declarative/qdeclarativeitem/data/keynavigation.qml deleted file mode 100644 index 08da901..0000000 --- a/tests/auto/declarative/qdeclarativeitem/data/keynavigation.qml +++ /dev/null @@ -1,47 +0,0 @@ -import Qt 4.6 - -Grid { - columns: 2 - width: 100; height: 100 - Rectangle { - id: item1 - objectName: "item1" - focus: true - width: 50; height: 50 - color: focus ? "red" : "lightgray" - KeyNavigation.right: item2 - KeyNavigation.down: item3 - KeyNavigation.tab: item2 - KeyNavigation.backtab: item4 - } - Rectangle { - id: item2 - objectName: "item2" - width: 50; height: 50 - color: focus ? "red" : "lightgray" - KeyNavigation.left: item1 - KeyNavigation.down: item4 - KeyNavigation.tab: item3 - KeyNavigation.backtab: item1 - } - Rectangle { - id: item3 - objectName: "item3" - width: 50; height: 50 - color: focus ? "red" : "lightgray" - KeyNavigation.right: item4 - KeyNavigation.up: item1 - KeyNavigation.tab: item4 - KeyNavigation.backtab: item2 - } - Rectangle { - id: item4 - objectName: "item4" - width: 50; height: 50 - color: focus ? "red" : "lightgray" - KeyNavigation.left: item3 - KeyNavigation.up: item2 - KeyNavigation.tab: item1 - KeyNavigation.backtab: item3 - } -} diff --git a/tests/auto/declarative/qdeclarativeitem/data/keynavigationtest.qml b/tests/auto/declarative/qdeclarativeitem/data/keynavigationtest.qml new file mode 100644 index 0000000..08da901 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeitem/data/keynavigationtest.qml @@ -0,0 +1,47 @@ +import Qt 4.6 + +Grid { + columns: 2 + width: 100; height: 100 + Rectangle { + id: item1 + objectName: "item1" + focus: true + width: 50; height: 50 + color: focus ? "red" : "lightgray" + KeyNavigation.right: item2 + KeyNavigation.down: item3 + KeyNavigation.tab: item2 + KeyNavigation.backtab: item4 + } + Rectangle { + id: item2 + objectName: "item2" + width: 50; height: 50 + color: focus ? "red" : "lightgray" + KeyNavigation.left: item1 + KeyNavigation.down: item4 + KeyNavigation.tab: item3 + KeyNavigation.backtab: item1 + } + Rectangle { + id: item3 + objectName: "item3" + width: 50; height: 50 + color: focus ? "red" : "lightgray" + KeyNavigation.right: item4 + KeyNavigation.up: item1 + KeyNavigation.tab: item4 + KeyNavigation.backtab: item2 + } + Rectangle { + id: item4 + objectName: "item4" + width: 50; height: 50 + color: focus ? "red" : "lightgray" + KeyNavigation.left: item3 + KeyNavigation.up: item2 + KeyNavigation.tab: item1 + KeyNavigation.backtab: item3 + } +} diff --git a/tests/auto/declarative/qdeclarativeitem/data/keys.qml b/tests/auto/declarative/qdeclarativeitem/data/keys.qml deleted file mode 100644 index 7d34fc8..0000000 --- a/tests/auto/declarative/qdeclarativeitem/data/keys.qml +++ /dev/null @@ -1,20 +0,0 @@ -import Qt 4.6 - -Item { - focus: true - Keys.onPressed: keysTestObject.keyPress(event.key, event.text, event.modifiers) - Keys.onReleased: { keysTestObject.keyRelease(event.key, event.text, event.modifiers); event.accepted = true; } - Keys.onReturnPressed: keysTestObject.keyPress(event.key, "Return", event.modifiers) - Keys.onDigit0Pressed: keysTestObject.keyPress(event.key, event.text, event.modifiers) - Keys.onDigit9Pressed: { event.accepted = false; keysTestObject.keyPress(event.key, event.text, event.modifiers) } - Keys.onTabPressed: keysTestObject.keyPress(event.key, "Tab", event.modifiers) - Keys.onBacktabPressed: keysTestObject.keyPress(event.key, "Backtab", event.modifiers) - Keys.forwardTo: [ item2 ] - Keys.enabled: enableKeyHanding - - Item { - id: item2 - Keys.onPressed: keysTestObject.forwardedKey(event.key) - Keys.onReleased: keysTestObject.forwardedKey(event.key) - } -} diff --git a/tests/auto/declarative/qdeclarativeitem/data/keystest.qml b/tests/auto/declarative/qdeclarativeitem/data/keystest.qml new file mode 100644 index 0000000..7d34fc8 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeitem/data/keystest.qml @@ -0,0 +1,20 @@ +import Qt 4.6 + +Item { + focus: true + Keys.onPressed: keysTestObject.keyPress(event.key, event.text, event.modifiers) + Keys.onReleased: { keysTestObject.keyRelease(event.key, event.text, event.modifiers); event.accepted = true; } + Keys.onReturnPressed: keysTestObject.keyPress(event.key, "Return", event.modifiers) + Keys.onDigit0Pressed: keysTestObject.keyPress(event.key, event.text, event.modifiers) + Keys.onDigit9Pressed: { event.accepted = false; keysTestObject.keyPress(event.key, event.text, event.modifiers) } + Keys.onTabPressed: keysTestObject.keyPress(event.key, "Tab", event.modifiers) + Keys.onBacktabPressed: keysTestObject.keyPress(event.key, "Backtab", event.modifiers) + Keys.forwardTo: [ item2 ] + Keys.enabled: enableKeyHanding + + Item { + id: item2 + Keys.onPressed: keysTestObject.forwardedKey(event.key) + Keys.onReleased: keysTestObject.forwardedKey(event.key) + } +} diff --git a/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp b/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp index 45d670f..ba69cd8 100644 --- a/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp +++ b/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp @@ -120,7 +120,7 @@ void tst_QDeclarativeItem::keys() canvas->rootContext()->setContextProperty("enableKeyHanding", QVariant(true)); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/keys.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/keystest.qml")); canvas->show(); qApp->processEvents(); @@ -215,7 +215,7 @@ void tst_QDeclarativeItem::keyNavigation() QDeclarativeView *canvas = new QDeclarativeView(0); canvas->setFixedSize(240,320); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/keynavigation.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/keynavigationtest.qml")); canvas->show(); qApp->processEvents(); diff --git a/tests/auto/declarative/qdeclarativelistview/data/listview.qml b/tests/auto/declarative/qdeclarativelistview/data/listview.qml deleted file mode 100644 index 1c1b3f8..0000000 --- a/tests/auto/declarative/qdeclarativelistview/data/listview.qml +++ /dev/null @@ -1,119 +0,0 @@ -import Qt 4.6 - -Rectangle { - width: 240 - height: 320 - color: "#ffffff" - function checkProperties() { - testObject.error = false; - if (list.model != testModel) { - console.log("model property incorrect"); - testObject.error = true; - } - if (!testObject.animate && list.delegate != myDelegate) { - console.log("delegate property incorrect - expected myDelegate"); - testObject.error = true; - } - if (testObject.animate && list.delegate != animatedDelegate) { - console.log("delegate property incorrect - expected animatedDelegate"); - testObject.error = true; - } - if (testObject.invalidHighlight && list.highlight != invalidHl) { - console.log("highlight property incorrect - expected invalidHl"); - testObject.error = true; - } - if (!testObject.invalidHighlight && list.highlight != myHighlight) { - console.log("highlight property incorrect - expected myHighlight"); - testObject.error = true; - } - } - resources: [ - Component { - id: myDelegate - Rectangle { - id: wrapper - objectName: "wrapper" - height: 20 - width: 240 - Text { - text: index - } - Text { - x: 30 - id: textName - objectName: "textName" - text: name - } - Text { - x: 120 - id: textNumber - objectName: "textNumber" - text: number - } - Text { - x: 200 - text: wrapper.y - } - color: ListView.isCurrentItem ? "lightsteelblue" : "white" - } - }, - Component { - id: animatedDelegate - Rectangle { - id: wrapper - objectName: "wrapper" - height: 20 - width: 240 - Text { - text: index - } - Text { - x: 30 - id: textName - objectName: "textName" - text: name - } - Text { - x: 120 - id: textNumber - objectName: "textNumber" - text: number - } - Text { - x: 200 - text: wrapper.y - } - color: ListView.isCurrentItem ? "lightsteelblue" : "white" - ListView.onRemove: SequentialAnimation { - ScriptAction { script: console.log("Fix PropertyAction with attached properties") } -/* - PropertyAction { target: wrapper; property: "ListView.delayRemove"; value: true } - NumberAnimation { target: wrapper; property: "scale"; to: 0; duration: 250; easing.type: "InOutQuad" } - PropertyAction { target: wrapper; property: "ListView.delayRemove"; value: false } -*/ - } - } - }, - Component { - id: myHighlight - Rectangle { color: "green" } - }, - Component { - id: invalidHl - EaseFollow {} - } - ] - ListView { - id: list - objectName: "list" - focus: true - width: 240 - height: 320 - model: testModel - delegate: testObject.animate ? animatedDelegate : myDelegate - highlight: testObject.invalidHighlight ? invalidHl : myHighlight - highlightMoveSpeed: 1000 - highlightResizeSpeed: 1000 - cacheBuffer: testObject.cacheBuffer - } -} diff --git a/tests/auto/declarative/qdeclarativelistview/data/listviewtest.qml b/tests/auto/declarative/qdeclarativelistview/data/listviewtest.qml new file mode 100644 index 0000000..1c1b3f8 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelistview/data/listviewtest.qml @@ -0,0 +1,119 @@ +import Qt 4.6 + +Rectangle { + width: 240 + height: 320 + color: "#ffffff" + function checkProperties() { + testObject.error = false; + if (list.model != testModel) { + console.log("model property incorrect"); + testObject.error = true; + } + if (!testObject.animate && list.delegate != myDelegate) { + console.log("delegate property incorrect - expected myDelegate"); + testObject.error = true; + } + if (testObject.animate && list.delegate != animatedDelegate) { + console.log("delegate property incorrect - expected animatedDelegate"); + testObject.error = true; + } + if (testObject.invalidHighlight && list.highlight != invalidHl) { + console.log("highlight property incorrect - expected invalidHl"); + testObject.error = true; + } + if (!testObject.invalidHighlight && list.highlight != myHighlight) { + console.log("highlight property incorrect - expected myHighlight"); + testObject.error = true; + } + } + resources: [ + Component { + id: myDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + height: 20 + width: 240 + Text { + text: index + } + Text { + x: 30 + id: textName + objectName: "textName" + text: name + } + Text { + x: 120 + id: textNumber + objectName: "textNumber" + text: number + } + Text { + x: 200 + text: wrapper.y + } + color: ListView.isCurrentItem ? "lightsteelblue" : "white" + } + }, + Component { + id: animatedDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + height: 20 + width: 240 + Text { + text: index + } + Text { + x: 30 + id: textName + objectName: "textName" + text: name + } + Text { + x: 120 + id: textNumber + objectName: "textNumber" + text: number + } + Text { + x: 200 + text: wrapper.y + } + color: ListView.isCurrentItem ? "lightsteelblue" : "white" + ListView.onRemove: SequentialAnimation { + ScriptAction { script: console.log("Fix PropertyAction with attached properties") } +/* + PropertyAction { target: wrapper; property: "ListView.delayRemove"; value: true } + NumberAnimation { target: wrapper; property: "scale"; to: 0; duration: 250; easing.type: "InOutQuad" } + PropertyAction { target: wrapper; property: "ListView.delayRemove"; value: false } +*/ + } + } + }, + Component { + id: myHighlight + Rectangle { color: "green" } + }, + Component { + id: invalidHl + EaseFollow {} + } + ] + ListView { + id: list + objectName: "list" + focus: true + width: 240 + height: 320 + model: testModel + delegate: testObject.animate ? animatedDelegate : myDelegate + highlight: testObject.invalidHighlight ? invalidHl : myHighlight + highlightMoveSpeed: 1000 + highlightResizeSpeed: 1000 + cacheBuffer: testObject.cacheBuffer + } +} diff --git a/tests/auto/declarative/qdeclarativelistview/data/propertychanges.qml b/tests/auto/declarative/qdeclarativelistview/data/propertychanges.qml deleted file mode 100644 index a41f003..0000000 --- a/tests/auto/declarative/qdeclarativelistview/data/propertychanges.qml +++ /dev/null @@ -1,71 +0,0 @@ -import Qt 4.6 - -Rectangle { - width: 180; height: 120; color: "white" - Component { - id: delegate - Item { - id: wrapper - width: 180; height: 40; - Column { - x: 5; y: 5 - Text { text: 'Name: ' + name } - Text { text: 'Number: ' + number } - } - } - } - Component { - id: highlightRed - Rectangle { - color: "red" - radius: 10 - opacity: 0.5 - } - } - ListView { - objectName: "listView" - anchors.fill: parent - model: listModel - delegate: delegate - highlight: highlightRed - focus: true - highlightFollowsCurrentItem: true - preferredHighlightBegin: 0.0 - preferredHighlightEnd: 0.0 - highlightRangeMode: ListView.ApplyRange - keyNavigationWraps: true - cacheBuffer: 10 - snapMode: ListView.SnapToItem - } - - data:[ - ListModel { - id: listModel - ListElement { - name: "Bill Smith" - number: "555 3264" - } - ListElement { - name: "John Brown" - number: "555 8426" - } - ListElement { - name: "Sam Wise" - number: "555 0473" - } - }, - ListModel { - objectName: "alternateModel" - ListElement { - name: "Jack" - number: "555 8426" - } - ListElement { - name: "Mary" - number: "555 3264" - } - } - ] -} - - \ No newline at end of file diff --git a/tests/auto/declarative/qdeclarativelistview/data/propertychangestest.qml b/tests/auto/declarative/qdeclarativelistview/data/propertychangestest.qml new file mode 100644 index 0000000..a41f003 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelistview/data/propertychangestest.qml @@ -0,0 +1,71 @@ +import Qt 4.6 + +Rectangle { + width: 180; height: 120; color: "white" + Component { + id: delegate + Item { + id: wrapper + width: 180; height: 40; + Column { + x: 5; y: 5 + Text { text: 'Name: ' + name } + Text { text: 'Number: ' + number } + } + } + } + Component { + id: highlightRed + Rectangle { + color: "red" + radius: 10 + opacity: 0.5 + } + } + ListView { + objectName: "listView" + anchors.fill: parent + model: listModel + delegate: delegate + highlight: highlightRed + focus: true + highlightFollowsCurrentItem: true + preferredHighlightBegin: 0.0 + preferredHighlightEnd: 0.0 + highlightRangeMode: ListView.ApplyRange + keyNavigationWraps: true + cacheBuffer: 10 + snapMode: ListView.SnapToItem + } + + data:[ + ListModel { + id: listModel + ListElement { + name: "Bill Smith" + number: "555 3264" + } + ListElement { + name: "John Brown" + number: "555 8426" + } + ListElement { + name: "Sam Wise" + number: "555 0473" + } + }, + ListModel { + objectName: "alternateModel" + ListElement { + name: "Jack" + number: "555 8426" + } + ListElement { + name: "Mary" + number: "555 3264" + } + } + ] +} + + \ No newline at end of file diff --git a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp index 5b57487..8d94804 100644 --- a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp +++ b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp @@ -321,7 +321,7 @@ void tst_QDeclarativeListView::items() TestObject *testObject = new TestObject; ctxt->setContextProperty("testObject", testObject); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml")); qApp->processEvents(); QDeclarativeListView *listview = findItem(canvas->rootObject(), "list"); @@ -402,7 +402,7 @@ void tst_QDeclarativeListView::changed() TestObject *testObject = new TestObject; ctxt->setContextProperty("testObject", testObject); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml")); qApp->processEvents(); QDeclarativeFlickable *listview = findItem(canvas->rootObject(), "list"); @@ -438,7 +438,7 @@ void tst_QDeclarativeListView::inserted() TestObject *testObject = new TestObject; ctxt->setContextProperty("testObject", testObject); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml")); qApp->processEvents(); QDeclarativeListView *listview = findItem(canvas->rootObject(), "list"); @@ -531,7 +531,7 @@ void tst_QDeclarativeListView::removed(bool animated) testObject->setAnimate(animated); ctxt->setContextProperty("testObject", testObject); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml")); qApp->processEvents(); QDeclarativeListView *listview = findItem(canvas->rootObject(), "list"); @@ -673,7 +673,7 @@ void tst_QDeclarativeListView::clear() TestObject *testObject = new TestObject; ctxt->setContextProperty("testObject", testObject); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml")); qApp->processEvents(); QDeclarativeListView *listview = findItem(canvas->rootObject(), "list"); @@ -710,7 +710,7 @@ void tst_QDeclarativeListView::moved() TestObject *testObject = new TestObject; ctxt->setContextProperty("testObject", testObject); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml")); qApp->processEvents(); QDeclarativeListView *listview = findItem(canvas->rootObject(), "list"); @@ -851,7 +851,7 @@ void tst_QDeclarativeListView::spacing() TestObject *testObject = new TestObject; ctxt->setContextProperty("testObject", testObject); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml")); qApp->processEvents(); QDeclarativeListView *listview = findItem(canvas->rootObject(), "list"); @@ -1122,7 +1122,7 @@ void tst_QDeclarativeListView::cacheBuffer() TestObject *testObject = new TestObject; ctxt->setContextProperty("testObject", testObject); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml")); qApp->processEvents(); QDeclarativeListView *listview = findItem(canvas->rootObject(), "list"); @@ -1174,7 +1174,7 @@ void tst_QDeclarativeListView::positionViewAtIndex() TestObject *testObject = new TestObject; ctxt->setContextProperty("testObject", testObject); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml")); qApp->processEvents(); QDeclarativeListView *listview = findItem(canvas->rootObject(), "list"); @@ -1333,7 +1333,7 @@ void tst_QDeclarativeListView::propertyChanges() { QDeclarativeView *canvas = createView(); QVERIFY(canvas); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml")); QDeclarativeListView *listView = canvas->rootObject()->findChild("listView"); QVERIFY(listView); @@ -1401,7 +1401,7 @@ void tst_QDeclarativeListView::componentChanges() { QDeclarativeView *canvas = createView(); QVERIFY(canvas); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml")); QDeclarativeListView *listView = canvas->rootObject()->findChild("listView"); QVERIFY(listView); @@ -1449,7 +1449,7 @@ void tst_QDeclarativeListView::modelChanges() { QDeclarativeView *canvas = createView(); QVERIFY(canvas); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml")); QDeclarativeListView *listView = canvas->rootObject()->findChild("listView"); QVERIFY(listView); diff --git a/tests/auto/declarative/qdeclarativeparticles/data/particlemotion.qml b/tests/auto/declarative/qdeclarativeparticles/data/particlemotion.qml deleted file mode 100644 index f1e4909..0000000 --- a/tests/auto/declarative/qdeclarativeparticles/data/particlemotion.qml +++ /dev/null @@ -1,35 +0,0 @@ -import Qt 4.6 -import Qt.labs.particles 1.0 - -Rectangle { - width: 240 - height: 320 - color: "black" - Particles { - objectName: "particles" - anchors.fill: parent - width: 1 - height: 1 - source: "particle.png" - lifeSpan: 5000 - count: 200 - angle: 270 - angleDeviation: 45 - velocity: 50 - velocityDeviation: 30 - ParticleMotionGravity { - objectName: "motionGravity" - yattractor: 1000 - xattractor: 0 - acceleration: 25 - } - } - resources: [ - ParticleMotionWander { - objectName: "motionWander" - xvariance: 30 - yvariance: 30 - pace: 100 - } - ] -} diff --git a/tests/auto/declarative/qdeclarativeparticles/data/particlemotiontest.qml b/tests/auto/declarative/qdeclarativeparticles/data/particlemotiontest.qml new file mode 100644 index 0000000..f1e4909 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeparticles/data/particlemotiontest.qml @@ -0,0 +1,35 @@ +import Qt 4.6 +import Qt.labs.particles 1.0 + +Rectangle { + width: 240 + height: 320 + color: "black" + Particles { + objectName: "particles" + anchors.fill: parent + width: 1 + height: 1 + source: "particle.png" + lifeSpan: 5000 + count: 200 + angle: 270 + angleDeviation: 45 + velocity: 50 + velocityDeviation: 30 + ParticleMotionGravity { + objectName: "motionGravity" + yattractor: 1000 + xattractor: 0 + acceleration: 25 + } + } + resources: [ + ParticleMotionWander { + objectName: "motionWander" + xvariance: 30 + yvariance: 30 + pace: 100 + } + ] +} diff --git a/tests/auto/declarative/qdeclarativeparticles/data/particles.qml b/tests/auto/declarative/qdeclarativeparticles/data/particles.qml deleted file mode 100644 index 4f168a9..0000000 --- a/tests/auto/declarative/qdeclarativeparticles/data/particles.qml +++ /dev/null @@ -1,17 +0,0 @@ -import Qt 4.6 -import Qt.labs.particles 1.0 - -Rectangle{ - width: 100 - height: 100 - color: "black" - objectName: "rect" - Particles { id: particles - objectName: "particles" - width:1; height:1; anchors.centerIn: parent; opacity: 1 - lifeSpan: 100; lifeSpanDeviation: 20; count:1000; - fadeInDuration: 20; fadeOutDuration: 20; emissionRate: 1000 - angle: 0; angleDeviation: 360; velocity: 500; velocityDeviation:30 - source: "particle.png" - } -} diff --git a/tests/auto/declarative/qdeclarativeparticles/data/particlestest.qml b/tests/auto/declarative/qdeclarativeparticles/data/particlestest.qml new file mode 100644 index 0000000..4f168a9 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeparticles/data/particlestest.qml @@ -0,0 +1,17 @@ +import Qt 4.6 +import Qt.labs.particles 1.0 + +Rectangle{ + width: 100 + height: 100 + color: "black" + objectName: "rect" + Particles { id: particles + objectName: "particles" + width:1; height:1; anchors.centerIn: parent; opacity: 1 + lifeSpan: 100; lifeSpanDeviation: 20; count:1000; + fadeInDuration: 20; fadeOutDuration: 20; emissionRate: 1000 + angle: 0; angleDeviation: 360; velocity: 500; velocityDeviation:30 + source: "particle.png" + } +} diff --git a/tests/auto/declarative/qdeclarativeparticles/tst_qdeclarativeparticles.cpp b/tests/auto/declarative/qdeclarativeparticles/tst_qdeclarativeparticles.cpp index f4e9a27..093190c 100644 --- a/tests/auto/declarative/qdeclarativeparticles/tst_qdeclarativeparticles.cpp +++ b/tests/auto/declarative/qdeclarativeparticles/tst_qdeclarativeparticles.cpp @@ -65,7 +65,7 @@ tst_QDeclarativeParticles::tst_QDeclarativeParticles() void tst_QDeclarativeParticles::properties() { - QDeclarativeView *canvas = createView(SRCDIR "/data/particles.qml"); + QDeclarativeView *canvas = createView(SRCDIR "/data/particlestest.qml"); QVERIFY(canvas->rootObject()); QObject* particles = canvas->rootObject()->findChild("particles"); @@ -104,7 +104,7 @@ void tst_QDeclarativeParticles::properties() void tst_QDeclarativeParticles::motionGravity() { - QDeclarativeView *canvas = createView(SRCDIR "/data/particlemotion.qml"); + QDeclarativeView *canvas = createView(SRCDIR "/data/particlemotiontest.qml"); QVERIFY(canvas->rootObject()); QObject* particles = canvas->rootObject()->findChild("particles"); @@ -144,7 +144,7 @@ void tst_QDeclarativeParticles::motionGravity() void tst_QDeclarativeParticles::motionWander() { - QDeclarativeView *canvas = createView(SRCDIR "/data/particlemotion.qml"); + QDeclarativeView *canvas = createView(SRCDIR "/data/particlemotiontest.qml"); QVERIFY(canvas->rootObject()); QObject* particles = canvas->rootObject()->findChild("particles"); @@ -192,7 +192,7 @@ void tst_QDeclarativeParticles::motionWander() void tst_QDeclarativeParticles::runs() { - QDeclarativeView *canvas = createView(SRCDIR "/data/particles.qml"); + QDeclarativeView *canvas = createView(SRCDIR "/data/particlestest.qml"); QVERIFY(canvas->rootObject()); QObject* particles = canvas->rootObject()->findChild("particles"); diff --git a/tests/auto/declarative/qdeclarativepathview/data/path.qml b/tests/auto/declarative/qdeclarativepathview/data/path.qml deleted file mode 100644 index 7e82a48..0000000 --- a/tests/auto/declarative/qdeclarativepathview/data/path.qml +++ /dev/null @@ -1,14 +0,0 @@ -import Qt 4.6 - -Path { - startX: 120; startY: 100 - - PathAttribute { name: "scale"; value: 1.0 } - PathQuad { x: 120; y: 25; controlX: 260; controlY: 75 } - PathPercent { value: 0.3 } - PathLine { x: 120; y: 100 } - PathCubic { - x: 180; y: 0; control1X: -10; control1Y: 90 - control2X: 210; control2Y: 90 - } -} diff --git a/tests/auto/declarative/qdeclarativepathview/data/pathtest.qml b/tests/auto/declarative/qdeclarativepathview/data/pathtest.qml new file mode 100644 index 0000000..7e82a48 --- /dev/null +++ b/tests/auto/declarative/qdeclarativepathview/data/pathtest.qml @@ -0,0 +1,14 @@ +import Qt 4.6 + +Path { + startX: 120; startY: 100 + + PathAttribute { name: "scale"; value: 1.0 } + PathQuad { x: 120; y: 25; controlX: 260; controlY: 75 } + PathPercent { value: 0.3 } + PathLine { x: 120; y: 100 } + PathCubic { + x: 180; y: 0; control1X: -10; control1Y: 90 + control2X: 210; control2Y: 90 + } +} diff --git a/tests/auto/declarative/qdeclarativepathview/data/pathview.qml b/tests/auto/declarative/qdeclarativepathview/data/pathview.qml deleted file mode 100644 index ae0c86a..0000000 --- a/tests/auto/declarative/qdeclarativepathview/data/pathview.qml +++ /dev/null @@ -1,75 +0,0 @@ -import Qt 4.6 - -Rectangle { - id: root - property int currentA: -1 - property int currentB: -1 - width: 240 - height: 320 - color: "#ffffff" - resources: [ - Component { - id: delegate - Rectangle { - id: wrapper - objectName: "wrapper" - height: 20 - width: 60 - color: PathView.isCurrentItem ? "lightsteelblue" : "white" - border.color: "black" - Text { - text: index - } - Text { - x: 20 - id: textName - objectName: "textName" - text: name - } - Text { - x: 40 - id: textNumber - objectName: "textNumber" - text: number - } - PathView.onCurrentItemChanged: { - if (PathView.isCurrentItem) { - root.currentA = index; - root.currentB = wrapper.PathView.view.currentIndex; - } - } - } - } - ] - PathView { - id: view - objectName: "view" - width: 240 - height: 320 - model: testModel - delegate: delegate - snapPosition: 0.0001 - path: Path { - startY: 120 - startX: 160 - PathQuad { - y: 120 - x: 80 - controlY: 330 - controlX: 100 - } - PathLine { - y: 160 - x: 20 - } - PathCubic { - y: 120 - x: 160 - control1Y: 0 - control1X: 100 - control2Y: 000 - control2X: 200 - } - } - } -} diff --git a/tests/auto/declarative/qdeclarativepathview/data/pathview0.qml b/tests/auto/declarative/qdeclarativepathview/data/pathview0.qml new file mode 100644 index 0000000..ae0c86a --- /dev/null +++ b/tests/auto/declarative/qdeclarativepathview/data/pathview0.qml @@ -0,0 +1,75 @@ +import Qt 4.6 + +Rectangle { + id: root + property int currentA: -1 + property int currentB: -1 + width: 240 + height: 320 + color: "#ffffff" + resources: [ + Component { + id: delegate + Rectangle { + id: wrapper + objectName: "wrapper" + height: 20 + width: 60 + color: PathView.isCurrentItem ? "lightsteelblue" : "white" + border.color: "black" + Text { + text: index + } + Text { + x: 20 + id: textName + objectName: "textName" + text: name + } + Text { + x: 40 + id: textNumber + objectName: "textNumber" + text: number + } + PathView.onCurrentItemChanged: { + if (PathView.isCurrentItem) { + root.currentA = index; + root.currentB = wrapper.PathView.view.currentIndex; + } + } + } + } + ] + PathView { + id: view + objectName: "view" + width: 240 + height: 320 + model: testModel + delegate: delegate + snapPosition: 0.0001 + path: Path { + startY: 120 + startX: 160 + PathQuad { + y: 120 + x: 80 + controlY: 330 + controlX: 100 + } + PathLine { + y: 160 + x: 20 + } + PathCubic { + y: 120 + x: 160 + control1Y: 0 + control1X: 100 + control2Y: 000 + control2X: 200 + } + } + } +} diff --git a/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp b/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp index cc1a8d5..c16c46f 100644 --- a/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp +++ b/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp @@ -213,7 +213,7 @@ void tst_QDeclarativePathView::items() QDeclarativeContext *ctxt = canvas->rootContext(); ctxt->setContextProperty("testModel", &model); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview0.qml")); qApp->processEvents(); QDeclarativePathView *pathview = findItem(canvas->rootObject(), "view"); @@ -272,7 +272,7 @@ void tst_QDeclarativePathView::pathview3() void tst_QDeclarativePathView::path() { QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/path.qml")); + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/pathtest.qml")); QDeclarativePath *obj = qobject_cast(c.create()); QVERIFY(obj != 0); @@ -407,7 +407,7 @@ void tst_QDeclarativePathView::pathMoved() QDeclarativeContext *ctxt = canvas->rootContext(); ctxt->setContextProperty("testModel", &model); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview0.qml")); qApp->processEvents(); QDeclarativePathView *pathview = findItem(canvas->rootObject(), "view"); @@ -448,7 +448,7 @@ void tst_QDeclarativePathView::setCurrentIndex() QDeclarativeContext *ctxt = canvas->rootContext(); ctxt->setContextProperty("testModel", &model); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview0.qml")); qApp->processEvents(); QDeclarativePathView *pathview = findItem(canvas->rootObject(), "view"); diff --git a/tests/auto/declarative/qdeclarativepositioners/data/grid.qml b/tests/auto/declarative/qdeclarativepositioners/data/grid.qml deleted file mode 100644 index 830df6a..0000000 --- a/tests/auto/declarative/qdeclarativepositioners/data/grid.qml +++ /dev/null @@ -1,39 +0,0 @@ -import Qt 4.6 - -Item { - width: 640 - height: 480 - Grid { - columns: 3 - Rectangle { - objectName: "one" - color: "red" - width: 50 - height: 50 - } - Rectangle { - objectName: "two" - color: "green" - width: 20 - height: 50 - } - Rectangle { - objectName: "three" - color: "blue" - width: 50 - height: 20 - } - Rectangle { - objectName: "four" - color: "cyan" - width: 50 - height: 50 - } - Rectangle { - objectName: "five" - color: "magenta" - width: 10 - height: 10 - } - } -} diff --git a/tests/auto/declarative/qdeclarativepositioners/data/gridtest.qml b/tests/auto/declarative/qdeclarativepositioners/data/gridtest.qml new file mode 100644 index 0000000..830df6a --- /dev/null +++ b/tests/auto/declarative/qdeclarativepositioners/data/gridtest.qml @@ -0,0 +1,39 @@ +import Qt 4.6 + +Item { + width: 640 + height: 480 + Grid { + columns: 3 + Rectangle { + objectName: "one" + color: "red" + width: 50 + height: 50 + } + Rectangle { + objectName: "two" + color: "green" + width: 20 + height: 50 + } + Rectangle { + objectName: "three" + color: "blue" + width: 50 + height: 20 + } + Rectangle { + objectName: "four" + color: "cyan" + width: 50 + height: 50 + } + Rectangle { + objectName: "five" + color: "magenta" + width: 10 + height: 10 + } + } +} diff --git a/tests/auto/declarative/qdeclarativepositioners/data/propertychanges.qml b/tests/auto/declarative/qdeclarativepositioners/data/propertychanges.qml deleted file mode 100644 index 4370a18..0000000 --- a/tests/auto/declarative/qdeclarativepositioners/data/propertychanges.qml +++ /dev/null @@ -1,39 +0,0 @@ -import Qt 4.6 - -Grid { - id: myGrid - - width: 270 - height: 270 - x: 3 - y: 3 - columns: 4 - spacing: 3 - - add: columnTransition - move: columnTransition - - Repeater { - model: 20 - Rectangle { color: "black"; width: 50; height: 50 } - } - - data: [ - Transition { - id: rowTransition - objectName: "rowTransition" - NumberAnimation { - properties: "x,y"; - easing.type: "OutInCubic" - } - }, - Transition { - id: columnTransition - objectName: "columnTransition" - NumberAnimation { - properties: "x,y"; - easing.type: "OutInCubic" - } - } - ] -} diff --git a/tests/auto/declarative/qdeclarativepositioners/data/propertychangestest.qml b/tests/auto/declarative/qdeclarativepositioners/data/propertychangestest.qml new file mode 100644 index 0000000..4370a18 --- /dev/null +++ b/tests/auto/declarative/qdeclarativepositioners/data/propertychangestest.qml @@ -0,0 +1,39 @@ +import Qt 4.6 + +Grid { + id: myGrid + + width: 270 + height: 270 + x: 3 + y: 3 + columns: 4 + spacing: 3 + + add: columnTransition + move: columnTransition + + Repeater { + model: 20 + Rectangle { color: "black"; width: 50; height: 50 } + } + + data: [ + Transition { + id: rowTransition + objectName: "rowTransition" + NumberAnimation { + properties: "x,y"; + easing.type: "OutInCubic" + } + }, + Transition { + id: columnTransition + objectName: "columnTransition" + NumberAnimation { + properties: "x,y"; + easing.type: "OutInCubic" + } + } + ] +} diff --git a/tests/auto/declarative/qdeclarativepositioners/data/repeater.qml b/tests/auto/declarative/qdeclarativepositioners/data/repeater.qml deleted file mode 100644 index 2bc5e94..0000000 --- a/tests/auto/declarative/qdeclarativepositioners/data/repeater.qml +++ /dev/null @@ -1,20 +0,0 @@ -import Qt 4.6 - -Item { - width: 640 - height: 480 - Row { - Repeater{ model: 3; - delegate: Component { - Rectangle { - color: "red" - width: 50 - height: 50 - z: {if(index == 0){2;}else if(index == 1){1;} else{3;}} - objectName: {if(index == 0){"one";}else if(index == 1){"two";} else{"three";}} - - } - } - } - } -} diff --git a/tests/auto/declarative/qdeclarativepositioners/data/repeatertest.qml b/tests/auto/declarative/qdeclarativepositioners/data/repeatertest.qml new file mode 100644 index 0000000..2bc5e94 --- /dev/null +++ b/tests/auto/declarative/qdeclarativepositioners/data/repeatertest.qml @@ -0,0 +1,20 @@ +import Qt 4.6 + +Item { + width: 640 + height: 480 + Row { + Repeater{ model: 3; + delegate: Component { + Rectangle { + color: "red" + width: 50 + height: 50 + z: {if(index == 0){2;}else if(index == 1){1;} else{3;}} + objectName: {if(index == 0){"one";}else if(index == 1){"two";} else{"three";}} + + } + } + } + } +} diff --git a/tests/auto/declarative/qdeclarativepositioners/tst_qdeclarativepositioners.cpp b/tests/auto/declarative/qdeclarativepositioners/tst_qdeclarativepositioners.cpp index d23d74c..0e1fee2 100644 --- a/tests/auto/declarative/qdeclarativepositioners/tst_qdeclarativepositioners.cpp +++ b/tests/auto/declarative/qdeclarativepositioners/tst_qdeclarativepositioners.cpp @@ -239,7 +239,7 @@ void tst_QDeclarativePositioners::test_vertical_animated() void tst_QDeclarativePositioners::test_grid() { - QDeclarativeView *canvas = createView(SRCDIR "/data/grid.qml"); + QDeclarativeView *canvas = createView(SRCDIR "/data/gridtest.qml"); QDeclarativeRectangle *one = canvas->rootObject()->findChild("one"); QVERIFY(one != 0); @@ -365,9 +365,10 @@ void tst_QDeclarativePositioners::test_grid_animated() } void tst_QDeclarativePositioners::test_propertychanges() { - QDeclarativeView *canvas = createView(SRCDIR "/data/propertychanges.qml"); + QDeclarativeView *canvas = createView(SRCDIR "/data/propertychangestest.qml"); QDeclarativeGrid *grid = qobject_cast(canvas->rootObject()); + QVERIFY(grid != 0); QDeclarativeTransition *rowTransition = canvas->rootObject()->findChild("rowTransition"); QDeclarativeTransition *columnTransition = canvas->rootObject()->findChild("columnTransition"); @@ -421,7 +422,7 @@ void tst_QDeclarativePositioners::test_propertychanges() void tst_QDeclarativePositioners::test_repeater() { - QDeclarativeView *canvas = createView(SRCDIR "/data/repeater.qml"); + QDeclarativeView *canvas = createView(SRCDIR "/data/repeatertest.qml"); QDeclarativeRectangle *one = canvas->rootObject()->findChild("one"); QVERIFY(one != 0); diff --git a/tests/auto/declarative/qdeclarativerepeater/data/repeater.qml b/tests/auto/declarative/qdeclarativerepeater/data/repeater.qml deleted file mode 100644 index 7d83230..0000000 --- a/tests/auto/declarative/qdeclarativerepeater/data/repeater.qml +++ /dev/null @@ -1,28 +0,0 @@ -import Qt 4.6 - -Rectangle { - id: container - objectName: "container" - width: 240 - height: 320 - color: "white" - Text { - text: "Zero" - } - Repeater { - id: repeater - objectName: "repeater" - width: 240 - height: 320 - model: testData - Component { - Text { - y: index*20 - text: modelData - } - } - } - Text { - text: "Last" - } -} diff --git a/tests/auto/declarative/qdeclarativerepeater/data/repeater1.qml b/tests/auto/declarative/qdeclarativerepeater/data/repeater1.qml new file mode 100644 index 0000000..7d83230 --- /dev/null +++ b/tests/auto/declarative/qdeclarativerepeater/data/repeater1.qml @@ -0,0 +1,28 @@ +import Qt 4.6 + +Rectangle { + id: container + objectName: "container" + width: 240 + height: 320 + color: "white" + Text { + text: "Zero" + } + Repeater { + id: repeater + objectName: "repeater" + width: 240 + height: 320 + model: testData + Component { + Text { + y: index*20 + text: modelData + } + } + } + Text { + text: "Last" + } +} diff --git a/tests/auto/declarative/qdeclarativerepeater/tst_qdeclarativerepeater.cpp b/tests/auto/declarative/qdeclarativerepeater/tst_qdeclarativerepeater.cpp index 7da9454..09c4879 100644 --- a/tests/auto/declarative/qdeclarativerepeater/tst_qdeclarativerepeater.cpp +++ b/tests/auto/declarative/qdeclarativerepeater/tst_qdeclarativerepeater.cpp @@ -224,7 +224,7 @@ void tst_QDeclarativeRepeater::stringList() QDeclarativeContext *ctxt = canvas->rootContext(); ctxt->setContextProperty("testData", data); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/repeater.qml")); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/repeater1.qml")); qApp->processEvents(); QDeclarativeRepeater *repeater = findItem(canvas->rootObject(), "repeater"); diff --git a/tests/auto/declarative/qdeclarativestates/data/anchorChanges.qml b/tests/auto/declarative/qdeclarativestates/data/anchorChanges.qml deleted file mode 100644 index 7dce889..0000000 --- a/tests/auto/declarative/qdeclarativestates/data/anchorChanges.qml +++ /dev/null @@ -1,23 +0,0 @@ -import Qt 4.6 - -Rectangle { - id: container - width: 200; height: 200 - Rectangle { - id: myRect - objectName: "MyRect" - width: 50; height: 50 - color: "green"; - anchors.left: parent.left - anchors.leftMargin: 5 - } - states: State { - name: "right" - AnchorChanges { - id: ancCh - target: myRect; - reset: "left" - right: container.right - } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/anchorChanges1.qml b/tests/auto/declarative/qdeclarativestates/data/anchorChanges1.qml new file mode 100644 index 0000000..7dce889 --- /dev/null +++ b/tests/auto/declarative/qdeclarativestates/data/anchorChanges1.qml @@ -0,0 +1,23 @@ +import Qt 4.6 + +Rectangle { + id: container + width: 200; height: 200 + Rectangle { + id: myRect + objectName: "MyRect" + width: 50; height: 50 + color: "green"; + anchors.left: parent.left + anchors.leftMargin: 5 + } + states: State { + name: "right" + AnchorChanges { + id: ancCh + target: myRect; + reset: "left" + right: container.right + } + } +} diff --git a/tests/auto/declarative/qdeclarativestates/data/parentChange.qml b/tests/auto/declarative/qdeclarativestates/data/parentChange.qml deleted file mode 100644 index b8c7818..0000000 --- a/tests/auto/declarative/qdeclarativestates/data/parentChange.qml +++ /dev/null @@ -1,37 +0,0 @@ -import Qt 4.6 - -Rectangle { - width: 400; height: 400 - Item { - x: 10; y: 10 - Rectangle { - id: myRect - objectName: "MyRect" - x: 5 - width: 100; height: 100 - color: "red" - } - } - MouseArea { - id: clickable - anchors.fill: parent - } - - Item { - x: -100; y: -50 - Item { - id: newParent - objectName: "NewParent" - x: 248; y: 360 - } - } - - states: State { - name: "reparented" - when: clickable.pressed - ParentChange { - target: myRect - parent: newParent - } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/parentChange1.qml b/tests/auto/declarative/qdeclarativestates/data/parentChange1.qml new file mode 100644 index 0000000..b8c7818 --- /dev/null +++ b/tests/auto/declarative/qdeclarativestates/data/parentChange1.qml @@ -0,0 +1,37 @@ +import Qt 4.6 + +Rectangle { + width: 400; height: 400 + Item { + x: 10; y: 10 + Rectangle { + id: myRect + objectName: "MyRect" + x: 5 + width: 100; height: 100 + color: "red" + } + } + MouseArea { + id: clickable + anchors.fill: parent + } + + Item { + x: -100; y: -50 + Item { + id: newParent + objectName: "NewParent" + x: 248; y: 360 + } + } + + states: State { + name: "reparented" + when: clickable.pressed + ParentChange { + target: myRect + parent: newParent + } + } +} diff --git a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp index c16a870..fe7ec15 100644 --- a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp +++ b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp @@ -441,7 +441,7 @@ void tst_qdeclarativestates::parentChange() QDeclarativeEngine engine; { - QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/parentChange.qml"); + QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/parentChange1.qml"); QDeclarativeRectangle *rect = qobject_cast(rectComponent.create()); QVERIFY(rect != 0); @@ -546,7 +546,7 @@ void tst_qdeclarativestates::anchorChanges() { QDeclarativeEngine engine; - QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges.qml"); + QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges1.qml"); QDeclarativeRectangle *rect = qobject_cast(rectComponent.create()); QVERIFY(rect != 0); -- cgit v0.12 From ad49a46304c4b74ebc7dea8f314b89bc6aef63a3 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 18 Mar 2010 11:16:53 +1000 Subject: Don't destroy cookie jar until while someone may be using it. --- tools/qml/qmlruntime.cpp | 58 ++++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/tools/qml/qmlruntime.cpp b/tools/qml/qmlruntime.cpp index c7acf2c..6660947 100644 --- a/tools/qml/qmlruntime.cpp +++ b/tools/qml/qmlruntime.cpp @@ -351,30 +351,10 @@ private: class NetworkAccessManagerFactory : public QDeclarativeNetworkAccessManagerFactory { public: - NetworkAccessManagerFactory() : cookieJar(0), cacheSize(0) {} - ~NetworkAccessManagerFactory() { - delete cookieJar; - } + NetworkAccessManagerFactory() : cacheSize(0) {} + ~NetworkAccessManagerFactory() {} - QNetworkAccessManager *create(QObject *parent) { - QMutexLocker lock(&mutex); - QNetworkAccessManager *manager = new QNetworkAccessManager(parent); - if (!cookieJar) - cookieJar = new PersistentCookieJar(0); - manager->setCookieJar(cookieJar); - cookieJar->setParent(0); - setupProxy(manager); - if (cacheSize > 0) { - QNetworkDiskCache *cache = new QNetworkDiskCache; - cache->setCacheDirectory(QDir::tempPath()+QLatin1String("/qml-duiviewer-network-cache")); - cache->setMaximumCacheSize(cacheSize); - manager->setCache(cache); - } else { - manager->setCache(0); - } - qDebug() << "created new network access manager for" << parent; - return manager; - } + QNetworkAccessManager *create(QObject *parent); void setupProxy(QNetworkAccessManager *nam) { @@ -419,11 +399,41 @@ public: } } - PersistentCookieJar *cookieJar; + static PersistentCookieJar *cookieJar; QMutex mutex; int cacheSize; }; +PersistentCookieJar *NetworkAccessManagerFactory::cookieJar = 0; + +static void cleanup_cookieJar() +{ + delete NetworkAccessManagerFactory::cookieJar; + NetworkAccessManagerFactory::cookieJar = 0; +} + +QNetworkAccessManager *NetworkAccessManagerFactory::create(QObject *parent) +{ + QMutexLocker lock(&mutex); + QNetworkAccessManager *manager = new QNetworkAccessManager(parent); + if (!cookieJar) { + qAddPostRoutine(cleanup_cookieJar); + cookieJar = new PersistentCookieJar(0); + } + manager->setCookieJar(cookieJar); + cookieJar->setParent(0); + setupProxy(manager); + if (cacheSize > 0) { + QNetworkDiskCache *cache = new QNetworkDiskCache; + cache->setCacheDirectory(QDir::tempPath()+QLatin1String("/qml-duiviewer-network-cache")); + cache->setMaximumCacheSize(cacheSize); + manager->setCache(cache); + } else { + manager->setCache(0); + } + qDebug() << "created new network access manager for" << parent; + return manager; +} QString QDeclarativeViewer::getVideoFileName() { -- cgit v0.12 From 04776ee4cac6edfba910d5e0082f32b01948db51 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 18 Mar 2010 11:29:44 +1000 Subject: Block modifications to internal QDeclarativeContexts --- src/declarative/qml/qdeclarativecontext.cpp | 20 +++++++++++++- .../tst_qdeclarativecontext.cpp | 31 ++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp index 60fc1d1..782c0d7 100644 --- a/src/declarative/qml/qdeclarativecontext.cpp +++ b/src/declarative/qml/qdeclarativecontext.cpp @@ -242,7 +242,15 @@ QObject *QDeclarativeContext::contextObject() const void QDeclarativeContext::setContextObject(QObject *object) { Q_D(QDeclarativeContext); - d->data->contextObject = object; + + QDeclarativeContextData *data = d->data; + + if (data->isInternal) { + qWarning("QDeclarativeContext: Cannot set context object for internal context."); + return; + } + + data->contextObject = object; } /*! @@ -256,6 +264,11 @@ void QDeclarativeContext::setContextProperty(const QString &name, const QVariant QDeclarativeContextData *data = d->data; + if (data->isInternal) { + qWarning("QDeclarativeContext: Cannot set property on internal context."); + return; + } + if (data->engine) { bool ok; QObject *o = QDeclarativeEnginePrivate::get(data->engine)->toQObject(value, &ok); @@ -292,6 +305,11 @@ void QDeclarativeContext::setContextProperty(const QString &name, QObject *value QDeclarativeContextData *data = d->data; + if (data->isInternal) { + qWarning("QDeclarativeContext: Cannot set property on internal context."); + return; + } + if (!data->propertyNames) data->propertyNames = new QDeclarativeIntegerCache(data->engine); int idx = data->propertyNames->value(name); diff --git a/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp b/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp index b212820..be20ba1 100644 --- a/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp +++ b/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp @@ -61,6 +61,7 @@ private slots: void setContextObject(); void destruction(); void idAsContextProperty(); + void readOnlyContexts(); private: QDeclarativeEngine engine; @@ -427,6 +428,36 @@ void tst_qdeclarativecontext::idAsContextProperty() delete obj; } +// Internal contexts should be read-only +void tst_qdeclarativecontext::readOnlyContexts() +{ + QDeclarativeComponent component(&engine); + component.setData("import Qt 4.6; QtObject { id: me }", QUrl()); + + QObject *obj = component.create(); + QVERIFY(obj); + + QDeclarativeContext *context = qmlContext(obj); + QVERIFY(context); + + QVERIFY(qvariant_cast(context->contextProperty("me")) == obj); + QVERIFY(context->contextObject() == obj); + + QTest::ignoreMessage(QtWarningMsg, "QDeclarativeContext: Cannot set property on internal context."); + context->setContextProperty("hello", 12); + QVERIFY(context->contextProperty("hello") == QVariant()); + + QTest::ignoreMessage(QtWarningMsg, "QDeclarativeContext: Cannot set property on internal context."); + context->setContextProperty("hello", obj); + QVERIFY(context->contextProperty("hello") == QVariant()); + + QTest::ignoreMessage(QtWarningMsg, "QDeclarativeContext: Cannot set context object for internal context."); + context->setContextObject(0); + QVERIFY(context->contextObject() == obj); + + delete obj; +} + QTEST_MAIN(tst_qdeclarativecontext) #include "tst_qdeclarativecontext.moc" -- cgit v0.12 From a096555227b39c3107ab5eea497176746083cd4b Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Thu, 18 Mar 2010 14:00:25 +1000 Subject: Adjust test now that redundant contexts are not create due to commit 26cd94ef47ffc969dc835e98b58eded14e669964. --- .../auto/declarative/qdeclarativewebview/tst_qdeclarativewebview.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/declarative/qdeclarativewebview/tst_qdeclarativewebview.cpp b/tests/auto/declarative/qdeclarativewebview/tst_qdeclarativewebview.cpp index 91115e4..ce389f3 100644 --- a/tests/auto/declarative/qdeclarativewebview/tst_qdeclarativewebview.cpp +++ b/tests/auto/declarative/qdeclarativewebview/tst_qdeclarativewebview.cpp @@ -312,8 +312,8 @@ void tst_qdeclarativewebview::multipleWindows() QDeclarativeGrid *grid = qobject_cast(component.create()); QVERIFY(grid != 0); - QTRY_COMPARE(grid->children().count(), 2+5); // Component, Loader, 5 WebViews - QDeclarativeItem* popup = qobject_cast(grid->children().at(3)); // first popup after Component, Loaded, original. + QTRY_COMPARE(grid->children().count(), 2+4); // Component, Loader (with 1 WebView), 4 new-window WebViews + QDeclarativeItem* popup = qobject_cast(grid->children().at(2)); // first popup after Component and Loader. QVERIFY(popup != 0); QTRY_COMPARE(popup->x(), 150.0); } -- cgit v0.12 From 67fedb14501b47fec6892cf6b88739fba985b366 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 18 Mar 2010 14:02:59 +1000 Subject: Make it harder to accidentally delete a binding --- src/declarative/qml/qdeclarativebinding_p.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/declarative/qml/qdeclarativebinding_p.h b/src/declarative/qml/qdeclarativebinding_p.h index 533b6d4..56f1715 100644 --- a/src/declarative/qml/qdeclarativebinding_p.h +++ b/src/declarative/qml/qdeclarativebinding_p.h @@ -68,7 +68,6 @@ class Q_DECLARATIVE_EXPORT QDeclarativeAbstractBinding { public: QDeclarativeAbstractBinding(); - virtual ~QDeclarativeAbstractBinding(); virtual void destroy(); @@ -88,14 +87,15 @@ public: void removeFromObject(); protected: + virtual ~QDeclarativeAbstractBinding(); void clear(); private: + friend class QDeclarativeDeclarativeData; - friend class QDeclarativeProperty; + friend class QDeclarativeValueTypeProxyBinding; friend class QDeclarativePropertyPrivate; friend class QDeclarativeVME; - friend class QDeclarativeValueTypeProxyBinding; QObject *m_object; QDeclarativeAbstractBinding **m_mePtr; @@ -107,7 +107,6 @@ class QDeclarativeValueTypeProxyBinding : public QDeclarativeAbstractBinding { public: QDeclarativeValueTypeProxyBinding(QObject *o, int coreIndex); - virtual ~QDeclarativeValueTypeProxyBinding(); virtual Type bindingType() const { return ValueTypeProxy; } @@ -117,6 +116,9 @@ public: QDeclarativeAbstractBinding *binding(int propertyIndex); +protected: + ~QDeclarativeValueTypeProxyBinding(); + private: void recursiveEnable(QDeclarativeAbstractBinding *, QDeclarativePropertyPrivate::WriteFlags); void recursiveDisable(QDeclarativeAbstractBinding *); @@ -137,7 +139,6 @@ public: QDeclarativeBinding(const QString &, QObject *, QDeclarativeContextData *, QObject *parent=0); QDeclarativeBinding(void *, QDeclarativeRefCount *, QObject *, QDeclarativeContextData *, const QString &, int, QObject *parent); - ~QDeclarativeBinding(); void setTarget(const QDeclarativeProperty &); QDeclarativeProperty property() const; @@ -154,6 +155,7 @@ public Q_SLOTS: void update() { update(QDeclarativePropertyPrivate::DontRemoveBinding); } protected: + ~QDeclarativeBinding(); void emitValueChanged(); private: -- cgit v0.12 From 014c811f8d178d585c4b05d8d35361dc93a5133d Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 18 Mar 2010 14:16:52 +1000 Subject: Only release the binding once we're finished with its memory --- src/declarative/qml/qdeclarativecompiledbindings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarative/qml/qdeclarativecompiledbindings.cpp b/src/declarative/qml/qdeclarativecompiledbindings.cpp index c8bff17..1acca2f 100644 --- a/src/declarative/qml/qdeclarativecompiledbindings.cpp +++ b/src/declarative/qml/qdeclarativecompiledbindings.cpp @@ -251,8 +251,8 @@ void QDeclarativeCompiledBindingsPrivate::Binding::destroy() { enabled = false; removeFromObject(); - parent->q_func()->release(); clear(); + parent->q_func()->release(); } int QDeclarativeCompiledBindings::qt_metacall(QMetaObject::Call c, int id, void **) -- cgit v0.12 From 4731b836a4754d6f3a403db5be8b9d3bf6de1570 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Thu, 18 Mar 2010 14:35:01 +1000 Subject: Skip test, to be fixed. --- .../declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp index 576fe21..0892402 100644 --- a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp +++ b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp @@ -290,6 +290,8 @@ void tst_QDeclarativeListModel::dynamic_worker_data() void tst_QDeclarativeListModel::dynamic_worker() { + QSKIP("Skip, awaiting imminent fixes", SkipAll); + QFETCH(QString, script); QFETCH(int, result); QFETCH(QString, warning); -- cgit v0.12 From 8bcae7dd3f9138030c6ac27868ca8574f03f4d31 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Thu, 18 Mar 2010 14:35:49 +1000 Subject: Don't use QScriptValueIterator to iterate over arrays. --- src/declarative/util/qdeclarativelistmodel.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/declarative/util/qdeclarativelistmodel.cpp b/src/declarative/util/qdeclarativelistmodel.cpp index 5b0a7ea..340e9ac 100644 --- a/src/declarative/util/qdeclarativelistmodel.cpp +++ b/src/declarative/util/qdeclarativelistmodel.cpp @@ -1286,10 +1286,10 @@ void ModelNode::setObjectValue(const QScriptValue& valuemap) { void ModelNode::setListValue(const QScriptValue& valuelist) { QScriptValueIterator it(valuelist); values.clear(); - while (it.hasNext()) { - it.next(); + int size = valuelist.property(QLatin1String("length")).toInt32(); + for (int i=0; iisArray = true; value->setListValue(v); @@ -1299,7 +1299,6 @@ void ModelNode::setListValue(const QScriptValue& valuelist) { value->values << v.toVariant(); } values.append(qVariantFromValue(value)); - } } -- cgit v0.12 From b440beba19519e9211752656fdfeda250a35c81f Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Thu, 18 Mar 2010 14:25:36 +1000 Subject: Fix examples after 47fb07c9fdf47584ae55f3412102bbeef5576b04. --- .../declarative/behaviours/behavior-example.qml | 72 ++++++++++++++++++++ examples/declarative/behaviours/behavior.qml | 72 -------------------- .../connections/connections-example.qml | 27 ++++++++ examples/declarative/connections/connections.qml | 27 -------- examples/declarative/dial/dial-example.qml | 35 ++++++++++ examples/declarative/dial/dial.qml | 35 ---------- examples/declarative/flipable/flipable-example.qml | 37 +++++++++++ examples/declarative/flipable/flipable.qml | 37 ----------- examples/declarative/gridview/gridview-example.qml | 38 +++++++++++ examples/declarative/gridview/gridview.qml | 38 ----------- .../imageprovider/imageprovider-example.qml | 23 +++++++ .../declarative/imageprovider/imageprovider.qml | 23 ------- examples/declarative/listview/listview-example.qml | 77 ++++++++++++++++++++++ examples/declarative/listview/listview.qml | 77 ---------------------- 14 files changed, 309 insertions(+), 309 deletions(-) create mode 100644 examples/declarative/behaviours/behavior-example.qml delete mode 100644 examples/declarative/behaviours/behavior.qml create mode 100644 examples/declarative/connections/connections-example.qml delete mode 100644 examples/declarative/connections/connections.qml create mode 100644 examples/declarative/dial/dial-example.qml delete mode 100644 examples/declarative/dial/dial.qml create mode 100644 examples/declarative/flipable/flipable-example.qml delete mode 100644 examples/declarative/flipable/flipable.qml create mode 100644 examples/declarative/gridview/gridview-example.qml delete mode 100644 examples/declarative/gridview/gridview.qml create mode 100644 examples/declarative/imageprovider/imageprovider-example.qml delete mode 100644 examples/declarative/imageprovider/imageprovider.qml create mode 100644 examples/declarative/listview/listview-example.qml delete mode 100644 examples/declarative/listview/listview.qml diff --git a/examples/declarative/behaviours/behavior-example.qml b/examples/declarative/behaviours/behavior-example.qml new file mode 100644 index 0000000..c84bf62 --- /dev/null +++ b/examples/declarative/behaviours/behavior-example.qml @@ -0,0 +1,72 @@ +import Qt 4.6 + +Rectangle { + color: "black" + width: 400; height: 400 + + Rectangle { + color: "transparent" + anchors.centerIn: parent + width: 200; height: 200 + radius: 30 + border.width: 10; border.color: "white"; + + SideRect { + id: leftRect + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.left + text: "Left" + } + + SideRect { + id: rightRect + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.right + text: "Right" + } + + SideRect { + id: topRect + anchors.verticalCenter: parent.top + anchors.horizontalCenter: parent.horizontalCenter + text: "Top" + } + + SideRect { + id: bottomRect + anchors.verticalCenter: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + text: "Bottom" + } + + + Rectangle { + id: focusRect + + property string text + + color: "red" + width: 75; height: 50 + radius: 5 + border.width: 10; border.color: "white"; + x: 100-37; y: 100-25 + Behavior on x { NumberAnimation { duration: 300 } } + Behavior on y { NumberAnimation { duration: 300 } } + Text { + id: focusText + text: focusRect.text; + Behavior on text { + SequentialAnimation { + NumberAnimation { target: focusText; property: "opacity"; to: 0; duration: 150 } + PropertyAction {} + NumberAnimation { target: focusText; property: "opacity"; to: 1; duration: 150 } + } + } + anchors.centerIn: parent; + color: "white"; + font.pixelSize: 16 + font.bold: true + } + } + } +} diff --git a/examples/declarative/behaviours/behavior.qml b/examples/declarative/behaviours/behavior.qml deleted file mode 100644 index c84bf62..0000000 --- a/examples/declarative/behaviours/behavior.qml +++ /dev/null @@ -1,72 +0,0 @@ -import Qt 4.6 - -Rectangle { - color: "black" - width: 400; height: 400 - - Rectangle { - color: "transparent" - anchors.centerIn: parent - width: 200; height: 200 - radius: 30 - border.width: 10; border.color: "white"; - - SideRect { - id: leftRect - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.left - text: "Left" - } - - SideRect { - id: rightRect - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.right - text: "Right" - } - - SideRect { - id: topRect - anchors.verticalCenter: parent.top - anchors.horizontalCenter: parent.horizontalCenter - text: "Top" - } - - SideRect { - id: bottomRect - anchors.verticalCenter: parent.bottom - anchors.horizontalCenter: parent.horizontalCenter - text: "Bottom" - } - - - Rectangle { - id: focusRect - - property string text - - color: "red" - width: 75; height: 50 - radius: 5 - border.width: 10; border.color: "white"; - x: 100-37; y: 100-25 - Behavior on x { NumberAnimation { duration: 300 } } - Behavior on y { NumberAnimation { duration: 300 } } - Text { - id: focusText - text: focusRect.text; - Behavior on text { - SequentialAnimation { - NumberAnimation { target: focusText; property: "opacity"; to: 0; duration: 150 } - PropertyAction {} - NumberAnimation { target: focusText; property: "opacity"; to: 1; duration: 150 } - } - } - anchors.centerIn: parent; - color: "white"; - font.pixelSize: 16 - font.bold: true - } - } - } -} diff --git a/examples/declarative/connections/connections-example.qml b/examples/declarative/connections/connections-example.qml new file mode 100644 index 0000000..c35bda5 --- /dev/null +++ b/examples/declarative/connections/connections-example.qml @@ -0,0 +1,27 @@ +import Qt 4.6 +import "content" + +Rectangle { + id: window; color: "#646464" + width: 640; height: 480 + + property int angle: 0 + + Image { + id: image; source: "content/bg1.jpg"; anchors.centerIn: parent; transformOrigin: Item.Center + rotation: window.angle + Behavior on rotation { NumberAnimation { easing.type: "OutCubic"; duration: 300 } } + } + + Button { + id: leftButton; image: "content/rotate-left.png" + anchors { left: parent.left; bottom: parent.bottom; leftMargin: 10; bottomMargin: 10 } + } + Button { + id: rightButton; image: "content/rotate-right.png" + anchors { right: parent.right; bottom: parent.bottom; rightMargin: 10; bottomMargin: 10 } + } + + Connections { target: leftButton; onClicked: window.angle -= 90 } + Connections { target: rightButton; onClicked: window.angle += 90 } +} diff --git a/examples/declarative/connections/connections.qml b/examples/declarative/connections/connections.qml deleted file mode 100644 index c35bda5..0000000 --- a/examples/declarative/connections/connections.qml +++ /dev/null @@ -1,27 +0,0 @@ -import Qt 4.6 -import "content" - -Rectangle { - id: window; color: "#646464" - width: 640; height: 480 - - property int angle: 0 - - Image { - id: image; source: "content/bg1.jpg"; anchors.centerIn: parent; transformOrigin: Item.Center - rotation: window.angle - Behavior on rotation { NumberAnimation { easing.type: "OutCubic"; duration: 300 } } - } - - Button { - id: leftButton; image: "content/rotate-left.png" - anchors { left: parent.left; bottom: parent.bottom; leftMargin: 10; bottomMargin: 10 } - } - Button { - id: rightButton; image: "content/rotate-right.png" - anchors { right: parent.right; bottom: parent.bottom; rightMargin: 10; bottomMargin: 10 } - } - - Connections { target: leftButton; onClicked: window.angle -= 90 } - Connections { target: rightButton; onClicked: window.angle += 90 } -} diff --git a/examples/declarative/dial/dial-example.qml b/examples/declarative/dial/dial-example.qml new file mode 100644 index 0000000..3aed70e --- /dev/null +++ b/examples/declarative/dial/dial-example.qml @@ -0,0 +1,35 @@ +import Qt 4.6 +import "content" + +Rectangle { + color: "#545454" + width: 300; height: 300 + + // Dial with a slider to adjust it + Dial { id: dial; anchors.centerIn: parent; value: slider.x *100 / (container.width - 34) } + + Rectangle { + id: container + anchors.bottom: parent.bottom; anchors.bottomMargin: 10 + anchors.left: parent.left; anchors.leftMargin: 20 + anchors.right: parent.right; anchors.rightMargin: 20; height: 16 + gradient: Gradient { + GradientStop { position: 0.0; color: "gray" } + GradientStop { position: 1.0; color: "white" } + } + radius: 8; opacity: 0.7; smooth: true + Rectangle { + id: slider + x: 1; y: 1; width: 30; height: 14 + radius: 6; smooth: true + gradient: Gradient { + GradientStop { position: 0.0; color: "#424242" } + GradientStop { position: 1.0; color: "black" } + } + MouseArea { + anchors.fill: parent + drag.target: parent; drag.axis: "XAxis"; drag.minimumX: 2; drag.maximumX: container.width - 32 + } + } + } +} diff --git a/examples/declarative/dial/dial.qml b/examples/declarative/dial/dial.qml deleted file mode 100644 index 3aed70e..0000000 --- a/examples/declarative/dial/dial.qml +++ /dev/null @@ -1,35 +0,0 @@ -import Qt 4.6 -import "content" - -Rectangle { - color: "#545454" - width: 300; height: 300 - - // Dial with a slider to adjust it - Dial { id: dial; anchors.centerIn: parent; value: slider.x *100 / (container.width - 34) } - - Rectangle { - id: container - anchors.bottom: parent.bottom; anchors.bottomMargin: 10 - anchors.left: parent.left; anchors.leftMargin: 20 - anchors.right: parent.right; anchors.rightMargin: 20; height: 16 - gradient: Gradient { - GradientStop { position: 0.0; color: "gray" } - GradientStop { position: 1.0; color: "white" } - } - radius: 8; opacity: 0.7; smooth: true - Rectangle { - id: slider - x: 1; y: 1; width: 30; height: 14 - radius: 6; smooth: true - gradient: Gradient { - GradientStop { position: 0.0; color: "#424242" } - GradientStop { position: 1.0; color: "black" } - } - MouseArea { - anchors.fill: parent - drag.target: parent; drag.axis: "XAxis"; drag.minimumX: 2; drag.maximumX: container.width - 32 - } - } - } -} diff --git a/examples/declarative/flipable/flipable-example.qml b/examples/declarative/flipable/flipable-example.qml new file mode 100644 index 0000000..c837ebc --- /dev/null +++ b/examples/declarative/flipable/flipable-example.qml @@ -0,0 +1,37 @@ +//! [0] +import Qt 4.6 + +Flipable { + id: flipable + width: 240 + height: 240 + + property int angle: 0 + property bool flipped: false + + front: Image { source: "front.png" } + back: Image { source: "back.png" } + + transform: Rotation { + origin.x: flipable.width/2; origin.y: flipable.height/2 + axis.x: 0; axis.y: 1; axis.z: 0 // rotate around y-axis + angle: flipable.angle + } + + states: State { + name: "back" + PropertyChanges { target: flipable; angle: 180 } + when: flipable.flipped + } + + transitions: Transition { + NumberAnimation { properties: "angle"; duration: 1000 } + } + + MouseArea { + anchors.fill: parent + onClicked: flipable.flipped = !flipable.flipped + } +} +//! [0] + diff --git a/examples/declarative/flipable/flipable.qml b/examples/declarative/flipable/flipable.qml deleted file mode 100644 index c837ebc..0000000 --- a/examples/declarative/flipable/flipable.qml +++ /dev/null @@ -1,37 +0,0 @@ -//! [0] -import Qt 4.6 - -Flipable { - id: flipable - width: 240 - height: 240 - - property int angle: 0 - property bool flipped: false - - front: Image { source: "front.png" } - back: Image { source: "back.png" } - - transform: Rotation { - origin.x: flipable.width/2; origin.y: flipable.height/2 - axis.x: 0; axis.y: 1; axis.z: 0 // rotate around y-axis - angle: flipable.angle - } - - states: State { - name: "back" - PropertyChanges { target: flipable; angle: 180 } - when: flipable.flipped - } - - transitions: Transition { - NumberAnimation { properties: "angle"; duration: 1000 } - } - - MouseArea { - anchors.fill: parent - onClicked: flipable.flipped = !flipable.flipped - } -} -//! [0] - diff --git a/examples/declarative/gridview/gridview-example.qml b/examples/declarative/gridview/gridview-example.qml new file mode 100644 index 0000000..93931c7 --- /dev/null +++ b/examples/declarative/gridview/gridview-example.qml @@ -0,0 +1,38 @@ +import Qt 4.6 + +Rectangle { + width: 300; height: 400; color: "white" + + ListModel { + id: appModel + ListElement { name: "Music"; icon: "pics/AudioPlayer_48.png" } + ListElement { name: "Movies"; icon: "pics/VideoPlayer_48.png" } + ListElement { name: "Camera"; icon: "pics/Camera_48.png" } + ListElement { name: "Calendar"; icon: "pics/DateBook_48.png" } + ListElement { name: "Messaging"; icon: "pics/EMail_48.png" } + ListElement { name: "Todo List"; icon: "pics/TodoList_48.png" } + ListElement { name: "Contacts"; icon: "pics/AddressBook_48.png" } + } + + Component { + id: appDelegate + Item { + width: 100; height: 100 + Image { id: myIcon; y: 20; anchors.horizontalCenter: parent.horizontalCenter; source: icon } + Text { anchors.top: myIcon.bottom; anchors.horizontalCenter: parent.horizontalCenter; text: name } + } + } + + Component { + id: appHighlight + Rectangle { width: 80; height: 80; color: "lightsteelblue" } + } + + GridView { + anchors.fill: parent + cellWidth: 100; cellHeight: 100 + model: appModel; delegate: appDelegate + highlight: appHighlight + focus: true + } +} diff --git a/examples/declarative/gridview/gridview.qml b/examples/declarative/gridview/gridview.qml deleted file mode 100644 index 93931c7..0000000 --- a/examples/declarative/gridview/gridview.qml +++ /dev/null @@ -1,38 +0,0 @@ -import Qt 4.6 - -Rectangle { - width: 300; height: 400; color: "white" - - ListModel { - id: appModel - ListElement { name: "Music"; icon: "pics/AudioPlayer_48.png" } - ListElement { name: "Movies"; icon: "pics/VideoPlayer_48.png" } - ListElement { name: "Camera"; icon: "pics/Camera_48.png" } - ListElement { name: "Calendar"; icon: "pics/DateBook_48.png" } - ListElement { name: "Messaging"; icon: "pics/EMail_48.png" } - ListElement { name: "Todo List"; icon: "pics/TodoList_48.png" } - ListElement { name: "Contacts"; icon: "pics/AddressBook_48.png" } - } - - Component { - id: appDelegate - Item { - width: 100; height: 100 - Image { id: myIcon; y: 20; anchors.horizontalCenter: parent.horizontalCenter; source: icon } - Text { anchors.top: myIcon.bottom; anchors.horizontalCenter: parent.horizontalCenter; text: name } - } - } - - Component { - id: appHighlight - Rectangle { width: 80; height: 80; color: "lightsteelblue" } - } - - GridView { - anchors.fill: parent - cellWidth: 100; cellHeight: 100 - model: appModel; delegate: appDelegate - highlight: appHighlight - focus: true - } -} diff --git a/examples/declarative/imageprovider/imageprovider-example.qml b/examples/declarative/imageprovider/imageprovider-example.qml new file mode 100644 index 0000000..a1f2794 --- /dev/null +++ b/examples/declarative/imageprovider/imageprovider-example.qml @@ -0,0 +1,23 @@ +import Qt 4.6 +import ImageProviderCore 1.0 +//![0] +ListView { + width: 100 + height: 100 + anchors.fill: parent + model: myModel + delegate: Component { + Item { + width: 100 + height: 50 + Text { + text: "Loading..." + anchors.centerIn: parent + } + Image { + source: modelData + } + } + } +} +//![0] diff --git a/examples/declarative/imageprovider/imageprovider.qml b/examples/declarative/imageprovider/imageprovider.qml deleted file mode 100644 index a1f2794..0000000 --- a/examples/declarative/imageprovider/imageprovider.qml +++ /dev/null @@ -1,23 +0,0 @@ -import Qt 4.6 -import ImageProviderCore 1.0 -//![0] -ListView { - width: 100 - height: 100 - anchors.fill: parent - model: myModel - delegate: Component { - Item { - width: 100 - height: 50 - Text { - text: "Loading..." - anchors.centerIn: parent - } - Image { - source: modelData - } - } - } -} -//![0] diff --git a/examples/declarative/listview/listview-example.qml b/examples/declarative/listview/listview-example.qml new file mode 100644 index 0000000..92acce1 --- /dev/null +++ b/examples/declarative/listview/listview-example.qml @@ -0,0 +1,77 @@ +import Qt 4.6 + +Rectangle { + width: 600; height: 300; color: "white" + + // MyPets model is defined in dummydata/MyPetsModel.qml + // The viewer automatically loads files in dummydata/* to assist + // development without a real data source. + // This one contains my pets. + // Define a delegate component. A component will be + // instantiated for each visible item in the list. + Component { + id: petDelegate + Item { + width: 200; height: 50 + Column { + Text { text: 'Name: ' + name } + Text { text: 'Type: ' + type } + Text { text: 'Age: ' + age } + } + } + } + + // Define a highlight component. Just one of these will be instantiated + // by each ListView and placed behind the current item. + Component { + id: petHighlight + Rectangle { color: "#FFFF88" } + } + + // Show the model in three lists, with different highlight ranges. + // preferredHighlightBegin and preferredHighlightEnd set the + // range in which to attempt to maintain the highlight. + // Note that the second and third ListView + // set their currentIndex to be the same as the first, and that + // the first ListView is given keyboard focus. + // The default mode allows the currentItem to move freely + // within the visible area. If it would move outside the visible + // area, the view is scrolled to keep it visible. + // The second list sets a highlight range which attempts to keep the + // current item within the the bounds of the range, however + // items will not scroll beyond the beginning or end of the view, + // forcing the highlight to move outside the range at the ends. + // The third list sets the highlightRangeMode to StrictlyEnforceRange + // and sets a range smaller than the height of an item. This + // forces the current item to change when the view is flicked, + // since the highlight is unable to move. + // Note that the first ListView sets its currentIndex to be equal to + // the third ListView's currentIndex. By flicking List3 with + // the mouse, the current index of List1 will be changed. + ListView { + id: list1 + width: 200; height: parent.height + model: MyPetsModel; delegate: petDelegate + highlight: petHighlight; currentIndex: list3.currentIndex + focus: true + } + ListView { + id: list2 + x: 200; width: 200; height: parent.height + model: MyPetsModel; delegate: petDelegate; highlight: petHighlight + preferredHighlightBegin: 80 + preferredHighlightEnd: 220 + highlightRangeMode: "ApplyRange" + currentIndex: list1.currentIndex + } + ListView { + id: list3 + x: 400; width: 200; height: parent.height + model: MyPetsModel; delegate: petDelegate; highlight: petHighlight + currentIndex: list1.currentIndex + preferredHighlightBegin: 125 + preferredHighlightEnd: 125 + highlightRangeMode: "StrictlyEnforceRange" + flickDeceleration: 1000 + } +} diff --git a/examples/declarative/listview/listview.qml b/examples/declarative/listview/listview.qml deleted file mode 100644 index 92acce1..0000000 --- a/examples/declarative/listview/listview.qml +++ /dev/null @@ -1,77 +0,0 @@ -import Qt 4.6 - -Rectangle { - width: 600; height: 300; color: "white" - - // MyPets model is defined in dummydata/MyPetsModel.qml - // The viewer automatically loads files in dummydata/* to assist - // development without a real data source. - // This one contains my pets. - // Define a delegate component. A component will be - // instantiated for each visible item in the list. - Component { - id: petDelegate - Item { - width: 200; height: 50 - Column { - Text { text: 'Name: ' + name } - Text { text: 'Type: ' + type } - Text { text: 'Age: ' + age } - } - } - } - - // Define a highlight component. Just one of these will be instantiated - // by each ListView and placed behind the current item. - Component { - id: petHighlight - Rectangle { color: "#FFFF88" } - } - - // Show the model in three lists, with different highlight ranges. - // preferredHighlightBegin and preferredHighlightEnd set the - // range in which to attempt to maintain the highlight. - // Note that the second and third ListView - // set their currentIndex to be the same as the first, and that - // the first ListView is given keyboard focus. - // The default mode allows the currentItem to move freely - // within the visible area. If it would move outside the visible - // area, the view is scrolled to keep it visible. - // The second list sets a highlight range which attempts to keep the - // current item within the the bounds of the range, however - // items will not scroll beyond the beginning or end of the view, - // forcing the highlight to move outside the range at the ends. - // The third list sets the highlightRangeMode to StrictlyEnforceRange - // and sets a range smaller than the height of an item. This - // forces the current item to change when the view is flicked, - // since the highlight is unable to move. - // Note that the first ListView sets its currentIndex to be equal to - // the third ListView's currentIndex. By flicking List3 with - // the mouse, the current index of List1 will be changed. - ListView { - id: list1 - width: 200; height: parent.height - model: MyPetsModel; delegate: petDelegate - highlight: petHighlight; currentIndex: list3.currentIndex - focus: true - } - ListView { - id: list2 - x: 200; width: 200; height: parent.height - model: MyPetsModel; delegate: petDelegate; highlight: petHighlight - preferredHighlightBegin: 80 - preferredHighlightEnd: 220 - highlightRangeMode: "ApplyRange" - currentIndex: list1.currentIndex - } - ListView { - id: list3 - x: 400; width: 200; height: parent.height - model: MyPetsModel; delegate: petDelegate; highlight: petHighlight - currentIndex: list1.currentIndex - preferredHighlightBegin: 125 - preferredHighlightEnd: 125 - highlightRangeMode: "StrictlyEnforceRange" - flickDeceleration: 1000 - } -} -- cgit v0.12 From 131f03f5725a57412d29323edf595ee3199103a4 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Thu, 18 Mar 2010 14:38:22 +1000 Subject: Optimize id checking. id must be lowercase; types and namespaces must be uppercase cannot conflict, so remove check. --- src/declarative/qml/qdeclarativecompiler.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index c085556..42d2950 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -1713,16 +1713,6 @@ bool QDeclarativeCompiler::buildIdProperty(QDeclarativeParser::Property *prop, COMPILE_CHECK(checkValidId(idValue, val)); - // We disallow id's that conflict with import prefixes and types - QDeclarativeEnginePrivate::ImportedNamespace *ns = 0; - QDeclarativeType *type = 0; - QDeclarativeEnginePrivate::get(engine)->resolveType(unit->imports, val.toUtf8(), - &type, 0, 0, 0, &ns); - if (type) - COMPILE_EXCEPTION(idValue, QCoreApplication::translate("QDeclarativeCompiler","id conflicts with type name")); - if (ns) - COMPILE_EXCEPTION(idValue, QCoreApplication::translate("QDeclarativeCompiler","id conflicts with namespace prefix")); - if (compileState.ids.contains(val)) COMPILE_EXCEPTION(prop, QCoreApplication::translate("QDeclarativeCompiler","id is not unique")); -- cgit v0.12 From 261f8eecfe0580c198d8d4f71f2afa59abd080e0 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Thu, 18 Mar 2010 15:00:11 +1000 Subject: Remove timing sensitivity. --- tests/auto/declarative/qdeclarativewebview/data/newwindows.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/declarative/qdeclarativewebview/data/newwindows.qml b/tests/auto/declarative/qdeclarativewebview/data/newwindows.qml index 4d9df43..5f9f757 100644 --- a/tests/auto/declarative/qdeclarativewebview/data/newwindows.qml +++ b/tests/auto/declarative/qdeclarativewebview/data/newwindows.qml @@ -23,8 +23,8 @@ Grid { newWindowParent: pages url: "newwindows.html" Timer { - interval: 10; running: webView.status==WebView.Ready && total<4; repeat: false; - onTriggered: {total++; webView.evaluateJavaScript("clickTheLink()")} + interval: 10; running: total<4; repeat: false; + onTriggered: { if (webView.status==WebView.Ready) { total++; webView.evaluateJavaScript("clickTheLink()") } } } } } -- cgit v0.12 From b338db7f6091629dcfa4cbde3ea58a76e6fa6733 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 18 Mar 2010 16:12:32 +1000 Subject: Use the correct base URL in resolveUri --- src/declarative/qml/qdeclarativeengine.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index a097b02..800434a 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1476,9 +1476,8 @@ public: QStringList paths; - QUrl baseUrl = QDeclarativeEnginePrivate::get(engine)->baseUrl; - if (!baseUrl.isEmpty()) { - QString baseDir = QFileInfo(toLocalFileOrQrc(baseUrl)).path(); + if (!base.isEmpty()) { + QString baseDir = QFileInfo(toLocalFileOrQrc(base)).path(); paths += baseDir; } -- cgit v0.12 From fee38b5c766b0285ebd3283df0d1b29a978da316 Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Thu, 18 Mar 2010 16:36:46 +1000 Subject: Add missing semicolons. moc was confused and positionViewAtIndex not invokable. --- src/declarative/graphicsitems/qdeclarativegridview_p.h | 2 +- src/declarative/graphicsitems/qdeclarativelistview_p.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativegridview_p.h b/src/declarative/graphicsitems/qdeclarativegridview_p.h index f032240..90f13d2 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview_p.h +++ b/src/declarative/graphicsitems/qdeclarativegridview_p.h @@ -138,7 +138,7 @@ public: void setSnapMode(SnapMode mode); enum PositionMode { Beginning, Center, End, Visible, Contain }; - Q_ENUMS(PositionMode) + Q_ENUMS(PositionMode); Q_INVOKABLE void positionViewAtIndex(int index, int mode); Q_INVOKABLE int indexAt(int x, int y) const; diff --git a/src/declarative/graphicsitems/qdeclarativelistview_p.h b/src/declarative/graphicsitems/qdeclarativelistview_p.h index 1ea0080..3635b39 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview_p.h +++ b/src/declarative/graphicsitems/qdeclarativelistview_p.h @@ -192,7 +192,7 @@ public: static QDeclarativeListViewAttached *qmlAttachedProperties(QObject *); enum PositionMode { Beginning, Center, End, Visible, Contain }; - Q_ENUMS(PositionMode) + Q_ENUMS(PositionMode); Q_INVOKABLE void positionViewAtIndex(int index, int mode); Q_INVOKABLE int indexAt(int x, int y) const; -- cgit v0.12