diff options
author | Mahmoud Badri <mahmoud.badri@qt.io> | 2022-08-09 12:56:47 +0300 |
---|---|---|
committer | Mahmoud Badri <mahmoud.badri@qt.io> | 2022-08-18 09:12:10 +0000 |
commit | d4cc3fddc908bc87d806796f426ac91e5ee34f30 (patch) | |
tree | bbe1476d0059af1c0a9ebed2bbb800576a5a7561 | |
parent | ec733999e1d5c31e75e5aa950f75bd41c136554b (diff) |
QmlDesigner: Implement copy/paste material properties
Fixes: QDS-7014
Change-Id: I2a8b779f97de353836a4d506b715720b490c349f
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Samuel Ghinet <samuel.ghinet@qt.io>
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
4 files changed, 111 insertions, 21 deletions
diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml index 0419b945b9..bc8582d359 100644 --- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml +++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml @@ -92,27 +92,48 @@ Item { StudioControls.MenuItem { text: qsTr("Apply to selected (replace)") - enabled: currentMaterial && materialBrowserModel.hasModelSelection - onTriggered: materialBrowserModel.applyToSelected(currentMaterial.materialInternalId, false) + enabled: root.currentMaterial && materialBrowserModel.hasModelSelection + onTriggered: materialBrowserModel.applyToSelected(root.currentMaterial.materialInternalId, false) } StudioControls.MenuItem { text: qsTr("Apply to selected (add)") - enabled: currentMaterial && materialBrowserModel.hasModelSelection - onTriggered: materialBrowserModel.applyToSelected(currentMaterial.materialInternalId, true) + enabled: root.currentMaterial && materialBrowserModel.hasModelSelection + onTriggered: materialBrowserModel.applyToSelected(root.currentMaterial.materialInternalId, true) + } + + StudioControls.MenuSeparator { + height: StudioTheme.Values.border + } + + StudioControls.MenuItem { + text: qsTr("Copy properties") + enabled: root.currentMaterial + onTriggered: materialBrowserModel.copyMaterialProperties(root.currentMaterialIdx) + } + + StudioControls.MenuItem { + text: qsTr("Paste properties") + enabled: root.currentMaterial && root.currentMaterial.materialType.toString() + === materialBrowserModel.copiedMaterialType.toString() + onTriggered: materialBrowserModel.pasteMaterialProperties(root.currentMaterialIdx) + } + + StudioControls.MenuSeparator { + height: StudioTheme.Values.border } StudioControls.MenuItem { text: qsTr("Duplicate") - enabled: currentMaterial - onTriggered: materialBrowserModel.duplicateMaterial(currentMaterialIdx) + enabled: root.currentMaterial + onTriggered: materialBrowserModel.duplicateMaterial(root.currentMaterialIdx) } StudioControls.MenuItem { text: qsTr("Rename") - enabled: currentMaterial + enabled: root.currentMaterial onTriggered: { - var item = gridRepeater.itemAt(currentMaterialIdx); + var item = gridRepeater.itemAt(root.currentMaterialIdx); if (item) item.startRename(); } @@ -120,9 +141,9 @@ Item { StudioControls.MenuItem { text: qsTr("Delete") - enabled: currentMaterial + enabled: root.currentMaterial - onTriggered: materialBrowserModel.deleteMaterial(currentMaterialIdx) + onTriggered: materialBrowserModel.deleteMaterial(root.currentMaterialIdx) } StudioControls.MenuSeparator {} diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp index af74c1489d..2998cc38c8 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp @@ -24,9 +24,13 @@ ****************************************************************************/ #include "materialbrowsermodel.h" -#include "variantproperty.h" + +#include <bindingproperty.h> #include <designmodewidget.h> #include <qmldesignerplugin.h> +#include <qmlobjectnode.h> +#include "variantproperty.h" +#include "utils/qtcassert.h" namespace QmlDesigner { @@ -46,24 +50,23 @@ int MaterialBrowserModel::rowCount(const QModelIndex &) const QVariant MaterialBrowserModel::data(const QModelIndex &index, int role) const { - if (!index.isValid() || index.row() >= m_materialList.count()) { - qWarning() << Q_FUNC_INFO << "invalid index requested"; - return {}; - } + QTC_ASSERT(index.isValid() && index.row() < m_materialList.count(), return {}); + QTC_ASSERT(roleNames().contains(role), return {}); - if (roleNames().value(role) == "materialName") { + QByteArray roleName = roleNames().value(role); + if (roleName == "materialName") { QVariant objName = m_materialList.at(index.row()).variantProperty("objectName").value(); return objName.isValid() ? objName : ""; } - if (roleNames().value(role) == "materialInternalId") + if (roleName == "materialInternalId") return m_materialList.at(index.row()).internalId(); - if (roleNames().value(role) == "materialVisible") + if (roleName == "materialVisible") return isMaterialVisible(index.row()); - if (!roleNames().contains(role)) - qWarning() << Q_FUNC_INFO << "invalid role requested"; + if (roleName == "materialType") + return m_materialList.at(index.row()).type(); return {}; } @@ -88,6 +91,7 @@ QHash<int, QByteArray> MaterialBrowserModel::roleNames() const {Qt::UserRole + 1, "materialName"}, {Qt::UserRole + 2, "materialInternalId"}, {Qt::UserRole + 3, "materialVisible"}, + {Qt::UserRole + 4, "materialType"} }; return roles; } @@ -120,6 +124,20 @@ void MaterialBrowserModel::setHasModelSelection(bool b) emit hasModelSelectionChanged(); } +TypeName MaterialBrowserModel::copiedMaterialType() const +{ + return m_copiedMaterialType; +} + +void MaterialBrowserModel::setCopiedMaterialType(const TypeName &matType) +{ + if (matType == m_copiedMaterialType) + return; + + m_copiedMaterialType = matType; + emit copiedMaterialTypeChanged(); +} + QList<ModelNode> MaterialBrowserModel::materials() const { return m_materialList; @@ -262,6 +280,18 @@ void MaterialBrowserModel::duplicateMaterial(int idx) emit duplicateMaterialTriggered(m_materialList.at(idx)); } +void MaterialBrowserModel::copyMaterialProperties(int idx) +{ + ModelNode mat = m_materialList.at(idx); + m_copiedMaterialProps = mat.properties(); + setCopiedMaterialType(mat.type()); +} + +void MaterialBrowserModel::pasteMaterialProperties(int idx) +{ + emit pasteMaterialPropertiesTriggered(m_materialList.at(idx), m_copiedMaterialProps); +} + void MaterialBrowserModel::deleteMaterial(int idx) { m_materialList[idx].destroy(); diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h index eb258b1efe..cb40ecd9d5 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h @@ -26,6 +26,7 @@ #pragma once #include <modelnode.h> +#include <qmlobjectnode.h> #include <QAbstractListModel> #include <QObject> @@ -41,6 +42,7 @@ class MaterialBrowserModel : public QAbstractListModel Q_PROPERTY(int selectedIndex MEMBER m_selectedIndex NOTIFY selectedIndexChanged) Q_PROPERTY(bool hasQuick3DImport READ hasQuick3DImport WRITE setHasQuick3DImport NOTIFY hasQuick3DImportChanged) Q_PROPERTY(bool hasModelSelection READ hasModelSelection WRITE setHasModelSelection NOTIFY hasModelSelectionChanged) + Q_PROPERTY(TypeName copiedMaterialType READ copiedMaterialType WRITE setCopiedMaterialType NOTIFY copiedMaterialTypeChanged) public: MaterialBrowserModel(QObject *parent = nullptr); @@ -58,6 +60,9 @@ public: bool hasModelSelection() const; void setHasModelSelection(bool b); + TypeName copiedMaterialType() const; + void setCopiedMaterialType(const TypeName &matType); + QList<ModelNode> materials() const; void setMaterials(const QList<ModelNode> &materials, bool hasQuick3DImport); void removeMaterial(const ModelNode &material); @@ -71,6 +76,8 @@ public: Q_INVOKABLE void selectMaterial(int idx, bool force = false); Q_INVOKABLE void duplicateMaterial(int idx); + Q_INVOKABLE void copyMaterialProperties(int idx); + Q_INVOKABLE void pasteMaterialProperties(int idx); Q_INVOKABLE void deleteMaterial(int idx); Q_INVOKABLE void renameMaterial(int idx, const QString &newName); Q_INVOKABLE void addNewMaterial(); @@ -81,11 +88,14 @@ signals: void isEmptyChanged(); void hasQuick3DImportChanged(); void hasModelSelectionChanged(); + void copiedMaterialTypeChanged(); void selectedIndexChanged(int idx); void renameMaterialTriggered(const QmlDesigner::ModelNode &material, const QString &newName); void applyToSelectedTriggered(const QmlDesigner::ModelNode &material, bool add = false); void addNewMaterialTriggered(); void duplicateMaterialTriggered(const QmlDesigner::ModelNode &material); + void pasteMaterialPropertiesTriggered(const QmlDesigner::ModelNode &material, + const QList<QmlDesigner::AbstractProperty> &props); private: bool isMaterialVisible(int idx) const; @@ -93,12 +103,14 @@ private: QString m_searchText; QList<ModelNode> m_materialList; + QList<AbstractProperty> m_copiedMaterialProps; QHash<qint32, int> m_materialIndexHash; // internalId -> index int m_selectedIndex = 0; bool m_isEmpty = true; bool m_hasQuick3DImport = false; bool m_hasModelSelection = false; + TypeName m_copiedMaterialType; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp index ebb9671e50..c8b788ea3a 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp @@ -24,15 +24,18 @@ ****************************************************************************/ #include "materialbrowserview.h" + +#include "bindingproperty.h" #include "materialbrowserwidget.h" #include "materialbrowsermodel.h" #include "nodeabstractproperty.h" #include "qmlobjectnode.h" #include "variantproperty.h" + #include <coreplugin/icore.h> +#include <designmodecontext.h> #include <nodeinstanceview.h> #include <qmldesignerconstants.h> -#include <designmodecontext.h> #include <QQuickItem> @@ -86,6 +89,30 @@ WidgetInfo MaterialBrowserView::widgetInfo() [&] (const ModelNode &material) { emitCustomNotification("duplicate_material", {material}); }); + + connect(matBrowserModel, &MaterialBrowserModel::pasteMaterialPropertiesTriggered, this, + [&] (const ModelNode &material, const QList<AbstractProperty> &props) { + QmlObjectNode mat(material); + executeInTransaction(__FUNCTION__, [&] { + // remove current properties + const PropertyNameList propNames = material.propertyNames(); + for (const PropertyName &propName : propNames) { + if (propName != "objectName") + mat.removeProperty(propName); + } + + // apply pasted properties + for (const AbstractProperty &prop : props) { + if (prop.name() == "objectName") + continue; + + if (prop.isVariantProperty()) + mat.setVariantProperty(prop.name(), prop.toVariantProperty().value()); + else if (prop.isBindingProperty()) + mat.setBindingProperty(prop.name(), prop.toBindingProperty().expression()); + } + }); + }); } return createWidgetInfo(m_widget.data(), |