Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qqmlpropertytopropertybinding_p.h
Go to the documentation of this file.
1// Copyright (C) 2022 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// Qt-Security score:significant
4
5#ifndef QQMLPROPERTYTOPROPERTYBINDINDING_P_H
6#define QQMLPROPERTYTOPROPERTYBINDINDING_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <private/qqmlabstractbinding_p.h>
20#include <private/qqmlengine_p.h>
21#include <private/qqmlnotifier_p.h>
22#include <private/qqmlpropertybindingbase_p.h>
23#include <private/qqmlvaluetype_p.h>
24#include <private/qv4jscall_p.h>
25
26QT_BEGIN_NAMESPACE
27
28// Different forms of property-to-property binding
29// unbindable -> unbindable: QQmlAbstractBinding + QQmlNotifierEndpoint
30// unbindable -> bindable: QPropertyBindingPrivate + QQmlNotifierEndpoint
31// bindable -> unbindable: QQmlAbstractBinding + QPropertyObserver
32// bindable -> bindable: QPropertyBindingPrivate only
33
34class QQmlPropertyToPropertyBinding
35{
36public:
37 static Q_QML_EXPORT QQmlAnyBinding create(
38 QQmlEngine *engine, const QQmlProperty &source, const QQmlProperty &target);
39
40private:
41 friend class QQmlPropertyToUnbindablePropertyBinding;
42 friend class QQmlUnbindableToUnbindablePropertyBinding;
43 friend class QQmlBindableToUnbindablePropertyBinding;
44 friend class QQmlPropertyToBindablePropertyBinding;
45 friend class QQmlUnbindableToBindablePropertyBinding;
46 friend class QQmlBindableToBindablePropertyBinding;
47
48 QQmlPropertyToPropertyBinding(QQmlEngine *engine, const QQmlProperty &source);
49
50 template<typename Capture>
51 QVariant readSourceValue(Capture &&capture) const
52 {
53 const QMetaObject *sourceMetaObject = sourceObject->metaObject();
54 const QMetaProperty property
55 = sourceMetaObject->property(sourcePropertyIndex.coreIndex());
56 if (!property.isConstant())
57 capture(sourceMetaObject, property);
58
59 QVariant value;
60
61 const int valueTypeIndex = sourcePropertyIndex.valueTypeIndex();
62 if (valueTypeIndex == -1) {
63 value = property.read(sourceObject);
64 } else {
65 QQmlGadgetPtrWrapper *wrapper
66 = QQmlEnginePrivate::get(engine)->valueTypeInstance(property.metaType());
67 wrapper->read(sourceObject, sourcePropertyIndex.coreIndex());
68 value = wrapper->readOnGadget(wrapper->property(valueTypeIndex));
69 }
70
71 return value;
72 }
73
74 void doConnectNotify(QQmlNotifierEndpoint *endpoint, const QMetaProperty &property)
75 {
76 const int notifyIndex = QMetaObjectPrivate::signalIndex(property.notifySignal());
77
78 // We cannot capture non-bindable properties without signals
79 if (notifyIndex == -1)
80 return;
81
82 if (endpoint->isConnected(sourceObject, notifyIndex))
83 endpoint->cancelNotify();
84 else
85 QQmlData::connectEndpoint(endpoint, sourceObject, notifyIndex, engine, true);
86 }
87
88 QQmlEngine *engine = nullptr;
89 QObject *sourceObject = nullptr;
90 QQmlPropertyIndex sourcePropertyIndex;
91};
92
94{
95public:
96 Kind kind() const final;
97 void setEnabled(bool e, QQmlPropertyData::WriteFlags flags) final;
98 void update(QQmlPropertyData::WriteFlags flags = QQmlPropertyData::DontRemoveBinding);
99
100 QObject *source() const { return m_binding.sourceObject; }
101
102protected:
104 QQmlEngine *engine, const QQmlProperty &source, const QQmlProperty &target);
105
106 virtual void captureProperty(
107 const QMetaObject *sourceMetaObject, const QMetaProperty &sourceProperty) = 0;
108
109 QQmlPropertyToPropertyBinding m_binding;
110};
111
114{
115public:
117 QQmlEngine *engine, const QQmlProperty &source, const QQmlProperty &target);
118protected:
119 void captureProperty(
120 const QMetaObject *sourceMetaObject, const QMetaProperty &sourceProperty) final;
121};
122
125{
126public:
128 QQmlEngine *engine, const QQmlProperty &source, const QQmlProperty &target);
129
130 static void update(QPropertyObserver *observer, QUntypedPropertyData *);
131
132protected:
133 void captureProperty(
134 const QMetaObject *sourceMetaObject, const QMetaProperty &sourceProperty) final;
135private:
136 bool m_isObserving = false;
137};
138
140{
141public:
143 QQmlEngine *engine, const QQmlProperty &source, const QQmlProperty &target,
144 const QtPrivate::BindingFunctionVTable *vtable);
145
146 QObject *source() const { return m_binding.sourceObject; }
147
148 template<typename Concrete>
149 static bool update(QMetaType metaType, QUntypedPropertyData *dataPtr, void *f)
150 {
151 Concrete *self = reinterpret_cast<Concrete *>(
152 // Address of QPropertyBindingPrivate subobject
153 static_cast<std::byte *>(f) - QPropertyBindingPrivate::getSizeEnsuringAlignment());
154
155 const QVariant value = self->m_binding.readSourceValue(
156 [self](const QMetaObject *metaObject, const QMetaProperty &property) {
157 self->captureProperty(metaObject, property);
158 });
159
160 QV4::coerce(
161 self->m_binding.engine->handle(), value.metaType(), value.constData(),
162 metaType, dataPtr);
163 return true;
164 }
165
166protected:
167 QQmlPropertyToPropertyBinding m_binding;
168};
169
172{
173public:
175 QQmlEngine *engine, const QQmlProperty &source, const QQmlProperty &target);
176
177 void update();
178
179 void captureProperty(const QMetaObject *, const QMetaProperty &property)
180 {
181 m_binding.doConnectNotify(this, property);
182 }
183};
184
186{
187public:
189 QQmlEngine *engine, const QQmlProperty &source, const QQmlProperty &target);
190
191 void captureProperty(const QMetaObject *, const QMetaProperty &) {}
192};
193
194void QQmlUnbindableToUnbindableGuard_callback(QQmlNotifierEndpoint *e, void **);
195void QQmlUnbindableToBindableGuard_callback(QQmlNotifierEndpoint *e, void **);
196
197QT_END_NAMESPACE
198
199#endif
QQmlBindableToBindablePropertyBinding(QQmlEngine *engine, const QQmlProperty &source, const QQmlProperty &target)
void captureProperty(const QMetaObject *, const QMetaProperty &)
void captureProperty(const QMetaObject *sourceMetaObject, const QMetaProperty &sourceProperty) final
QQmlBindableToUnbindablePropertyBinding(QQmlEngine *engine, const QQmlProperty &source, const QQmlProperty &target)
static void update(QPropertyObserver *observer, QUntypedPropertyData *)
QQmlPropertyToBindablePropertyBinding(QQmlEngine *engine, const QQmlProperty &source, const QQmlProperty &target, const QtPrivate::BindingFunctionVTable *vtable)
static bool update(QMetaType metaType, QUntypedPropertyData *dataPtr, void *f)
void setEnabled(bool e, QQmlPropertyData::WriteFlags flags) final
QQmlPropertyToUnbindablePropertyBinding(QQmlEngine *engine, const QQmlProperty &source, const QQmlProperty &target)
virtual void captureProperty(const QMetaObject *sourceMetaObject, const QMetaProperty &sourceProperty)=0
void update(QQmlPropertyData::WriteFlags flags=QQmlPropertyData::DontRemoveBinding)
void captureProperty(const QMetaObject *, const QMetaProperty &property)
QQmlUnbindableToBindablePropertyBinding(QQmlEngine *engine, const QQmlProperty &source, const QQmlProperty &target)
QQmlUnbindableToUnbindablePropertyBinding(QQmlEngine *engine, const QQmlProperty &source, const QQmlProperty &target)
void captureProperty(const QMetaObject *sourceMetaObject, const QMetaProperty &sourceProperty) final
Combined button and popup list for selecting options.
constexpr BindingFunctionVTable bindingFunctionVTableForQQmlPropertyToBindablePropertyBinding
void QQmlUnbindableToUnbindableGuard_callback(QQmlNotifierEndpoint *, void **)
void QQmlUnbindableToBindableGuard_callback(QQmlNotifierEndpoint *, void **)