diff options
Diffstat (limited to 'src/declarative/qml')
-rw-r--r-- | src/declarative/qml/qdeclarativecompiler.cpp | 37 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativecompiler_p.h | 6 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativecomponent.cpp | 67 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativecomponent_p.h | 19 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativecontext.cpp | 57 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativecontext_p.h | 7 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativedata_p.h | 4 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeengine.cpp | 17 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeengine_p.h | 2 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeproperty.cpp | 34 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeproperty_p.h | 3 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativepropertycache.cpp | 6 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativevaluetype.cpp | 6 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativevaluetype_p.h | 5 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativevaluetypescriptclass.cpp | 123 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativevaluetypescriptclass_p.h | 1 |
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); |