diff options
Diffstat (limited to 'src/tools/qml2puppet/qmlprivategate/qmlprivategate.cpp')
-rw-r--r-- | src/tools/qml2puppet/qmlprivategate/qmlprivategate.cpp | 624 |
1 files changed, 624 insertions, 0 deletions
diff --git a/src/tools/qml2puppet/qmlprivategate/qmlprivategate.cpp b/src/tools/qml2puppet/qmlprivategate/qmlprivategate.cpp new file mode 100644 index 0000000000..5d36ff8755 --- /dev/null +++ b/src/tools/qml2puppet/qmlprivategate/qmlprivategate.cpp @@ -0,0 +1,624 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0 WITH Qt-GPL-exception-1.0 + +#include "qmlprivategate.h" + +#include <objectnodeinstance.h> +#include <nodeinstanceserver.h> + +#include <QQuickItem> +#include <QQmlComponent> +#include <QFileInfo> +#include <QProcessEnvironment> + +#include <private/qabstractfileengine_p.h> +#include <private/qfsfileengine_p.h> + +#include <private/qquickdesignersupport_p.h> +#include <private/qquickdesignersupportmetainfo_p.h> +#include <private/qquickdesignersupportitems_p.h> +#include <private/qquickdesignersupportproperties_p.h> +#include <private/qquickdesignersupportpropertychanges_p.h> +#include <private/qquickdesignersupportstates_p.h> +#include <private/qqmldata_p.h> +#include <private/qqmlcomponentattached_p.h> + +#include <private/qabstractanimation_p.h> +#include <private/qobject_p.h> +#include <private/qquickbehavior_p.h> +#include <private/qquicktext_p.h> +#include <private/qquicktextinput_p.h> +#include <private/qquicktextedit_p.h> +#include <private/qquicktransition_p.h> +#include <private/qquickloader_p.h> + +#include <private/qquickanimation_p.h> +#include <private/qqmlmetatype_p.h> +#include <private/qqmltimer_p.h> + +#ifdef QUICK3D_MODULE +#include <private/qquick3dobject_p.h> +#include <private/qquick3drepeater_p.h> +#endif + +namespace QmlDesigner { + +namespace Internal { + +namespace QmlPrivateGate { + +bool isPropertyBlackListed(const QmlDesigner::PropertyName &propertyName) +{ + return QQuickDesignerSupportProperties::isPropertyBlackListed(propertyName); +} + +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) && (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) + +static void addToPropertyNameListIfNotBlackListed( + PropertyNameList *propertyNameList, const QQuickQQuickDesignerSupport::PropertyName &propertyName) +{ + if (!QQuickDesignerSupportProperties::isPropertyBlackListed(propertyName)) + propertyNameList->append(propertyName); +} + +PropertyNameList allPropertyNamesInline(QObject *object, + const PropertyName &baseName = {}, + QObjectList *inspectedObjects = nullptr, + int depth = 0) +{ + QQuickQQuickDesignerSupport::PropertyNameList propertyNameList; + + QObjectList localObjectList; + + if (inspectedObjects == nullptr) + inspectedObjects = &localObjectList; + + if (depth > 2) + return propertyNameList; + + if (!inspectedObjects->contains(object)) + inspectedObjects->append(object); + + const QMetaObject *metaObject = object->metaObject(); + + QStringList deferredPropertyNames; + const int namesIndex = metaObject->indexOfClassInfo("DeferredPropertyNames"); + if (namesIndex != -1) { + QMetaClassInfo classInfo = metaObject->classInfo(namesIndex); + deferredPropertyNames = QString::fromUtf8(classInfo.value()).split(QLatin1Char(',')); + } + + for (int index = 0; index < metaObject->propertyCount(); ++index) { + QMetaProperty metaProperty = metaObject->property(index); + QQmlProperty declarativeProperty(object, QString::fromUtf8(metaProperty.name())); + if (declarativeProperty.isValid() + && declarativeProperty.propertyTypeCategory() == QQmlProperty::Object) { + if (declarativeProperty.name() != QLatin1String("parent") + && !deferredPropertyNames.contains(declarativeProperty.name())) { + QObject *childObject = QQmlMetaType::toQObject(declarativeProperty.read()); + if (childObject) + propertyNameList.append( + allPropertyNamesInline(childObject, + baseName + + QQuickQQuickDesignerSupport::PropertyName( + metaProperty.name()) + + '.', + inspectedObjects, + depth + 1)); + } + } else if (QQmlGadgetPtrWrapper *valueType + = QQmlGadgetPtrWrapper::instance(qmlEngine(object), metaProperty.userType())) { + valueType->setValue(metaProperty.read(object)); + propertyNameList.append(baseName + + QQuickQQuickDesignerSupport::PropertyName(metaProperty.name())); + propertyNameList.append( + allPropertyNamesInline(valueType, + baseName + + QQuickQQuickDesignerSupport::PropertyName(metaProperty.name()) + + '.', + inspectedObjects, + depth + 1)); + } else { + addToPropertyNameListIfNotBlackListed(&propertyNameList, + baseName + + QQuickQQuickDesignerSupport::PropertyName( + metaProperty.name())); + } + } + + return propertyNameList; +} +#endif + +PropertyNameList allPropertyNames(QObject *object) +{ +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + return QQuickDesignerSupportProperties::allPropertyNames(object); +#elif QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) + return allPropertyNamesInline(object); +#else + return QQuickDesignerSupportProperties::allPropertyNames(object); +#endif +} + +PropertyNameList propertyNameListForWritableProperties(QObject *object) +{ + return QQuickDesignerSupportProperties::propertyNameListForWritableProperties(object); +} + +void tweakObjects(QObject *object) +{ + QQuickDesignerSupportItems::tweakObjects(object); +} + +void createNewDynamicProperty(QObject *object, QQmlEngine *engine, const QString &name) +{ + QQuickDesignerSupportProperties::createNewDynamicProperty(object, engine, name); +} + +void registerNodeInstanceMetaObject(QObject *object, QQmlEngine *engine) +{ + QQuickDesignerSupportProperties::registerNodeInstanceMetaObject(object, engine); +} + +static bool isMetaObjectofType(const QMetaObject *metaObject, const QByteArray &type) +{ + if (metaObject) { + if (metaObject->className() == type) + return true; + + return isMetaObjectofType(metaObject->superClass(), type); + } + + return false; +} + +static bool isQuickStyleItem(QObject *object) +{ + if (object) + return isMetaObjectofType(object->metaObject(), "QQuickStyleItem"); + + return false; +} + +static bool isDelegateModel(QObject *object) +{ + if (object) + return isMetaObjectofType(object->metaObject(), "QQmlDelegateModel"); + + return false; +} + +// This is used in share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp +QObject *createPrimitive(const QString &typeName, int majorNumber, int minorNumber, QQmlContext *context) +{ +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + + QTypeRevision revision = QTypeRevision::zero(); + if (majorNumber > 0) + revision = QTypeRevision::fromVersion(majorNumber, minorNumber); + return QQuickDesignerSupportItems::createPrimitive(typeName, revision, context); +#else + return QQuickDesignerSupportItems::createPrimitive(typeName, majorNumber, minorNumber, context); +#endif +} + +static QString qmlDesignerRCPath() +{ + static const QString qmlDesignerRcPathsString = QString::fromLocal8Bit( + qgetenv("QMLDESIGNER_RC_PATHS")); + return qmlDesignerRcPathsString; +} + +QVariant fixResourcePaths(const QVariant &value) +{ + if (value.type() == QVariant::Url) + { + const QUrl url = value.toUrl(); + if (url.scheme() == QLatin1String("qrc")) { + const QString path = QLatin1String("qrc:") + url.path(); + if (!qmlDesignerRCPath().isEmpty()) { + const QStringList searchPaths = qmlDesignerRCPath().split(QLatin1Char(';')); + foreach (const QString &qrcPath, searchPaths) { + const QStringList qrcDefintion = qrcPath.split(QLatin1Char('=')); + if (qrcDefintion.count() == 2) { + QString fixedPath = path; + fixedPath.replace(QLatin1String("qrc:") + qrcDefintion.first(), qrcDefintion.last() + QLatin1Char('/')); + if (QFileInfo::exists(fixedPath)) { + fixedPath.replace(QLatin1String("//"), QLatin1String("/")); + fixedPath.replace(QLatin1Char('\\'), QLatin1Char('/')); + return QUrl::fromLocalFile(fixedPath); + } + } + } + } + } + } + if (value.type() == QVariant::String) { + const QString str = value.toString(); + if (str.contains(QLatin1String("qrc:"))) { + if (!qmlDesignerRCPath().isEmpty()) { + const QStringList searchPaths = qmlDesignerRCPath().split(QLatin1Char(';')); + foreach (const QString &qrcPath, searchPaths) { + const QStringList qrcDefintion = qrcPath.split(QLatin1Char('=')); + if (qrcDefintion.count() == 2) { + QString fixedPath = str; + fixedPath.replace(QLatin1String("qrc:") + qrcDefintion.first(), qrcDefintion.last() + QLatin1Char('/')); + if (QFileInfo::exists(fixedPath)) { + fixedPath.replace(QLatin1String("//"), QLatin1String("/")); + fixedPath.replace(QLatin1Char('\\'), QLatin1Char('/')); + return QUrl::fromLocalFile(fixedPath); + } + } + } + } + } + } + return value; +} + +QObject *createComponent(const QUrl &componentUrl, QQmlContext *context) +{ + return QQuickDesignerSupportItems::createComponent(componentUrl, context); +} + +bool hasFullImplementedListInterface(const QQmlListReference &list) +{ + return list.isValid() && list.canCount() && list.canAt() && list.canAppend() && list.canClear(); +} + +void registerCustomData(QObject *object) +{ + QQuickDesignerSupportProperties::registerCustomData(object); +} + +QVariant getResetValue(QObject *object, const PropertyName &propertyName) +{ + if (propertyName == "Layout.rowSpan") + return 1; + else if (propertyName == "Layout.columnSpan") + return 1; + else if (propertyName == "Layout.fillHeight") + return false; + else if (propertyName == "Layout.fillWidth") + return false; + else + return QQuickDesignerSupportProperties::getResetValue(object, propertyName); +} + +static void setProperty(QObject *object, QQmlContext *context, const PropertyName &propertyName, const QVariant &value) +{ + QQmlProperty property(object, QString::fromUtf8(propertyName), context); + property.write(value); +} + +void doResetProperty(QObject *object, QQmlContext *context, const PropertyName &propertyName) +{ + if (propertyName == "Layout.rowSpan") + setProperty(object, context, propertyName, getResetValue(object, propertyName)); + else if (propertyName == "Layout.columnSpan") + setProperty(object, context, propertyName, getResetValue(object, propertyName)); + else if (propertyName == "Layout.fillHeight") + setProperty(object, context, propertyName, getResetValue(object, propertyName)); + else if (propertyName == "Layout.fillWidth") + setProperty(object, context, propertyName, getResetValue(object, propertyName)); + else + QQuickDesignerSupportProperties::doResetProperty(object, context, propertyName); +} + +bool hasValidResetBinding(QObject *object, const PropertyName &propertyName) +{ + if (propertyName == "Layout.rowSpan") + return true; + else if (propertyName == "Layout.columnSpan") + return true; + else if (propertyName == "Layout.fillHeight") + return true; + else if (propertyName == "Layout.fillWidth") + return true; + return QQuickDesignerSupportProperties::hasValidResetBinding(object, propertyName); +} + +bool hasBindingForProperty(QObject *object, QQmlContext *context, const PropertyName &propertyName, bool *hasChanged) +{ + return QQuickDesignerSupportProperties::hasBindingForProperty(object, context, propertyName, hasChanged); +} + +void setPropertyBinding(QObject *object, QQmlContext *context, const PropertyName &propertyName, const QString &expression) +{ + QQuickDesignerSupportProperties::setPropertyBinding(object, context, propertyName, expression); +} + +void emitComponentComplete(QObject *item) +{ + if (!item) + return; + + QQmlData *data = QQmlData::get(item); + if (data && data->context) { +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + QQmlComponentAttached *componentAttached = data->context->componentAttached; +#else + QQmlComponentAttached *componentAttached = data->context->componentAttacheds(); +#endif + while (componentAttached) { + if (componentAttached->parent()) + if (componentAttached->parent() == item) + emit componentAttached->completed(); + +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + componentAttached = componentAttached->next; +#else + componentAttached = componentAttached->next(); +#endif + } + } +} + +void doComponentCompleteRecursive(QObject *object, NodeInstanceServer *nodeInstanceServer) +{ + if (object) { + QQuickItem *item = qobject_cast<QQuickItem*>(object); + + if (item && QQuickDesignerSupport::isComponentComplete(item)) + return; +#ifdef QUICK3D_MODULE + auto obj3d = qobject_cast<QQuick3DRepeater *>(object); + if (obj3d && QQuick3DObjectPrivate::get(obj3d)->componentComplete) + return; +#endif + + if (!nodeInstanceServer->hasInstanceForObject(item)) + emitComponentComplete(object); + QList<QObject*> childList = object->children(); + + if (item) { + foreach (QQuickItem *childItem, item->childItems()) { + if (!childList.contains(childItem)) + childList.append(childItem); + } + } + + foreach (QObject *child, childList) { + if (!nodeInstanceServer->hasInstanceForObject(child)) + doComponentCompleteRecursive(child, nodeInstanceServer); + } + + if (!isQuickStyleItem(object) && !isDelegateModel(object)) { + if (item) { + static_cast<QQmlParserStatus *>(item)->componentComplete(); + } else { + QQmlParserStatus *qmlParserStatus = dynamic_cast<QQmlParserStatus *>(object); + if (qmlParserStatus) { + qmlParserStatus->componentComplete(); + auto *anim = dynamic_cast<QQuickAbstractAnimation *>(object); + if (anim && ViewConfig::isParticleViewMode()) { + nodeInstanceServer->addAnimation(anim); + anim->setEnableUserControl(); + anim->stop(); + } + } + } + } + } +} + + +void keepBindingFromGettingDeleted(QObject *object, QQmlContext *context, const PropertyName &propertyName) +{ + QQuickDesignerSupportProperties::keepBindingFromGettingDeleted(object, context, propertyName); +} + +bool objectWasDeleted(QObject *object) +{ + return QQuickDesignerSupportItems::objectWasDeleted(object); +} + +void disableNativeTextRendering(QQuickItem *item) +{ + QQuickDesignerSupportItems::disableNativeTextRendering(item); +} + +void disableTextCursor(QQuickItem *item) +{ + QQuickDesignerSupportItems::disableTextCursor(item); +} + +void disableTransition(QObject *object) +{ + QQuickDesignerSupportItems::disableTransition(object); +} + +void disableBehaivour(QObject *object) +{ + QQuickDesignerSupportItems::disableBehaivour(object); +} + +void stopUnifiedTimer() +{ + QQuickDesignerSupportItems::stopUnifiedTimer(); +} + +bool isPropertyQObject(const QMetaProperty &metaProperty) +{ + return QQuickDesignerSupportProperties::isPropertyQObject(metaProperty); +} + +QObject *readQObjectProperty(const QMetaProperty &metaProperty, QObject *object) +{ + return QQuickDesignerSupportProperties::readQObjectProperty(metaProperty, object); +} + +namespace States { + +bool isStateActive(QObject *object, QQmlContext *context) +{ + + return QQuickDesignerSupportStates::isStateActive(object, context); +} + +void activateState(QObject *object, QQmlContext *context) +{ + QQuickDesignerSupportStates::activateState(object, context); +} + +void deactivateState(QObject *object) +{ + QQuickDesignerSupportStates::deactivateState(object); +} + +bool changeValueInRevertList(QObject *state, QObject *target, const PropertyName &propertyName, const QVariant &value) +{ + return QQuickDesignerSupportStates::changeValueInRevertList(state, target, propertyName, value); +} + +bool updateStateBinding(QObject *state, QObject *target, const PropertyName &propertyName, const QString &expression) +{ + return QQuickDesignerSupportStates::updateStateBinding(state, target, propertyName, expression); +} + +bool resetStateProperty(QObject *state, QObject *target, const PropertyName &propertyName, const QVariant &value) +{ + return QQuickDesignerSupportStates::resetStateProperty(state, target, propertyName, value); +} + +} //namespace States + +namespace PropertyChanges { + +void detachFromState(QObject *propertyChanges) +{ + return QQuickDesignerSupportPropertyChanges::detachFromState(propertyChanges); +} + +void attachToState(QObject *propertyChanges) +{ + return QQuickDesignerSupportPropertyChanges::attachToState(propertyChanges); +} + +QObject *targetObject(QObject *propertyChanges) +{ + return QQuickDesignerSupportPropertyChanges::targetObject(propertyChanges); +} + +void removeProperty(QObject *propertyChanges, const PropertyName &propertyName) +{ + QQuickDesignerSupportPropertyChanges::removeProperty(propertyChanges, propertyName); +} + +QVariant getProperty(QObject *propertyChanges, const PropertyName &propertyName) +{ + return QQuickDesignerSupportPropertyChanges::getProperty(propertyChanges, propertyName); +} + +void changeValue(QObject *propertyChanges, const PropertyName &propertyName, const QVariant &value) +{ + QQuickDesignerSupportPropertyChanges::changeValue(propertyChanges, propertyName, value); +} + +void changeExpression(QObject *propertyChanges, const PropertyName &propertyName, const QString &expression) +{ + QQuickDesignerSupportPropertyChanges::changeExpression(propertyChanges, propertyName, expression); +} + +QObject *stateObject(QObject *propertyChanges) +{ + return QQuickDesignerSupportPropertyChanges::stateObject(propertyChanges); +} + +bool isNormalProperty(const PropertyName &propertyName) +{ + return QQuickDesignerSupportPropertyChanges::isNormalProperty(propertyName); +} + +} // namespace PropertyChanges + +bool isSubclassOf(QObject *object, const QByteArray &superTypeName) +{ + return QQuickDesignerSupportMetaInfo::isSubclassOf(object, superTypeName); +} + +void getPropertyCache(QObject *object, QQmlEngine *engine) +{ +#if QT_VERSION < QT_VERSION_CHECK(6, 4, 0) + QQuickDesignerSupportProperties::getPropertyCache(object, engine); +#else + Q_UNUSED(engine); + QQuickDesignerSupportProperties::getPropertyCache(object); +#endif +} + +void registerNotifyPropertyChangeCallBack(void (*callback)(QObject *, const PropertyName &)) +{ + QQuickDesignerSupportMetaInfo::registerNotifyPropertyChangeCallBack(callback); +} + +ComponentCompleteDisabler::ComponentCompleteDisabler() +{ + QQuickDesignerSupport::disableComponentComplete(); +} + +ComponentCompleteDisabler::~ComponentCompleteDisabler() +{ + QQuickDesignerSupport::enableComponentComplete(); +} + +class QrcEngineHandler : public QAbstractFileEngineHandler +{ +public: + QAbstractFileEngine *create(const QString &fileName) const final; +}; + +QAbstractFileEngine *QrcEngineHandler::create(const QString &fileName) const +{ + if (fileName.startsWith(":/qt-project.org")) + return nullptr; + + if (fileName.startsWith(":/qtquickplugin")) + return nullptr; + + if (fileName.startsWith(":/")) { + const QStringList searchPaths = qmlDesignerRCPath().split(';'); + foreach (const QString &qrcPath, searchPaths) { + const QStringList qrcDefintion = qrcPath.split('='); + if (qrcDefintion.count() == 2) { + QString fixedPath = fileName; + fixedPath.replace(":" + qrcDefintion.first(), qrcDefintion.last() + '/'); + + if (fileName == fixedPath) + return nullptr; + + if (QFileInfo::exists(fixedPath)) { + fixedPath.replace("//", "/"); + fixedPath.replace('\\', '/'); + return new QFSFileEngine(fixedPath); + } + } + } + } + + return nullptr; +} + +static QrcEngineHandler* s_qrcEngineHandler = nullptr; + +class EngineHandlerDeleter +{ +public: + EngineHandlerDeleter() + {} + ~EngineHandlerDeleter() + { delete s_qrcEngineHandler; } +}; + +void registerFixResourcePathsForObjectCallBack() +{ + static EngineHandlerDeleter deleter; + + if (!s_qrcEngineHandler) + s_qrcEngineHandler = new QrcEngineHandler(); +} + +} // namespace QmlPrivateGate +} // namespace Internal +} // namespace QmlDesigner |