9#include <QGlobalStatic>
13#include <private/qqmlanybinding_p.h>
17using namespace Qt::StringLiterals;
31 populateResetHashes();
32 s_designerObjectToDataHash()->insert(object,
this);
36 QObject::connect(object, &QObject::destroyed, functor);
47 return s_designerObjectToDataHash()->value(object);
55 return data->getResetValue(propertyName);
65 data->doResetProperty(context, propertyName);
73 return data->hasValidResetBinding(propertyName);
80 const QQuickDesignerSupport::PropertyName &propertyName,
86 return data->hasBindingForProperty(context, propertyName, hasChanged);
93 const QQuickDesignerSupport::PropertyName &propertyName,
94 const QString &expression)
99 data->setPropertyBinding(context, propertyName, expression);
103 QQmlContext *context,
104 const QQuickDesignerSupport::PropertyName &propertyName)
109 data->keepBindingFromGettingDeleted(context, propertyName);
114 const QQuickDesignerSupport::PropertyNameList propertyNameList =
115 QQuickDesignerSupportProperties::propertyNameListForWritableProperties(object());
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(
',');
125 for (
const QQuickDesignerSupport::PropertyName &propertyName : propertyNameList) {
127 if (deferredPropertyNames.contains(propertyName))
130 QQmlProperty property(object(), QString::fromUtf8(propertyName), QQmlEngine::contextForObject(object()));
132 auto binding = QQmlAnyBinding::ofProperty(property);
135 m_resetBindingHash.insert(propertyName, binding);
136 }
else if (property.isWritable()) {
137 m_resetValueHash.insert(propertyName, property.read());
142QObject *QQuickDesignerCustomObjectData::object()
const
147QVariant QQuickDesignerCustomObjectData::getResetValue(
const QQuickDesignerSupport::PropertyName &propertyName)
const
149 return m_resetValueHash.value(propertyName);
152void QQuickDesignerCustomObjectData::doResetProperty(QQmlContext *context,
const QQuickDesignerSupport::PropertyName &propertyName)
154 QQmlProperty property(object(), QString::fromUtf8(propertyName), context);
156 if (!property.isValid())
160 QQmlAnyBinding::takeFrom(property);
163 if (hasValidResetBinding(propertyName)) {
164 QQmlAnyBinding binding = getResetBinding(propertyName);
165 binding.installOn(property);
167 if (binding.isAbstractPropertyBinding()) {
169 static_cast<QQmlBinding *>(binding.asAbstractBinding())->update();
172 }
else if (property.isResettable()) {
174 }
else if (property.propertyTypeCategory() == QQmlProperty::List) {
175 QQmlListReference list = qvariant_cast<QQmlListReference>(property.read());
177 if (!QQuickDesignerSupportProperties::hasFullImplementedListInterface(list)) {
178 qWarning() <<
"Property list interface not fully implemented for Class " << property.property().typeName() <<
" in property " << property.name() <<
"!";
183 }
else if (property.isWritable()) {
184 if (property.read() == getResetValue(propertyName))
187 property.write(getResetValue(propertyName));
191bool QQuickDesignerCustomObjectData::hasValidResetBinding(
const QQuickDesignerSupport::PropertyName &propertyName)
const
193 return m_resetBindingHash.contains(propertyName) && m_resetBindingHash.value(propertyName);
196QQmlAnyBinding QQuickDesignerCustomObjectData::getResetBinding(
const QQuickDesignerSupport::PropertyName &propertyName)
const
198 return m_resetBindingHash.value(propertyName);
201bool QQuickDesignerCustomObjectData::hasBindingForProperty(QQmlContext *context,
202 const QQuickDesignerSupport::PropertyName &propertyName,
203 bool *hasChanged)
const
205 if (QQuickDesignerSupportProperties::isPropertyBlackListed(propertyName))
208 QQmlProperty property(object(), QString::fromUtf8(propertyName), context);
210 bool hasBinding = QQmlAnyBinding::ofProperty(property);
213 *hasChanged = hasBinding != m_hasBindingHash.value(propertyName,
false);
215 m_hasBindingHash.insert(propertyName, hasBinding);
221void QQuickDesignerCustomObjectData::setPropertyBinding(QQmlContext *context,
222 const QQuickDesignerSupport::PropertyName &propertyName,
223 const QString &expression)
225 QQmlProperty property(object(), QString::fromUtf8(propertyName), context);
227 if (!property.isValid())
230 if (property.isProperty()) {
231 QString url = u"@designer"_s;
233 QQmlAnyBinding binding = QQmlAnyBinding::createFromCodeString(property,
234 expression, object(), QQmlContextData::get(context), url, lineNumber);
236 binding.installOn(property);
237 if (binding.isAbstractPropertyBinding()) {
239 static_cast<QQmlBinding *>(binding.asAbstractBinding())->update();
242 if (binding.hasError()) {
243 if (property.property().userType() == QMetaType::QString)
244 property.write(QVariant(QLatin1Char(
'#') + expression + QLatin1Char(
'#')));
248 qWarning() << Q_FUNC_INFO <<
": Cannot set binding for property" << propertyName <<
": property is unknown for type";
252void QQuickDesignerCustomObjectData::keepBindingFromGettingDeleted(QQmlContext *context,
253 const QQuickDesignerSupport::PropertyName &propertyName)
257 Q_UNUSED(propertyName);
260void QQuickDesignerCustomObjectData::handleDestroyed()
262 s_designerObjectToDataHash()->remove(m_object);
static void registerData(QObject *object)
static QQuickDesignerCustomObjectData * get(QObject *object)
Q_GLOBAL_STATIC(QReadWriteLock, g_updateMutex)
QHash< QObject *, QQuickDesignerCustomObjectData * > CustomObjectDataHash
QQuickDesignerCustomObjectData * data