summaryrefslogtreecommitdiffstats
path: root/src/declarative/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/qml')
-rw-r--r--src/declarative/qml/qdeclarativecompiler.cpp37
-rw-r--r--src/declarative/qml/qdeclarativecompiler_p.h6
-rw-r--r--src/declarative/qml/qdeclarativecomponent.cpp67
-rw-r--r--src/declarative/qml/qdeclarativecomponent_p.h19
-rw-r--r--src/declarative/qml/qdeclarativecontext.cpp57
-rw-r--r--src/declarative/qml/qdeclarativecontext_p.h7
-rw-r--r--src/declarative/qml/qdeclarativedata_p.h4
-rw-r--r--src/declarative/qml/qdeclarativeengine.cpp17
-rw-r--r--src/declarative/qml/qdeclarativeengine_p.h2
-rw-r--r--src/declarative/qml/qdeclarativeproperty.cpp34
-rw-r--r--src/declarative/qml/qdeclarativeproperty_p.h3
-rw-r--r--src/declarative/qml/qdeclarativepropertycache.cpp6
-rw-r--r--src/declarative/qml/qdeclarativevaluetype.cpp6
-rw-r--r--src/declarative/qml/qdeclarativevaluetype_p.h5
-rw-r--r--src/declarative/qml/qdeclarativevaluetypescriptclass.cpp123
-rw-r--r--src/declarative/qml/qdeclarativevaluetypescriptclass_p.h1
16 files changed, 247 insertions, 147 deletions
diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp
index fad7779..065009a 100644
--- a/src/declarative/qml/qdeclarativecompiler.cpp
+++ b/src/declarative/qml/qdeclarativecompiler.cpp
@@ -67,7 +67,6 @@
#include "private/qdeclarativecompiledbindings_p.h"
#include "private/qdeclarativeglobalscriptclass_p.h"
-#include <QCoreApplication>
#include <QColor>
#include <QDebug>
#include <QPointF>
@@ -1364,35 +1363,6 @@ int QDeclarativeCompiler::componentTypeRef()
return output->types.count() - 1;
}
-QMetaMethod QDeclarativeCompiler::findSignalByName(const QMetaObject *mo, const QByteArray &name)
-{
- Q_ASSERT(mo);
- int methods = mo->methodCount();
- for (int ii = methods - 1; ii >= 0; --ii) {
- QMetaMethod method = mo->method(ii);
- QByteArray methodName = method.signature();
- int idx = methodName.indexOf('(');
- methodName = methodName.left(idx);
-
- if (methodName == name)
- return method;
- }
-
- // If no signal is found, but the signal is of the form "onBlahChanged",
- // return the notify signal for the property "Blah"
- if (name.endsWith("Changed")) {
- QByteArray propName = name.mid(0, name.length() - 7);
- int propIdx = mo->indexOfProperty(propName.constData());
- if (propIdx >= 0) {
- QMetaProperty prop = mo->property(propIdx);
- if (prop.hasNotifySignal())
- return prop.notifySignal();
- }
- }
-
- return QMetaMethod();
-}
-
bool QDeclarativeCompiler::buildSignal(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj,
const BindingContext &ctxt)
{
@@ -1404,7 +1374,7 @@ bool QDeclarativeCompiler::buildSignal(QDeclarativeParser::Property *prop, QDecl
if(name[0] >= 'A' && name[0] <= 'Z')
name[0] = name[0] - 'A' + 'a';
- int sigIdx = findSignalByName(obj->metaObject(), name).methodIndex();
+ int sigIdx = QDeclarativePropertyPrivate::findSignalByName(obj->metaObject(), name).methodIndex();
if (sigIdx == -1) {
@@ -2976,9 +2946,4 @@ QStringList QDeclarativeCompiler::deferredProperties(QDeclarativeParser::Object
return rv;
}
-QString QDeclarativeCompiler::tr(const char *str)
-{
- return QCoreApplication::translate("QDeclarativeCompiler", str);
-}
-
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativecompiler_p.h b/src/declarative/qml/qdeclarativecompiler_p.h
index 0e47774..867db2c 100644
--- a/src/declarative/qml/qdeclarativecompiler_p.h
+++ b/src/declarative/qml/qdeclarativecompiler_p.h
@@ -66,6 +66,7 @@
#include <QtCore/qbytearray.h>
#include <QtCore/qset.h>
+#include <QtCore/QCoreApplication>
QT_BEGIN_NAMESPACE
@@ -148,6 +149,7 @@ private:
class QMetaObjectBuilder;
class Q_DECLARATIVE_EXPORT QDeclarativeCompiler
{
+ Q_DECLARE_TR_FUNCTIONS(QDeclarativeCompiler)
public:
QDeclarativeCompiler();
@@ -159,8 +161,6 @@ public:
static bool isAttachedPropertyName(const QByteArray &);
static bool isSignalPropertyName(const QByteArray &);
- static QMetaMethod findSignalByName(const QMetaObject *, const QByteArray &name);
-
int evaluateEnum(const QByteArray& script) const; // for QDeclarativeCustomParser::evaluateEnum
private:
@@ -281,8 +281,6 @@ private:
void addId(const QString &, QDeclarativeParser::Object *);
- QString tr(const char *);
-
void dumpStats();
struct BindingReference {
diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp
index 1903006..3e4651c 100644
--- a/src/declarative/qml/qdeclarativecomponent.cpp
+++ b/src/declarative/qml/qdeclarativecomponent.cpp
@@ -120,6 +120,26 @@ Item {
}
}
\endqml
+
+ \e onDestruction
+
+ Emitted as the component begins destruction. This can be used to undo
+ work done in the onCompleted signal, or other imperative code in your
+ application.
+
+ The \c {Component::onDestruction} attached property can be applied to
+ any element. However, it applies to the destruction of the component as
+ a whole, and not the destruction of the specific object. The order of
+ running the \c onDestruction scripts is undefined.
+
+ \qml
+ Rectangle {
+ Component.onDestruction: console.log("Destruction Beginning!")
+ Rectangle {
+ Component.onDestruction: console.log("Nested Destruction Beginning!")
+ }
+ }
+ \endqml
*/
/*!
@@ -657,11 +677,11 @@ QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContextData *ctxt, QDe
state->bindValues = enginePriv->bindValues;
state->parserStatus = enginePriv->parserStatus;
- state->componentAttacheds = enginePriv->componentAttacheds;
- if (state->componentAttacheds)
- state->componentAttacheds->prev = &state->componentAttacheds;
+ state->componentAttached = enginePriv->componentAttached;
+ if (state->componentAttached)
+ state->componentAttached->prev = &state->componentAttached;
- enginePriv->componentAttacheds = 0;
+ enginePriv->componentAttached = 0;
enginePriv->bindValues.clear();
enginePriv->parserStatus.clear();
state->completePending = true;
@@ -671,7 +691,7 @@ QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContextData *ctxt, QDe
return rv;
}
-void QDeclarativeComponentPrivate::beginDeferred(QDeclarativeContextData *, QDeclarativeEnginePrivate *enginePriv,
+void QDeclarativeComponentPrivate::beginDeferred(QDeclarativeEnginePrivate *enginePriv,
QObject *object, ConstructionState *state)
{
bool isRoot = !enginePriv->inBeginCreate;
@@ -688,11 +708,11 @@ void QDeclarativeComponentPrivate::beginDeferred(QDeclarativeContextData *, QDec
state->bindValues = enginePriv->bindValues;
state->parserStatus = enginePriv->parserStatus;
- state->componentAttacheds = enginePriv->componentAttacheds;
- if (state->componentAttacheds)
- state->componentAttacheds->prev = &state->componentAttacheds;
+ state->componentAttached = enginePriv->componentAttached;
+ if (state->componentAttached)
+ state->componentAttached->prev = &state->componentAttached;
- enginePriv->componentAttacheds = 0;
+ enginePriv->componentAttached = 0;
enginePriv->bindValues.clear();
enginePriv->parserStatus.clear();
state->completePending = true;
@@ -729,11 +749,13 @@ void QDeclarativeComponentPrivate::complete(QDeclarativeEnginePrivate *enginePri
QDeclarativeEnginePrivate::clear(ps);
}
- while (state->componentAttacheds) {
- QDeclarativeComponentAttached *a = state->componentAttacheds;
- if (a->next) a->next->prev = &state->componentAttacheds;
- state->componentAttacheds = a->next;
- a->prev = 0; a->next = 0;
+ while (state->componentAttached) {
+ QDeclarativeComponentAttached *a = state->componentAttached;
+ a->rem();
+ QDeclarativeData *d = QDeclarativeData::get(a->parent());
+ Q_ASSERT(d);
+ Q_ASSERT(d->context);
+ a->add(&d->context->componentAttached);
emit a->completed();
}
@@ -793,15 +815,18 @@ QDeclarativeComponentAttached *QDeclarativeComponent::qmlAttachedProperties(QObj
QDeclarativeComponentAttached *a = new QDeclarativeComponentAttached(obj);
QDeclarativeEngine *engine = qmlEngine(obj);
- if (!engine || !QDeclarativeEnginePrivate::get(engine)->inBeginCreate)
+ if (!engine)
return a;
- QDeclarativeEnginePrivate *p = QDeclarativeEnginePrivate::get(engine);
-
- a->next = p->componentAttacheds;
- a->prev = &p->componentAttacheds;
- if (a->next) a->next->prev = &a->next;
- p->componentAttacheds = a;
+ if (QDeclarativeEnginePrivate::get(engine)->inBeginCreate) {
+ QDeclarativeEnginePrivate *p = QDeclarativeEnginePrivate::get(engine);
+ a->add(&p->componentAttached);
+ } else {
+ QDeclarativeData *d = QDeclarativeData::get(obj);
+ Q_ASSERT(d);
+ Q_ASSERT(d->context);
+ a->add(&d->context->componentAttached);
+ }
return a;
}
diff --git a/src/declarative/qml/qdeclarativecomponent_p.h b/src/declarative/qml/qdeclarativecomponent_p.h
index dfe327b..24e5386 100644
--- a/src/declarative/qml/qdeclarativecomponent_p.h
+++ b/src/declarative/qml/qdeclarativecomponent_p.h
@@ -99,10 +99,10 @@ public:
QDeclarativeCompiledData *cc;
struct ConstructionState {
- ConstructionState() : componentAttacheds(0), completePending(false) {}
+ ConstructionState() : componentAttached(0), completePending(false) {}
QList<QDeclarativeEnginePrivate::SimpleList<QDeclarativeAbstractBinding> > bindValues;
QList<QDeclarativeEnginePrivate::SimpleList<QDeclarativeParserStatus> > parserStatus;
- QDeclarativeComponentAttached *componentAttacheds;
+ QDeclarativeComponentAttached *componentAttached;
QList<QDeclarativeError> errors;
bool completePending;
};
@@ -111,8 +111,8 @@ public:
static QObject *begin(QDeclarativeContextData *ctxt, QDeclarativeEnginePrivate *enginePriv,
QDeclarativeCompiledData *component, int start, int count,
ConstructionState *state, const QBitField &bindings = QBitField());
- static void beginDeferred(QDeclarativeContextData *ctxt, QDeclarativeEnginePrivate *enginePriv,
- QObject *object, ConstructionState *state);
+ static void beginDeferred(QDeclarativeEnginePrivate *enginePriv, QObject *object,
+ ConstructionState *state);
static void complete(QDeclarativeEnginePrivate *enginePriv, ConstructionState *state);
QDeclarativeEngine *engine;
@@ -132,13 +132,24 @@ public:
QDeclarativeComponentAttached(QObject *parent = 0);
~QDeclarativeComponentAttached();
+ void add(QDeclarativeComponentAttached **a) {
+ prev = a; next = *a; *a = this;
+ if (next) next->prev = &next;
+ }
+ void rem() {
+ if (next) next->prev = prev;
+ *prev = next;
+ next = 0; prev = 0;
+ }
QDeclarativeComponentAttached **prev;
QDeclarativeComponentAttached *next;
Q_SIGNALS:
void completed();
+ void destruction();
private:
+ friend class QDeclarativeContextData;;
friend class QDeclarativeComponentPrivate;
};
diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp
index 42e7386..6657fea 100644
--- a/src/declarative/qml/qdeclarativecontext.cpp
+++ b/src/declarative/qml/qdeclarativecontext.cpp
@@ -42,6 +42,7 @@
#include "qdeclarativecontext.h"
#include "private/qdeclarativecontext_p.h"
+#include "private/qdeclarativecomponent_p.h"
#include "private/qdeclarativeexpression_p.h"
#include "private/qdeclarativeengine_p.h"
#include "qdeclarativeengine.h"
@@ -476,21 +477,34 @@ QObject *QDeclarativeContextPrivate::context_at(QDeclarativeListProperty<QObject
QDeclarativeContextData::QDeclarativeContextData()
: parent(0), engine(0), isInternal(false), publicContext(0), propertyNames(0), contextObject(0),
imports(0), childContexts(0), nextChild(0), prevChild(0), expressions(0), contextObjects(0),
- contextGuards(0), idValues(0), idValueCount(0), optimizedBindings(0), linkedContext(0)
+ contextGuards(0), idValues(0), idValueCount(0), optimizedBindings(0), linkedContext(0),
+ componentAttached(0)
{
}
QDeclarativeContextData::QDeclarativeContextData(QDeclarativeContext *ctxt)
: parent(0), engine(0), isInternal(false), publicContext(ctxt), propertyNames(0), contextObject(0),
imports(0), childContexts(0), nextChild(0), prevChild(0), expressions(0), contextObjects(0),
- contextGuards(0), idValues(0), idValueCount(0), optimizedBindings(0), linkedContext(0)
+ contextGuards(0), idValues(0), idValueCount(0), optimizedBindings(0), linkedContext(0),
+ componentAttached(0)
{
}
-void QDeclarativeContextData::destroy()
+void QDeclarativeContextData::invalidate()
{
- if (linkedContext)
- linkedContext->destroy();
+ while (childContexts)
+ childContexts->invalidate();
+
+ while (componentAttached) {
+ QDeclarativeComponentAttached *a = componentAttached;
+ componentAttached = a->next;
+ if (componentAttached) componentAttached->prev = &componentAttached;
+
+ a->next = 0;
+ a->prev = 0;
+
+ emit a->destruction();
+ }
if (prevChild) {
*prevChild = nextChild;
@@ -498,19 +512,17 @@ void QDeclarativeContextData::destroy()
nextChild = 0;
prevChild = 0;
}
-
- QDeclarativeContextData *child = childContexts;
- while (child) {
- QDeclarativeContextData *next = child->nextChild;
- child->invalidateEngines();
- child->parent = 0;
- child->nextChild = 0;
- child->prevChild = 0;
+ engine = 0;
+ parent = 0;
+}
- child = next;
- }
- childContexts = 0;
+void QDeclarativeContextData::destroy()
+{
+ if (linkedContext)
+ linkedContext->destroy();
+
+ if (engine) invalidate();
QDeclarativeAbstractExpression *expression = expressions;
while (expression) {
@@ -573,19 +585,6 @@ void QDeclarativeContextData::setParent(QDeclarativeContextData *p)
}
}
-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
diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h
index 5d26e7e..77a6d94 100644
--- a/src/declarative/qml/qdeclarativecontext_p.h
+++ b/src/declarative/qml/qdeclarativecontext_p.h
@@ -106,6 +106,7 @@ public:
static QObject *context_at(QDeclarativeListProperty<QObject> *, int);
};
+class QDeclarativeComponentAttached;
class QDeclarativeGuardedContextData;
class QDeclarativeContextData
{
@@ -113,6 +114,7 @@ public:
QDeclarativeContextData();
QDeclarativeContextData(QDeclarativeContext *);
void destroy();
+ void invalidate();
inline bool isValid() const {
return engine && (!isInternal || !contextObject || !QObjectPrivate::get(contextObject)->wasDeleted);
@@ -123,7 +125,6 @@ public:
QDeclarativeEngine *engine;
void setParent(QDeclarativeContextData *);
- void invalidateEngines();
void refreshExpressions();
void addObject(QObject *);
@@ -194,6 +195,10 @@ public:
// Linked contexts. this owns linkedContext.
QDeclarativeContextData *linkedContext;
+ // Linked list of uses of the Component attached property in this
+ // context
+ QDeclarativeComponentAttached *componentAttached;
+
QString findObjectId(const QObject *obj) const;
static QDeclarativeContextData *get(QDeclarativeContext *context) {
diff --git a/src/declarative/qml/qdeclarativedata_p.h b/src/declarative/qml/qdeclarativedata_p.h
index 3676d8d..2ddd7e5 100644
--- a/src/declarative/qml/qdeclarativedata_p.h
+++ b/src/declarative/qml/qdeclarativedata_p.h
@@ -100,7 +100,9 @@ public:
quint32 explicitIndestructibleSet:1;
quint32 dummy:28;
- QDeclarativeContextData *context;
+ // The context that created the C++ object
+ QDeclarativeContextData *context;
+ // The outermost context in which this object lives
QDeclarativeContextData *outerContext;
QDeclarativeAbstractBinding *bindings;
diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp
index ae0929b..96145fb 100644
--- a/src/declarative/qml/qdeclarativeengine.cpp
+++ b/src/declarative/qml/qdeclarativeengine.cpp
@@ -155,7 +155,7 @@ QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e)
: captureProperties(false), rootContext(0), currentExpression(0), isDebugging(false),
contextClass(0), sharedContext(0), sharedScope(0), objectClass(0), valueTypeClass(0),
globalClass(0), cleanup(0), erroredBindings(0), inProgressCreations(0),
- scriptEngine(this), workerScriptEngine(0), componentAttacheds(0), inBeginCreate(false),
+ scriptEngine(this), workerScriptEngine(0), componentAttached(0), inBeginCreate(false),
networkAccessManager(0), networkAccessManagerFactory(0),
typeManager(e), uniqueId(1)
{
@@ -350,8 +350,13 @@ typedef QMap<QString, QString> StringStringMap;
Q_GLOBAL_STATIC(StringStringMap, qmlEnginePluginsWithRegisteredTypes); // stores the uri
-void QDeclarativePrivate::qdeclarativeelement_destructor(QObject *)
+void QDeclarativePrivate::qdeclarativeelement_destructor(QObject *o)
{
+ QObjectPrivate *p = QObjectPrivate::get(o);
+ Q_ASSERT(p->declarativeData);
+ QDeclarativeData *d = static_cast<QDeclarativeData*>(p->declarativeData);
+ if (d->ownContext)
+ d->context->destroy();
}
void QDeclarativeData::destroyed(QAbstractDeclarativeData *d, QObject *o)
@@ -767,7 +772,7 @@ void qmlExecuteDeferred(QObject *object)
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(data->context->engine);
QDeclarativeComponentPrivate::ConstructionState state;
- QDeclarativeComponentPrivate::beginDeferred(data->context, ep, object, &state);
+ QDeclarativeComponentPrivate::beginDeferred(ep, object, &state);
data->deferredComponent->release();
data->deferredComponent = 0;
@@ -855,7 +860,7 @@ void QDeclarativeData::destroyed(QObject *object)
if (propertyCache)
propertyCache->release();
- if (ownContext)
+ if (ownContext && context)
context->destroy();
QDeclarativeGuard<QObject> *guard = guards;
@@ -1360,7 +1365,9 @@ QScriptValue QDeclarativeEnginePrivate::scriptValueFromVariant(const QVariant &v
rv.setProperty(ii, objectClass->newQObject(object));
}
return rv;
- }
+ } else if (QDeclarativeValueType *vt = valueTypes[val.userType()]) {
+ return valueTypeClass->newObject(val, vt);
+ }
bool objOk;
QObject *obj = QDeclarativeMetaType::toQObject(val, &objOk);
diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h
index 7766ad6..b3bba43 100644
--- a/src/declarative/qml/qdeclarativeengine_p.h
+++ b/src/declarative/qml/qdeclarativeengine_p.h
@@ -215,7 +215,7 @@ public:
QList<SimpleList<QDeclarativeAbstractBinding> > bindValues;
QList<SimpleList<QDeclarativeParserStatus> > parserStatus;
- QDeclarativeComponentAttached *componentAttacheds;
+ QDeclarativeComponentAttached *componentAttached;
bool inBeginCreate;
diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp
index 9cb2416..afd0d84 100644
--- a/src/declarative/qml/qdeclarativeproperty.cpp
+++ b/src/declarative/qml/qdeclarativeproperty.cpp
@@ -286,7 +286,7 @@ void QDeclarativePropertyPrivate::initProperty(QObject *obj, const QString &name
QString signalName = terminal.mid(2);
signalName[0] = signalName.at(0).toLower();
- QMetaMethod method = QDeclarativeCompiler::findSignalByName(currentObject->metaObject(), signalName.toLatin1().constData());
+ QMetaMethod method = findSignalByName(currentObject->metaObject(), signalName.toLatin1().constData());
if (method.signature()) {
object = currentObject;
core.load(method);
@@ -1353,4 +1353,36 @@ bool QDeclarativePropertyPrivate::canConvert(const QMetaObject *from, const QMet
return false;
}
+/*!
+ Return the signal corresponding to \a name
+*/
+QMetaMethod QDeclarativePropertyPrivate::findSignalByName(const QMetaObject *mo, const QByteArray &name)
+{
+ Q_ASSERT(mo);
+ int methods = mo->methodCount();
+ for (int ii = methods - 1; ii >= 2; --ii) { // >= 2 to block the destroyed signal
+ QMetaMethod method = mo->method(ii);
+ QByteArray methodName = method.signature();
+ int idx = methodName.indexOf('(');
+ methodName = methodName.left(idx);
+
+ if (methodName == name)
+ return method;
+ }
+
+ // If no signal is found, but the signal is of the form "onBlahChanged",
+ // return the notify signal for the property "Blah"
+ if (name.endsWith("Changed")) {
+ QByteArray propName = name.mid(0, name.length() - 7);
+ int propIdx = mo->indexOfProperty(propName.constData());
+ if (propIdx >= 0) {
+ QMetaProperty prop = mo->property(propIdx);
+ if (prop.hasNotifySignal())
+ return prop.notifySignal();
+ }
+ }
+
+ return QMetaMethod();
+}
+
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativeproperty_p.h b/src/declarative/qml/qdeclarativeproperty_p.h
index 420a1ba..8522561 100644
--- a/src/declarative/qml/qdeclarativeproperty_p.h
+++ b/src/declarative/qml/qdeclarativeproperty_p.h
@@ -96,8 +96,6 @@ public:
void initProperty(QObject *obj, const QString &name);
void initDefault(QObject *obj);
- QMetaMethod findSignal(QObject *, const QString &);
-
bool isValueType() const;
int propertyType() const;
QDeclarativeProperty::PropertyTypeCategory propertyTypeCategory() const;
@@ -134,6 +132,7 @@ public:
static bool write(const QDeclarativeProperty &that, const QVariant &, WriteFlags);
static int valueTypeCoreIndex(const QDeclarativeProperty &that);
static int bindingIndex(const QDeclarativeProperty &that);
+ static QMetaMethod findSignalByName(const QMetaObject *mo, const QByteArray &);
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativePropertyPrivate::WriteFlags)
diff --git a/src/declarative/qml/qdeclarativepropertycache.cpp b/src/declarative/qml/qdeclarativepropertycache.cpp
index 4b4b142..888945b 100644
--- a/src/declarative/qml/qdeclarativepropertycache.cpp
+++ b/src/declarative/qml/qdeclarativepropertycache.cpp
@@ -147,7 +147,7 @@ QDeclarativePropertyCache::Data QDeclarativePropertyCache::create(const QMetaObj
}
int methodCount = metaObject->methodCount();
- for (int ii = methodCount - 1; ii >= 0; --ii) {
+ for (int ii = methodCount - 1; ii >= 2; --ii) { // >=2 to block the destroyed signal
QMetaMethod m = metaObject->method(ii);
if (m.access() == QMetaMethod::Private)
continue;
@@ -216,7 +216,7 @@ void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaOb
}
int methodCount = metaObject->methodCount();
- int methodOffset = metaObject->methodOffset();
+ int methodOffset = qMax(2, metaObject->methodOffset()); // 2 to block the destroyed signal
for (int ii = methodOffset; ii < methodCount; ++ii) {
QMetaMethod m = metaObject->method(ii);
if (m.access() == QMetaMethod::Private)
@@ -289,7 +289,7 @@ void QDeclarativePropertyCache::update(QDeclarativeEngine *engine, const QMetaOb
}
int methodCount = metaObject->methodCount();
- for (int ii = methodCount - 1; ii >= 0; --ii) {
+ for (int ii = methodCount - 1; ii >= 2; --ii) { // >=2 to block the destroyed signal
QMetaMethod m = metaObject->method(ii);
if (m.access() == QMetaMethod::Private)
continue;
diff --git a/src/declarative/qml/qdeclarativevaluetype.cpp b/src/declarative/qml/qdeclarativevaluetype.cpp
index 261c84a..352a6c0 100644
--- a/src/declarative/qml/qdeclarativevaluetype.cpp
+++ b/src/declarative/qml/qdeclarativevaluetype.cpp
@@ -99,12 +99,6 @@ void QDeclarativeValueTypeFactory::registerValueTypes()
qmlRegisterValueTypeEnums<QDeclarativeFontValueType>("Font");
}
-QDeclarativeValueType *QDeclarativeValueTypeFactory::operator[](int idx) const
-{
- return valueTypes[idx];
-}
-
-
QDeclarativeValueType *QDeclarativeValueTypeFactory::valueType(int t)
{
switch (t) {
diff --git a/src/declarative/qml/qdeclarativevaluetype_p.h b/src/declarative/qml/qdeclarativevaluetype_p.h
index 5bfc27d..d1833bb 100644
--- a/src/declarative/qml/qdeclarativevaluetype_p.h
+++ b/src/declarative/qml/qdeclarativevaluetype_p.h
@@ -86,7 +86,10 @@ public:
static void registerValueTypes();
- QDeclarativeValueType *operator[](int idx) const;
+ QDeclarativeValueType *operator[](int idx) const {
+ if (idx >= (int)QVariant::UserType) return 0;
+ else return valueTypes[idx];
+ }
private:
QDeclarativeValueType *valueTypes[QVariant::UserType - 1];
diff --git a/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp b/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp
index fdb71c6..cb1f27d 100644
--- a/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp
+++ b/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp
@@ -48,12 +48,24 @@
QT_BEGIN_NAMESPACE
-struct QDeclarativeValueTypeReference : public QScriptDeclarativeClass::Object {
+struct QDeclarativeValueTypeObject : public QScriptDeclarativeClass::Object {
+ enum Type { Reference, Copy };
+ QDeclarativeValueTypeObject(Type t) : objectType(t) {}
+ Type objectType;
QDeclarativeValueType *type;
+};
+
+struct QDeclarativeValueTypeReference : public QDeclarativeValueTypeObject {
+ QDeclarativeValueTypeReference() : QDeclarativeValueTypeObject(Reference) {}
QDeclarativeGuard<QObject> object;
int property;
};
+struct QDeclarativeValueTypeCopy : public QDeclarativeValueTypeObject {
+ QDeclarativeValueTypeCopy() : QDeclarativeValueTypeObject(Copy) {}
+ QVariant value;
+};
+
QDeclarativeValueTypeScriptClass::QDeclarativeValueTypeScriptClass(QDeclarativeEngine *bindEngine)
: QScriptDeclarativeClass(QDeclarativeEnginePrivate::getScriptEngine(bindEngine)), engine(bindEngine)
{
@@ -73,40 +85,67 @@ QScriptValue QDeclarativeValueTypeScriptClass::newObject(QObject *object, int co
return QScriptDeclarativeClass::newObject(scriptEngine, this, ref);
}
+QScriptValue QDeclarativeValueTypeScriptClass::newObject(const QVariant &v, QDeclarativeValueType *type)
+{
+ QDeclarativeValueTypeCopy *copy = new QDeclarativeValueTypeCopy;
+ copy->type = type;
+ copy->value = v;
+ QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
+ return QScriptDeclarativeClass::newObject(scriptEngine, this, copy);
+}
+
QScriptClass::QueryFlags
QDeclarativeValueTypeScriptClass::queryProperty(Object *obj, const Identifier &name,
- QScriptClass::QueryFlags)
+ QScriptClass::QueryFlags)
{
- QDeclarativeValueTypeReference *ref = static_cast<QDeclarativeValueTypeReference *>(obj);
+ QDeclarativeValueTypeObject *o = static_cast<QDeclarativeValueTypeObject *>(obj);
m_lastIndex = -1;
- if (!ref->object)
- return 0;
-
QByteArray propName = toString(name).toUtf8();
- m_lastIndex = ref->type->metaObject()->indexOfProperty(propName.constData());
+ m_lastIndex = o->type->metaObject()->indexOfProperty(propName.constData());
if (m_lastIndex == -1)
return 0;
- QMetaProperty prop = ref->object->metaObject()->property(m_lastIndex);
+ QScriptClass::QueryFlags rv = 0;
+
+ if (o->objectType == QDeclarativeValueTypeObject::Reference) {
+ QDeclarativeValueTypeReference *ref = static_cast<QDeclarativeValueTypeReference *>(o);
+
+ if (!ref->object)
+ return 0;
- QScriptClass::QueryFlags rv =
- QScriptClass::HandlesReadAccess;
- if (prop.isWritable())
- rv |= QScriptClass::HandlesWriteAccess;
+ QMetaProperty prop = ref->object->metaObject()->property(m_lastIndex);
+
+ rv = QScriptClass::HandlesReadAccess;
+ if (prop.isWritable())
+ rv |= QScriptClass::HandlesWriteAccess;
+ } else {
+ rv = QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess;
+ }
return rv;
}
QDeclarativeValueTypeScriptClass::Value QDeclarativeValueTypeScriptClass::property(Object *obj, const Identifier &)
{
- QDeclarativeValueTypeReference *ref = static_cast<QDeclarativeValueTypeReference *>(obj);
+ QDeclarativeValueTypeObject *o = static_cast<QDeclarativeValueTypeObject *>(obj);
- QMetaProperty p = ref->type->metaObject()->property(m_lastIndex);
- ref->type->read(ref->object, ref->property);
- QVariant rv = p.read(ref->type);
+ QVariant rv;
+ if (o->objectType == QDeclarativeValueTypeObject::Reference) {
+ QDeclarativeValueTypeReference *ref = static_cast<QDeclarativeValueTypeReference *>(obj);
+
+ QMetaProperty p = ref->type->metaObject()->property(m_lastIndex);
+ ref->type->read(ref->object, ref->property);
+ rv = p.read(ref->type);
+ } else {
+ QDeclarativeValueTypeCopy *copy = static_cast<QDeclarativeValueTypeCopy *>(obj);
+
+ QMetaProperty p = copy->type->metaObject()->property(m_lastIndex);
+ copy->type->setValue(copy->value);
+ rv = p.read(copy->type);
+ }
QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
return Value(scriptEngine, static_cast<QDeclarativeEnginePrivate *>(QObjectPrivate::get(engine))->scriptValueFromVariant(rv));
@@ -115,33 +154,53 @@ QDeclarativeValueTypeScriptClass::Value QDeclarativeValueTypeScriptClass::proper
void QDeclarativeValueTypeScriptClass::setProperty(Object *obj, const Identifier &,
const QScriptValue &value)
{
- QDeclarativeValueTypeReference *ref = static_cast<QDeclarativeValueTypeReference *>(obj);
-
- QDeclarativeAbstractBinding *delBinding =
- QDeclarativePropertyPrivate::setBinding(ref->object, ref->property, m_lastIndex, 0);
- if (delBinding)
- delBinding->destroy();
+ QDeclarativeValueTypeObject *o = static_cast<QDeclarativeValueTypeObject *>(obj);
QVariant v = QDeclarativeEnginePrivate::get(engine)->scriptValueToVariant(value);
- ref->type->read(ref->object, ref->property);
- QMetaProperty p = ref->type->metaObject()->property(m_lastIndex);
- p.write(ref->type, v);
- ref->type->write(ref->object, ref->property, 0);
+ if (o->objectType == QDeclarativeValueTypeObject::Reference) {
+ QDeclarativeValueTypeReference *ref = static_cast<QDeclarativeValueTypeReference *>(obj);
+
+ QDeclarativeAbstractBinding *delBinding =
+ QDeclarativePropertyPrivate::setBinding(ref->object, ref->property, m_lastIndex, 0);
+ if (delBinding)
+ delBinding->destroy();
+
+ ref->type->read(ref->object, ref->property);
+ QMetaProperty p = ref->type->metaObject()->property(m_lastIndex);
+ 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);
+ QMetaProperty p = copy->type->metaObject()->property(m_lastIndex);
+ p.write(copy->type, v);
+ copy->value = copy->type->value();
+ }
}
QVariant QDeclarativeValueTypeScriptClass::toVariant(Object *obj, bool *ok)
{
- QDeclarativeValueTypeReference *ref = static_cast<QDeclarativeValueTypeReference *>(obj);
+ QDeclarativeValueTypeObject *o = static_cast<QDeclarativeValueTypeObject *>(obj);
- if (ok) *ok = true;
+ if (o->objectType == QDeclarativeValueTypeObject::Reference) {
+ QDeclarativeValueTypeReference *ref = static_cast<QDeclarativeValueTypeReference *>(obj);
- if (ref->object) {
- ref->type->read(ref->object, ref->property);
- return ref->type->value();
+ if (ok) *ok = true;
+
+ if (ref->object) {
+ ref->type->read(ref->object, ref->property);
+ return ref->type->value();
+ }
} else {
- return QVariant();
+ QDeclarativeValueTypeCopy *copy = static_cast<QDeclarativeValueTypeCopy *>(obj);
+
+ if (ok) *ok = true;
+
+ return copy->value;
}
+
+ return QVariant();
}
QVariant QDeclarativeValueTypeScriptClass::toVariant(const QScriptValue &value)
diff --git a/src/declarative/qml/qdeclarativevaluetypescriptclass_p.h b/src/declarative/qml/qdeclarativevaluetypescriptclass_p.h
index 2bbb61f..9dafa99 100644
--- a/src/declarative/qml/qdeclarativevaluetypescriptclass_p.h
+++ b/src/declarative/qml/qdeclarativevaluetypescriptclass_p.h
@@ -67,6 +67,7 @@ public:
~QDeclarativeValueTypeScriptClass();
QScriptValue newObject(QObject *object, int coreIndex, QDeclarativeValueType *);
+ QScriptValue newObject(const QVariant &, QDeclarativeValueType *);
virtual QScriptClass::QueryFlags queryProperty(Object *, const Identifier &,
QScriptClass::QueryFlags flags);