From 114adc64fe8deb7d59e608924355f64810f8fe64 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Fri, 2 Oct 2009 19:31:12 +1000 Subject: Fix attached properties/enums from ecmascript --- src/declarative/qml/qmlcontextscriptclass.cpp | 3 +- src/declarative/qml/qmlobjectscriptclass.cpp | 30 +++++++++++++++++-- src/declarative/qml/qmlobjectscriptclass_p.h | 7 ++++- src/declarative/qml/qmltypenamescriptclass.cpp | 41 ++++++++++++++------------ src/declarative/qml/qmltypenamescriptclass_p.h | 5 ++-- 5 files changed, 61 insertions(+), 25 deletions(-) diff --git a/src/declarative/qml/qmlcontextscriptclass.cpp b/src/declarative/qml/qmlcontextscriptclass.cpp index 4b149f7..8f45870 100644 --- a/src/declarative/qml/qmlcontextscriptclass.cpp +++ b/src/declarative/qml/qmlcontextscriptclass.cpp @@ -104,7 +104,8 @@ QmlContextScriptClass::queryProperty(Object *object, const Identifier &name, for (int ii = 0; ii < cp->defaultObjects.count(); ++ii) { QScriptClass::QueryFlags rv = - ep->objectClass->queryProperty(cp->defaultObjects.at(ii), name, flags); + ep->objectClass->queryProperty(cp->defaultObjects.at(ii), name, flags, + QmlObjectScriptClass::SkipAttachedProperties); if (rv) { lastDefaultObject = ii; diff --git a/src/declarative/qml/qmlobjectscriptclass.cpp b/src/declarative/qml/qmlobjectscriptclass.cpp index 33fd409..7c7b13f 100644 --- a/src/declarative/qml/qmlobjectscriptclass.cpp +++ b/src/declarative/qml/qmlobjectscriptclass.cpp @@ -42,7 +42,9 @@ #include "qmlobjectscriptclass_p.h" #include #include +#include #include +#include QT_BEGIN_NAMESPACE @@ -94,10 +96,11 @@ QmlObjectScriptClass::queryProperty(Object *object, const Identifier &name, QScriptClass::QueryFlags QmlObjectScriptClass::queryProperty(QObject *obj, const Identifier &name, - QScriptClass::QueryFlags flags) + QScriptClass::QueryFlags flags, QueryMode mode) { Q_UNUSED(flags); lastData = 0; + lastTNData = 0; if (name == m_destroyId.identifier || name == m_toStringId.identifier) @@ -107,6 +110,22 @@ QmlObjectScriptClass::queryProperty(QObject *obj, const Identifier &name, return 0; QmlEnginePrivate *enginePrivate = QmlEnginePrivate::get(engine); + + if (mode == IncludeAttachedProperties) { + QmlContext *evalContext = enginePrivate->currentExpression->context(); + QmlContextPrivate *cp = QmlContextPrivate::get(evalContext); + // ### Check for attached properties + + if (cp->imports) { + QmlTypeNameCache::Data *data = cp->imports->data(name); + if (data) { + lastTNData = data; + return QScriptClass::HandlesReadAccess; + } + } + + } + QmlPropertyCache *cache = 0; QmlDeclarativeData *ddata = QmlDeclarativeData::get(obj); if (ddata) @@ -150,7 +169,14 @@ QScriptValue QmlObjectScriptClass::property(QObject *obj, const Identifier &name QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine); QmlEnginePrivate *enginePriv = QmlEnginePrivate::get(engine); - if (lastData->flags & QmlPropertyCache::Data::IsFunction) { + if (lastTNData) { + + if (lastTNData->type) + return enginePriv->typeNameClass->newObject(obj, lastTNData->type); + else + return enginePriv->typeNameClass->newObject(obj, lastTNData->typeNamespace); + + } else if (lastData->flags & QmlPropertyCache::Data::IsFunction) { // ### Optimize QScriptValue sobj = scriptEngine->newQObject(obj); return sobj.property(toString(name)); diff --git a/src/declarative/qml/qmlobjectscriptclass_p.h b/src/declarative/qml/qmlobjectscriptclass_p.h index 6406f0d..6de63ca 100644 --- a/src/declarative/qml/qmlobjectscriptclass_p.h +++ b/src/declarative/qml/qmlobjectscriptclass_p.h @@ -56,6 +56,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -71,8 +72,11 @@ public: QScriptValue newQObject(QObject *); QObject *toQObject(const QScriptValue &) const; + enum QueryMode { IncludeAttachedProperties, SkipAttachedProperties }; + QScriptClass::QueryFlags queryProperty(QObject *, const Identifier &, - QScriptClass::QueryFlags flags); + QScriptClass::QueryFlags flags, + QueryMode = IncludeAttachedProperties); QScriptValue property(QObject *, const Identifier &); void setProperty(QObject *, const Identifier &name, const QScriptValue &); @@ -85,6 +89,7 @@ protected: virtual QObject *toQObject(Object *, bool *ok = 0); private: + QmlTypeNameCache::Data *lastTNData; QmlPropertyCache::Data *lastData; QmlPropertyCache::Data local; diff --git a/src/declarative/qml/qmltypenamescriptclass.cpp b/src/declarative/qml/qmltypenamescriptclass.cpp index 61b57c4..4e1ac4b 100644 --- a/src/declarative/qml/qmltypenamescriptclass.cpp +++ b/src/declarative/qml/qmltypenamescriptclass.cpp @@ -46,8 +46,8 @@ QT_BEGIN_NAMESPACE struct TypeNameData : public QScriptDeclarativeClass::Object { - TypeNameData(QObject *o, QmlType *t) : object(o), type(t), typeNamespace(0) {} - TypeNameData(QObject *o, QmlTypeNameCache *n) : object(o), type(0), typeNamespace(n) { + TypeNameData(QObject *o, QmlType *t, QmlTypeNameScriptClass::TypeNameMode m) : object(o), type(t), typeNamespace(0), mode(m) {} + TypeNameData(QObject *o, QmlTypeNameCache *n, QmlTypeNameScriptClass::TypeNameMode m) : object(o), type(0), typeNamespace(n), mode(m) { if (typeNamespace) typeNamespace->addref(); } ~TypeNameData() { @@ -57,6 +57,7 @@ struct TypeNameData : public QScriptDeclarativeClass::Object { QObject *object; QmlType *type; QmlTypeNameCache *typeNamespace; + QmlTypeNameScriptClass::TypeNameMode mode; }; QmlTypeNameScriptClass::QmlTypeNameScriptClass(QmlEngine *bindEngine) @@ -69,21 +70,20 @@ QmlTypeNameScriptClass::~QmlTypeNameScriptClass() { } -QScriptValue QmlTypeNameScriptClass::newObject(QObject *object, QmlType *type) +QScriptValue QmlTypeNameScriptClass::newObject(QObject *object, QmlType *type, TypeNameMode mode) { QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine); - return QScriptDeclarativeClass::newObject(scriptEngine, this, new TypeNameData(object, type)); + return QScriptDeclarativeClass::newObject(scriptEngine, this, new TypeNameData(object, type, mode)); } -QScriptValue QmlTypeNameScriptClass::newObject(QObject *object, QmlTypeNameCache *ns) +QScriptValue QmlTypeNameScriptClass::newObject(QObject *object, QmlTypeNameCache *ns, TypeNameMode mode) { QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine); - return QScriptDeclarativeClass::newObject(scriptEngine, this, new TypeNameData(object, ns)); + return QScriptDeclarativeClass::newObject(scriptEngine, this, new TypeNameData(object, ns, mode)); } - QScriptClass::QueryFlags QmlTypeNameScriptClass::queryProperty(Object *obj, const Identifier &name, QScriptClass::QueryFlags flags) @@ -113,15 +113,17 @@ QmlTypeNameScriptClass::queryProperty(Object *obj, const Identifier &name, if (strName.at(0).isUpper()) { // Must be an enum - // ### Optimize - const char *enumName = strName.toUtf8().constData(); - const QMetaObject *metaObject = data->type->baseMetaObject(); - for (int ii = metaObject->enumeratorCount() - 1; ii >= 0; --ii) { - QMetaEnum e = metaObject->enumerator(ii); - int value = e.keyToValue(enumName); - if (value != -1) { - enumValue = value; - return QScriptClass::HandlesReadAccess; + if (data->mode == IncludeEnums) { + // ### Optimize + const char *enumName = strName.toUtf8().constData(); + const QMetaObject *metaObject = data->type->baseMetaObject(); + for (int ii = metaObject->enumeratorCount() - 1; ii >= 0; --ii) { + QMetaEnum e = metaObject->enumerator(ii); + int value = e.keyToValue(enumName); + if (value != -1) { + enumValue = value; + return QScriptClass::HandlesReadAccess; + } } } return 0; @@ -129,7 +131,8 @@ QmlTypeNameScriptClass::queryProperty(Object *obj, const Identifier &name, // Must be an attached property object = qmlAttachedPropertiesObjectById(data->type->index(), data->object); if (!object) return 0; - return ep->objectClass->queryProperty(object, name, flags); + return ep->objectClass->queryProperty(object, name, flags, + QmlObjectScriptClass::SkipAttachedProperties); } } @@ -140,9 +143,9 @@ QScriptValue QmlTypeNameScriptClass::property(Object *obj, const Identifier &nam { QmlEnginePrivate *ep = QmlEnginePrivate::get(engine); if (type) { - return newObject(object, type); + return newObject(((TypeNameData *)obj)->object, type, ((TypeNameData *)obj)->mode); } else if (object) { - return ep->objectClass->property(((TypeNameData *)obj)->object, name); + return ep->objectClass->property(object, name); } else { return QScriptValue(enumValue); } diff --git a/src/declarative/qml/qmltypenamescriptclass_p.h b/src/declarative/qml/qmltypenamescriptclass_p.h index 3bd51e6..d8112d2 100644 --- a/src/declarative/qml/qmltypenamescriptclass_p.h +++ b/src/declarative/qml/qmltypenamescriptclass_p.h @@ -67,8 +67,9 @@ public: QmlTypeNameScriptClass(QmlEngine *); ~QmlTypeNameScriptClass(); - QScriptValue newObject(QObject *, QmlType *); - QScriptValue newObject(QObject *, QmlTypeNameCache *); + enum TypeNameMode { IncludeEnums, ExcludeEnums }; + QScriptValue newObject(QObject *, QmlType *, TypeNameMode = IncludeEnums); + QScriptValue newObject(QObject *, QmlTypeNameCache *, TypeNameMode = IncludeEnums); protected: virtual QScriptClass::QueryFlags queryProperty(Object *, const Identifier &, -- cgit v0.12