32QQmlAnyBinding QQmlPropertyToPropertyBinding::create(
33 QQmlEngine *engine,
const QQmlProperty &source,
const QQmlProperty &target)
35 QQmlAnyBinding result;
36 if (target.isBindable() && !QQmlPropertyPrivate::get(target)->isValueType()) {
37 QPropertyBindingPrivate *binding =
nullptr;
38 if (source.isBindable())
39 binding =
new QQmlBindableToBindablePropertyBinding(engine, source, target);
41 binding =
new QQmlUnbindableToBindablePropertyBinding(engine, source, target);
42 result = QPropertyBindingPrivate::makeUntyped(binding);
46 if (source.isBindable()) {
47 result =
new QQmlBindableToUnbindablePropertyBinding(engine, source, target);
51 result =
new QQmlUnbindableToUnbindablePropertyBinding(engine, source, target);
91 QObject *target = targetObject();
92 if (QQmlData::wasDeleted(target))
95 const QQmlPropertyData *d =
nullptr;
97 getPropertyData(&d, &vtd);
101 if (Q_UNLIKELY(updatingFlag()))
104 setUpdatingFlag(
true);
105 const auto resetUpdating = qScopeGuard([
this]() { setUpdatingFlag(
false); });
107 if (canUseAccessor())
108 flags.setFlag(QQmlPropertyData::BypassInterceptor);
110 QVariant value = m_binding.readSourceValue(
111 [&](
const QMetaObject *sourceMetaObject,
const QMetaProperty &property) {
112 captureProperty(sourceMetaObject, property);
115 QV4::ExecutionEngine *v4 = m_binding.engine->handle();
118 const QMetaType targetMetaType = vtd.isValid() ? vtd.propType() : d->propType();
119 const QMetaType valueMetaType = value.metaType();
121 if (QV4::ExecutionEngine::isUndefinedVariant(value)) {
123
124
125
126
127 if (vtd.isValid() ? vtd.isResettable() : d->isResettable()) {
128 QQmlPropertyPrivate::resetValueProperty(target, *d, vtd, {}, flags);
132 if (!QQmlMetaType::canLosslesslyHoldUndefined(targetMetaType)) {
133 const char *typeName = targetMetaType.name();
135 << QStringLiteral(
"Unable to assign [undefined] to \"%1\" of type %2")
136 .arg(QQmlPropertyPrivate::restore(target, *d, &vtd,
nullptr).name(),
137 typeName ? QString::fromUtf8(typeName)
138 : QStringLiteral(
"[unknown property type]"));
144 if (valueMetaType != targetMetaType && targetMetaType != QMetaType::fromType<QVariant>()) {
147 QVariant coerced(targetMetaType);
148 QV4::Scope scope(v4);
149 QV4::ScopedValue jsValue(
150 scope, value.isValid()
151 ? v4->metaTypeToJS(valueMetaType, value.constData())
152 : QV4::Encode::undefined());
155 if (QV4::ExecutionEngine::metaTypeFromJS(jsValue, targetMetaType, coerced.data()))
156 value = std::move(coerced);
159 QQmlPropertyPrivate::writeValueProperty(target, *d, vtd, value, {}, flags);
191 const QMetaObject *sourceMetaObject,
const QMetaProperty &sourceProperty)
193 Q_UNUSED(sourceProperty);
199 QUntypedBindable bindable;
200 void *argv[] = { &bindable };
201 sourceMetaObject->metacall(
202 m_binding.sourceObject, QMetaObject::BindableProperty,
203 m_binding.sourcePropertyIndex.coreIndex(), argv);
204 bindable.observe(
this);
205 m_isObserving =
true;
220 QQmlEngine *engine,
const QQmlProperty &source,
const QQmlProperty &target,
221 const QtPrivate::BindingFunctionVTable *vtable)
226 errorCallBack = [](QPropertyBindingPrivate *that) {
227 auto self =
static_cast<QQmlPropertyToBindablePropertyBinding *>(that);
228 if (self->m_binding.engine) {
229 const auto error = self->bindingError();
230 if (error.type() == QPropertyBindingError::BindingLoop) {
231 qmlWarning(self->m_binding.sourceObject)
232 << QStringLiteral(
"Binding loop detected for property bound to ")
233 << self->propertyDataPtr;