From fd258651bde204459ab4668f84e1da6864a7e9c7 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 10 Mar 2025 16:21:37 +0200 Subject: [PATCH] QmlDesigner: Separate property view dynamic properties handling Now property view and connections view have separate dynamic property handling. This allows property view to change dynamic properties when connections view is detached, and also will better support the upcoming selection locking feature in property view. Fixes: QDS-14891 Change-Id: Ic1a03a635ec595800f995ac5920b7e94f7dc0ab9 Reviewed-by: Ali Kianian Reviewed-by: Thomas Hartmann Reviewed-by: Mahmoud Badri --- .../QtQuick/ItemPane.qml | 2 +- .../QtQuick/QtObjectPane.qml | 2 +- .../QtQuick3D/MaterialPane.qml | 2 +- .../QtQuick3D/Object3DPane.qml | 2 +- .../QtQuick3D/TexturePane.qml | 2 +- src/plugins/qmldesigner/CMakeLists.txt | 1 + ...pertyeditordynamicpropertiesproxymodel.cpp | 47 +++++++++++++++++++ ...ropertyeditordynamicpropertiesproxymodel.h | 41 ++++++++++++++++ .../propertyeditor/propertyeditorview.cpp | 46 +++++++++++++++++- .../propertyeditor/propertyeditorview.h | 9 ++++ .../quick2propertyeditorview.cpp | 4 +- 11 files changed, 150 insertions(+), 8 deletions(-) create mode 100644 src/plugins/qmldesigner/components/propertyeditor/propertyeditordynamicpropertiesproxymodel.cpp create mode 100644 src/plugins/qmldesigner/components/propertyeditor/propertyeditordynamicpropertiesproxymodel.h diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml index aeef8a9598e..9e80c293192 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml @@ -20,7 +20,7 @@ PropertyEditorPane { } DynamicPropertiesSection { - propertiesModel: SelectionDynamicPropertiesModel {} + propertiesModel: PropertyEditorDynamicPropertiesModel {} visible: !hasMultiSelection } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/QtObjectPane.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/QtObjectPane.qml index 12be7b8f346..78e0c2fd480 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/QtObjectPane.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/QtObjectPane.qml @@ -12,7 +12,7 @@ PropertyEditorPane { ComponentSection {} DynamicPropertiesSection { - propertiesModel: SelectionDynamicPropertiesModel {} + propertiesModel: PropertyEditorDynamicPropertiesModel {} visible: !hasMultiSelection } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/MaterialPane.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/MaterialPane.qml index 099ed904bba..b8174ad4be6 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/MaterialPane.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/MaterialPane.qml @@ -82,7 +82,7 @@ Item { } DynamicPropertiesSection { - propertiesModel: SelectionDynamicPropertiesModel {} + propertiesModel: PropertyEditorDynamicPropertiesModel {} visible: !hasMultiSelection } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Object3DPane.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Object3DPane.qml index e4f7554442c..142bd08ef64 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Object3DPane.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/Object3DPane.qml @@ -18,7 +18,7 @@ PropertyEditorPane { anchors.right: parent.right DynamicPropertiesSection { - propertiesModel: SelectionDynamicPropertiesModel {} + propertiesModel: PropertyEditorDynamicPropertiesModel {} visible: !hasMultiSelection } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/TexturePane.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/TexturePane.qml index a7a3613c663..e7c25024108 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/TexturePane.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick3D/TexturePane.qml @@ -45,7 +45,7 @@ Rectangle { Layout.fillHeight: true DynamicPropertiesSection { - propertiesModel: SelectionDynamicPropertiesModel {} + propertiesModel: PropertyEditorDynamicPropertiesModel {} visible: !hasMultiSelection } diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index 919ef925df3..e2d3d8303d2 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -423,6 +423,7 @@ extend_qtc_plugin(QmlDesigner gradientpresetlistmodel.cpp gradientpresetlistmodel.h instanceimageprovider.cpp instanceimageprovider.h propertyeditorcontextobject.cpp propertyeditorcontextobject.h + propertyeditordynamicpropertiesproxymodel.cpp propertyeditordynamicpropertiesproxymodel.h propertyeditorqmlbackend.cpp propertyeditorqmlbackend.h propertyeditortransaction.cpp propertyeditortransaction.h propertyeditorvalue.cpp propertyeditorvalue.h diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditordynamicpropertiesproxymodel.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditordynamicpropertiesproxymodel.cpp new file mode 100644 index 00000000000..29fb649143e --- /dev/null +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditordynamicpropertiesproxymodel.cpp @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2025 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "propertyeditordynamicpropertiesproxymodel.h" + +#include + +#include + +namespace QmlDesigner { + +PropertyEditorDynamicPropertiesProxyModel::PropertyEditorDynamicPropertiesProxyModel(QObject *parent) + : DynamicPropertiesProxyModel(parent) +{ + if (PropertyEditorView::instance()) + initModel(PropertyEditorView::instance()->dynamicPropertiesModel()); +} + +void PropertyEditorDynamicPropertiesProxyModel::registerDeclarativeType() +{ + DynamicPropertiesProxyModel::registerDeclarativeType(); + qmlRegisterType("HelperWidgets", 2, 0, "PropertyEditorDynamicPropertiesModel"); +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditordynamicpropertiesproxymodel.h b/src/plugins/qmldesigner/components/propertyeditor/propertyeditordynamicpropertiesproxymodel.h new file mode 100644 index 00000000000..18e93bda895 --- /dev/null +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditordynamicpropertiesproxymodel.h @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2025 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include "dynamicpropertiesproxymodel.h" + +namespace QmlDesigner { + +class PropertyEditorDynamicPropertiesProxyModel : public DynamicPropertiesProxyModel +{ + Q_OBJECT +public: + explicit PropertyEditorDynamicPropertiesProxyModel(QObject *parent = nullptr); + + static void registerDeclarativeType(); +}; + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp index f374e4c72f9..4f1626203cd 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp @@ -10,8 +10,10 @@ #include #include +#include #include #include +#include "qmldesignerplugin.h" #include #include @@ -69,7 +71,7 @@ PropertyEditorView::PropertyEditorView(AsynchronousImageCache &imageCache, , m_qmlBackEndForCurrentType(nullptr) , m_propertyComponentGenerator{PropertyEditorQmlBackend::propertyEditorResourcesPath(), model()} , m_locked(false) - + , m_dynamicPropertiesModel(new DynamicPropertiesModel(true, this)) { m_qmlDir = PropertyEditorQmlBackend::propertyEditorResourcesPath(); @@ -290,6 +292,11 @@ void PropertyEditorView::refreshMetaInfos(const TypeIds &deletedTypeIds) m_propertyComponentGenerator.refreshMetaInfos(deletedTypeIds); } +DynamicPropertiesModel *PropertyEditorView::dynamicPropertiesModel() const +{ + return m_dynamicPropertiesModel; +} + void PropertyEditorView::setExpressionOnObjectNode(const QmlObjectNode &constObjectNode, PropertyNameView name, const QString &newExpression) @@ -392,6 +399,24 @@ void PropertyEditorView::removeAliasForProperty(const ModelNode &modelNode, cons } } +PropertyEditorView *PropertyEditorView::instance() +{ + static PropertyEditorView *s_instance = nullptr; + + if (s_instance) + return s_instance; + + const QList views = QmlDesignerPlugin::instance()->viewManager().views(); + for (AbstractView *view : views) { + PropertyEditorView *propView = qobject_cast(view); + if (propView) + s_instance = propView; + } + + QTC_ASSERT(s_instance, return nullptr); + return s_instance; +} + void PropertyEditorView::updateSize() { if (!m_qmlBackEndForCurrentType) @@ -632,6 +657,8 @@ void PropertyEditorView::setupQmlBackend() setupInsight(rootModelNode(), currentQmlBackend); #endif // QDS_USE_PROJECTSTORAGE + + m_dynamicPropertiesModel->setSelectedNode(m_selectedNode); } void PropertyEditorView::commitVariantValueToModel(PropertyNameView propertyName, const QVariant &value) @@ -750,6 +777,7 @@ void PropertyEditorView::modelAboutToBeDetached(Model *model) m_qmlBackEndForCurrentType->propertyEditorTransaction()->end(); resetView(); + m_dynamicPropertiesModel->reset(); } void PropertyEditorView::propertiesRemoved(const QList &propertyList) @@ -818,12 +846,20 @@ void PropertyEditorView::propertiesRemoved(const QList &proper if (propertyName.contains("anchor")) m_qmlBackEndForCurrentType->backendAnchorBinding().invalidate(m_selectedNode); + + dynamicPropertiesModel()->dispatchPropertyChanges(property); } } if (changed) m_qmlBackEndForCurrentType->updateInstanceImage(); } +void PropertyEditorView::propertiesAboutToBeRemoved(const QList &propertyList) +{ + for (const auto &property : propertyList) + m_dynamicPropertiesModel->removeItem(property); +} + void PropertyEditorView::variantPropertiesChanged(const QList& propertyList, PropertyChangeFlags /*propertyChange*/) { if (noValidSelection()) @@ -850,6 +886,8 @@ void PropertyEditorView::variantPropertiesChanged(const QList& property.name()); if (node == m_selectedNode || QmlObjectNode(m_selectedNode).propertyChangeForCurrentState() == node) { + if (property.isDynamic()) + m_dynamicPropertiesModel->updateItem(property); if ( QmlObjectNode(m_selectedNode).modelNode().property(property.name()).isBindingProperty()) setValue(m_selectedNode, property.name(), QmlObjectNode(m_selectedNode).instanceValue(property.name())); else @@ -865,6 +903,7 @@ void PropertyEditorView::variantPropertiesChanged(const QList& changed = true; } } + m_dynamicPropertiesModel->dispatchPropertyChanges(property); } if (changed) @@ -895,6 +934,8 @@ void PropertyEditorView::bindingPropertiesChanged(const QList & m_qmlBackEndForCurrentType->contextObject()->setHasAliasExport(QmlObjectNode(m_selectedNode).isAliasExported()); if (node == m_selectedNode || QmlObjectNode(m_selectedNode).propertyChangeForCurrentState() == node) { + if (property.isDynamic()) + m_dynamicPropertiesModel->updateItem(property); if (property.name().contains("anchor")) m_qmlBackEndForCurrentType->backendAnchorBinding().invalidate(m_selectedNode); @@ -904,6 +945,7 @@ void PropertyEditorView::bindingPropertiesChanged(const QList & m_locked = false; changed = true; } + m_dynamicPropertiesModel->dispatchPropertyChanges(property); } if (changed) @@ -961,6 +1003,8 @@ void PropertyEditorView::nodeIdChanged(const ModelNode &node, const QString &new if (!QmlObjectNode(m_selectedNode).isValid()) return; + m_dynamicPropertiesModel->reset(); + if (m_qmlBackEndForCurrentType) { if (newId == Constants::MATERIAL_LIB_ID) m_qmlBackEndForCurrentType->contextObject()->setHasMaterialLibrary(true); diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.h b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.h index a8a6d525342..547a6d2aa7c 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.h +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.h @@ -21,6 +21,7 @@ QT_END_NAMESPACE namespace QmlDesigner { class CollapseButton; +class DynamicPropertiesModel; class ModelNode; class PropertyEditorQmlBackend; class PropertyEditorView; @@ -46,6 +47,7 @@ public: const NodeAbstractProperty &parentProperty, PropertyChangeFlags propertyChange) override; void propertiesRemoved(const QList& propertyList) override; + void propertiesAboutToBeRemoved(const QList &propertyList) override; void modelAttached(Model *model) override; @@ -93,6 +95,8 @@ public: void refreshMetaInfos(const TypeIds &deletedTypeIds) override; + DynamicPropertiesModel *dynamicPropertiesModel() const; + static void setExpressionOnObjectNode(const QmlObjectNode &objectNode, PropertyNameView name, const QString &expression); @@ -124,6 +128,8 @@ private: //functions bool noValidSelection() const; void highlightTextureProperties(bool highlight = true); + static PropertyEditorView *instance(); + private: //variables AsynchronousImageCache &m_imageCache; ModelNode m_selectedNode; @@ -137,6 +143,9 @@ private: //variables PropertyEditorComponentGenerator m_propertyEditorComponentGenerator{m_propertyComponentGenerator}; bool m_locked; bool m_textureAboutToBeRemoved = false; + DynamicPropertiesModel *m_dynamicPropertiesModel = nullptr; + + friend class PropertyEditorDynamicPropertiesProxyModel; }; } //QmlDesigner diff --git a/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp b/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp index c5cf236bdcc..9e3a397fa90 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp @@ -29,7 +29,7 @@ #include "qmlmaterialnodeproxy.h" #include "qmltexturenodeproxy.h" #include "richtexteditor/richtexteditorproxy.h" -#include "selectiondynamicpropertiesproxymodel.h" +#include "propertyeditordynamicpropertiesproxymodel.h" #include "theme.h" #include "tooltip.h" @@ -76,7 +76,7 @@ void Quick2PropertyEditorView::registerQmlTypes() Tooltip::registerDeclarativeType(); EasingCurveEditor::registerDeclarativeType(); RichTextEditorProxy::registerDeclarativeType(); - SelectionDynamicPropertiesProxyModel::registerDeclarativeType(); + PropertyEditorDynamicPropertiesProxyModel::registerDeclarativeType(); DynamicPropertyRow::registerDeclarativeType(); PropertyChangesModel::registerDeclarativeType(); PropertyModel::registerDeclarativeType();