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
qquickdesignercustomobjectdata.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
6
8
9#include <QGlobalStatic>
10#include <QQmlContext>
11#include <QQmlEngine>
12
13#include <private/qqmlanybinding_p.h>
14
16
17using namespace Qt::StringLiterals;
18
19typedef QHash<QObject*, QQuickDesignerCustomObjectData*> CustomObjectDataHash;
20Q_GLOBAL_STATIC(CustomObjectDataHash, s_designerObjectToDataHash)
21
26
27QQuickDesignerCustomObjectData::QQuickDesignerCustomObjectData(QObject *object)
28 : m_object(object)
29{
30 if (object) {
31 populateResetHashes();
32 s_designerObjectToDataHash()->insert(object, this);
33
35 functor.data = this;
36 QObject::connect(object, &QObject::destroyed, functor);
37 }
38}
39
44
46{
47 return s_designerObjectToDataHash()->value(object);
48}
49
51{
53
54 if (data)
55 return data->getResetValue(propertyName);
56
57 return QVariant();
58}
59
61{
63
64 if (data)
65 data->doResetProperty(context, propertyName);
66}
67
69{
71
72 if (data)
73 return data->hasValidResetBinding(propertyName);
74
75 return false;
76}
77
80 const QQuickDesignerSupport::PropertyName &propertyName,
81 bool *hasChanged)
82{
84
85 if (data)
86 return data->hasBindingForProperty(context, propertyName, hasChanged);
87
88 return false;
89}
90
93 const QQuickDesignerSupport::PropertyName &propertyName,
94 const QString &expression)
95{
97
98 if (data)
99 data->setPropertyBinding(context, propertyName, expression);
100}
101
104 const QQuickDesignerSupport::PropertyName &propertyName)
105{
107
108 if (data)
109 data->keepBindingFromGettingDeleted(context, propertyName);
110}
111
112void QQuickDesignerCustomObjectData::populateResetHashes()
113{
114 const QQuickDesignerSupport::PropertyNameList propertyNameList =
116
117 const QMetaObject *mo = object()->metaObject();
118 QByteArrayList deferredPropertyNames;
119 const int namesIndex = mo->indexOfClassInfo("DeferredPropertyNames");
120 if (namesIndex != -1) {
121 QMetaClassInfo classInfo = mo->classInfo(namesIndex);
122 deferredPropertyNames = QByteArray(classInfo.value()).split(',');
123 }
124
125 for (const QQuickDesignerSupport::PropertyName &propertyName : propertyNameList) {
126
127 if (deferredPropertyNames.contains(propertyName))
128 continue;
129
130 QQmlProperty property(object(), QString::fromUtf8(propertyName), QQmlEngine::contextForObject(object()));
131
132 auto binding = QQmlAnyBinding::ofProperty(property);
133
134 if (binding) {
135 m_resetBindingHash.insert(propertyName, binding);
136 } else if (property.isWritable()) {
137 m_resetValueHash.insert(propertyName, property.read());
138 }
139 }
140}
141
142QObject *QQuickDesignerCustomObjectData::object() const
143{
144 return m_object;
145}
146
148{
149 return m_resetValueHash.value(propertyName);
150}
151
153{
154 QQmlProperty property(object(), QString::fromUtf8(propertyName), context);
155
156 if (!property.isValid())
157 return;
158
159 // remove existing binding
161
162
163 if (hasValidResetBinding(propertyName)) {
164 QQmlAnyBinding binding = getResetBinding(propertyName);
165 binding.installOn(property);
166
167 if (binding.isAbstractPropertyBinding()) {
168 // for new style properties, we will evaluate during setBinding anyway
169 static_cast<QQmlBinding *>(binding.asAbstractBinding())->update();
170 }
171
172 } else if (property.isResettable()) {
173 property.reset();
174 } else if (property.propertyTypeCategory() == QQmlProperty::List) {
175 QQmlListReference list = qvariant_cast<QQmlListReference>(property.read());
176
178 qWarning() << "Property list interface not fully implemented for Class " << property.property().typeName() << " in property " << property.name() << "!";
179 return;
180 }
181
182 list.clear();
183 } else if (property.isWritable()) {
184 if (property.read() == getResetValue(propertyName))
185 return;
186
187 property.write(getResetValue(propertyName));
188 }
189}
190
192{
193 return m_resetBindingHash.contains(propertyName) && m_resetBindingHash.value(propertyName);
194}
195
196QQmlAnyBinding QQuickDesignerCustomObjectData::getResetBinding(const QQuickDesignerSupport::PropertyName &propertyName) const
197{
198 return m_resetBindingHash.value(propertyName);
199}
200
202 const QQuickDesignerSupport::PropertyName &propertyName,
203 bool *hasChanged) const
204{
206 return false;
207
208 QQmlProperty property(object(), QString::fromUtf8(propertyName), context);
209
210 bool hasBinding = QQmlAnyBinding::ofProperty(property);
211
212 if (hasChanged) {
213 *hasChanged = hasBinding != m_hasBindingHash.value(propertyName, false);
214 if (*hasChanged)
215 m_hasBindingHash.insert(propertyName, hasBinding);
216 }
217
218 return hasBinding;
219}
220
222 const QQuickDesignerSupport::PropertyName &propertyName,
223 const QString &expression)
224{
225 QQmlProperty property(object(), QString::fromUtf8(propertyName), context);
226
227 if (!property.isValid())
228 return;
229
230 if (property.isProperty()) {
231 QString url = u"@designer"_s;
232 int lineNumber = 0;
234 expression, object(), QQmlContextData::get(context), url, lineNumber);
235
236 binding.installOn(property);
237 if (binding.isAbstractPropertyBinding()) {
238 // for new style properties, we will evaluate during setBinding anyway
239 static_cast<QQmlBinding *>(binding.asAbstractBinding())->update();
240 }
241
242 if (binding.hasError()) {
243 if (property.property().userType() == QMetaType::QString)
244 property.write(QVariant(QLatin1Char('#') + expression + QLatin1Char('#')));
245 }
246
247 } else {
248 qWarning() << Q_FUNC_INFO << ": Cannot set binding for property" << propertyName << ": property is unknown for type";
249 }
250}
251
253 const QQuickDesignerSupport::PropertyName &propertyName)
254{
255 //Refcounting is taking care
257 Q_UNUSED(propertyName);
258}
259
261{
262 s_designerObjectToDataHash()->remove(m_object);
263 delete this;
264}
265
267
\inmodule QtCore
\inmodule QtCore
Definition qbytearray.h:57
void clear()
Definition qlist.h:434
\inmodule QtCore
\inmodule QtCore
Definition qobject.h:103
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
void destroyed(QObject *=nullptr)
This signal is emitted immediately before the object obj is destroyed, after any instances of QPointe...
QQmlAnyBinding is an abstraction over the various bindings in QML.
static QQmlAnyBinding createFromCodeString(const QQmlProperty &prop, const QString &code, QObject *obj, const QQmlRefPointer< QQmlContextData > &ctxt, const QString &url, quint16 lineNumber)
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
void installOn(const QQmlProperty &target, InterceptorMode mode=IgnoreInterceptors)
bool isAbstractPropertyBinding() const
static QQmlAnyBinding ofProperty(const QQmlProperty &prop)
static QQmlRefPointer< QQmlContextData > get(QQmlContext *context)
The QQmlContext class defines a context within a QML engine.
Definition qqmlcontext.h:25
static QQmlContext * contextForObject(const QObject *)
Returns the QQmlContext for the object, or nullptr if no context has been set.
The QQmlListReference class allows the manipulation of QQmlListProperty properties.
Definition qqmllist.h:183
The QQmlProperty class abstracts accessing properties on objects created from QML.
static void doResetProperty(QObject *object, QQmlContext *context, const QQuickDesignerSupport::PropertyName &propertyName)
static void setPropertyBinding(QObject *object, QQmlContext *context, const QQuickDesignerSupport::PropertyName &propertyName, const QString &expression)
static bool hasValidResetBinding(QObject *object, const QQuickDesignerSupport::PropertyName &propertyName)
static QVariant getResetValue(QObject *object, const QQuickDesignerSupport::PropertyName &propertyName)
static bool hasBindingForProperty(QObject *object, QQmlContext *context, const QQuickDesignerSupport::PropertyName &propertyName, bool *hasChanged)
static void keepBindingFromGettingDeleted(QObject *object, QQmlContext *context, const QQuickDesignerSupport::PropertyName &propertyName)
static QQuickDesignerCustomObjectData * get(QObject *object)
static QQuickDesignerSupport::PropertyNameList propertyNameListForWritableProperties(QObject *object)
static bool hasFullImplementedListInterface(const QQmlListReference &list)
static bool isPropertyBlackListed(const QQuickDesignerSupport::PropertyName &propertyName)
QList< PropertyName > PropertyNameList
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:6018
\inmodule QtCore
Definition qvariant.h:65
auto mo
[7]
Combined button and popup list for selecting options.
static void * context
#define Q_FUNC_INFO
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
#define qWarning
Definition qlogging.h:166
GLuint object
[3]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
QHash< QObject *, QQuickDesignerCustomObjectData * > CustomObjectDataHash
#define Q_UNUSED(x)
const char property[13]
Definition qwizard.cpp:101
QList< int > list
[14]
QUrl url("example.com")
[constructor-url-reference]
QQuickDesignerCustomObjectData * data
\inmodule QtCore \reentrant
Definition qchar.h:18
\inmodule QtCore