diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-10-10 01:00:21 +0200 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-10-10 01:00:21 +0200 |
commit | 1bddf29287b4c42c321688376147d14bfecb46a1 (patch) | |
tree | 2939d848a3a5496963aa2749b9deead6df9c49f4 /src/qml/types | |
parent | a02b5d48cf63228ed8faf6abf4724df2c4500269 (diff) | |
parent | 3fde977a817498817e98ce350d493658b0ed4458 (diff) |
Merge remote-tracking branch 'origin/5.14' into 5.15
Change-Id: I2835748c27616103f275849141fbe5a93e3dfd8c
Diffstat (limited to 'src/qml/types')
-rw-r--r-- | src/qml/types/qqmlbind.cpp | 68 | ||||
-rw-r--r-- | src/qml/types/qqmlbind_p.h | 3 |
2 files changed, 63 insertions, 8 deletions
diff --git a/src/qml/types/qqmlbind.cpp b/src/qml/types/qqmlbind.cpp index 36de16a818..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(); @@ -193,6 +198,13 @@ QQmlBind::~QQmlBind() When the binding becomes inactive again, any direct bindings that were previously set on the property will be restored. + + \note By default, a previously set literal value is not restored when the Binding becomes + inactive. Rather, the last value set by the now inactive Binding is retained. You can customize + the restoration behavior for literal values as well as bindings using the \l restoreMode + property. The default will change in Qt 6.0. + + \sa restoreMode */ bool QQmlBind::when() const { @@ -235,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(); @@ -281,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(); @@ -360,7 +372,7 @@ void QQmlBind::setDelayed(bool delayed) \endlist \warning The default value is Binding.RestoreBinding. This will change in - Qt 5.15 to Binding.RestoreBindingOrValue. + Qt 6.0 to Binding.RestoreBindingOrValue. If you rely on any specific behavior regarding the restoration of plain values when bindings get disabled you should migrate to explicitly set the @@ -394,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; } @@ -408,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(); @@ -461,8 +486,8 @@ void QQmlBind::eval() qmlWarning(this) << "Not restoring previous value because restoreMode has not been set." << "This behavior is deprecated." - << "In Qt < 5.15 the default is Binding.RestoreBinding." - << "In Qt >= 5.15 the default is Binding.RestoreBindingOrValue."; + << "In Qt < 6.0 the default is Binding.RestoreBinding." + << "In Qt >= 6.0 the default is Binding.RestoreBindingOrValue."; } } else if (d->prevIsVariant) { if (d->restoreValue) { @@ -472,8 +497,8 @@ void QQmlBind::eval() qmlWarning(this) << "Not restoring previous value because restoreMode has not been set." << "This behavior is deprecated." - << "In Qt < 5.15 the default is Binding.RestoreBinding." - << "In Qt >= 5.15 the default is Binding.RestoreBindingOrValue."; + << "In Qt < 6.0 the default is Binding.RestoreBinding." + << "In Qt >= 6.0 the default is Binding.RestoreBindingOrValue."; } } return; @@ -502,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 a100b1552c..c709224c23 100644 --- a/src/qml/types/qqmlbind_p.h +++ b/src/qml/types/qqmlbind_p.h @@ -116,6 +116,9 @@ protected: private: void prepareEval(); void eval(); + +private Q_SLOTS: + void targetValueChanged(); }; QT_END_NAMESPACE |