diff options
-rw-r--r-- | src/qml/types/qqmlbind.cpp | 51 | ||||
-rw-r--r-- | src/qml/types/qqmlbind_p.h | 3 |
2 files changed, 51 insertions, 3 deletions
diff --git a/src/qml/types/qqmlbind.cpp b/src/qml/types/qqmlbind.cpp index 7ab854dad0..921d60caa1 100644 --- a/src/qml/types/qqmlbind.cpp +++ b/src/qml/types/qqmlbind.cpp @@ -54,11 +54,14 @@ #include <QtCore/qfile.h> #include <QtCore/qdebug.h> #include <QtCore/qtimer.h> +#include <QtCore/qloggingcategory.h> #include <private/qobject_p.h> QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(lcBindingRemoval) + class QQmlBindPrivate : public QObjectPrivate { public: @@ -72,6 +75,7 @@ public: , restoreBinding(true) , restoreValue(false) , restoreModeExplicit(false) + , writingProperty(false) {} ~QQmlBindPrivate() { } @@ -90,6 +94,7 @@ public: bool restoreBinding:1; bool restoreValue:1; bool restoreModeExplicit:1; + bool writingProperty: 1; void validate(QObject *binding) const; void clearPrev(); @@ -242,7 +247,7 @@ void QQmlBind::setObject(QObject *obj) } d->obj = obj; if (d->componentComplete) { - d->prop = QQmlProperty(d->obj, d->propName, qmlContext(this)); + setTarget(QQmlProperty(d->obj, d->propName, qmlContext(this))); d->validate(this); } eval(); @@ -288,7 +293,7 @@ void QQmlBind::setProperty(const QString &p) } d->propName = p; if (d->componentComplete) { - d->prop = QQmlProperty(d->obj, d->propName, qmlContext(this)); + setTarget(QQmlProperty(d->obj, d->propName, qmlContext(this))); d->validate(this); } eval(); @@ -401,6 +406,19 @@ void QQmlBind::setRestoreMode(RestorationMode newMode) void QQmlBind::setTarget(const QQmlProperty &p) { Q_D(QQmlBind); + + if (Q_UNLIKELY(lcBindingRemoval().isInfoEnabled())) { + if (QObject *oldObject = d->prop.object()) { + QMetaProperty prop = oldObject->metaObject()->property(d->prop.index()); + if (prop.hasNotifySignal()) { + QByteArray signal('2' + prop.notifySignal().methodSignature()); + QObject::disconnect(oldObject, signal.constData(), + this, SLOT(targetValueChanged())); + } + } + p.connectNotifySignal(this, SLOT(targetValueChanged())); + } + d->prop = p; } @@ -415,7 +433,7 @@ void QQmlBind::componentComplete() Q_D(QQmlBind); d->componentComplete = true; if (!d->prop.isValid()) { - d->prop = QQmlProperty(d->obj, d->propName, qmlContext(this)); + setTarget(QQmlProperty(d->obj, d->propName, qmlContext(this))); d->validate(this); } eval(); @@ -509,7 +527,34 @@ void QQmlBind::eval() QQmlPropertyPrivate::removeBinding(d->prop); } + d->writingProperty = true; d->prop.write(d->value.value.toVariant()); + d->writingProperty = false; +} + +void QQmlBind::targetValueChanged() +{ + Q_D(QQmlBind); + if (d->writingProperty) + return; + + if (d->when.isValid() && !d->when) + return; + + QUrl url; + quint16 line = 0; + + const QQmlData *ddata = QQmlData::get(this, false); + if (ddata && ddata->outerContext) { + url = ddata->outerContext->url(); + line = ddata->lineNumber; + } + + qCInfo(lcBindingRemoval, + "The target property of the Binding element created at %s:%d was changed from " + "elsewhere. This does not overwrite the binding. The target property will still be " + "updated when the value of the Binding element changes.", + qPrintable(url.toString()), line); } QT_END_NAMESPACE diff --git a/src/qml/types/qqmlbind_p.h b/src/qml/types/qqmlbind_p.h index ba040d2a0b..7bf4fc4dfd 100644 --- a/src/qml/types/qqmlbind_p.h +++ b/src/qml/types/qqmlbind_p.h @@ -115,6 +115,9 @@ protected: private: void prepareEval(); void eval(); + +private Q_SLOTS: + void targetValueChanged(); }; QT_END_NAMESPACE |