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
qqmldesignermetaobject.cpp
Go to the documentation of this file.
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// Qt-Security score:significant reason:default
4
6
7#include <QSharedPointer>
8#include <QMetaProperty>
9#include <QtCore/private/qnumeric_p.h>
10#include <QDebug>
11
12#include <private/qqmlengine_p.h>
13
15
17static void (*notifyPropertyChangeCallBack)(QObject*, const QQuickDesignerSupport::PropertyName &propertyName) = nullptr;
18
20 inline std::pair<QVariant, bool> &getDataRef(int idx) {
21 while (m_data.size() <= idx)
22 m_data << std::pair<QVariant, bool>(QVariant(), false);
23 return m_data[idx];
24 }
25
26 inline QVariant &getData(int idx) {
27 std::pair<QVariant, bool> &prop = getDataRef(idx);
28 if (!prop.second) {
29 prop.first = QVariant();
30 prop.second = true;
31 }
32 return prop.first;
33 }
34
35 inline bool hasData(int idx) const {
36 if (idx >= m_data.size())
37 return false;
38 return m_data[idx].second;
39 }
40
41 inline int count() { return m_data.size(); }
42
44};
45
46QQmlDesignerMetaObject* QQmlDesignerMetaObject::getNodeInstanceMetaObject(QObject *object, QQmlEngine *engine)
47{
48 //Avoid setting up multiple MetaObjects on the same QObject
49 QObjectPrivate *op = QObjectPrivate::get(object);
50 QDynamicMetaObjectData *parent = op->metaObject;
51 if (nodeInstanceMetaObjectList.contains(parent))
52 return static_cast<QQmlDesignerMetaObject *>(parent);
53
54 // we just create one and the ownership goes automatically to the object in nodeinstance see init method
55
56 QQmlData *ddata = QQmlData::get(object, false);
57
58 QQmlDesignerMetaObject *mo = new QQmlDesignerMetaObject(object, engine);
59 ddata->hasVMEMetaObject = false;
60 ddata->hasInterceptorMetaObject = false;
61
62 return mo;
63}
64
65void QQmlDesignerMetaObject::init(QObject *object)
66{
67 //Assign this to object
68 QObjectPrivate *op = QObjectPrivate::get(object);
69 op->metaObject = this;
70 nodeInstanceMetaObjectList.insert(this, true);
71}
72
73QQmlPropertyCache::Ptr QQmlDesignerMetaObject::cache() const
74{
75 return type()->cache();
76}
77
78QQmlDesignerMetaObject::QQmlDesignerMetaObject(QObject *object, QQmlEngine *engine)
79 : QQmlOpenMetaObject(object),
80 m_context(engine->contextForObject(object)),
81 m_data(new MetaPropertyData)
82{
83 init(object);
84 setCached(true);
85}
86
91
93{
94 int id = type()->createProperty(name.toUtf8());
95 setValue(id, QVariant());
96 Q_ASSERT(id >= 0);
97
98 //Updating cache
99 cache()->invalidate(this);
100
101 QQmlProperty property(myObject(), name, m_context);
102 Q_ASSERT(property.isValid());
103}
104
105int QQmlDesignerMetaObject::createProperty(const char *name, const char *passAlong)
106{
107 int ret = QQmlOpenMetaObject::createProperty(name, passAlong);
108 if (ret != -1) {
109 // compare createNewDynamicProperty
110 cache()->invalidate(this);
111 }
112 return ret;
113}
114
115void QQmlDesignerMetaObject::setValue(int id, const QVariant &value)
116{
117 std::pair<QVariant, bool> &prop = m_data->getDataRef(id);
118 prop.first = propertyWriteValue(id, value);
119 prop.second = true;
120 QMetaObject::activate(myObject(), id + type()->signalOffset(), nullptr);
121}
122
124{
125 return value;
126}
127
132
134{
135 return cache()->propertyOffset();
136}
137
138int QQmlDesignerMetaObject::openMetaCall(QObject *o, QMetaObject::Call call, int id, void **a)
139{
140 if ((call == QMetaObject::ReadProperty || call == QMetaObject::WriteProperty)
141 && id >= type()->propertyOffset()) {
142 int propId = id - type()->propertyOffset();
143 if (call == QMetaObject::ReadProperty) {
144 //propertyRead(propId);
145 *reinterpret_cast<QVariant *>(a[0]) = m_data->getData(propId);
146 } else if (call == QMetaObject::WriteProperty) {
147 if (propId <= m_data->count() || m_data->m_data[propId].first != *reinterpret_cast<QVariant *>(a[0])) {
148 //propertyWrite(propId);
149 std::pair<QVariant, bool> &prop = m_data->getDataRef(propId);
150 prop.first = propertyWriteValue(propId, *reinterpret_cast<QVariant *>(a[0]));
151 prop.second = true;
152 //propertyWritten(propId);
153 activate(myObject(), type()->signalOffset() + propId, nullptr);
154 }
155 }
156 return -1;
157 } else {
158 QDynamicMetaObjectData *dynamicParent = dynamicMetaObjectParent();
159 if (dynamicParent)
160 return dynamicParent->metaCall(o, call, id, a);
161 else
162 return myObject()->qt_metacall(call, id, a);
163 }
164}
165
166int QQmlDesignerMetaObject::metaCall(QObject *o, QMetaObject::Call call, int id, void **a)
167{
168 Q_ASSERT(myObject() == o);
169
170 int metaCallReturnValue = -1;
171
172 const QMetaProperty propertyById = property(id);
173
174 if (call == QMetaObject::WriteProperty
175 && propertyById.userType() == QMetaType::QVariant
176 && reinterpret_cast<QVariant *>(a[0])->userType() == QMetaType::Double
177 && qt_is_nan(reinterpret_cast<QVariant *>(a[0])->toDouble())) {
178 return -1;
179 }
180
181 if (call == QMetaObject::WriteProperty
182 && propertyById.userType() == QMetaType::Double
183 && qt_is_nan(*reinterpret_cast<double*>(a[0]))) {
184 return -1;
185 }
186
187 if (call == QMetaObject::WriteProperty
188 && propertyById.userType() == QMetaType::Float
189 && qt_is_nan(*reinterpret_cast<float*>(a[0]))) {
190 return -1;
191 }
192
193 QVariant oldValue;
194
195 if (call == QMetaObject::WriteProperty && !propertyById.hasNotifySignal())
196 {
197 oldValue = propertyById.read(myObject());
198 }
199
200 QDynamicMetaObjectData *dynamicParent = dynamicMetaObjectParent();
201 const QMetaObject *staticParent = dynamicParent
202 ? dynamicParent->toDynamicMetaObject(object())
203 : nullptr;
204 if (staticParent && id < staticParent->propertyOffset())
205 metaCallReturnValue = dynamicParent->metaCall(o, call, id, a);
206 else
207 openMetaCall(o, call, id, a);
208
209
210 if (call == QMetaObject::WriteProperty
211 && !propertyById.hasNotifySignal()
212 && oldValue != propertyById.read(myObject()))
214
215 return metaCallReturnValue;
216}
217
219{
220 const QMetaProperty propertyById = property(id);
221
222 if (id < propertyOffset()) {
225 } else {
227 notifyPropertyChangeCallBack(myObject(), name(id - propertyOffset()));
228 }
229}
230
232{
233 return type()->propertyCount();
234}
235
237{
238 return type()->propertyName(idx);
239}
240
241void QQmlDesignerMetaObject::registerNotifyPropertyChangeCallBack(void (*callback)(QObject *, const QQuickDesignerSupport::PropertyName &))
242{
244}
245
246QT_END_NAMESPACE
int metaCall(QObject *o, QMetaObject::Call _c, int _id, void **_a) override
void createNewDynamicProperty(const QString &name)
QDynamicMetaObjectData * dynamicMetaObjectParent() const
static void registerNotifyPropertyChangeCallBack(void(*callback)(QObject *, const QQuickDesignerSupport::PropertyName &propertyName))
void setValue(int id, const QVariant &value)
QVariant propertyWriteValue(int, const QVariant &) override
int createProperty(const char *name, const char *passAlong) override
int openMetaCall(QObject *o, QMetaObject::Call _c, int _id, void **_a)
Combined button and popup list for selecting options.
static QT_BEGIN_NAMESPACE QHash< QDynamicMetaObjectData *, bool > nodeInstanceMetaObjectList
static void(* notifyPropertyChangeCallBack)(QObject *, const QQuickDesignerSupport::PropertyName &propertyName)
std::pair< QVariant, bool > & getDataRef(int idx)
bool hasData(int idx) const
QList< std::pair< QVariant, bool > > m_data
QVariant & getData(int idx)