forked from qt-creator/qt-creator
QmlPuppet: add workaround for reading list<> property crash
it skips the problematic QQmlProperty::read() calls Pick-to: qds/4.7 Change-Id: Ic28e0de2143c4543c0815eda27d3886af1524f80 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
@@ -347,7 +347,8 @@ void DesignerCustomObjectDataFork::populateResetHashes()
|
|||||||
if (binding) {
|
if (binding) {
|
||||||
m_resetBindingHash.insert(propertyName, binding);
|
m_resetBindingHash.insert(propertyName, binding);
|
||||||
} else if (property.isWritable()) {
|
} else if (property.isWritable()) {
|
||||||
m_resetValueHash.insert(propertyName, property.read());
|
if (!QmlPrivateGate::useCrashQTBUG136735Workaround(property, Q_FUNC_INFO))
|
||||||
|
m_resetValueHash.insert(propertyName, property.read());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -994,6 +995,53 @@ void registerFixResourcePathsForObjectCallBack()
|
|||||||
s_qrcEngineHandler = new QrcEngineHandler();
|
s_qrcEngineHandler = new QrcEngineHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool useCrashQTBUG136735Workaround(const QQmlProperty &property, const char *callerInfo)
|
||||||
|
{
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 4)
|
||||||
|
Q_UNUSED(property)
|
||||||
|
Q_UNUSED(callerInfo)
|
||||||
|
return false; // fixed in Qt
|
||||||
|
#else
|
||||||
|
if (!property.isValid())
|
||||||
|
return false;
|
||||||
|
auto coreMetaType = property.propertyMetaType();
|
||||||
|
|
||||||
|
// property.propertyTypeCategory() == QQmlProperty::PropertyTypeCategory::List
|
||||||
|
// for unknown reason the simple check is sometimes not working in the editor QMLPuppet
|
||||||
|
const bool listLike = coreMetaType.id() == QMetaType::QStringList
|
||||||
|
|| coreMetaType.id() == QMetaType::QVariantList
|
||||||
|
|| QtPrivate::hasRegisteredConverterFunctionToIterableMetaSequence(
|
||||||
|
coreMetaType);
|
||||||
|
|
||||||
|
if (!listLike)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const QMetaObject *metaObject = property.object()->metaObject();
|
||||||
|
QString ownerClassName;
|
||||||
|
|
||||||
|
do {
|
||||||
|
bool isDirectProperty = property.property().enclosingMetaObject() == metaObject;
|
||||||
|
if (isDirectProperty) {
|
||||||
|
ownerClassName = QString::fromLatin1(metaObject->className());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while ((metaObject = metaObject->superClass()));
|
||||||
|
|
||||||
|
// is generated QML type
|
||||||
|
static const QRegularExpression
|
||||||
|
re(QStringLiteral(R"(_QML(?:TYPE)?_\d+$)"), QRegularExpression::CaseInsensitiveOption);
|
||||||
|
if (!re.match(ownerClassName).hasMatch())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QString debugString("skipped read() on %1::%2 (direct owned list<T> property, QTBUG-136735)");
|
||||||
|
qWarning().noquote() << callerInfo
|
||||||
|
<< qPrintable(debugString.arg(ownerClassName, property.name()))
|
||||||
|
<< QString("propertyCategory(%3)").arg(property.propertyTypeCategory());
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace QmlPrivateGate
|
} // namespace QmlPrivateGate
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -24,6 +24,8 @@ typedef QWeakPointer<ObjectNodeInstance> ObjectNodeInstanceWeakPointer;
|
|||||||
|
|
||||||
namespace QmlPrivateGate {
|
namespace QmlPrivateGate {
|
||||||
|
|
||||||
|
bool useCrashQTBUG136735Workaround(const QQmlProperty &property, const char *callerInfo);
|
||||||
|
|
||||||
class ComponentCompleteDisabler
|
class ComponentCompleteDisabler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@@ -623,14 +623,16 @@ static bool isPropertyBlackListed(const PropertyName &propertyName)
|
|||||||
QVariant ObjectNodeInstance::property(const PropertyName &name) const
|
QVariant ObjectNodeInstance::property(const PropertyName &name) const
|
||||||
{
|
{
|
||||||
if (ignoredProperties().contains(name))
|
if (ignoredProperties().contains(name))
|
||||||
return QVariant();
|
return {};
|
||||||
|
|
||||||
// TODO: handle model nodes
|
// TODO: handle model nodes
|
||||||
|
|
||||||
if (isPropertyBlackListed(name))
|
if (isPropertyBlackListed(name))
|
||||||
return QVariant();
|
return {};
|
||||||
|
|
||||||
QQmlProperty property(object(), QString::fromUtf8(name), context());
|
QQmlProperty property(object(), QString::fromUtf8(name), context());
|
||||||
|
if (QmlPrivateGate::useCrashQTBUG136735Workaround(property, Q_FUNC_INFO))
|
||||||
|
return {};
|
||||||
if (property.property().isEnumType()) {
|
if (property.property().isEnumType()) {
|
||||||
QVariant value = property.read();
|
QVariant value = property.read();
|
||||||
QMetaEnum me = property.property().enumerator();
|
QMetaEnum me = property.property().enumerator();
|
||||||
@@ -640,7 +642,7 @@ QVariant ObjectNodeInstance::property(const PropertyName &name) const
|
|||||||
if (property.propertyType() == QMetaType::QUrl) {
|
if (property.propertyType() == QMetaType::QUrl) {
|
||||||
QUrl url = property.read().toUrl();
|
QUrl url = property.read().toUrl();
|
||||||
if (url.isEmpty())
|
if (url.isEmpty())
|
||||||
return QVariant();
|
return {};
|
||||||
|
|
||||||
if (url.scheme() == "file") {
|
if (url.scheme() == "file") {
|
||||||
QFileInfo fi{nodeInstanceServer()->fileUrl().toLocalFile()};
|
QFileInfo fi{nodeInstanceServer()->fileUrl().toLocalFile()};
|
||||||
|
Reference in New Issue
Block a user