summaryrefslogtreecommitdiffstats
path: root/src/declarative
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2011-01-27 06:52:19 (GMT)
committerMartin Jones <martin.jones@nokia.com>2011-01-27 06:52:19 (GMT)
commit5d2817cd668a705729df1727de49adf00713ac97 (patch)
treecf1b5fbce270e13203387ab2ed8e5ffba04f884c /src/declarative
parentb427b69a8efc0502cb06c388c70c8877a13db2f4 (diff)
parentaa40f956bab22678b62f630af97f51f9e8fab9f8 (diff)
downloadQt-5d2817cd668a705729df1727de49adf00713ac97.zip
Qt-5d2817cd668a705729df1727de49adf00713ac97.tar.gz
Qt-5d2817cd668a705729df1727de49adf00713ac97.tar.bz2
Merge branch 'qtquick11' of scm.dev.nokia.troll.no:qt/qt-qml into qtquick11
Diffstat (limited to 'src/declarative')
-rw-r--r--src/declarative/graphicsitems/qdeclarativeflickable.cpp2
-rw-r--r--src/declarative/graphicsitems/qdeclarativegridview.cpp5
-rw-r--r--src/declarative/graphicsitems/qdeclarativelistview.cpp4
-rw-r--r--src/declarative/graphicsitems/qdeclarativeloader.cpp9
-rw-r--r--src/declarative/graphicsitems/qdeclarativeloader_p_p.h1
-rw-r--r--src/declarative/graphicsitems/qdeclarativescalegrid.cpp10
-rw-r--r--src/declarative/qml/qdeclarativebinding.cpp20
-rw-r--r--src/declarative/qml/qdeclarativebinding_p.h9
-rw-r--r--src/declarative/qml/qdeclarativecomponent.cpp67
-rw-r--r--src/declarative/qml/qdeclarativecomponent.h1
-rw-r--r--src/declarative/qml/qdeclarativecomponent_p.h2
-rw-r--r--src/declarative/qml/qdeclarativeexpression.cpp41
-rw-r--r--src/declarative/qml/qdeclarativeexpression.h3
-rw-r--r--src/declarative/qml/qdeclarativeexpression_p.h12
-rw-r--r--src/declarative/qml/qdeclarativeobjectscriptclass.cpp19
-rw-r--r--src/declarative/qml/qdeclarativeproperty.cpp25
-rw-r--r--src/declarative/qml/qdeclarativeproperty_p.h5
-rw-r--r--src/declarative/qml/qdeclarativevaluetypescriptclass.cpp32
18 files changed, 221 insertions, 46 deletions
diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
index a713bf0..ba5e12c 100644
--- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
@@ -299,7 +299,7 @@ void QDeclarativeFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal
timeline.move(data.move, maxExtent - dist/2, QEasingCurve(QEasingCurve::InQuad), fixupDuration/4);
timeline.move(data.move, maxExtent, QEasingCurve(QEasingCurve::OutExpo), 3*fixupDuration/4);
} else {
- timeline.set(data.move, minExtent);
+ timeline.set(data.move, maxExtent);
}
}
vTime = timeline.time();
diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp
index 5669812..6a6ff64 100644
--- a/src/declarative/graphicsitems/qdeclarativegridview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp
@@ -2139,13 +2139,15 @@ void QDeclarativeGridViewPrivate::positionViewAtIndex(int index, int mode)
layout();
qreal pos = position();
FxGridItem *item = visibleItem(idx);
+ qreal maxExtent = flow == QDeclarativeGridView::LeftToRight ? -q->maxYExtent() : -q->maxXExtent();
if (!item) {
int itemPos = rowPosAt(idx);
// save the currently visible items in case any of them end up visible again
QList<FxGridItem*> oldVisible = visibleItems;
visibleItems.clear();
visibleIndex = idx - idx % columns;
- setPosition(itemPos);
+ maxExtent = flow == QDeclarativeGridView::LeftToRight ? -q->maxYExtent() : -q->maxXExtent();
+ setPosition(qMin(qreal(itemPos), maxExtent));
// now release the reference to all the old visible items.
for (int i = 0; i < oldVisible.count(); ++i)
releaseItem(oldVisible.at(i));
@@ -2185,7 +2187,6 @@ void QDeclarativeGridViewPrivate::positionViewAtIndex(int index, int mode)
if (itemPos < pos)
pos = itemPos;
}
- qreal maxExtent = flow == QDeclarativeGridView::LeftToRight ? -q->maxYExtent() : -q->maxXExtent();
pos = qMin(pos, maxExtent);
qreal minExtent = flow == QDeclarativeGridView::LeftToRight ? -q->minYExtent() : -q->minXExtent();
pos = qMax(pos, minExtent);
diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp
index da1e33d..cbc4311 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp
@@ -2572,6 +2572,7 @@ void QDeclarativeListViewPrivate::positionViewAtIndex(int index, int mode)
layout();
qreal pos = position();
FxListItem *item = visibleItem(idx);
+ qreal maxExtent = orient == QDeclarativeListView::Vertical ? -q->maxYExtent() : -q->maxXExtent();
if (!item) {
int itemPos = positionAt(idx);
// save the currently visible items in case any of them end up visible again
@@ -2579,7 +2580,7 @@ void QDeclarativeListViewPrivate::positionViewAtIndex(int index, int mode)
visibleItems.clear();
visiblePos = itemPos;
visibleIndex = idx;
- setPosition(itemPos);
+ setPosition(qMin(qreal(itemPos), maxExtent));
// now release the reference to all the old visible items.
for (int i = 0; i < oldVisible.count(); ++i)
releaseItem(oldVisible.at(i));
@@ -2613,7 +2614,6 @@ void QDeclarativeListViewPrivate::positionViewAtIndex(int index, int mode)
if (itemPos < pos)
pos = itemPos;
}
- qreal maxExtent = orient == QDeclarativeListView::Vertical ? -q->maxYExtent() : -q->maxXExtent();
pos = qMin(pos, maxExtent);
qreal minExtent = orient == QDeclarativeListView::Vertical ? -q->minYExtent() : -q->minXExtent();
pos = qMax(pos, minExtent);
diff --git a/src/declarative/graphicsitems/qdeclarativeloader.cpp b/src/declarative/graphicsitems/qdeclarativeloader.cpp
index b5f8b1d..562ef08 100644
--- a/src/declarative/graphicsitems/qdeclarativeloader.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeloader.cpp
@@ -48,7 +48,7 @@
QT_BEGIN_NAMESPACE
QDeclarativeLoaderPrivate::QDeclarativeLoaderPrivate()
- : item(0), component(0), ownComponent(false), isComponentComplete(false), updatingSize(false),
+ : item(0), component(0), ownComponent(false), updatingSize(false),
itemWidthValid(false), itemHeightValid(false)
{
}
@@ -279,7 +279,7 @@ void QDeclarativeLoader::setSource(const QUrl &url)
d->component = new QDeclarativeComponent(qmlEngine(this), d->source, this);
d->ownComponent = true;
- if (d->isComponentComplete)
+ if (isComponentComplete())
d->load();
}
@@ -330,7 +330,7 @@ void QDeclarativeLoader::setSourceComponent(QDeclarativeComponent *comp)
return;
}
- if (d->isComponentComplete)
+ if (isComponentComplete())
d->load();
}
@@ -343,7 +343,7 @@ void QDeclarativeLoaderPrivate::load()
{
Q_Q(QDeclarativeLoader);
- if (!isComponentComplete || !component)
+ if (!q->isComponentComplete() || !component)
return;
if (!component->isLoading()) {
@@ -477,7 +477,6 @@ void QDeclarativeLoader::componentComplete()
Q_D(QDeclarativeLoader);
QDeclarativeItem::componentComplete();
- d->isComponentComplete = true;
d->load();
}
diff --git a/src/declarative/graphicsitems/qdeclarativeloader_p_p.h b/src/declarative/graphicsitems/qdeclarativeloader_p_p.h
index 6a40bf3..4593dfc 100644
--- a/src/declarative/graphicsitems/qdeclarativeloader_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeloader_p_p.h
@@ -78,7 +78,6 @@ public:
QGraphicsObject *item;
QDeclarativeComponent *component;
bool ownComponent : 1;
- bool isComponentComplete : 1;
bool updatingSize: 1;
bool itemWidthValid : 1;
bool itemHeightValid : 1;
diff --git a/src/declarative/graphicsitems/qdeclarativescalegrid.cpp b/src/declarative/graphicsitems/qdeclarativescalegrid.cpp
index 804e91d..3ad0da6 100644
--- a/src/declarative/graphicsitems/qdeclarativescalegrid.cpp
+++ b/src/declarative/graphicsitems/qdeclarativescalegrid.cpp
@@ -136,12 +136,12 @@ QDeclarativeGridScaledImage::QDeclarativeGridScaledImage(QIODevice *data)
if (line.isEmpty() || line.startsWith(QLatin1Char('#')))
continue;
- QStringList list = line.split(QLatin1Char(':'));
- if (list.count() != 2)
+ int colonId = line.indexOf(QLatin1Char(':'));
+ if (colonId <= 0)
return;
-
- list[0] = list[0].trimmed();
- list[1] = list[1].trimmed();
+ QStringList list;
+ list.append(line.left(colonId).trimmed());
+ list.append(line.mid(colonId+1).trimmed());
if (list[0] == QLatin1String("border.left"))
l = list[1].toInt();
diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp
index b2d0738..a5bd604 100644
--- a/src/declarative/qml/qdeclarativebinding.cpp
+++ b/src/declarative/qml/qdeclarativebinding.cpp
@@ -274,6 +274,13 @@ QDeclarativeBinding::QDeclarativeBinding(const QString &str, QObject *obj, QDecl
setNotifyOnValueChanged(true);
}
+QDeclarativeBinding::QDeclarativeBinding(const QScriptValue &func, QObject *obj, QDeclarativeContextData *ctxt, QObject *parent)
+: QDeclarativeExpression(ctxt, obj, func, *new QDeclarativeBindingPrivate)
+{
+ setParent(parent);
+ setNotifyOnValueChanged(true);
+}
+
QDeclarativeBinding::~QDeclarativeBinding()
{
}
@@ -292,6 +299,19 @@ QDeclarativeProperty QDeclarativeBinding::property() const
return d->property;
}
+void QDeclarativeBinding::setEvaluateFlags(EvaluateFlags flags)
+{
+ Q_D(QDeclarativeBinding);
+ d->setEvaluateFlags(QDeclarativeQtScriptExpression::EvaluateFlags(static_cast<int>(flags)));
+}
+
+QDeclarativeBinding::EvaluateFlags QDeclarativeBinding::evaluateFlags() const
+{
+ Q_D(const QDeclarativeBinding);
+ return QDeclarativeBinding::EvaluateFlags(static_cast<int>(d->evaluateFlags()));
+}
+
+
class QDeclarativeBindingProfiler {
public:
QDeclarativeBindingProfiler(QDeclarativeBinding *bind)
diff --git a/src/declarative/qml/qdeclarativebinding_p.h b/src/declarative/qml/qdeclarativebinding_p.h
index 19e7099..0260b95 100644
--- a/src/declarative/qml/qdeclarativebinding_p.h
+++ b/src/declarative/qml/qdeclarativebinding_p.h
@@ -147,14 +147,21 @@ class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeBinding : public QDeclarativeExpr
{
Q_OBJECT
public:
+ enum EvaluateFlag { RequiresThisObject = 0x01 };
+ Q_DECLARE_FLAGS(EvaluateFlags, EvaluateFlag)
+
QDeclarativeBinding(const QString &, QObject *, QDeclarativeContext *, QObject *parent=0);
QDeclarativeBinding(const QString &, QObject *, QDeclarativeContextData *, QObject *parent=0);
QDeclarativeBinding(void *, QDeclarativeRefCount *, QObject *, QDeclarativeContextData *,
const QString &, int, QObject *parent);
+ QDeclarativeBinding(const QScriptValue &, QObject *, QDeclarativeContextData *, QObject *parent=0);
void setTarget(const QDeclarativeProperty &);
QDeclarativeProperty property() const;
+ void setEvaluateFlags(EvaluateFlags flags);
+ EvaluateFlags evaluateFlags() const;
+
bool enabled() const;
// Inherited from QDeclarativeAbstractBinding
@@ -177,6 +184,8 @@ private:
Q_DECLARE_PRIVATE(QDeclarativeBinding)
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativeBinding::EvaluateFlags)
+
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QDeclarativeBinding*)
diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp
index 8865ddd..bd6e2d8 100644
--- a/src/declarative/qml/qdeclarativecomponent.cpp
+++ b/src/declarative/qml/qdeclarativecomponent.cpp
@@ -54,11 +54,13 @@
#include "private/qdeclarativescriptparser_p.h"
#include "private/qdeclarativedebugtrace_p.h"
#include "private/qdeclarativeenginedebug_p.h"
+#include <QtScript/qscriptvalueiterator.h>
#include <QStack>
#include <QStringList>
#include <QtCore/qdebug.h>
#include <QApplication>
+#include <qdeclarativeinfo.h>
QT_BEGIN_NAMESPACE
@@ -613,7 +615,7 @@ QDeclarativeComponent::QDeclarativeComponent(QDeclarativeComponentPrivate &dd, Q
}
/*!
- \qmlmethod object Component::createObject(Item parent)
+ \qmlmethod object Component::createObject(Item parent, Script valuemap = null)
Creates and returns an object instance of this component that will have the given
\a parent. Returns null if object creation fails.
@@ -631,6 +633,12 @@ QDeclarativeComponent::QDeclarativeComponent(QDeclarativeComponentPrivate &dd, Q
it is not destroyed by the garbage collector. This is regardless of Item.parent being set afterwards,
since setting the Item parent does not change object ownership; only the graphical parent is changed.
+ Since QtQuick 1.1, a map of property values can be optionally passed to the method that applies values to the object's properties
+ before its creation is finalised. This will avoid binding issues that can occur when the object is
+ instantiated before property bindings have been set. For example:
+
+ \code component.createObject(parent, {"x": 100, "y": 100, "specialProperty": someObject}); \endcode
+
Dynamically created instances can be deleted with the \c destroy() method.
See \l {Dynamic Object Management in QML} for more information.
*/
@@ -646,25 +654,46 @@ QDeclarativeComponent::QDeclarativeComponent(QDeclarativeComponentPrivate &dd, Q
QScriptValue QDeclarativeComponent::createObject(QObject* parent)
{
Q_D(QDeclarativeComponent);
- QDeclarativeContext* ctxt = creationContext();
- if(!ctxt && d->engine)
- ctxt = d->engine->rootContext();
+ return d->createObject(parent, QScriptValue(QScriptValue::NullValue));
+}
+
+/*!
+ \internal
+ Overloadable method allows properties to be set during creation
+*/
+QScriptValue QDeclarativeComponent::createObject(QObject* parent, const QScriptValue& valuemap)
+{
+ Q_D(QDeclarativeComponent);
+
+ if (valuemap.isObject() && !valuemap.isArray()) {
+ qmlInfo(this) << tr("creatObject: value is not an object");
+ return QScriptValue(QScriptValue::NullValue);
+ }
+ return d->createObject(parent, valuemap);
+}
+
+QScriptValue QDeclarativeComponentPrivate::createObject(QObject *publicParent, const QScriptValue valuemap)
+{
+ Q_Q(QDeclarativeComponent);
+ QDeclarativeContext* ctxt = q->creationContext();
+ if(!ctxt && engine)
+ ctxt = engine->rootContext();
if (!ctxt)
return QScriptValue(QScriptValue::NullValue);
- QObject* ret = beginCreate(ctxt);
+ QObject* ret = q->beginCreate(ctxt);
if (!ret) {
- completeCreate();
+ q->completeCreate();
return QScriptValue(QScriptValue::NullValue);
}
- if (parent) {
- ret->setParent(parent);
+ if (publicParent) {
+ ret->setParent(publicParent);
QList<QDeclarativePrivate::AutoParentFunction> functions = QDeclarativeMetaType::parentFunctions();
bool needParent = false;
for (int ii = 0; ii < functions.count(); ++ii) {
- QDeclarativePrivate::AutoParentResult res = functions.at(ii)(ret, parent);
+ QDeclarativePrivate::AutoParentResult res = functions.at(ii)(ret, publicParent);
if (res == QDeclarativePrivate::Parented) {
needParent = false;
break;
@@ -673,14 +702,26 @@ QScriptValue QDeclarativeComponent::createObject(QObject* parent)
}
}
- if (needParent)
+ if (needParent)
qWarning("QDeclarativeComponent: Created graphical object was not placed in the graphics scene.");
}
- completeCreate();
- QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(d->engine);
+ QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(engine);
QDeclarativeData::get(ret, true)->setImplicitDestructible();
- return priv->objectClass->newQObject(ret, QMetaType::QObjectStar);
+ QScriptValue newObject = priv->objectClass->newQObject(ret, QMetaType::QObjectStar);
+
+ if (valuemap.isObject() && !valuemap.isArray()) {
+ //Iterate through and assign properties
+ QScriptValueIterator it(valuemap);
+ while (it.hasNext()) {
+ it.next();
+ newObject.setProperty(it.name(), it.value(), QScriptValue::KeepExistingFlags);
+ }
+ }
+
+ q->completeCreate();
+
+ return newObject;
}
/*!
diff --git a/src/declarative/qml/qdeclarativecomponent.h b/src/declarative/qml/qdeclarativecomponent.h
index 6f28f2e..3d318c3 100644
--- a/src/declarative/qml/qdeclarativecomponent.h
+++ b/src/declarative/qml/qdeclarativecomponent.h
@@ -110,6 +110,7 @@ Q_SIGNALS:
protected:
QDeclarativeComponent(QDeclarativeComponentPrivate &dd, QObject* parent);
Q_INVOKABLE QScriptValue createObject(QObject* parent);
+ Q_INVOKABLE QScriptValue createObject(QObject* parent, const QScriptValue& valuemap); //XXX Versioning
private:
QDeclarativeComponent(QDeclarativeEngine *, QDeclarativeCompiledData *, int, int, QObject *parent);
diff --git a/src/declarative/qml/qdeclarativecomponent_p.h b/src/declarative/qml/qdeclarativecomponent_p.h
index 02a6ce8..f8bec2b 100644
--- a/src/declarative/qml/qdeclarativecomponent_p.h
+++ b/src/declarative/qml/qdeclarativecomponent_p.h
@@ -116,6 +116,8 @@ public:
ConstructionState *state);
static void complete(QDeclarativeEnginePrivate *enginePriv, ConstructionState *state);
+ QScriptValue createObject(QObject *publicParent, const QScriptValue valuemap);
+
QDeclarativeEngine *engine;
QDeclarativeGuardedContextData creationContext;
diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp
index 26c91a5..7a85ada 100644
--- a/src/declarative/qml/qdeclarativeexpression.cpp
+++ b/src/declarative/qml/qdeclarativeexpression.cpp
@@ -103,6 +103,19 @@ void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, const QS
expressionFunctionValid = false;
}
+void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, const QScriptValue &func,
+ QObject *me)
+{
+ expression = func.toString();
+
+ QDeclarativeAbstractExpression::setContext(ctxt);
+ scopeObject = me;
+
+ expressionFunction = func;
+ expressionFunctionMode = ExplicitContext;
+ expressionFunctionValid = true;
+}
+
void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, void *expr,
QDeclarativeRefCount *rc,
QObject *me, const QString &srcUrl, int lineNumber)
@@ -304,6 +317,19 @@ QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, QO
d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
}
+/*! \internal */
+QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, QObject *scope, const QScriptValue &func,
+ QDeclarativeExpressionPrivate &dd)
+: QObject(dd, 0)
+{
+ Q_D(QDeclarativeExpression);
+ d->init(ctxt, func, scope);
+
+ if (QDeclarativeExpression_notifyIdx == -1)
+ QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
+ d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
+}
+
/*!
Destroy the QDeclarativeExpression instance.
*/
@@ -412,6 +438,16 @@ void QDeclarativeQtScriptExpression::setNotifyObject(QObject *object, int notify
}
}
+void QDeclarativeQtScriptExpression::setEvaluateFlags(EvaluateFlags flags)
+{
+ evalFlags = flags;
+}
+
+QDeclarativeQtScriptExpression::EvaluateFlags QDeclarativeQtScriptExpression::evaluateFlags() const
+{
+ return evalFlags;
+}
+
QScriptValue QDeclarativeQtScriptExpression::scriptValue(QObject *secondaryScope, bool *isUndefined)
{
Q_ASSERT(context() && context()->engine);
@@ -476,7 +512,10 @@ QScriptValue QDeclarativeQtScriptExpression::eval(QObject *secondaryScope, bool
oldOverride = ep->contextClass->setOverrideObject(expressionContext, secondaryScope);
}
- QScriptValue svalue = expressionFunction.call(); // This could cause this to be deleted
+ QScriptValue thisObject;
+ if (evalFlags & RequiresThisObject)
+ thisObject = ep->objectClass->newQObject(scopeObject);
+ QScriptValue svalue = expressionFunction.call(thisObject); // This could cause this c++ object to be deleted
if (isShared) {
ep->sharedContext = oldSharedContext;
diff --git a/src/declarative/qml/qdeclarativeexpression.h b/src/declarative/qml/qdeclarativeexpression.h
index 72c5947..d40094b 100644
--- a/src/declarative/qml/qdeclarativeexpression.h
+++ b/src/declarative/qml/qdeclarativeexpression.h
@@ -59,6 +59,7 @@ class QDeclarativeEngine;
class QDeclarativeContext;
class QDeclarativeExpressionPrivate;
class QDeclarativeContextData;
+class QScriptValue;
class Q_DECLARATIVE_EXPORT QDeclarativeExpression : public QObject
{
Q_OBJECT
@@ -94,6 +95,8 @@ Q_SIGNALS:
protected:
QDeclarativeExpression(QDeclarativeContextData *, QObject *, const QString &,
QDeclarativeExpressionPrivate &dd);
+ QDeclarativeExpression(QDeclarativeContextData *, QObject *, const QScriptValue &,
+ QDeclarativeExpressionPrivate &dd);
QDeclarativeExpression(QDeclarativeContextData *, void *, QDeclarativeRefCount *rc,
QObject *me, const QString &, int, QDeclarativeExpressionPrivate &dd);
diff --git a/src/declarative/qml/qdeclarativeexpression_p.h b/src/declarative/qml/qdeclarativeexpression_p.h
index 1d25609..51cae0f 100644
--- a/src/declarative/qml/qdeclarativeexpression_p.h
+++ b/src/declarative/qml/qdeclarativeexpression_p.h
@@ -113,6 +113,9 @@ class QDeclarativeQtScriptExpression : public QDeclarativeAbstractExpression,
public:
enum Mode { SharedContext, ExplicitContext };
+ enum EvaluateFlag { RequiresThisObject = 0x01 };
+ Q_DECLARE_FLAGS(EvaluateFlags, EvaluateFlag)
+
QDeclarativeQtScriptExpression();
virtual ~QDeclarativeQtScriptExpression();
@@ -131,6 +134,9 @@ public:
void resetNotifyOnChange();
void setNotifyObject(QObject *, int );
+ void setEvaluateFlags(EvaluateFlags flags);
+ EvaluateFlags evaluateFlags() const;
+
QScriptValue scriptValue(QObject *secondaryScope, bool *isUndefined);
class DeleteWatcher {
@@ -157,8 +163,13 @@ private:
QObject *guardObject;
int guardObjectNotifyIndex;
bool *deleted;
+
+ EvaluateFlags evalFlags;
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativeQtScriptExpression::EvaluateFlags)
+
+
class QDeclarativeExpression;
class QString;
class QDeclarativeExpressionPrivate : public QObjectPrivate, public QDeclarativeQtScriptExpression
@@ -169,6 +180,7 @@ public:
~QDeclarativeExpressionPrivate();
void init(QDeclarativeContextData *, const QString &, QObject *);
+ void init(QDeclarativeContextData *, const QScriptValue &, QObject *);
void init(QDeclarativeContextData *, void *, QDeclarativeRefCount *, QObject *, const QString &, int);
QVariant value(QObject *secondaryScope = 0, bool *isUndefined = 0);
diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
index cbbf2b9..7701a23 100644
--- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
+++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
@@ -359,8 +359,20 @@ void QDeclarativeObjectScriptClass::setProperty(QObject *obj,
}
}
+ QDeclarativeBinding *newBinding = 0;
+ if (value.isFunction() && !value.isRegExp()) {
+ QScriptContextInfo ctxtInfo(context);
+ QDeclarativePropertyCache::ValueTypeData valueTypeData;
+
+ newBinding = new QDeclarativeBinding(value, obj, evalContext);
+ newBinding->setSourceLocation(ctxtInfo.fileName(), ctxtInfo.functionStartLineNumber());
+ newBinding->setTarget(QDeclarativePropertyPrivate::restore(*lastData, valueTypeData, obj, evalContext));
+ if (newBinding->expression().contains("this"))
+ newBinding->setEvaluateFlags(newBinding->evaluateFlags() | QDeclarativeBinding::RequiresThisObject);
+ }
+
QDeclarativeAbstractBinding *delBinding =
- QDeclarativePropertyPrivate::setBinding(obj, lastData->coreIndex, -1, 0);
+ QDeclarativePropertyPrivate::setBinding(obj, lastData->coreIndex, -1, newBinding);
if (delBinding)
delBinding->destroy();
@@ -379,10 +391,7 @@ void QDeclarativeObjectScriptClass::setProperty(QObject *obj,
QString error = QLatin1String("Cannot assign [undefined] to ") +
QLatin1String(QMetaType::typeName(lastData->propType));
context->throwError(error);
- } else if (!value.isRegExp() && value.isFunction()) {
- QString error = QLatin1String("Cannot assign a function to a property.");
- context->throwError(error);
- } else {
+ } else if (!value.isFunction()) {
QVariant v;
if (lastData->flags & QDeclarativePropertyCache::Data::IsQList)
v = enginePriv->scriptValueToVariant(value, qMetaTypeId<QList<QObject *> >());
diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp
index 76829b7..61e3002 100644
--- a/src/declarative/qml/qdeclarativeproperty.cpp
+++ b/src/declarative/qml/qdeclarativeproperty.cpp
@@ -1480,19 +1480,28 @@ QDeclarativePropertyPrivate::restore(const QByteArray &data, QObject *object, QD
if (data.isEmpty())
return prop;
- prop.d = new QDeclarativePropertyPrivate;
- prop.d->object = object;
- prop.d->context = ctxt;
- prop.d->engine = ctxt->engine;
-
const SerializedData *sd = (const SerializedData *)data.constData();
if (sd->isValueType) {
const ValueTypeSerializedData *vt = (const ValueTypeSerializedData *)sd;
- prop.d->core = vt->core;
- prop.d->valueType = vt->valueType;
+ return restore(vt->core, vt->valueType, object, ctxt);
} else {
- prop.d->core = sd->core;
+ QDeclarativePropertyCache::ValueTypeData data;
+ return restore(sd->core, data, object, ctxt);
}
+}
+
+QDeclarativeProperty
+QDeclarativePropertyPrivate::restore(const QDeclarativePropertyCache::Data &data, const QDeclarativePropertyCache::ValueTypeData &valueType, QObject *object, QDeclarativeContextData *ctxt)
+{
+ QDeclarativeProperty prop;
+
+ prop.d = new QDeclarativePropertyPrivate;
+ prop.d->object = object;
+ prop.d->context = ctxt;
+ prop.d->engine = ctxt->engine;
+
+ prop.d->core = data;
+ prop.d->valueType = valueType;
return prop;
}
diff --git a/src/declarative/qml/qdeclarativeproperty_p.h b/src/declarative/qml/qdeclarativeproperty_p.h
index fa0fef4..bd2c891 100644
--- a/src/declarative/qml/qdeclarativeproperty_p.h
+++ b/src/declarative/qml/qdeclarativeproperty_p.h
@@ -112,7 +112,12 @@ public:
static QByteArray saveValueType(const QMetaObject *, int,
const QMetaObject *, int);
static QByteArray saveProperty(const QMetaObject *, int);
+
static QDeclarativeProperty restore(const QByteArray &, QObject *, QDeclarativeContextData *);
+ static QDeclarativeProperty restore(const QDeclarativePropertyCache::Data &,
+ const QDeclarativePropertyCache::ValueTypeData &,
+ QObject *,
+ QDeclarativeContextData *);
static bool equal(const QMetaObject *, const QMetaObject *);
static bool canConvert(const QMetaObject *from, const QMetaObject *to);
diff --git a/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp b/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp
index 558ef90..200cc1c 100644
--- a/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp
+++ b/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp
@@ -46,6 +46,8 @@
#include "private/qdeclarativeengine_p.h"
#include "private/qdeclarativeguard_p.h"
+#include <QtScript/qscriptcontextinfo.h>
+
QT_BEGIN_NAMESPACE
struct QDeclarativeValueTypeObject : public QScriptDeclarativeClass::Object {
@@ -161,17 +163,41 @@ void QDeclarativeValueTypeScriptClass::setProperty(Object *obj, const Identifier
if (o->objectType == QDeclarativeValueTypeObject::Reference) {
QDeclarativeValueTypeReference *ref = static_cast<QDeclarativeValueTypeReference *>(obj);
+ ref->type->read(ref->object, ref->property);
+ QMetaProperty p = ref->type->metaObject()->property(m_lastIndex);
+
+ QDeclarativeBinding *newBinding = 0;
+ if (value.isFunction() && !value.isRegExp()) {
+ QDeclarativeContextData *ctxt = QDeclarativeEnginePrivate::get(engine)->getContext(context());
+
+ QDeclarativePropertyCache::Data cacheData;
+ cacheData.flags = QDeclarativePropertyCache::Data::IsWritable;
+ cacheData.propType = ref->object->metaObject()->property(ref->property).userType();
+ cacheData.coreIndex = ref->property;
+
+ QDeclarativePropertyCache::ValueTypeData valueTypeData;
+ valueTypeData.valueTypeCoreIdx = m_lastIndex;
+ valueTypeData.valueTypePropType = p.userType();
+
+ newBinding = new QDeclarativeBinding(value, ref->object, ctxt);
+ QScriptContextInfo ctxtInfo(context());
+ newBinding->setSourceLocation(ctxtInfo.fileName(), ctxtInfo.functionStartLineNumber());
+ QDeclarativeProperty prop = QDeclarativePropertyPrivate::restore(cacheData, valueTypeData, ref->object, ctxt);
+ newBinding->setTarget(prop);
+ if (newBinding->expression().contains("this"))
+ newBinding->setEvaluateFlags(newBinding->evaluateFlags() | QDeclarativeBinding::RequiresThisObject);
+ }
+
QDeclarativeAbstractBinding *delBinding =
- QDeclarativePropertyPrivate::setBinding(ref->object, ref->property, m_lastIndex, 0);
+ QDeclarativePropertyPrivate::setBinding(ref->object, ref->property, m_lastIndex, newBinding);
if (delBinding)
delBinding->destroy();
- ref->type->read(ref->object, ref->property);
- QMetaProperty p = ref->type->metaObject()->property(m_lastIndex);
if (p.isEnumType() && (QMetaType::Type)v.type() == QMetaType::Double)
v = v.toInt();
p.write(ref->type, v);
ref->type->write(ref->object, ref->property, 0);
+
} else {
QDeclarativeValueTypeCopy *copy = static_cast<QDeclarativeValueTypeCopy *>(obj);
copy->type->setValue(copy->value);