75 static QQmlAnyBinding ofProperty(QObject *object, QQmlPropertyIndex index)
77 const auto result = [](
auto &&result) -> QQmlAnyBinding {
78 QQmlAnyBinding binding;
79 binding = std::forward<
decltype(result)>(result);
84 const auto coreIndex = index.coreIndex();
87 if (index.hasValueTypeIndex())
88 return result(QQmlPropertyPrivate::binding(object, index));
90 if (QQmlPropertyCache::ConstPtr propertyCache = QQmlData::ensurePropertyCache(object)) {
91 const QQmlPropertyData *property = propertyCache->property(coreIndex);
92 return (property->acceptsQBinding())
93 ? result(property->propertyBindable(object).binding())
94 : result(QQmlPropertyPrivate::binding(object, index));
97 const QMetaObject *metaObject = object->metaObject();
98 const QMetaProperty metaProp = metaObject->property(coreIndex);
99 return metaProp.isBindable()
100 ? result(metaProp.bindable(object).binding())
101 : result(QQmlPropertyPrivate::binding(object, index));
109 static QQmlAnyBinding takeFrom(
const QQmlProperty &prop)
111 QQmlAnyBinding binding;
112 if (prop.isBindable()) {
113 QUntypedBindable bindable = prop.property().bindable(prop.object());
114 binding = bindable.takeBinding();
116 auto qmlBinding = QQmlPropertyPrivate::binding(prop);
118 binding = qmlBinding;
119 qmlBinding->setEnabled(
false, QQmlPropertyData::DontRemoveBinding | QQmlPropertyData::BypassInterceptor);
120 qmlBinding->removeFromObject();
133 static QQmlAnyBinding createFromFunction(
const QQmlProperty &prop, QV4::Function *function,
134 QObject *obj,
const QQmlRefPointer<QQmlContextData> &ctxt,
135 QV4::ExecutionContext *scope)
137 QQmlAnyBinding binding;
138 auto propPriv = QQmlPropertyPrivate::get(prop);
139 if (prop.isBindable()) {
140 auto index = QQmlPropertyIndex(propPriv->core.coreIndex(), -1);
141 binding = QQmlPropertyBinding::create(&propPriv->core,
143 scope, prop.object(), index);
145 auto qmlBinding = QQmlBinding::create(&propPriv->core, function, obj, ctxt, scope);
146 qmlBinding->setTarget(prop);
147 binding = qmlBinding;
159 static QQmlAnyBinding createFromScriptString(
const QQmlProperty &prop,
const QQmlScriptString &script,
160 QObject *obj, QQmlContext *ctxt)
162 QQmlAnyBinding binding;
163 auto propPriv = QQmlPropertyPrivate::get(prop);
164 if (prop.isBindable()) {
165 auto index = QQmlPropertyIndex(propPriv->core.coreIndex(), -1);
166 binding = QQmlPropertyBinding::createFromScriptString(&propPriv->core, script, obj, ctxt, prop.object(), index);
168 auto qmlBinding = QQmlBinding::create(&propPriv->core, script, obj, ctxt);
169 qmlBinding->setTarget(prop);
170 binding = qmlBinding;
195 static QQmlAnyBinding createFromCodeString(
const QQmlProperty &prop,
const QString& code, QObject *obj,
const QQmlRefPointer<QQmlContextData> &ctxt,
const QString &url, quint16 lineNumber) {
196 QQmlAnyBinding binding;
197 auto propPriv = QQmlPropertyPrivate::get(prop);
198 if (prop.isBindable()) {
199 auto index = QQmlPropertyIndex(propPriv->core.coreIndex(), -1);
200 binding = QQmlPropertyBinding::createFromCodeString(&propPriv->core,
203 prop.object(), index);
205 auto qmlBinding = QQmlBinding::create(&propPriv->core, code, obj, ctxt, url, lineNumber);
206 qmlBinding->setTarget(prop);
207 binding = qmlBinding;
217 static QQmlAnyBinding createTranslationBinding(
const QQmlProperty &prop,
const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit,
const QV4::CompiledData::Binding *translationBinding, QObject *scopeObject=
nullptr, QQmlRefPointer<QQmlContextData> context={})
219 QQmlAnyBinding binding;
220 auto propPriv = QQmlPropertyPrivate::get(prop);
221 if (prop.isBindable()) {
222 binding = QQmlTranslationPropertyBinding::create(&propPriv->core, compilationUnit, translationBinding);
224 auto qmlBinding = QQmlBinding::createTranslationBinding(compilationUnit, translationBinding, scopeObject, context);
225 binding = qmlBinding;
226 qmlBinding->setTarget(prop);
246 void installOn(
const QQmlProperty &target, InterceptorMode mode = IgnoreInterceptors)
248 Q_ASSERT(!d.isNull());
249 if (isAbstractPropertyBinding()) {
250 auto abstractBinding = asAbstractBinding();
251 Q_ASSERT(abstractBinding->targetObject() == target.object() || QQmlPropertyPrivate::get(target)->core.isAlias());
252 Q_ASSERT(!target.isBindable() || QQmlPropertyPrivate::get(target)->isValueType());
253 if (mode == IgnoreInterceptors)
254 QQmlPropertyPrivate::setBinding(abstractBinding, QQmlPropertyPrivate::None, QQmlPropertyData::DontRemoveBinding | QQmlPropertyData::BypassInterceptor);
256 QQmlPropertyPrivate::setBinding(abstractBinding);
258 Q_ASSERT(target.isBindable());
259 QUntypedBindable bindable;
260 void *argv[] = {&bindable};
261 if (mode == IgnoreInterceptors && QObjectPrivate::get(target.object())->metaObject) {
264 auto targetObject = target.object();
265 const QQmlPropertyData *targetProp = &QQmlPropertyPrivate::get(target)->core;
266 QQmlPropertyIndex originalIndex(targetProp->coreIndex());
267 QQmlPropertyIndex propIndex = originalIndex;
268 if (targetProp->isAlias()) {
269 QQmlPropertyPrivate::findAliasTarget(targetObject, originalIndex, &targetObject, &propIndex);
272 Q_ASSERT(propIndex.valueTypeIndex() == -1);
274 QQmlInterceptorMetaObject::setInterceptionMode(targetObject, QQmlInterceptorMetaObject::SkipInterception);
275 QMetaObject::metacall(targetObject, QMetaObject::BindableProperty, propIndex.coreIndex(), argv);
276 QQmlInterceptorMetaObject::setInterceptionMode(targetObject, QQmlInterceptorMetaObject::Intercept);
278 QMetaObject::metacall(target.object(), QMetaObject::BindableProperty, target.index(), argv);
280 bindable.setBinding(asUntypedPropertyBinding());
291 if (isAbstractPropertyBinding()) {
292 auto abstractBinding = asAbstractBinding();
293 if (abstractBinding->kind() != QQmlAbstractBinding::QmlBinding)
295 return static_cast<QQmlBinding *>(abstractBinding)->hasError();
297 return asUntypedPropertyBinding().error().hasError();