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();