diff options
author | Martin Jones <martin.jones@nokia.com> | 2010-07-14 05:33:35 (GMT) |
---|---|---|
committer | Martin Jones <martin.jones@nokia.com> | 2010-07-14 05:33:35 (GMT) |
commit | 86015c316c17f20667e786148d83d673886ad945 (patch) | |
tree | cfa3fdd5eec2aaf4d42df3a5844e42b0e663ab08 /src | |
parent | 9adc85fdfa0af2b6948408932188ee1b79247fa6 (diff) | |
parent | 32c2412d55d2387e8b05892fe1b1d2d54b624d02 (diff) | |
download | Qt-86015c316c17f20667e786148d83d673886ad945.zip Qt-86015c316c17f20667e786148d83d673886ad945.tar.gz Qt-86015c316c17f20667e786148d83d673886ad945.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-qml into 4.7
Diffstat (limited to 'src')
-rw-r--r-- | src/declarative/graphicsitems/qdeclarativeimage.cpp | 59 | ||||
-rw-r--r-- | src/declarative/graphicsitems/qdeclarativeitem.cpp | 6 | ||||
-rw-r--r-- | src/declarative/graphicsitems/qdeclarativemousearea.cpp | 10 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativebinding.cpp | 139 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativebinding_p_p.h | 28 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativecontext_p.h | 1 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeengine.cpp | 2 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeengine_p.h | 1 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeexpression.cpp | 478 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeexpression_p.h | 83 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeimageprovider.cpp | 16 | ||||
-rw-r--r-- | src/declarative/util/qdeclarativestateoperations.cpp | 2 | ||||
-rw-r--r-- | src/declarative/util/qdeclarativexmllistmodel.cpp | 17 |
13 files changed, 464 insertions, 378 deletions
diff --git a/src/declarative/graphicsitems/qdeclarativeimage.cpp b/src/declarative/graphicsitems/qdeclarativeimage.cpp index 34d33f5..90738c8 100644 --- a/src/declarative/graphicsitems/qdeclarativeimage.cpp +++ b/src/declarative/graphicsitems/qdeclarativeimage.cpp @@ -324,17 +324,34 @@ qreal QDeclarativeImage::paintedHeight() const /*! \qmlproperty QSize Image::sourceSize - This property holds the size of the loaded image, in pixels. + This property holds the actual width and height of the loaded image. - This is used to control the storage used by a loaded image. Unlike - the width and height properties, which scale the painting of the image, this property - affects the number of pixels stored. + Unlike the \l {Item::}{width} and \l {Item::}{height} properties, which scale + the painting of the image, this property sets the actual number of pixels + stored for the loaded image so that large images do not use more + memory than necessary. For example, this ensures the image is memory is no + larger than 1024x1024 pixels, regardless of the Image's \l {Item::}{width} and + \l {Item::}{height} values: + + \code + Rectangle { + width: ... + height: ... + + Image { + anchors.fill: parent + source: "reallyBigImage.jpg" + sourceSize.width: 1024 + sourceSize.height: 1024 + } + } + \endcode If the image's actual size is larger than the sourceSize, the image is scaled down. If only one dimension of the size is set to greater than 0, the other dimension is set in proportion to preserve the source image's aspect ratio. (The \l fillMode is independent of this.) - + If the source is an instrinsically scalable image (eg. SVG), this property determines the size of the loaded image regardless of intrinsic size. Avoid changing this property dynamically; rendering an SVG is \e slow compared @@ -344,34 +361,8 @@ qreal QDeclarativeImage::paintedHeight() const be no greater than this property specifies. For some formats (currently only JPEG), the whole image will never actually be loaded into memory. - \note \e{Changing this property dynamically will lead to the image source being reloaded, - potentially even from the network if it is not in the disk cache.} - - Here is an example that ensures the size of the image in memory is - no larger than 1024x1024 pixels, regardless of the size of the Image element. - - \code - Image { - anchors.fill: parent - source: "images/reallyBigImage.jpg" - sourceSize.width: 1024 - sourceSize.height: 1024 - } - \endcode - - The example below ensures the memory used by the image is no more than necessary - to display the image at the size of the Image element. - Of course if the Image element is resized a costly reload will be required, so - use this technique \e only when the Image size is fixed. - - \code - Image { - anchors.fill: parent - source: "images/reallyBigImage.jpg" - sourceSize.width: width - sourceSize.height: height - } - \endcode + \note \e {Changing this property dynamically causes the image source to be reloaded, + potentially even from the network, if it is not in the disk cache.} */ void QDeclarativeImage::updatePaintedGeometry() @@ -415,6 +406,8 @@ void QDeclarativeImage::geometryChanged(const QRectF &newGeometry, const QRectF Image can handle any image format supported by Qt, loaded from any URL scheme supported by Qt. The URL may be absolute, or relative to the URL of the component. + + \sa QDeclarativeImageProvider */ /*! diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp index 7022fac..190b22c 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp @@ -2097,7 +2097,7 @@ QDeclarativeAnchorLine QDeclarativeItemPrivate::baseline() const relationship with other items. Margins apply to top, bottom, left, right, and fill anchors. - The margins property can be used to set all of the various margins at once, to the same value. + The \c anchors.margins property can be used to set all of the various margins at once, to the same value. Offsets apply for horizontal center, vertical center, and baseline anchors. @@ -2132,10 +2132,12 @@ QDeclarativeAnchorLine QDeclarativeItemPrivate::baseline() const \endqml \endtable - anchors.fill provides a convenient way for one item to have the + \c anchors.fill provides a convenient way for one item to have the same geometry as another item, and is equivalent to connecting all four directional anchors. + To clear an anchor value, set it to \c undefined. + \note You can only anchor an item to siblings or a parent. For more information see \l {anchor-layout}{Anchor Layouts}. diff --git a/src/declarative/graphicsitems/qdeclarativemousearea.cpp b/src/declarative/graphicsitems/qdeclarativemousearea.cpp index 7b65ca7..b7b0c9e 100644 --- a/src/declarative/graphicsitems/qdeclarativemousearea.cpp +++ b/src/declarative/graphicsitems/qdeclarativemousearea.cpp @@ -767,10 +767,16 @@ QDeclarativeDrag *QDeclarativeMouseArea::drag() \i \c drag.minimum and \c drag.maximum limit how far the target can be dragged along the corresponding axes. \endlist - The following example displays an image that can be dragged along the X-axis. The opacity - of the image is reduced when it is dragged to the right. + The following example displays a \l Rectangle that can be dragged along the X-axis. The opacity + of the rectangle is reduced when it is dragged to the right. \snippet doc/src/snippets/declarative/mousearea.qml drag + + \note Items cannot be dragged if they are anchored for the requested + \c drag.axis. For example, if \c anchors.left or \c anchors.right was set + for \c rect in the above example, it cannot be dragged along the X-axis. + This can be avoided by settng the anchor value to \c undefined in + an \l onPressed handler. */ QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp index 882e981..e3b33c0 100644 --- a/src/declarative/qml/qdeclarativebinding.cpp +++ b/src/declarative/qml/qdeclarativebinding.cpp @@ -54,27 +54,20 @@ QT_BEGIN_NAMESPACE -QDeclarativeBindingData::QDeclarativeBindingData() -: updating(false), enabled(false) +void QDeclarativeBindingPrivate::refresh() { + Q_Q(QDeclarativeBinding); + q->update(); } -QDeclarativeBindingData::~QDeclarativeBindingData() -{ - removeError(); -} - -void QDeclarativeBindingData::refresh() +QDeclarativeBindingPrivate::QDeclarativeBindingPrivate() +: updating(false), enabled(false), deleted(0) { - if (enabled && !updating && q) { - QDeclarativeBinding *b = static_cast<QDeclarativeBinding *>(QDeclarativeExpressionPrivate::get(q)); - b->update(); - } } -QDeclarativeBindingPrivate::QDeclarativeBindingPrivate() -: QDeclarativeExpressionPrivate(new QDeclarativeBindingData) +QDeclarativeBindingPrivate::~QDeclarativeBindingPrivate() { + if (deleted) *deleted = true; } QDeclarativeBinding::QDeclarativeBinding(void *data, QDeclarativeRefCount *rc, QObject *obj, @@ -109,7 +102,7 @@ QDeclarativeBinding::~QDeclarativeBinding() void QDeclarativeBinding::setTarget(const QDeclarativeProperty &prop) { Q_D(QDeclarativeBinding); - d->bindingData()->property = prop; + d->property = prop; update(); } @@ -117,50 +110,53 @@ void QDeclarativeBinding::setTarget(const QDeclarativeProperty &prop) QDeclarativeProperty QDeclarativeBinding::property() const { Q_D(const QDeclarativeBinding); - return d->bindingData()->property; + return d->property; } void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags) { Q_D(QDeclarativeBinding); - QDeclarativeBindingData *data = d->bindingData(); - - if (!data->enabled || !data->context() || !data->context()->isValid()) + if (!d->enabled || !d->context() || !d->context()->isValid()) return; - data->addref(); + if (!d->updating) { + d->updating = true; + bool wasDeleted = false; + d->deleted = &wasDeleted; - if (!data->updating) { - data->updating = true; + if (d->property.propertyType() == qMetaTypeId<QDeclarativeBinding *>()) { - if (data->property.propertyType() == qMetaTypeId<QDeclarativeBinding *>()) { - - int idx = data->property.index(); + int idx = d->property.index(); Q_ASSERT(idx != -1); - QDeclarativeBinding *t = this; int status = -1; void *a[] = { &t, 0, &status, &flags }; - QMetaObject::metacall(data->property.object(), + QMetaObject::metacall(d->property.object(), QMetaObject::WriteProperty, idx, a); + if (wasDeleted) + return; + } else { - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(data->context()->engine); + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(d->context()->engine); bool isUndefined = false; QVariant value; QScriptValue scriptValue = d->scriptValue(0, &isUndefined); - if (data->property.propertyTypeCategory() == QDeclarativeProperty::List) { + if (wasDeleted) + return; + + if (d->property.propertyTypeCategory() == QDeclarativeProperty::List) { value = ep->scriptValueToVariant(scriptValue, qMetaTypeId<QList<QObject *> >()); } else if (scriptValue.isNull() && - data->property.propertyTypeCategory() == QDeclarativeProperty::Object) { + d->property.propertyTypeCategory() == QDeclarativeProperty::Object) { value = QVariant::fromValue((QObject *)0); } else { - value = ep->scriptValueToVariant(scriptValue, data->property.propertyType()); + value = ep->scriptValueToVariant(scriptValue, d->property.propertyType()); if (value.userType() == QMetaType::QObjectStar && !qvariant_cast<QObject*>(value)) { // If the object is null, we extract the predicted type. While this isn't // 100% reliable, in many cases it gives us better error messages if we @@ -172,73 +168,72 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags) } - if (data->error.isValid()) { + if (d->error.isValid()) { - } else if (isUndefined && data->property.isResettable()) { + } else if (isUndefined && d->property.isResettable()) { - data->property.reset(); + d->property.reset(); - } else if (isUndefined && data->property.propertyType() == qMetaTypeId<QVariant>()) { + } else if (isUndefined && d->property.propertyType() == qMetaTypeId<QVariant>()) { - QDeclarativePropertyPrivate::write(data->property, QVariant(), flags); + QDeclarativePropertyPrivate::write(d->property, QVariant(), flags); } else if (isUndefined) { - QUrl url = QUrl(data->url); - int line = data->line; + QUrl url = QUrl(d->url); + int line = d->line; if (url.isEmpty()) url = QUrl(QLatin1String("<Unknown File>")); - data->error.setUrl(url); - data->error.setLine(line); - data->error.setColumn(-1); - data->error.setDescription(QLatin1String("Unable to assign [undefined] to ") - + QLatin1String(QMetaType::typeName(data->property.propertyType())) - + QLatin1String(" ") + data->property.name()); + d->error.setUrl(url); + d->error.setLine(line); + d->error.setColumn(-1); + d->error.setDescription(QLatin1String("Unable to assign [undefined] to ") + + QLatin1String(QMetaType::typeName(d->property.propertyType())) + + QLatin1String(" ") + d->property.name()); } else if (!scriptValue.isRegExp() && scriptValue.isFunction()) { - QUrl url = QUrl(data->url); - int line = data->line; + QUrl url = QUrl(d->url); + int line = d->line; if (url.isEmpty()) url = QUrl(QLatin1String("<Unknown File>")); - data->error.setUrl(url); - data->error.setLine(line); - data->error.setColumn(-1); - data->error.setDescription(QLatin1String("Unable to assign a function to a property.")); + d->error.setUrl(url); + d->error.setLine(line); + d->error.setColumn(-1); + d->error.setDescription(QLatin1String("Unable to assign a function to a property.")); - } else if (data->property.object() && - !QDeclarativePropertyPrivate::write(data->property, value, flags)) { + } else if (d->property.object() && + !QDeclarativePropertyPrivate::write(d->property, value, flags)) { - QUrl url = QUrl(data->url); - int line = data->line; + QUrl url = QUrl(d->url); + int line = d->line; if (url.isEmpty()) url = QUrl(QLatin1String("<Unknown File>")); const char *valueType = 0; if (value.userType() == QVariant::Invalid) valueType = "null"; else valueType = QMetaType::typeName(value.userType()); - data->error.setUrl(url); - data->error.setLine(line); - data->error.setColumn(-1); - data->error.setDescription(QLatin1String("Unable to assign ") + - QLatin1String(valueType) + - QLatin1String(" to ") + - QLatin1String(QMetaType::typeName(data->property.propertyType()))); + d->error.setUrl(url); + d->error.setLine(line); + d->error.setColumn(-1); + d->error.setDescription(QLatin1String("Unable to assign ") + + QLatin1String(valueType) + + QLatin1String(" to ") + + QLatin1String(QMetaType::typeName(d->property.propertyType()))); } - if (data->error.isValid()) { - if (!data->addError(ep)) ep->warning(this->error()); + if (d->error.isValid()) { + if (!d->addError(ep)) ep->warning(this->error()); } else { - data->removeError(); + d->removeError(); } } - data->updating = false; + d->updating = false; + d->deleted = 0; } else { - qmlInfo(data->property.object()) << tr("Binding loop detected for property \"%1\"").arg(data->property.name()); + qmlInfo(d->property.object()) << tr("Binding loop detected for property \"%1\"").arg(d->property.name()); } - - data->release(); } void QDeclarativeBindingPrivate::emitValueChanged() @@ -250,13 +245,13 @@ void QDeclarativeBindingPrivate::emitValueChanged() void QDeclarativeBinding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteFlags flags) { Q_D(QDeclarativeBinding); - d->bindingData()->enabled = e; + d->enabled = e; setNotifyOnValueChanged(e); QDeclarativeAbstractBinding::setEnabled(e, flags); if (e) { - addToObject(d->bindingData()->property.object()); + addToObject(d->property.object()); update(flags); } else { removeFromObject(); @@ -266,14 +261,14 @@ void QDeclarativeBinding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteF int QDeclarativeBinding::propertyIndex() { Q_D(QDeclarativeBinding); - return QDeclarativePropertyPrivate::bindingIndex(d->bindingData()->property); + return QDeclarativePropertyPrivate::bindingIndex(d->property); } bool QDeclarativeBinding::enabled() const { Q_D(const QDeclarativeBinding); - return d->bindingData()->enabled; + return d->enabled; } QString QDeclarativeBinding::expression() const diff --git a/src/declarative/qml/qdeclarativebinding_p_p.h b/src/declarative/qml/qdeclarativebinding_p_p.h index 617ec4b..6926158 100644 --- a/src/declarative/qml/qdeclarativebinding_p_p.h +++ b/src/declarative/qml/qdeclarativebinding_p_p.h @@ -60,30 +60,24 @@ QT_BEGIN_NAMESPACE -class QDeclarativeBindingData : public QDeclarativeExpressionData -{ -public: - QDeclarativeBindingData(); - virtual ~QDeclarativeBindingData(); - - bool updating:1; - bool enabled:1; - - QDeclarativeProperty property; - - virtual void refresh(); -}; - class QDeclarativeBindingPrivate : public QDeclarativeExpressionPrivate { Q_DECLARE_PUBLIC(QDeclarativeBinding) public: QDeclarativeBindingPrivate(); - - QDeclarativeBindingData *bindingData() { return static_cast<QDeclarativeBindingData *>(data); } - const QDeclarativeBindingData *bindingData() const { return static_cast<const QDeclarativeBindingData *>(data); } + ~QDeclarativeBindingPrivate(); virtual void emitValueChanged(); + +protected: + virtual void refresh(); + +private: + bool updating:1; + bool enabled:1; + QDeclarativeProperty property; + + bool *deleted; }; QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h index 1f5aaf1..c5a039a 100644 --- a/src/declarative/qml/qdeclarativecontext_p.h +++ b/src/declarative/qml/qdeclarativecontext_p.h @@ -198,6 +198,7 @@ public: // context QDeclarativeComponentAttached *componentAttached; + // Return the outermost id for obj, if any. QString findObjectId(const QObject *obj) const; static QDeclarativeContextData *get(QDeclarativeContext *context) { diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 00bc1b7..97ef99c 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -219,7 +219,7 @@ of their use. QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e) -: captureProperties(false), rootContext(0), currentExpression(0), isDebugging(false), +: captureProperties(false), rootContext(0), isDebugging(false), outputWarningsToStdErr(true), contextClass(0), sharedContext(0), sharedScope(0), objectClass(0), valueTypeClass(0), globalClass(0), cleanup(0), erroredBindings(0), inProgressCreations(0), scriptEngine(this), workerScriptEngine(0), componentAttached(0), diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h index f457b53..a5c8c38 100644 --- a/src/declarative/qml/qdeclarativeengine_p.h +++ b/src/declarative/qml/qdeclarativeengine_p.h @@ -162,7 +162,6 @@ public: QPODVector<CapturedProperty> capturedProperties; QDeclarativeContext *rootContext; - QDeclarativeExpression *currentExpression; bool isDebugging; bool outputWarningsToStdErr; diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp index 96cdec1..9935e38 100644 --- a/src/declarative/qml/qdeclarativeexpression.cpp +++ b/src/declarative/qml/qdeclarativeexpression.cpp @@ -71,109 +71,95 @@ bool QDeclarativeDelayedError::addError(QDeclarativeEnginePrivate *e) return true; } -QDeclarativeExpressionData::QDeclarativeExpressionData() -: q(0), dataRef(0), expressionFunctionValid(false), expressionRewritten(false), me(0), - trackChange(false), isShared(false), line(-1), guardList(0), guardListLength(0) +QDeclarativeQtScriptExpression::QDeclarativeQtScriptExpression() +: dataRef(0), expressionFunctionMode(ExplicitContext), scopeObject(0), trackChange(false), + guardList(0), guardListLength(0), guardObject(0), guardObjectNotifyIndex(-1), deleted(0) { } -QDeclarativeExpressionData::~QDeclarativeExpressionData() +QDeclarativeQtScriptExpression::~QDeclarativeQtScriptExpression() { if (guardList) { delete [] guardList; guardList = 0; } if (dataRef) dataRef->release(); + if (deleted) *deleted = true; } QDeclarativeExpressionPrivate::QDeclarativeExpressionPrivate() -: data(new QDeclarativeExpressionData) +: expressionFunctionValid(true), line(-1) { - data->q = this; -} - -QDeclarativeExpressionPrivate::QDeclarativeExpressionPrivate(QDeclarativeExpressionData *d) -: data(d) -{ - data->q = this; } QDeclarativeExpressionPrivate::~QDeclarativeExpressionPrivate() { - if (data) { - delete [] data->guardList; - data->guardList = 0; - data->guardListLength = 0; - data->q = 0; - data->release(); - data = 0; - } } void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, const QString &expr, QObject *me) { - data->expression = expr; + expression = expr; - data->QDeclarativeAbstractExpression::setContext(ctxt); - data->me = me; + QDeclarativeAbstractExpression::setContext(ctxt); + scopeObject = me; + expressionFunctionValid = false; } -void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *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 &srcUrl, int lineNumber) { - data->url = url; - data->line = lineNumber; + url = srcUrl; + line = lineNumber; - if (data->dataRef) data->dataRef->release(); - data->dataRef = rc; - if (data->dataRef) data->dataRef->addref(); + if (dataRef) dataRef->release(); + dataRef = rc; + if (dataRef) dataRef->addref(); quint32 *exprData = (quint32 *)expr; QDeclarativeCompiledData *dd = (QDeclarativeCompiledData *)rc; - data->expressionRewritten = true; - data->expression = QString::fromRawData((QChar *)(exprData + 2), exprData[1]); + expression = QString::fromRawData((QChar *)(exprData + 2), exprData[1]); int progIdx = *(exprData); - bool isShared = progIdx & 0x80000000; + bool isSharedProgram = progIdx & 0x80000000; progIdx &= 0x7FFFFFFF; QDeclarativeEngine *engine = ctxt->engine; QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); - if (isShared) { + if (isSharedProgram) { if (!dd->cachedClosures.at(progIdx)) { QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine); scriptContext->pushScope(ep->contextClass->newSharedContext()); scriptContext->pushScope(ep->globalClass->staticGlobalObject()); - dd->cachedClosures[progIdx] = new QScriptValue(scriptEngine->evaluate(data->expression, data->url, data->line)); + dd->cachedClosures[progIdx] = new QScriptValue(scriptEngine->evaluate(expression, url, line)); scriptEngine->popContext(); } - data->expressionFunction = *dd->cachedClosures.at(progIdx); - data->isShared = true; - data->expressionFunctionValid = true; + expressionFunction = *dd->cachedClosures.at(progIdx); + expressionFunctionMode = SharedContext; + expressionFunctionValid = true; } else { #if !defined(Q_OS_SYMBIAN) //XXX Why doesn't this work? if (!dd->cachedPrograms.at(progIdx)) { - dd->cachedPrograms[progIdx] = - new QScriptProgram(data->expression, data->url, data->line); + dd->cachedPrograms[progIdx] = new QScriptProgram(expression, url, line); } - data->expressionFunction = evalInObjectScope(ctxt, me, *dd->cachedPrograms.at(progIdx), - &data->expressionContext); + expressionFunction = evalInObjectScope(ctxt, me, *dd->cachedPrograms.at(progIdx), + &expressionContext); #else - data->expressionFunction = evalInObjectScope(ctxt, me, data->expression, - &data->expressionContext); + expressionFunction = evalInObjectScope(ctxt, me, expression, &expressionContext); #endif - data->expressionFunctionValid = true; + expressionFunctionMode = ExplicitContext; + expressionFunctionValid = true; } - data->QDeclarativeAbstractExpression::setContext(ctxt); - data->me = me; + QDeclarativeAbstractExpression::setContext(ctxt); + scopeObject = me; } QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContextData *context, QObject *object, @@ -240,6 +226,8 @@ QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContex \endcode */ +static int QDeclarativeExpression_notifyIdx = -1; + /*! Create an invalid QDeclarativeExpression. @@ -249,6 +237,11 @@ QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContex QDeclarativeExpression::QDeclarativeExpression() : QObject(*new QDeclarativeExpressionPrivate, 0) { + Q_D(QDeclarativeExpression); + + if (QDeclarativeExpression_notifyIdx == -1) + QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()"); + d->setNotifyObject(this, QDeclarativeExpression_notifyIdx); } /*! \internal */ @@ -260,6 +253,10 @@ QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, vo { Q_D(QDeclarativeExpression); d->init(ctxt, expr, rc, me, url, lineNumber); + + if (QDeclarativeExpression_notifyIdx == -1) + QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()"); + d->setNotifyObject(this, QDeclarativeExpression_notifyIdx); } /*! @@ -277,6 +274,10 @@ QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContext *ctxt, { Q_D(QDeclarativeExpression); d->init(QDeclarativeContextData::get(ctxt), expression, scope); + + if (QDeclarativeExpression_notifyIdx == -1) + QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()"); + d->setNotifyObject(this, QDeclarativeExpression_notifyIdx); } /*! @@ -288,6 +289,10 @@ QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, QO { Q_D(QDeclarativeExpression); d->init(ctxt, expression, scope); + + if (QDeclarativeExpression_notifyIdx == -1) + QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()"); + d->setNotifyObject(this, QDeclarativeExpression_notifyIdx); } /*! \internal */ @@ -297,6 +302,10 @@ QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, QO { Q_D(QDeclarativeExpression); d->init(ctxt, expression, scope); + + if (QDeclarativeExpression_notifyIdx == -1) + QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()"); + d->setNotifyObject(this, QDeclarativeExpression_notifyIdx); } /*! @@ -313,7 +322,7 @@ QDeclarativeExpression::~QDeclarativeExpression() QDeclarativeEngine *QDeclarativeExpression::engine() const { Q_D(const QDeclarativeExpression); - return d->data->context()?d->data->context()->engine:0; + return d->context()?d->context()->engine:0; } /*! @@ -323,7 +332,7 @@ QDeclarativeEngine *QDeclarativeExpression::engine() const QDeclarativeContext *QDeclarativeExpression::context() const { Q_D(const QDeclarativeExpression); - QDeclarativeContextData *data = d->data->context(); + QDeclarativeContextData *data = d->context(); return data?data->asQDeclarativeContext():0; } @@ -333,7 +342,7 @@ QDeclarativeContext *QDeclarativeExpression::context() const QString QDeclarativeExpression::expression() const { Q_D(const QDeclarativeExpression); - return d->data->expression; + return d->expression; } /*! @@ -343,12 +352,10 @@ void QDeclarativeExpression::setExpression(const QString &expression) { Q_D(QDeclarativeExpression); - d->clearGuards(); - - d->data->expression = expression; - d->data->expressionFunctionValid = false; - d->data->expressionRewritten = false; - d->data->expressionFunction = QScriptValue(); + d->resetNotifyOnChange(); + d->expression = expression; + d->expressionFunctionValid = false; + d->expressionFunction = QScriptValue(); } void QDeclarativeExpressionPrivate::exceptionToError(QScriptEngine *scriptEngine, @@ -378,59 +385,108 @@ void QDeclarativeExpressionPrivate::exceptionToError(QScriptEngine *scriptEngine } } -QScriptValue QDeclarativeExpressionPrivate::eval(QObject *secondaryScope, bool *isUndefined) +bool QDeclarativeQtScriptExpression::notifyOnValueChange() const { - QDeclarativeExpressionData *data = this->data; - QDeclarativeEngine *engine = data->context()->engine; - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); + return trackChange; +} - QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); +void QDeclarativeQtScriptExpression::setNotifyOnValueChange(bool notify) +{ + trackChange = notify; + if (!notify && guardList) + clearGuards(); +} - if (!data->expressionFunctionValid) { +void QDeclarativeQtScriptExpression::resetNotifyOnChange() +{ + clearGuards(); +} - QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine); - data->expressionContext = ep->contextClass->newContext(data->context(), data->me); - scriptContext->pushScope(data->expressionContext); - scriptContext->pushScope(ep->globalClass->staticGlobalObject()); +void QDeclarativeQtScriptExpression::setNotifyObject(QObject *object, int notifyIndex) +{ + if (guardList) clearGuards(); + + if (!object || notifyIndex == -1) { + guardObject = 0; + notifyIndex = -1; + } else { + guardObject = object; + guardObjectNotifyIndex = notifyIndex; + + } +} + +QScriptValue QDeclarativeQtScriptExpression::scriptValue(QObject *secondaryScope, bool *isUndefined) +{ + Q_ASSERT(context() && context()->engine); + Q_ASSERT(!trackChange || (guardObject && guardObjectNotifyIndex != -1)); + + if (!expressionFunction.isValid()) { + if (isUndefined) *isUndefined = true; + return QScriptValue(); + } + + DeleteWatcher watcher(this); + + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context()->engine); + + bool lastCaptureProperties = ep->captureProperties; + QPODVector<QDeclarativeEnginePrivate::CapturedProperty> lastCapturedProperties; + ep->captureProperties = trackChange; + ep->capturedProperties.copyAndClear(lastCapturedProperties); + + QScriptValue value = eval(secondaryScope, isUndefined); + + if (!watcher.wasDeleted() && trackChange) { + if (ep->capturedProperties.count() == 0) { + + if (guardList) clearGuards(); - if (data->expressionRewritten) { - data->expressionFunction = scriptEngine->evaluate(data->expression, - data->url, data->line); } else { - QDeclarativeRewrite::RewriteBinding rewriteBinding; - bool ok = true; - const QString code = rewriteBinding(data->expression, &ok); - if (!ok) { - scriptEngine->popContext(); - return QScriptValue(); - } - data->expressionFunction = scriptEngine->evaluate(code, data->url, data->line); - } + updateGuards(ep->capturedProperties); - scriptEngine->popContext(); - data->expressionFunctionValid = true; + } } + lastCapturedProperties.copyAndClear(ep->capturedProperties); + ep->captureProperties = lastCaptureProperties; + + return value; +} + +QScriptValue QDeclarativeQtScriptExpression::eval(QObject *secondaryScope, bool *isUndefined) +{ + Q_ASSERT(context() && context()->engine); + + DeleteWatcher watcher(this); + + QDeclarativeEngine *engine = context()->engine; + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); + + QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); + QDeclarativeContextData *oldSharedContext = 0; QObject *oldSharedScope = 0; QObject *oldOverride = 0; - if (data->isShared) { + bool isShared = (expressionFunctionMode == SharedContext); + + if (isShared) { oldSharedContext = ep->sharedContext; oldSharedScope = ep->sharedScope; - ep->sharedContext = data->context(); - ep->sharedScope = data->me; + ep->sharedContext = context(); + ep->sharedScope = scopeObject; } else { - oldOverride = ep->contextClass->setOverrideObject(data->expressionContext, secondaryScope); + oldOverride = ep->contextClass->setOverrideObject(expressionContext, secondaryScope); } - QScriptValue svalue = data->expressionFunction.call(); + QScriptValue svalue = expressionFunction.call(); // This could cause this to be deleted - if (data->isShared) { + if (isShared) { ep->sharedContext = oldSharedContext; ep->sharedScope = oldSharedScope; - } else { - ep->contextClass->setOverrideObject(data->expressionContext, oldOverride); + } else if (!watcher.wasDeleted()) { + ep->contextClass->setOverrideObject(expressionContext, oldOverride); } if (isUndefined) @@ -438,63 +494,134 @@ QScriptValue QDeclarativeExpressionPrivate::eval(QObject *secondaryScope, bool * // Handle exception if (scriptEngine->hasUncaughtException()) { - exceptionToError(scriptEngine, data->error); + if (!watcher.wasDeleted()) + QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error); + scriptEngine->clearExceptions(); return QScriptValue(); } else { - data->error = QDeclarativeError(); + if (!watcher.wasDeleted()) + error = QDeclarativeError(); + return svalue; } } -QScriptValue QDeclarativeExpressionPrivate::scriptValue(QObject *secondaryScope, bool *isUndefined) +void QDeclarativeQtScriptExpression::updateGuards(const QPODVector<QDeclarativeEnginePrivate::CapturedProperty> &properties) { - Q_Q(QDeclarativeExpression); - Q_ASSERT(q->engine()); + Q_ASSERT(guardObject); + Q_ASSERT(guardObjectNotifyIndex != -1); - if (data->expression.isEmpty()) - return QScriptValue(); + if (properties.count() != guardListLength) { + QDeclarativeNotifierEndpoint *newGuardList = new QDeclarativeNotifierEndpoint[properties.count()]; - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(q->engine()); + for (int ii = 0; ii < qMin(guardListLength, properties.count()); ++ii) + guardList[ii].copyAndClear(newGuardList[ii]); - QDeclarativeExpression *lastCurrentExpression = ep->currentExpression; - bool lastCaptureProperties = ep->captureProperties; - QPODVector<QDeclarativeEnginePrivate::CapturedProperty> lastCapturedProperties; - ep->capturedProperties.copyAndClear(lastCapturedProperties); + delete [] guardList; + guardList = newGuardList; + guardListLength = properties.count(); + } - ep->currentExpression = q; - ep->captureProperties = data->trackChange; + bool outputWarningHeader = false; + bool noChanges = true; + for (int ii = 0; ii < properties.count(); ++ii) { + QDeclarativeNotifierEndpoint &guard = guardList[ii]; + const QDeclarativeEnginePrivate::CapturedProperty &property = properties.at(ii); - // This object might be deleted during the eval - QDeclarativeExpressionData *localData = data; - localData->addref(); + guard.target = guardObject; + guard.targetMethod = guardObjectNotifyIndex; - QScriptValue value = eval(secondaryScope, isUndefined); + if (property.notifier != 0) { - ep->currentExpression = lastCurrentExpression; - ep->captureProperties = lastCaptureProperties; + if (!noChanges && guard.isConnected(property.notifier)) { + // Nothing to do - // Check if we were deleted - if (localData->q) { - if ((!data->trackChange || !ep->capturedProperties.count()) && data->guardList) { - clearGuards(); - } else if(data->trackChange) { - updateGuards(ep->capturedProperties); + } else { + noChanges = false; + + bool existing = false; + for (int jj = 0; !existing && jj < ii; ++jj) + if (guardList[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 + + } else { + noChanges = false; + + bool existing = false; + for (int jj = 0; !existing && jj < ii; ++jj) + if (guardList[jj].isConnected(property.object, property.notifyIndex)) + existing = true; + + if (existing) { + // duplicate + guard.disconnect(); + } else { + guard.connect(property.object, property.notifyIndex); + } + } + + } else { + if (!outputWarningHeader) { + outputWarningHeader = true; + qWarning() << "QDeclarativeExpression: Expression" << expression + << "depends on non-NOTIFYable properties:"; + } + + const QMetaObject *metaObj = property.object->metaObject(); + QMetaProperty metaProp = metaObj->property(property.coreIndex); + + qWarning().nospace() << " " << metaObj->className() << "::" << metaProp.name(); } } +} - localData->release(); +QScriptValue QDeclarativeExpressionPrivate::scriptValue(QObject *secondaryScope, bool *isUndefined) +{ + if (!expressionFunctionValid) { + QDeclarativeEngine *engine = context()->engine; + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); - lastCapturedProperties.copyAndClear(ep->capturedProperties); + QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); - return value; + QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine); + expressionContext = ep->contextClass->newContext(context(), scopeObject); + scriptContext->pushScope(expressionContext); + scriptContext->pushScope(ep->globalClass->staticGlobalObject()); + + QDeclarativeRewrite::RewriteBinding rewriteBinding; + bool ok = true; + const QString code = rewriteBinding(expression, &ok); + if (ok) + expressionFunction = scriptEngine->evaluate(code, url, line); + + scriptEngine->popContext(); + expressionFunctionMode = ExplicitContext; + expressionFunctionValid = true; + } + + return QDeclarativeQtScriptExpression::scriptValue(secondaryScope, isUndefined); } QVariant QDeclarativeExpressionPrivate::value(QObject *secondaryScope, bool *isUndefined) { Q_Q(QDeclarativeExpression); - if (!data || !data->context() || !data->context()->isValid()) { + if (!context() || !context()->isValid()) { qWarning("QDeclarativeExpression: Attempted to evaluate an expression in an invalid context"); return QVariant(); } @@ -526,7 +653,7 @@ value changes. bool QDeclarativeExpression::notifyOnValueChanged() const { Q_D(const QDeclarativeExpression); - return d->data->trackChange; + return d->notifyOnValueChange(); } /*! @@ -548,7 +675,7 @@ bool QDeclarativeExpression::notifyOnValueChanged() const void QDeclarativeExpression::setNotifyOnValueChanged(bool notifyOnChange) { Q_D(QDeclarativeExpression); - d->data->trackChange = notifyOnChange; + d->setNotifyOnValueChange(notifyOnChange); } /*! @@ -558,7 +685,7 @@ void QDeclarativeExpression::setNotifyOnValueChanged(bool notifyOnChange) QString QDeclarativeExpression::sourceFile() const { Q_D(const QDeclarativeExpression); - return d->data->url; + return d->url; } /*! @@ -568,7 +695,7 @@ QString QDeclarativeExpression::sourceFile() const int QDeclarativeExpression::lineNumber() const { Q_D(const QDeclarativeExpression); - return d->data->line; + return d->line; } /*! @@ -578,8 +705,8 @@ int QDeclarativeExpression::lineNumber() const void QDeclarativeExpression::setSourceLocation(const QString &url, int line) { Q_D(QDeclarativeExpression); - d->data->url = url; - d->data->line = line; + d->url = url; + d->line = line; } /*! @@ -591,7 +718,7 @@ void QDeclarativeExpression::setSourceLocation(const QString &url, int line) QObject *QDeclarativeExpression::scopeObject() const { Q_D(const QDeclarativeExpression); - return d->data->me; + return d->scopeObject; } /*! @@ -603,7 +730,7 @@ QObject *QDeclarativeExpression::scopeObject() const bool QDeclarativeExpression::hasError() const { Q_D(const QDeclarativeExpression); - return d->data->error.isValid(); + return d->error.isValid(); } /*! @@ -615,7 +742,7 @@ bool QDeclarativeExpression::hasError() const void QDeclarativeExpression::clearError() { Q_D(QDeclarativeExpression); - d->data->error = QDeclarativeError(); + d->error = QDeclarativeError(); } /*! @@ -628,7 +755,7 @@ void QDeclarativeExpression::clearError() QDeclarativeError QDeclarativeExpression::error() const { Q_D(const QDeclarativeExpression); - return d->data->error; + return d->error; } /*! \internal */ @@ -637,98 +764,11 @@ void QDeclarativeExpressionPrivate::_q_notify() emitValueChanged(); } -void QDeclarativeExpressionPrivate::clearGuards() -{ - delete [] data->guardList; - data->guardList = 0; - data->guardListLength = 0; -} - -void QDeclarativeExpressionPrivate::updateGuards(const QPODVector<QDeclarativeEnginePrivate::CapturedProperty> &properties) +void QDeclarativeQtScriptExpression::clearGuards() { - Q_Q(QDeclarativeExpression); - - static int notifyIdx = -1; - if (notifyIdx == -1) - notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()"); - - 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; - bool noChanges = true; - for (int ii = 0; ii < properties.count(); ++ii) { - QDeclarativeNotifierEndpoint &guard = data->guardList[ii]; - const QDeclarativeEnginePrivate::CapturedProperty &property = properties.at(ii); - - guard.target = q; - guard.targetMethod = notifyIdx; - - if (property.notifier != 0) { - - if (!noChanges && guard.isConnected(property.notifier)) { - // Nothing to do - - } else { - noChanges = false; - - bool existing = false; - for (int jj = 0; !existing && jj < ii; ++jj) - if (data->guardList[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 - - } else { - noChanges = false; - - bool existing = false; - for (int jj = 0; !existing && jj < ii; ++jj) - if (data->guardList[jj].isConnected(property.object, property.notifyIndex)) - existing = true; - - if (existing) { - // duplicate - guard.disconnect(); - } else { - guard.connect(property.object, property.notifyIndex); - } - } - - } else { - if (!outputWarningHeader) { - outputWarningHeader = true; - qWarning() << "QDeclarativeExpression: Expression" << q->expression() - << "depends on non-NOTIFYable properties:"; - } - - const QMetaObject *metaObj = property.object->metaObject(); - QMetaProperty metaProp = metaObj->property(property.coreIndex); - - qWarning().nospace() << " " << metaObj->className() << "::" << metaProp.name(); - } - } + delete [] guardList; + guardList = 0; + guardListLength = 0; } /*! diff --git a/src/declarative/qml/qdeclarativeexpression_p.h b/src/declarative/qml/qdeclarativeexpression_p.h index 4ff3162..b629e20 100644 --- a/src/declarative/qml/qdeclarativeexpression_p.h +++ b/src/declarative/qml/qdeclarativeexpression_p.h @@ -107,56 +107,73 @@ private: QDeclarativeDelayedError **prevError; }; -class QDeclarativeExpressionData : public QDeclarativeAbstractExpression, public QDeclarativeDelayedError, public QDeclarativeRefCount +class QDeclarativeQtScriptExpression : public QDeclarativeAbstractExpression, + public QDeclarativeDelayedError { public: - QDeclarativeExpressionData(); - virtual ~QDeclarativeExpressionData(); + enum Mode { SharedContext, ExplicitContext }; - QDeclarativeExpressionPrivate *q; + QDeclarativeQtScriptExpression(); + virtual ~QDeclarativeQtScriptExpression(); QDeclarativeRefCount *dataRef; + QString expression; - bool expressionFunctionValid:1; - bool expressionRewritten:1; + + Mode expressionFunctionMode; QScriptValue expressionFunction; - QScriptValue expressionContext; - QObject *me; - bool trackChange; + QScriptValue expressionContext; // Only used in ExplicitContext + QObject *scopeObject; // Only used in SharedContext - bool isShared; + bool notifyOnValueChange() const; + void setNotifyOnValueChange(bool); + void resetNotifyOnChange(); + void setNotifyObject(QObject *, int ); - QString url; // This is a QString for a reason. QUrls are slooooooow... - int line; + QScriptValue scriptValue(QObject *secondaryScope, bool *isUndefined); + + class DeleteWatcher { + public: + inline DeleteWatcher(QDeclarativeQtScriptExpression *data); + inline ~DeleteWatcher(); + inline bool wasDeleted() const; + private: + bool *m_wasDeleted; + bool m_wasDeletedStorage; + QDeclarativeQtScriptExpression *m_d; + }; + +private: + void clearGuards(); + QScriptValue eval(QObject *secondaryScope, bool *isUndefined); + void updateGuards(const QPODVector<QDeclarativeEnginePrivate::CapturedProperty> &properties); + + bool trackChange; QDeclarativeNotifierEndpoint *guardList; int guardListLength; + + QObject *guardObject; + int guardObjectNotifyIndex; + bool *deleted; }; class QDeclarativeExpression; class QString; -class QDeclarativeExpressionPrivate : public QObjectPrivate +class QDeclarativeExpressionPrivate : public QObjectPrivate, public QDeclarativeQtScriptExpression { Q_DECLARE_PUBLIC(QDeclarativeExpression) public: QDeclarativeExpressionPrivate(); - QDeclarativeExpressionPrivate(QDeclarativeExpressionData *); ~QDeclarativeExpressionPrivate(); void init(QDeclarativeContextData *, const QString &, QObject *); void init(QDeclarativeContextData *, void *, QDeclarativeRefCount *, QObject *, const QString &, int); - QDeclarativeExpressionData *data; - QVariant value(QObject *secondaryScope = 0, bool *isUndefined = 0); QScriptValue scriptValue(QObject *secondaryScope = 0, bool *isUndefined = 0); - QScriptValue eval(QObject *secondaryScope, bool *isUndefined = 0); - - void updateGuards(const QPODVector<QDeclarativeEnginePrivate::CapturedProperty> &properties); - void clearGuards(); - static QDeclarativeExpressionPrivate *get(QDeclarativeExpression *expr) { return static_cast<QDeclarativeExpressionPrivate *>(QObjectPrivate::get(expr)); } @@ -172,8 +189,32 @@ public: int, QScriptValue *); static QScriptValue evalInObjectScope(QDeclarativeContextData *, QObject *, const QScriptProgram &, QScriptValue *); + + bool expressionFunctionValid:1; + + QString url; // This is a QString for a reason. QUrls are slooooooow... + int line; }; +QDeclarativeQtScriptExpression::DeleteWatcher::DeleteWatcher(QDeclarativeQtScriptExpression *data) +: m_wasDeletedStorage(false), m_d(data) +{ + if (!m_d->deleted) + m_d->deleted = &m_wasDeletedStorage; + m_wasDeleted = m_d->deleted; +} + +QDeclarativeQtScriptExpression::DeleteWatcher::~DeleteWatcher() +{ + if (false == *m_wasDeleted && m_wasDeleted == m_d->deleted) + m_d->deleted = 0; +} + +bool QDeclarativeQtScriptExpression::DeleteWatcher::wasDeleted() const +{ + return *m_wasDeleted; +} + QT_END_NAMESPACE #endif // QDECLARATIVEEXPRESSION_P_H diff --git a/src/declarative/qml/qdeclarativeimageprovider.cpp b/src/declarative/qml/qdeclarativeimageprovider.cpp index f38da4e..a294c38 100644 --- a/src/declarative/qml/qdeclarativeimageprovider.cpp +++ b/src/declarative/qml/qdeclarativeimageprovider.cpp @@ -180,9 +180,13 @@ QDeclarativeImageProvider::ImageType QDeclarativeImageProvider::imageType() cons Implement this method to return the image with \a id. The default implementation returns an empty image. - If \a requestedSize is a valid size, the image returned should be of that size. + The \a requestedSize corresponds to the \l {Image::sourceSize} requested by + an Image element. If \a requestedSize is a valid size, the image + returned should be of that size. - In all cases, \a size must be set to the original size of the image. + In all cases, \a size must be set to the original size of the image. This + is used to set the \l {Item::}{width} and \l {Item::}{height} of image + elements that should be automatically sized to the loaded image. \note this method may be called by multiple threads, so ensure the implementation of this method is reentrant. @@ -201,9 +205,13 @@ QImage QDeclarativeImageProvider::requestImage(const QString &id, QSize *size, c Implement this method to return the pixmap with \a id. The default implementation returns an empty pixmap. - If \a requestedSize is a valid size, the image returned should be of that size. + The \a requestedSize corresponds to the \l {Image::sourceSize} requested by + an Image element. If \a requestedSize is a valid size, the image + returned should be of that size. - In all cases, \a size must be set to the original size of the image. + In all cases, \a size must be set to the original size of the image. This + is used to set the \l {Item::}{width} and \l {Item::}{height} of image + elements that should be automatically sized to the loaded image. \note this method may be called by multiple threads, so ensure the implementation of this method is reentrant. diff --git a/src/declarative/util/qdeclarativestateoperations.cpp b/src/declarative/util/qdeclarativestateoperations.cpp index 51e6f99..5590449 100644 --- a/src/declarative/util/qdeclarativestateoperations.cpp +++ b/src/declarative/util/qdeclarativestateoperations.cpp @@ -1039,7 +1039,7 @@ public: /*! \qmlproperty Item AnchorChanges::target - This property holds the Item whose anchors will change + This property holds the \l Item for which the anchor changes will be applied. */ QDeclarativeAnchorChanges::QDeclarativeAnchorChanges(QObject *parent) diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp index 00169db..9895ff2 100644 --- a/src/declarative/util/qdeclarativexmllistmodel.cpp +++ b/src/declarative/util/qdeclarativexmllistmodel.cpp @@ -508,8 +508,8 @@ void QDeclarativeXmlListModelPrivate::clear_role(QDeclarativeListProperty<QDecla \since 4.7 \brief The XmlListModel element is used to specify a model using XPath expressions. - XmlListModel is used to create a model from XML data. XmlListModel can be used as a data source - for the view classes (such as ListView, PathView, GridView) and other classes that interact with model + XmlListModel is used to create a model from XML data. It can be used as a data source + for view elements (such as ListView, PathView, GridView) and other elements that interact with model data (such as \l Repeater). For example, if there is a XML document at http://www.mysite.com/feed.xml like this: @@ -520,11 +520,11 @@ void QDeclarativeXmlListModelPrivate::clear_role(QDeclarativeListProperty<QDecla ... <channel> <item> - <title>Item A</title> + <title>A blog post</title> <pubDate>Sat, 07 Sep 2010 10:00:01 GMT</pubDate> </item> <item> - <title>Item B</title> + <title>Another blog post</title> <pubDate>Sat, 07 Sep 2010 15:35:01 GMT</pubDate> </item> </channel> @@ -560,10 +560,17 @@ void QDeclarativeXmlListModelPrivate::clear_role(QDeclarativeListProperty<QDecla ListView { width: 180; height: 300 model: xmlModel - delegate: Text { title + " (" + pubDate + ")" } + delegate: Text { text: title + " (" + pubDate + ")" } } \endqml + \image qml-xmllistmodel-example.png + + The XmlListModel data is loaded asynchronously, and \l status + is set to \l XmlListModel::Ready when loading is complete. + Note this means when XmlListModel is used for a view, the view is not + populated until the model is loaded. + \section2 Using key XML roles |