diff options
-rw-r--r-- | src/declarative/qml/qdeclarativeboundsignal.cpp | 4 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativecompiler.cpp | 6 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativenotifier.cpp | 16 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativenotifier_p.h | 17 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeproperty.cpp | 56 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeproperty_p.h | 3 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativepropertycache.cpp | 19 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativepropertycache_p.h | 9 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeproxymetaobject.cpp | 4 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativevme.cpp | 2 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativevmemetaobject.cpp | 48 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativevmemetaobject_p.h | 2 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativewatcher.cpp | 3 | ||||
-rw-r--r-- | tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp | 1 |
14 files changed, 147 insertions, 43 deletions
diff --git a/src/declarative/qml/qdeclarativeboundsignal.cpp b/src/declarative/qml/qdeclarativeboundsignal.cpp index 8769122..6af3e05 100644 --- a/src/declarative/qml/qdeclarativeboundsignal.cpp +++ b/src/declarative/qml/qdeclarativeboundsignal.cpp @@ -103,7 +103,7 @@ QDeclarativeBoundSignal::QDeclarativeBoundSignal(QObject *scope, const QMetaMeth if (evaluateIdx == -1) evaluateIdx = metaObject()->methodCount(); QDeclarative_setParent_noEvent(this, parent); - QMetaObject::connect(scope, m_signal.methodIndex(), this, evaluateIdx); + QDeclarativePropertyPrivate::connect(scope, m_signal.methodIndex(), this, evaluateIdx); } QDeclarativeBoundSignal::QDeclarativeBoundSignal(QDeclarativeContext *ctxt, const QString &val, @@ -117,7 +117,7 @@ QDeclarativeBoundSignal::QDeclarativeBoundSignal(QDeclarativeContext *ctxt, cons if (evaluateIdx == -1) evaluateIdx = metaObject()->methodCount(); QDeclarative_setParent_noEvent(this, parent); - QMetaObject::connect(scope, m_signal.methodIndex(), this, evaluateIdx); + QDeclarativePropertyPrivate::connect(scope, m_signal.methodIndex(), this, evaluateIdx); m_expression = new QDeclarativeExpression(ctxt, scope, val); } diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index 90d38b3..dc28e22 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -945,7 +945,8 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj) propertyCache = enginePrivate->cache(obj->metaObject()->superClass())->copy(); propertyCache->append(engine, obj->metaObject(), QDeclarativePropertyCache::Data::NoFlags, - QDeclarativePropertyCache::Data::IsVMEFunction); + QDeclarativePropertyCache::Data::IsVMEFunction, + QDeclarativePropertyCache::Data::IsVMESignal); if (obj == unitRoot) { propertyCache->addref(); @@ -1098,7 +1099,8 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj) QDeclarativePropertyCache *propertyCache = enginePrivate->cache(prop->value->metaObject()->superClass())->copy(); propertyCache->append(engine, prop->value->metaObject(), QDeclarativePropertyCache::Data::NoFlags, - QDeclarativePropertyCache::Data::IsVMEFunction); + QDeclarativePropertyCache::Data::IsVMEFunction, + QDeclarativePropertyCache::Data::IsVMESignal); output->propertyCaches << propertyCache; output->bytecode << meta; diff --git a/src/declarative/qml/qdeclarativenotifier.cpp b/src/declarative/qml/qdeclarativenotifier.cpp index 8c946f8..2e3f756 100644 --- a/src/declarative/qml/qdeclarativenotifier.cpp +++ b/src/declarative/qml/qdeclarativenotifier.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "private/qdeclarativenotifier_p.h" +#include "private/qdeclarativeproperty_p.h" QT_BEGIN_NAMESPACE @@ -66,6 +67,21 @@ void QDeclarativeNotifier::emitNotify(QDeclarativeNotifierEndpoint *endpoint) if (oldDisconnected) *oldDisconnected = endpoint; } +void QDeclarativeNotifierEndpoint::connect(QObject *source, int sourceSignal) +{ + Signal *s = toSignal(); + + if (s->source == source && s->sourceSignal == sourceSignal) + return; + + disconnect(); + + QDeclarativePropertyPrivate::connect(source, sourceSignal, target, targetMethod); + + s->source = source; + s->sourceSignal = sourceSignal; +} + void QDeclarativeNotifierEndpoint::copyAndClear(QDeclarativeNotifierEndpoint &other) { other.disconnect(); diff --git a/src/declarative/qml/qdeclarativenotifier_p.h b/src/declarative/qml/qdeclarativenotifier_p.h index 0781caf..ad04ba8 100644 --- a/src/declarative/qml/qdeclarativenotifier_p.h +++ b/src/declarative/qml/qdeclarativenotifier_p.h @@ -75,7 +75,7 @@ public: inline bool isConnected(QObject *source, int sourceSignal); inline bool isConnected(QDeclarativeNotifier *); - inline void connect(QObject *source, int sourceSignal); + void connect(QObject *source, int sourceSignal); inline void connect(QDeclarativeNotifier *); inline void disconnect(); @@ -175,21 +175,6 @@ bool QDeclarativeNotifierEndpoint::isConnected(QDeclarativeNotifier *notifier) return NotifierType == type && asNotifier()->notifier == notifier; } -void QDeclarativeNotifierEndpoint::connect(QObject *source, int sourceSignal) -{ - Signal *s = toSignal(); - - if (s->source == source && s->sourceSignal == sourceSignal) - return; - - disconnect(); - - QMetaObject::connect(source, sourceSignal, target, targetMethod); - - s->source = source; - s->sourceSignal = sourceSignal; -} - void QDeclarativeNotifierEndpoint::connect(QDeclarativeNotifier *notifier) { Notifier *n = toNotifier(); diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp index bc20bff..b5fb619 100644 --- a/src/declarative/qml/qdeclarativeproperty.cpp +++ b/src/declarative/qml/qdeclarativeproperty.cpp @@ -53,6 +53,7 @@ #include "private/qdeclarativestringconverters_p.h" #include "private/qdeclarativelist_p.h" #include "private/qdeclarativecompiler_p.h" +#include "private/qdeclarativevmemetaobject_p.h" #include <QStringList> #include <QtCore/qdebug.h> @@ -1212,7 +1213,7 @@ bool QDeclarativeProperty::connectNotifySignal(QObject *dest, int method) const QMetaProperty prop = d->object->metaObject()->property(d->core.coreIndex); if (prop.hasNotifySignal()) { - return QMetaObject::connect(d->object, prop.notifySignalIndex(), dest, method, Qt::DirectConnection); + return QDeclarativePropertyPrivate::connect(d->object, prop.notifySignalIndex(), dest, method, Qt::DirectConnection); } else { return false; } @@ -1383,4 +1384,57 @@ QMetaMethod QDeclarativePropertyPrivate::findSignalByName(const QMetaObject *mo, return QMetaMethod(); } +static inline int QMetaObject_methods(const QMetaObject *metaObject) +{ + struct Private + { + int revision; + int className; + int classInfoCount, classInfoData; + int methodCount, methodData; + }; + + return reinterpret_cast<const Private *>(metaObject->d.data)->methodCount; +} + +static inline void flush_vme_signal(const QObject *object, int index) +{ + QDeclarativeData *data = static_cast<QDeclarativeData *>(QObjectPrivate::get(const_cast<QObject *>(object))->declarativeData); + if (data && data->propertyCache) { + QDeclarativePropertyCache::Data *property = data->propertyCache->method(index); + + if (property && property->flags & QDeclarativePropertyCache::Data::IsVMESignal) { + const QMetaObject *metaObject = object->metaObject(); + int methodOffset = metaObject->methodOffset(); + + while (methodOffset > index) { + methodOffset -= QMetaObject_methods(metaObject); + metaObject = metaObject->d.superdata; + } + + QDeclarativeVMEMetaObject *vme = + static_cast<QDeclarativeVMEMetaObject *>(const_cast<QMetaObject *>(metaObject)); + + vme->connectAliasSignal(index); + } + } +} + +/*! +Connect \a sender \a signal_index to \a receiver \a method_index with the specified +\a type and \a types. This behaves identically to QMetaObject::connect() except that +it connects any lazy "proxy" signal connections set up by QML. + +It is possible that this logic should be moved to QMetaObject::connect(). +*/ +bool QDeclarativePropertyPrivate::connect(const QObject *sender, int signal_index, + const QObject *receiver, int method_index, + int type, int *types) +{ + flush_vme_signal(sender, signal_index); + flush_vme_signal(receiver, method_index); + + return QMetaObject::connect(sender, signal_index, receiver, method_index, type, types); +} + QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativeproperty_p.h b/src/declarative/qml/qdeclarativeproperty_p.h index 8522561..a8438c8 100644 --- a/src/declarative/qml/qdeclarativeproperty_p.h +++ b/src/declarative/qml/qdeclarativeproperty_p.h @@ -133,6 +133,9 @@ public: static int valueTypeCoreIndex(const QDeclarativeProperty &that); static int bindingIndex(const QDeclarativeProperty &that); static QMetaMethod findSignalByName(const QMetaObject *mo, const QByteArray &); + static bool connect(const QObject *sender, int signal_index, + const QObject *receiver, int method_index, + int type = 0, int *types = 0); }; Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativePropertyPrivate::WriteFlags) diff --git a/src/declarative/qml/qdeclarativepropertycache.cpp b/src/declarative/qml/qdeclarativepropertycache.cpp index 08503c2..9e1ceb8 100644 --- a/src/declarative/qml/qdeclarativepropertycache.cpp +++ b/src/declarative/qml/qdeclarativepropertycache.cpp @@ -94,6 +94,8 @@ void QDeclarativePropertyCache::Data::load(const QMetaMethod &m) { coreIndex = m.methodIndex(); flags |= Data::IsFunction; + if (m.methodType() == QMetaMethod::Signal) + flags |= Data::IsSignal; propType = QVariant::Invalid; const char *returnType = m.typeName(); @@ -215,7 +217,7 @@ QDeclarativePropertyCache *QDeclarativePropertyCache::copy() const } void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaObject *metaObject, - Data::Flag propertyFlags, Data::Flag methodFlags) + Data::Flag propertyFlags, Data::Flag methodFlags, Data::Flag signalFlags) { QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine); @@ -251,6 +253,8 @@ void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaOb int methodCount = metaObject->methodCount(); int methodOffset = qMax(2, metaObject->methodOffset()); // 2 to block the destroyed signal + + methodIndexCache.resize(methodCount); for (int ii = methodOffset; ii < methodCount; ++ii) { QMetaMethod m = metaObject->method(ii); if (m.access() == QMetaMethod::Private) @@ -272,6 +276,10 @@ void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaOb data->load(m); if (m.methodType() == QMetaMethod::Slot || m.methodType() == QMetaMethod::Method) data->flags |= methodFlags; + else if (m.methodType() == QMetaMethod::Signal) + data->flags |= signalFlags; + + methodIndexCache[ii] = data; stringCache.insert(methodName, data); identifierCache.insert(data->identifier.identifier, data); @@ -350,6 +358,15 @@ QDeclarativePropertyCache::property(int index) const } QDeclarativePropertyCache::Data * +QDeclarativePropertyCache::method(int index) const +{ + if (index < 0 || index >= methodIndexCache.count()) + return 0; + + return methodIndexCache.at(index); +} + +QDeclarativePropertyCache::Data * QDeclarativePropertyCache::property(const QString &str) const { return stringCache.value(str); diff --git a/src/declarative/qml/qdeclarativepropertycache_p.h b/src/declarative/qml/qdeclarativepropertycache_p.h index 72cfeba..79b126d 100644 --- a/src/declarative/qml/qdeclarativepropertycache_p.h +++ b/src/declarative/qml/qdeclarativepropertycache_p.h @@ -94,8 +94,9 @@ public: // Apply only to IsFunctions IsVMEFunction = 0x00000400, - HasArguments = 0x00000800 - + HasArguments = 0x00000800, + IsSignal = 0x00001000, + IsVMESignal = 0x00002000, }; Q_DECLARE_FLAGS(Flags, Flag) @@ -125,7 +126,7 @@ public: QDeclarativePropertyCache *copy() const; void append(QDeclarativeEngine *, const QMetaObject *, Data::Flag propertyFlags = Data::NoFlags, - Data::Flag methodFlags = Data::NoFlags); + Data::Flag methodFlags = Data::NoFlags, Data::Flag signalFlags = Data::NoFlags); static QDeclarativePropertyCache *create(QDeclarativeEngine *, const QMetaObject *); static Data create(const QMetaObject *, const QString &); @@ -133,6 +134,7 @@ public: inline Data *property(const QScriptDeclarativeClass::Identifier &id) const; Data *property(const QString &) const; Data *property(int) const; + Data *method(int) const; QStringList propertyNames() const; inline QDeclarativeEngine *qmlEngine() const; @@ -152,6 +154,7 @@ private: QDeclarativeEngine *engine; IndexCache indexCache; + IndexCache methodIndexCache; StringCache stringCache; IdentifierCache identifierCache; }; diff --git a/src/declarative/qml/qdeclarativeproxymetaobject.cpp b/src/declarative/qml/qdeclarativeproxymetaobject.cpp index c2dce0a..ceb6977 100644 --- a/src/declarative/qml/qdeclarativeproxymetaobject.cpp +++ b/src/declarative/qml/qdeclarativeproxymetaobject.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "private/qdeclarativeproxymetaobject_p.h" +#include "private/qdeclarativeproperty_p.h" QT_BEGIN_NAMESPACE @@ -95,8 +96,7 @@ int QDeclarativeProxyMetaObject::metaCall(QMetaObject::Call c, int id, void **a) QMetaMethod method = metaObject->method(jj + methodOffset); if (method.methodType() == QMetaMethod::Signal) - QMetaObject::connect(proxy, methodOffset + jj, - object, localOffset + jj); + QDeclarativePropertyPrivate::connect(proxy, methodOffset + jj, object, localOffset + jj); } } diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp index 4e41c22..360186c 100644 --- a/src/declarative/qml/qdeclarativevme.cpp +++ b/src/declarative/qml/qdeclarativevme.cpp @@ -608,7 +608,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, if (!QMetaObject::checkConnectArgs(prop.method().signature(), method.signature())) VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot connect mismatched signal/slot %1 %vs. %2").arg(QString::fromLatin1(method.signature())).arg(QString::fromLatin1(prop.method().signature()))); - QMetaObject::connect(target, prop.index(), assign, method.methodIndex()); + QDeclarativePropertyPrivate::connect(target, prop.index(), assign, method.methodIndex()); } else { VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign an object to signal property %1").arg(QString::fromUtf8(pr))); diff --git a/src/declarative/qml/qdeclarativevmemetaobject.cpp b/src/declarative/qml/qdeclarativevmemetaobject.cpp index 3e32006..37f08fc 100644 --- a/src/declarative/qml/qdeclarativevmemetaobject.cpp +++ b/src/declarative/qml/qdeclarativevmemetaobject.cpp @@ -584,19 +584,7 @@ int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) if (!target) return -1; - if (c == QMetaObject::ReadProperty && !aConnected.testBit(id)) { - int sigIdx = methodOffset + id + metaData->propertyCount; - QMetaObject::connect(context, d->contextIdx + ctxtPriv->notifyIndex, object, sigIdx); - - if (d->propertyIdx != -1) { - QMetaProperty prop = - target->metaObject()->property(d->propertyIdx); - if (prop.hasNotifySignal()) - QMetaObject::connect(target, prop.notifySignalIndex(), - object, sigIdx); - } - aConnected.setBit(id); - } + connectAlias(id); if (d->propertyIdx == -1) { *reinterpret_cast<QObject **>(a[0]) = target; @@ -818,4 +806,38 @@ void QDeclarativeVMEMetaObject::setVMEProperty(int index, const QScriptValue &v) return writeVarProperty(index - propOffset, v); } +void QDeclarativeVMEMetaObject::connectAlias(int aliasId) +{ + if (!aConnected.testBit(aliasId)) { + aConnected.setBit(aliasId); + + QDeclarativeContext *context = ctxt->asQDeclarativeContext(); + QDeclarativeContextPrivate *ctxtPriv = QDeclarativeContextPrivate::get(context); + + QDeclarativeVMEMetaData::AliasData *d = metaData->aliasData() + aliasId; + + QObject *target = ctxtPriv->data->idValues[d->contextIdx].data(); + if (!target) + return; + + int sigIdx = methodOffset + aliasId + metaData->propertyCount; + QMetaObject::connect(context, d->contextIdx + ctxtPriv->notifyIndex, object, sigIdx); + + if (d->propertyIdx != -1) { + QMetaProperty prop = target->metaObject()->property(d->propertyIdx); + if (prop.hasNotifySignal()) + QDeclarativePropertyPrivate::connect(target, prop.notifySignalIndex(), object, sigIdx); + } + } +} + +void QDeclarativeVMEMetaObject::connectAliasSignal(int index) +{ + int aliasId = (index - methodOffset) - metaData->propertyCount; + if (aliasId < 0 || aliasId >= metaData->aliasCount) + return; + + connectAlias(aliasId); +} + QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativevmemetaobject_p.h b/src/declarative/qml/qdeclarativevmemetaobject_p.h index 20ca80b..4ccaa73 100644 --- a/src/declarative/qml/qdeclarativevmemetaobject_p.h +++ b/src/declarative/qml/qdeclarativevmemetaobject_p.h @@ -126,6 +126,7 @@ public: QScriptValue vmeProperty(int index); void setVMEProperty(int index, const QScriptValue &); + void connectAliasSignal(int index); protected: virtual int metaCall(QMetaObject::Call _c, int _id, void **_a); @@ -140,6 +141,7 @@ private: QDeclarativeVMEVariant *data; + void connectAlias(int aliasId); QBitArray aConnected; QBitArray aInterceptors; QHash<int, QPair<int, QDeclarativePropertyValueInterceptor*> > interceptors; diff --git a/src/declarative/qml/qdeclarativewatcher.cpp b/src/declarative/qml/qdeclarativewatcher.cpp index da1419f..b9d5ec8 100644 --- a/src/declarative/qml/qdeclarativewatcher.cpp +++ b/src/declarative/qml/qdeclarativewatcher.cpp @@ -46,6 +46,7 @@ #include "qdeclarative.h" #include <qdeclarativedebugservice_p.h> +#include "private/qdeclarativeproperty_p.h" #include <QtCore/qmetaobject.h> #include <QtCore/qdebug.h> @@ -103,7 +104,7 @@ QDeclarativeWatchProxy::QDeclarativeWatchProxy(int id, refreshIdx = QDeclarativeWatchProxy::staticMetaObject.indexOfMethod("notifyValueChanged()"); if (prop.hasNotifySignal()) - QMetaObject::connect(m_object, prop.notifySignalIndex(), this, refreshIdx); + QDeclarativePropertyPrivate::connect(m_object, prop.notifySignalIndex(), this, refreshIdx); } void QDeclarativeWatchProxy::notifyValueChanged() diff --git a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp index 3c82fc5..9a8c944 100644 --- a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp +++ b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp @@ -1825,7 +1825,6 @@ void tst_qdeclarativelanguage::aliasPropertyChangeSignals() QObject *o = component.create(); QVERIFY(o != 0); - QEXPECT_FAIL("", "QTBUG-14089", Abort); QCOMPARE(o->property("test").toBool(), true); delete o; |