Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qqmlanybinding_p.h
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QQMLANYBINDINGPTR_P_H
5#define QQMLANYBINDINGPTR_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <qqmlproperty.h>
19#include <private/qqmlpropertybinding_p.h>
20#include <private/qqmlbinding_p.h>
21
23
24// Fully inline so that subsequent prop.isBindable check might get ellided.
25
45public:
46
47 constexpr QQmlAnyBinding() noexcept = default;
48 QQmlAnyBinding(std::nullptr_t) : d(static_cast<QQmlAbstractBinding *>(nullptr)) {}
49
57 QQmlAnyBinding binding;
58 if (prop.isBindable()) {
59 QUntypedBindable bindable = prop.property().bindable(prop.object());
60 binding = bindable.binding();
61 } else {
62 binding = QQmlPropertyPrivate::binding(prop);
63 }
64 return binding;
65 }
66
73 {
74 QQmlAnyBinding binding;
75 Q_ASSERT(object);
76 auto coreIndex = index.coreIndex();
77 // we don't support bindable properties on value types so far
78 if (!index.hasValueTypeIndex()
79 && QQmlData::ensurePropertyCache(object)->property(coreIndex)->isBindable()) {
80 auto metaProp = object->metaObject()->property(coreIndex);
81 QUntypedBindable bindable = metaProp.bindable(object);
82 binding = bindable.binding();
83 } else {
84 binding = QQmlPropertyPrivate::binding(object, index);
85 }
86 return binding;
87 }
88
95 {
96 QQmlAnyBinding binding;
97 if (prop.isBindable()) {
98 QUntypedBindable bindable = prop.property().bindable(prop.object());
99 binding = bindable.takeBinding();
100 } else {
101 auto qmlBinding = QQmlPropertyPrivate::binding(prop);
102 if (qmlBinding) {
103 binding = qmlBinding; // this needs to run before removeFromObject, else the refcount might reach zero
105 qmlBinding->removeFromObject();
106 }
107 }
108 return binding;
109 }
110
119 QObject *obj, const QQmlRefPointer<QQmlContextData> &ctxt,
121 {
122 QQmlAnyBinding binding;
123 auto propPriv = QQmlPropertyPrivate::get(prop);
124 if (prop.isBindable()) {
125 auto index = QQmlPropertyIndex(propPriv->core.coreIndex(), -1);
126 binding = QQmlPropertyBinding::create(&propPriv->core,
127 function, obj, ctxt,
128 scope, prop.object(), index);
129 } else {
130 auto qmlBinding = QQmlBinding::create(&propPriv->core, function, obj, ctxt, scope);
131 qmlBinding->setTarget(prop);
132 binding = qmlBinding;
133 }
134 return binding;
135 }
136
145 QObject *obj, QQmlContext *ctxt)
146 {
147 QQmlAnyBinding binding;
148 auto propPriv = QQmlPropertyPrivate::get(prop);
149 if (prop.isBindable()) {
150 auto index = QQmlPropertyIndex(propPriv->core.coreIndex(), -1);
151 binding = QQmlPropertyBinding::createFromScriptString(&propPriv->core, script, obj, ctxt, prop.object(), index);
152 } else {
153 auto qmlBinding = QQmlBinding::create(&propPriv->core, script, obj, ctxt);
154 qmlBinding->setTarget(prop);
155 binding = qmlBinding;
156 }
157 return binding;
158 }
159
160
166 {
167 if (prop.isBindable())
168 prop.property().bindable(prop.object()).takeBinding();
169 else
171 }
172
180 static QQmlAnyBinding createFromCodeString(const QQmlProperty &prop, const QString& code, QObject *obj, const QQmlRefPointer<QQmlContextData> &ctxt, const QString &url, quint16 lineNumber) {
181 QQmlAnyBinding binding;
182 auto propPriv = QQmlPropertyPrivate::get(prop);
183 if (prop.isBindable()) {
184 auto index = QQmlPropertyIndex(propPriv->core.coreIndex(), -1);
185 binding = QQmlPropertyBinding::createFromCodeString(&propPriv->core,
186 code, obj, ctxt,
187 url, lineNumber,
188 prop.object(), index);
189 } else {
190 auto qmlBinding = QQmlBinding::create(&propPriv->core, code, obj, ctxt, url, lineNumber);
191 qmlBinding->setTarget(prop);
192 binding = qmlBinding;
193 }
194 return binding;
195 }
196
202 static QQmlAnyBinding createTranslationBinding(const QQmlProperty &prop, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, const QV4::CompiledData::Binding *translationBinding, QObject *scopeObject=nullptr, QQmlRefPointer<QQmlContextData> context={})
203 {
204 QQmlAnyBinding binding;
205 auto propPriv = QQmlPropertyPrivate::get(prop);
206 if (prop.isBindable()) {
207 binding = QQmlTranslationPropertyBinding::create(&propPriv->core, compilationUnit, translationBinding);
208 } else {
209 auto qmlBinding = QQmlBinding::createTranslationBinding(compilationUnit, translationBinding, scopeObject, context);
210 binding = qmlBinding;
211 qmlBinding->setTarget(prop);
212 }
213 return binding;
214 }
215
230
232 {
233 Q_ASSERT(!d.isNull());
235 auto abstractBinding = asAbstractBinding();
236 Q_ASSERT(abstractBinding->targetObject() == target.object() || QQmlPropertyPrivate::get(target)->core.isAlias());
237 Q_ASSERT(!target.isBindable());
240 else
241 QQmlPropertyPrivate::setBinding(abstractBinding);
242 } else {
243 Q_ASSERT(target.isBindable());
244 QUntypedBindable bindable;
245 void *argv[] = {&bindable};
246 if (mode == IgnoreInterceptors) {
247 target.object()->qt_metacall(QMetaObject::BindableProperty, target.index(), argv);
248 } else {
250 }
252 }
253 }
254
261 bool hasError() {
263 auto abstractBinding = asAbstractBinding();
264 if (abstractBinding->kind() != QQmlAbstractBinding::QmlBinding)
265 return false;
266 return static_cast<QQmlBinding *>(abstractBinding)->hasError();
267 } else {
269 }
270 }
271
276 QQmlAnyBinding &operator=(std::nullptr_t)
277 {
278 clear();
279 return *this;
280 }
281
282 operator bool() const{
283 return !d.isNull();
284 }
285
292 { return d.isT1(); }
293
300 { return d.isT2(); }
301
308 {
309 if (d.isT1() || d.isNull())
310 return {};
311 auto priv = d.asT2();
313 }
314
321 {
322 if (d.isT2() || d.isNull())
323 return nullptr;
324 return d.asT1();
325 }
326
332 void refresh()
333 {
334 if (d.isNull())
335 return;
336 if (d.isT1()) {
337 auto binding = static_cast<QQmlBinding *>(d.asT1());
338 binding->setEnabledFlag(true);
339 binding->refresh();
340 } else {
341 auto bindingPriv = d.asT2();
342 PendingBindingObserverList bindingObservers;
343 bindingPriv->evaluateRecursive(bindingObservers);
344 bindingPriv->notifyNonRecursive(bindingObservers);
345 }
346
347 }
348
354 {
355 clear();
356 if (binding) {
357 d = binding;
358 binding->ref.ref();
359 }
360 return *this;
361 }
362
368 {
369 clear();
370 if (binding) {
371 d = binding.data();
372 binding->ref.ref();
373 }
374 return *this;
375 }
376
382 {
383 clear();
384 if (binding) {
385 d = binding.take();
386 }
387 return *this;
388 }
389
395 {
396 clear();
397 auto binding = QPropertyBindingPrivate::get(untypedBinding);
398 if (binding) {
399 d = binding;
400 binding->addRef();
401 }
402 return *this;
403 }
404
411 {
412 clear();
413 auto binding = QPropertyBindingPrivate::get(untypedBinding);
415 if (binding) {
416 d = static_cast<QPropertyBindingPrivate *>(ptr.take());
417 }
418 return *this;
419 }
420
422 : d(std::exchange(other.d, QBiPointer<QQmlAbstractBinding, QPropertyBindingPrivate>()))
423 {}
424
425 QQmlAnyBinding(const QQmlAnyBinding &other) noexcept { *this = other; }
426 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QQmlAnyBinding)
427
428 void swap(QQmlAnyBinding &other) noexcept { d.swap(other.d); }
429 friend void swap(QQmlAnyBinding &lhs, QQmlAnyBinding &rhs) noexcept { lhs.swap(rhs); }
430
432 {
433 clear();
434 if (auto abstractBinding = other.asAbstractBinding())
435 *this = abstractBinding;
436 else if (auto untypedBinding = other.asUntypedPropertyBinding(); !untypedBinding.isNull())
437 *this = untypedBinding;
438 return *this;
439 }
440
441 friend inline bool operator==(const QQmlAnyBinding &p1, const QQmlAnyBinding &p2)
442 {
443 return p1.d == p2.d;
444 }
445
446 friend inline bool operator!=(const QQmlAnyBinding &p1, const QQmlAnyBinding &p2)
447 {
448 return p1.d != p2.d;
449 }
450
451 ~QQmlAnyBinding() noexcept { clear(); }
452private:
453 void clear() noexcept {
454 if (d.isNull())
455 return;
456 if (d.isT1()) {
457 QQmlAbstractBinding *qqmlptr = d.asT1();
458 if (!qqmlptr->ref.deref())
459 delete qqmlptr;
460 } else if (d.isT2()) {
462 if (!priv->deref())
464 }
465 d = static_cast<QQmlAbstractBinding *>(nullptr);
466 }
467 QBiPointer<QQmlAbstractBinding, QPropertyBindingPrivate> d;
468};
469
471
472
473#endif // QQMLANYBINDINGPTR_P_H
T * asT1() const
void swap(QBiPointer &other) noexcept
bool isNull() const
bool isT1() const
T2 * asT2() const
bool isT2() const
T * data() const noexcept
Returns a pointer to the shared data object.
QUntypedBindable bindable(QObject *object) const
\inmodule QtCore
Definition qobject.h:103
bool hasError() const
Definition qproperty.h:149
static void destroyAndFreeMemory(QPropertyBindingPrivate *priv)
static QPropertyBindingPrivate * get(const QUntypedPropertyBinding &binding)
QQmlAnyBinding is an abstraction over the various bindings in QML.
QUntypedPropertyBinding asUntypedPropertyBinding() const
static QQmlAnyBinding createFromCodeString(const QQmlProperty &prop, const QString &code, QObject *obj, const QQmlRefPointer< QQmlContextData > &ctxt, const QString &url, quint16 lineNumber)
static void removeBindingFrom(QQmlProperty &prop)
static QQmlAnyBinding createFromScriptString(const QQmlProperty &prop, const QQmlScriptString &script, QObject *obj, QQmlContext *ctxt)
bool isUntypedPropertyBinding() const
friend bool operator!=(const QQmlAnyBinding &p1, const QQmlAnyBinding &p2)
static QQmlAnyBinding createTranslationBinding(const QQmlProperty &prop, const QQmlRefPointer< QV4::ExecutableCompilationUnit > &compilationUnit, const QV4::CompiledData::Binding *translationBinding, QObject *scopeObject=nullptr, QQmlRefPointer< QQmlContextData > context={})
QQmlAnyBinding & operator=(const QQmlAnyBinding &other) noexcept
friend bool operator==(const QQmlAnyBinding &p1, const QQmlAnyBinding &p2)
QQmlAnyBinding & operator=(QUntypedPropertyBinding &&untypedBinding)
QQmlAnyBinding & operator=(std::nullptr_t)
Stores a null binding.
static QQmlAnyBinding takeFrom(const QQmlProperty &prop)
Removes the binding from the property prop, and returns it as a QQmlAnyBinding if there was any.
QQmlAbstractBinding * asAbstractBinding() const
static QQmlAnyBinding ofProperty(QObject *object, QQmlPropertyIndex index)
This is an overloaded member function, provided for convenience. It differs from the above function o...
void installOn(const QQmlProperty &target, InterceptorMode mode=IgnoreInterceptors)
QQmlAnyBinding & operator=(QQmlAbstractBinding *binding)
QQmlAnyBinding & operator=(const QUntypedPropertyBinding &untypedBinding)
bool isAbstractPropertyBinding() const
~QQmlAnyBinding() noexcept
QQmlAnyBinding(QQmlAnyBinding &&other) noexcept
friend void swap(QQmlAnyBinding &lhs, QQmlAnyBinding &rhs) noexcept
static QQmlAnyBinding ofProperty(const QQmlProperty &prop)
QQmlAnyBinding(const QQmlAnyBinding &other) noexcept
QQmlAnyBinding & operator=(QQmlAbstractBinding::Ptr &&binding)
static QQmlAnyBinding createFromFunction(const QQmlProperty &prop, QV4::Function *function, QObject *obj, const QQmlRefPointer< QQmlContextData > &ctxt, QV4::ExecutionContext *scope)
constexpr QQmlAnyBinding() noexcept=default
QQmlAnyBinding & operator=(const QQmlAbstractBinding::Ptr &binding)
static QQmlBinding * createTranslationBinding(const QQmlRefPointer< QV4::ExecutableCompilationUnit > &unit, const QV4::CompiledData::Binding *binding, QObject *obj, const QQmlRefPointer< QQmlContextData > &ctxt)
static QQmlBinding * create(const QQmlPropertyData *, const QQmlScriptString &, QObject *, QQmlContext *)
The QQmlContext class defines a context within a QML engine.
Definition qqmlcontext.h:25
static QQmlPropertyCache::ConstPtr ensurePropertyCache(QObject *object)
Definition qqmldata_p.h:252
static QUntypedPropertyBinding createFromCodeString(const QQmlPropertyData *property, const QString &str, QObject *obj, const QQmlRefPointer< QQmlContextData > &ctxt, const QString &url, quint16 lineNumber, QObject *target, QQmlPropertyIndex targetIndex)
static QUntypedPropertyBinding create(const QQmlPropertyData *pd, QV4::Function *function, QObject *obj, const QQmlRefPointer< QQmlContextData > &ctxt, QV4::ExecutionContext *scope, QObject *target, QQmlPropertyIndex targetIndex)
static QUntypedPropertyBinding createFromScriptString(const QQmlPropertyData *property, const QQmlScriptString &script, QObject *obj, QQmlContext *ctxt, QObject *target, QQmlPropertyIndex targetIndex)
static void setBinding(QQmlAbstractBinding *binding, BindingFlags flags=None, QQmlPropertyData::WriteFlags writeFlags=QQmlPropertyData::DontRemoveBinding)
static void removeBinding(const QQmlProperty &that)
static QQmlPropertyPrivate * get(const QQmlProperty &p)
static QQmlAbstractBinding * binding(QObject *, QQmlPropertyIndex index)
The QQmlProperty class abstracts accessing properties on objects created from QML.
bool isBindable() const
QMetaProperty property() const
Returns the \l{QMetaProperty} {Qt property} associated with this QML property.
QML_ANONYMOUSQObject * object
The QQmlScriptString class encapsulates a script and its context.
static QUntypedPropertyBinding Q_QML_EXPORT create(const QQmlPropertyData *pd, const QQmlRefPointer< QV4::ExecutableCompilationUnit > &compilationUnit, const QV4::CompiledData::Binding *binding)
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
\inmodule QtCore
Definition qproperty.h:679
QUntypedPropertyBinding binding() const
Returns the underlying property's binding if there is any, or a default constructed QUntypedPropertyB...
Definition qproperty.h:757
QUntypedPropertyBinding takeBinding()
Removes the currently set binding from the property and returns it.
Definition qproperty.h:708
bool setBinding(const QUntypedPropertyBinding &binding)
Sets the underlying property's binding to binding.
Definition qproperty.h:768
QPropertyBindingError error() const
Returns the error state of the binding.
QPixmap p2
QPixmap p1
[0]
Combined button and popup list for selecting options.
static void * context
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
static ControlElement< T > * ptr(QWidget *widget)
static const QMetaObjectPrivate * priv(const uint *data)
GLenum mode
GLuint index
[2]
GLenum target
GLhandleARB obj
[2]
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
unsigned short quint16
Definition qtypes.h:48
QUrl url("example.com")
[constructor-url-reference]
QSharedPointer< T > other(t)
[5]
static int metacall(QObject *, Call, int, void **)