10#include <QGlobalStatic>
14#include <private/qqmlanybinding_p.h>
18using namespace Qt::StringLiterals;
32 populateResetHashes();
33 s_designerObjectToDataHash()->insert(object,
this);
37 QObject::connect(object, &QObject::destroyed, functor);
48 return s_designerObjectToDataHash()->value(object);
56 return data->getResetValue(propertyName);
66 data->doResetProperty(context, propertyName);
74 return data->hasValidResetBinding(propertyName);
81 const QQuickDesignerSupport::PropertyName &propertyName,
87 return data->hasBindingForProperty(context, propertyName, hasChanged);
94 const QQuickDesignerSupport::PropertyName &propertyName,
95 const QString &expression)
100 data->setPropertyBinding(context, propertyName, expression);
104 QQmlContext *context,
105 const QQuickDesignerSupport::PropertyName &propertyName)
110 data->keepBindingFromGettingDeleted(context, propertyName);
115 const QQuickDesignerSupport::PropertyNameList propertyNameList =
116 QQuickDesignerSupportProperties::propertyNameListForWritableProperties(object());
118 const QMetaObject *mo = object()->metaObject();
119 QByteArrayList deferredPropertyNames;
120 const int namesIndex = mo->indexOfClassInfo(
"DeferredPropertyNames");
121 if (namesIndex != -1) {
122 QMetaClassInfo classInfo = mo->classInfo(namesIndex);
123 deferredPropertyNames = QByteArray(classInfo.value()).split(
',');
126 for (
const QQuickDesignerSupport::PropertyName &propertyName : propertyNameList) {
128 if (deferredPropertyNames.contains(propertyName))
131 QQmlProperty property(object(), QString::fromUtf8(propertyName), QQmlEngine::contextForObject(object()));
133 auto binding = QQmlAnyBinding::ofProperty(property);
136 m_resetBindingHash.insert(propertyName, binding);
137 }
else if (property.isWritable()) {
138 m_resetValueHash.insert(propertyName, property.read());
143QObject *QQuickDesignerCustomObjectData::object()
const
148QVariant QQuickDesignerCustomObjectData::getResetValue(
const QQuickDesignerSupport::PropertyName &propertyName)
const
150 return m_resetValueHash.value(propertyName);
153void QQuickDesignerCustomObjectData::doResetProperty(QQmlContext *context,
const QQuickDesignerSupport::PropertyName &propertyName)
155 QQmlProperty property(object(), QString::fromUtf8(propertyName), context);
157 if (!property.isValid())
161 QQmlAnyBinding::takeFrom(property);
164 if (hasValidResetBinding(propertyName)) {
165 QQmlAnyBinding binding = getResetBinding(propertyName);
166 binding.installOn(property);
168 if (binding.isAbstractPropertyBinding()) {
170 static_cast<QQmlBinding *>(binding.asAbstractBinding())->update();
173 }
else if (property.isResettable()) {
175 }
else if (property.propertyTypeCategory() == QQmlProperty::List) {
176 QQmlListReference list = qvariant_cast<QQmlListReference>(property.read());
178 if (!QQuickDesignerSupportProperties::hasFullImplementedListInterface(list)) {
179 qWarning() <<
"Property list interface not fully implemented for Class " << property.property().typeName() <<
" in property " << property.name() <<
"!";
184 }
else if (property.isWritable()) {
185 if (property.read() == getResetValue(propertyName))
188 property.write(getResetValue(propertyName));
192bool QQuickDesignerCustomObjectData::hasValidResetBinding(
const QQuickDesignerSupport::PropertyName &propertyName)
const
194 return m_resetBindingHash.contains(propertyName) && m_resetBindingHash.value(propertyName);
197QQmlAnyBinding QQuickDesignerCustomObjectData::getResetBinding(
const QQuickDesignerSupport::PropertyName &propertyName)
const
199 return m_resetBindingHash.value(propertyName);
202bool QQuickDesignerCustomObjectData::hasBindingForProperty(QQmlContext *context,
203 const QQuickDesignerSupport::PropertyName &propertyName,
204 bool *hasChanged)
const
206 if (QQuickDesignerSupportProperties::isPropertyBlackListed(propertyName))
209 QQmlProperty property(object(), QString::fromUtf8(propertyName), context);
211 bool hasBinding = QQmlAnyBinding::ofProperty(property);
214 *hasChanged = hasBinding != m_hasBindingHash.value(propertyName,
false);
216 m_hasBindingHash.insert(propertyName, hasBinding);
222void QQuickDesignerCustomObjectData::setPropertyBinding(QQmlContext *context,
223 const QQuickDesignerSupport::PropertyName &propertyName,
224 const QString &expression)
226 QQmlProperty property(object(), QString::fromUtf8(propertyName), context);
228 if (!property.isValid())
231 if (property.isProperty()) {
232 QString url = u"@designer"_s;
234 QQmlAnyBinding binding = QQmlAnyBinding::createFromCodeString(property,
235 expression, object(), QQmlContextData::get(context), url, lineNumber);
237 binding.installOn(property);
238 if (binding.isAbstractPropertyBinding()) {
240 static_cast<QQmlBinding *>(binding.asAbstractBinding())->update();
243 if (binding.hasError()) {
244 if (property.property().userType() == QMetaType::QString)
245 property.write(QVariant(QLatin1Char(
'#') + expression + QLatin1Char(
'#')));
249 qWarning() << Q_FUNC_INFO <<
": Cannot set binding for property" << propertyName <<
": property is unknown for type";
253void QQuickDesignerCustomObjectData::keepBindingFromGettingDeleted(QQmlContext *context,
254 const QQuickDesignerSupport::PropertyName &propertyName)
258 Q_UNUSED(propertyName);
261void QQuickDesignerCustomObjectData::handleDestroyed()
263 s_designerObjectToDataHash()->remove(m_object);
static void registerData(QObject *object)
static QQuickDesignerCustomObjectData * get(QObject *object)
Combined button and popup list for selecting options.
Q_GLOBAL_STATIC(QReadWriteLock, g_updateMutex)
QHash< QObject *, QQuickDesignerCustomObjectData * > CustomObjectDataHash
QQuickDesignerCustomObjectData * data