diff options
author | Lars Knoll <lars.knoll@qt.io> | 2017-08-22 17:17:57 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2017-08-22 17:17:57 +0200 |
commit | f1aff1f2d495562460a87d351e62c06109045a3a (patch) | |
tree | 93e4659421a3dc1fc664b539bf7e48ce28f64e84 /src/qml/qml/qqmlbinding.cpp | |
parent | 842ada7b04d68cd37df2556bf50b48d8a5f39ec4 (diff) | |
parent | 46ed14da325c6c0382c0bc54cacc347d2d7f2b0a (diff) |
Merge remote-tracking branch 'origin/dev' into wip/new-backend
Change-Id: Iff06429f948ac6cdec77a9e5bb8c5375c56fe705
Diffstat (limited to 'src/qml/qml/qqmlbinding.cpp')
-rw-r--r-- | src/qml/qml/qqmlbinding.cpp | 85 |
1 files changed, 83 insertions, 2 deletions
diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index 911df78595..fa60ba3216 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -54,6 +54,7 @@ #include <QVariant> #include <QtCore/qdebug.h> +#include <QVector> QT_BEGIN_NAMESPACE @@ -195,7 +196,7 @@ class QQmlNonbindingBinding: public QQmlBinding { protected: void doUpdate(const DeleteWatcher &watcher, - QQmlPropertyData::WriteFlags flags, QV4::Scope &scope) Q_DECL_OVERRIDE Q_DECL_FINAL + QQmlPropertyData::WriteFlags flags, QV4::Scope &scope) Q_DECL_OVERRIDE { auto ep = QQmlEnginePrivate::get(scope.engine); ep->referenceScarceResources(); @@ -295,6 +296,50 @@ protected: } }; +class QQmlTranslationBinding : public GenericBinding<QMetaType::QString> { +public: + QQmlTranslationBinding(QV4::CompiledData::CompilationUnit *compilationUnit, const QV4::CompiledData::Binding *binding) + { + setCompilationUnit(compilationUnit); + m_binding = binding; + setSourceLocation(QQmlSourceLocation(compilationUnit->fileName(), binding->valueLocation.line, binding->valueLocation.column)); + } + + void doUpdate(const DeleteWatcher &watcher, + QQmlPropertyData::WriteFlags flags, QV4::Scope &) Q_DECL_OVERRIDE Q_DECL_FINAL + { + if (watcher.wasDeleted()) + return; + + if (!isAddedToObject() || hasError()) + return; + + const QString result = m_binding->valueAsString(m_compilationUnit->data); + + Q_ASSERT(targetObject()); + + QQmlPropertyData *pd; + QQmlPropertyData vpd; + getPropertyData(&pd, &vpd); + Q_ASSERT(pd); + doStore(result, pd, flags); + } + +private: + const QV4::CompiledData::Binding *m_binding; +}; + +QQmlBinding *QQmlBinding::createTranslationBinding(QV4::CompiledData::CompilationUnit *unit, const QV4::CompiledData::Binding *binding, QObject *obj, QQmlContextData *ctxt) +{ + QQmlTranslationBinding *b = new QQmlTranslationBinding(unit, binding); + + b->setNotifyOnValueChanged(true); + b->QQmlJavaScriptExpression::setContext(ctxt); + b->setScopeObject(obj); + + return b; +} + Q_NEVER_INLINE bool QQmlBinding::slowWrite(const QQmlPropertyData &core, const QQmlPropertyData &valueTypeData, const QV4::Value &result, @@ -513,7 +558,12 @@ void QQmlBinding::getPropertyData(QQmlPropertyData **propertyData, QQmlPropertyD Q_ASSERT(propertyData); QQmlData *data = QQmlData::get(*m_target, false); - Q_ASSERT(data && data->propertyCache); + Q_ASSERT(data); + + if (Q_UNLIKELY(!data->propertyCache)) { + data->propertyCache = QQmlEnginePrivate::get(context()->engine)->cache(m_target->metaObject()); + data->propertyCache->addref(); + } *propertyData = data->propertyCache->property(m_targetIndex.coreIndex()); Q_ASSERT(*propertyData); @@ -528,6 +578,37 @@ void QQmlBinding::getPropertyData(QQmlPropertyData **propertyData, QQmlPropertyD } } +QVector<QQmlProperty> QQmlBinding::dependencies() const +{ + QVector<QQmlProperty> dependencies; + if (!m_target.data()) + return dependencies; + + for (const auto &guardList : { permanentGuards, activeGuards }) { + for (QQmlJavaScriptExpressionGuard *guard = guardList.first(); guard; guard = guardList.next(guard)) { + if (guard->signalIndex() == -1) // guard's sender is a QQmlNotifier, not a QObject*. + continue; + + QObject *senderObject = guard->senderAsObject(); + if (!senderObject) + continue; + + const QMetaObject *senderMeta = senderObject->metaObject(); + if (!senderMeta) + continue; + + for (int i = 0; i < senderMeta->propertyCount(); i++) { + QMetaProperty property = senderMeta->property(i); + if (property.notifySignalIndex() == QMetaObjectPrivate::signal(senderMeta, guard->signalIndex()).methodIndex()) { + dependencies.push_back(QQmlProperty(senderObject, QString::fromUtf8(senderObject->metaObject()->property(i).name()))); + } + } + } + } + + return dependencies; +} + class QObjectPointerBinding: public QQmlNonbindingBinding { QQmlMetaObject targetMetaObject; |