1// Copyright (C) 2016 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 QQMLABSTRACTBINDING_P_H
5#define QQMLABSTRACTBINDING_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 <QtCore/qsharedpointer.h>
19#include <QtCore/qshareddata.h>
20#include <private/qtqmlglobal_p.h>
21#include <private/qqmlproperty_p.h>
22
23QT_BEGIN_NAMESPACE
24
25class QQmlObjectCreator;
26class QQmlAnyBinding;
27
28class Q_QML_PRIVATE_EXPORT QQmlAbstractBinding
29{
30 friend class QQmlAnyBinding;
31protected:
32 QQmlAbstractBinding();
33public:
34 enum Kind {
35 ValueTypeProxy,
36 QmlBinding,
37 PropertyToPropertyBinding,
38 };
39
40 virtual ~QQmlAbstractBinding();
41
42 typedef QExplicitlySharedDataPointer<QQmlAbstractBinding> Ptr;
43
44 virtual QString expression() const;
45
46 virtual Kind kind() const = 0;
47
48 // Should return the encoded property index for the binding. Should return this value
49 // even if the binding is not enabled or added to an object.
50 // Encoding is: coreIndex | (valueTypeIndex << 16)
51 QQmlPropertyIndex targetPropertyIndex() const { return m_targetIndex; }
52
53 // Should return the object for the binding. Should return this object even if the
54 // binding is not enabled or added to the object.
55 QObject *targetObject() const { return m_target.data(); }
56
57 void setTarget(const QQmlProperty &);
58 bool setTarget(QObject *, const QQmlPropertyData &, const QQmlPropertyData *valueType);
59 bool setTarget(QObject *, int coreIndex, bool coreIsAlias, int valueTypeIndex);
60
61 virtual void setEnabled(bool e, QQmlPropertyData::WriteFlags f = QQmlPropertyData::DontRemoveBinding) = 0;
62
63 void addToObject();
64 void removeFromObject();
65
66 static void printBindingLoopError(const QQmlProperty &prop);
67
68 inline QQmlAbstractBinding *nextBinding() const;
69
70 inline bool canUseAccessor() const
71 { return m_nextBinding.tag().testFlag(flag: CanUseAccessor); }
72 void setCanUseAccessor(bool canUseAccessor)
73 { m_nextBinding.setTag(m_nextBinding.tag().setFlag(flag: CanUseAccessor, on: canUseAccessor)); }
74
75 struct RefCount {
76 RefCount() {}
77 int refCount = 0;
78 void ref() { ++refCount; }
79 int deref() { return --refCount; }
80 operator int() const { return refCount; }
81 };
82 RefCount ref;
83
84 enum TargetTag {
85 NoTargetTag = 0x0,
86 UpdatingBinding = 0x1,
87 BindingEnabled = 0x2
88 };
89 Q_DECLARE_FLAGS(TargetTags, TargetTag)
90
91 enum NextBindingTag {
92 NoBindingTag = 0x0,
93 AddedToObject = 0x1,
94 CanUseAccessor = 0x2
95 };
96 Q_DECLARE_FLAGS(NextBindingTags, NextBindingTag)
97
98protected:
99 friend class QQmlData;
100 friend class QQmlValueTypeProxyBinding;
101 friend class QQmlObjectCreator;
102
103 inline void setAddedToObject(bool v);
104 inline bool isAddedToObject() const;
105
106 inline void setNextBinding(QQmlAbstractBinding *);
107
108 void getPropertyData(
109 const QQmlPropertyData **propertyData, QQmlPropertyData *valueTypeData) const;
110
111 inline bool updatingFlag() const;
112 inline void setUpdatingFlag(bool);
113 inline bool enabledFlag() const;
114 inline void setEnabledFlag(bool);
115 void updateCanUseAccessor();
116
117 QQmlPropertyIndex m_targetIndex;
118
119 // Pointer is the target object to which the binding binds
120 QTaggedPointer<QObject, TargetTags> m_target;
121
122 // Pointer to the next binding in the linked list of bindings.
123 QTaggedPointer<QQmlAbstractBinding, NextBindingTags> m_nextBinding;
124};
125
126Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlAbstractBinding::TargetTags)
127Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlAbstractBinding::NextBindingTags)
128
129void QQmlAbstractBinding::setAddedToObject(bool v)
130{
131 m_nextBinding.setTag(m_nextBinding.tag().setFlag(flag: AddedToObject, on: v));
132}
133
134bool QQmlAbstractBinding::isAddedToObject() const
135{
136 return m_nextBinding.tag().testFlag(flag: AddedToObject);
137}
138
139QQmlAbstractBinding *QQmlAbstractBinding::nextBinding() const
140{
141 return m_nextBinding.data();
142}
143
144void QQmlAbstractBinding::setNextBinding(QQmlAbstractBinding *b)
145{
146 if (b)
147 b->ref.ref();
148 if (m_nextBinding.data() && !m_nextBinding->ref.deref())
149 delete m_nextBinding.data();
150 m_nextBinding = b;
151}
152
153bool QQmlAbstractBinding::updatingFlag() const
154{
155 return m_target.tag().testFlag(flag: UpdatingBinding);
156}
157
158void QQmlAbstractBinding::setUpdatingFlag(bool v)
159{
160 m_target.setTag(m_target.tag().setFlag(flag: UpdatingBinding, on: v));
161}
162
163bool QQmlAbstractBinding::enabledFlag() const
164{
165 return m_target.tag().testFlag(flag: BindingEnabled);
166}
167
168void QQmlAbstractBinding::setEnabledFlag(bool v)
169{
170 m_target.setTag(m_target.tag().setFlag(flag: BindingEnabled, on: v));
171}
172
173QT_END_NAMESPACE
174
175#endif // QQMLABSTRACTBINDING_P_H
176

source code of qtdeclarative/src/qml/qml/qqmlabstractbinding_p.h