diff options
author | Mahmoud Badri <mahmoud.badri@qt.io> | 2022-05-25 21:42:15 +0300 |
---|---|---|
committer | Mahmoud Badri <mahmoud.badri@qt.io> | 2022-05-27 11:20:48 +0000 |
commit | 0b51afe21d6aa72b4b9faafc14f759d77f428e32 (patch) | |
tree | f2c7f0bde07a66ce7dca11d8c7a8f94ecfa8ea3e | |
parent | e2f20ddcd5f515d39d1eb5ae0d13b766ddfa73b6 (diff) |
QmlDesigner: Implement "duplicate material" feature
Fixes: QDS-7013
Change-Id: I28a11dbd9d6586631c0edcf8003e551917eaac98
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Reviewed-by: Samuel Ghinet <samuel.ghinet@qt.io>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
7 files changed, 81 insertions, 46 deletions
diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml index 77eedc67de..ab061e4289 100644 --- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml +++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml @@ -103,6 +103,12 @@ Item { } StudioControls.MenuItem { + text: qsTr("Duplicate") + enabled: currentMaterial + onTriggered: materialBrowserModel.duplicateMaterial(currentMaterialIdx) + } + + StudioControls.MenuItem { text: qsTr("Rename") enabled: currentMaterial onTriggered: { @@ -116,7 +122,7 @@ Item { text: qsTr("Delete") enabled: currentMaterial - onTriggered: materialBrowserModel.deleteMaterial(currentMaterial.materialInternalId) + onTriggered: materialBrowserModel.deleteMaterial(currentMaterialIdx) } StudioControls.MenuSeparator {} diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp index d4bee4fcce..d0420163c3 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp @@ -246,11 +246,14 @@ void MaterialBrowserModel::selectMaterial(int idx, bool force) } } -void MaterialBrowserModel::deleteMaterial(qint32 internalId) +void MaterialBrowserModel::duplicateMaterial(int idx) { - int idx = m_materialIndexHash.value(internalId); - if (isValidIndex(idx)) - m_materialList[idx].destroy(); + emit duplicateMaterialTriggered(m_materialList.at(idx)); +} + +void MaterialBrowserModel::deleteMaterial(int idx) +{ + m_materialList[idx].destroy(); } void MaterialBrowserModel::renameMaterial(int idx, const QString &newName) diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h index 5f00596ef9..32db357cae 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h @@ -68,6 +68,7 @@ public: void resetModel(); Q_INVOKABLE void selectMaterial(int idx, bool force = false); + Q_INVOKABLE void duplicateMaterial(int idx); Q_INVOKABLE void deleteMaterial(int idx); Q_INVOKABLE void renameMaterial(int idx, const QString &newName); Q_INVOKABLE void addNewMaterial(); @@ -82,6 +83,7 @@ signals: 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); private: bool isMaterialVisible(int idx) const; diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp index 3239d2f302..4118630214 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp @@ -54,16 +54,33 @@ WidgetInfo MaterialBrowserView::widgetInfo() { if (m_widget.isNull()) { m_widget = new MaterialBrowserWidget; - connect(m_widget->materialBrowserModel().data(), SIGNAL(selectedIndexChanged(int)), - this, SLOT(handleSelectedMaterialChanged(int))); - connect(m_widget->materialBrowserModel().data(), - SIGNAL(applyToSelectedTriggered(const QmlDesigner::ModelNode &, bool)), - this, SLOT(handleApplyToSelectedTriggered(const QmlDesigner::ModelNode &, bool))); - connect(m_widget->materialBrowserModel().data(), - SIGNAL(renameMaterialTriggered(const QmlDesigner::ModelNode &, const QString &)), - this, SLOT(handleRenameMaterial(const QmlDesigner::ModelNode &, const QString &))); - connect(m_widget->materialBrowserModel().data(), SIGNAL(addNewMaterialTriggered()), - this, SLOT(handleAddNewMaterial())); + MaterialBrowserModel *matBrowserModel = m_widget->materialBrowserModel().data(); + + // custom notifications below are sent to the MaterialEditor + + connect(matBrowserModel, &MaterialBrowserModel::selectedIndexChanged, this, [&] (int idx) { + ModelNode matNode = m_widget->materialBrowserModel()->materialAt(idx); + emitCustomNotification("selected_material_changed", {matNode}, {}); + }); + + connect(matBrowserModel, &MaterialBrowserModel::applyToSelectedTriggered, this, + [&] (const ModelNode &material, bool add) { + emitCustomNotification("apply_to_selected_triggered", {material}, {add}); + }); + + connect(matBrowserModel, &MaterialBrowserModel::renameMaterialTriggered, this, + [&] (const ModelNode &material, const QString &newName) { + emitCustomNotification("rename_material", {material}, {newName}); + }); + + connect(matBrowserModel, &MaterialBrowserModel::addNewMaterialTriggered, this, [&] { + emitCustomNotification("add_new_material"); + }); + + connect(matBrowserModel, &MaterialBrowserModel::duplicateMaterialTriggered, this, + [&] (const ModelNode &material) { + emitCustomNotification("duplicate_material", {material}); + }); } return createWidgetInfo(m_widget.data(), @@ -240,29 +257,4 @@ void MaterialBrowserView::customNotification(const AbstractView *view, const QSt } } -void MaterialBrowserView::handleSelectedMaterialChanged(int idx) -{ - ModelNode matNode = m_widget->materialBrowserModel()->materialAt(idx); - // to MaterialEditor... - emitCustomNotification("selected_material_changed", {matNode}, {}); -} - -void MaterialBrowserView::handleApplyToSelectedTriggered(const ModelNode &material, bool add) -{ - // to MaterialEditor... - emitCustomNotification("apply_to_selected_triggered", {material}, {add}); -} - -void MaterialBrowserView::handleRenameMaterial(const ModelNode &material, const QString &newName) -{ - // to MaterialEditor... - emitCustomNotification("rename_material", {material}, {newName}); -} - -void MaterialBrowserView::handleAddNewMaterial() -{ - // to MaterialEditor... - emitCustomNotification("add_new_material"); -} - } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h index 28e4694cd6..e140eede13 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h @@ -68,12 +68,6 @@ private: QPointer<MaterialBrowserWidget> m_widget; bool m_hasQuick3DImport = false; bool m_autoSelectModelMaterial = false; // TODO: wire this to some action - -private slots: - void handleSelectedMaterialChanged(int idx); - void handleApplyToSelectedTriggered(const QmlDesigner::ModelNode &material, bool add = false); - void handleRenameMaterial(const QmlDesigner::ModelNode &material, const QString &newName); - void handleAddNewMaterial(); }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp index c28152276c..1b4ce59fb5 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp @@ -745,6 +745,41 @@ void MaterialEditorView::renameMaterial(ModelNode &material, const QString &newN }); } +void MaterialEditorView::duplicateMaterial(const ModelNode &material) +{ + QTC_ASSERT(material.isValid(), return); + + ensureMaterialLibraryNode(); + + TypeName matType = material.type(); + QmlObjectNode sourceMat(material); + + executeInTransaction(__FUNCTION__, [&] { + // create the duplicate material + NodeMetaInfo metaInfo = model()->metaInfo(matType); + QmlObjectNode duplicateMat = createModelNode(matType, metaInfo.majorVersion(), metaInfo.minorVersion()); + + // set name and id + QString newName = sourceMat.modelNode().variantProperty("objectName").value().toString() + " copy"; + duplicateMat.modelNode().variantProperty("objectName").setValue(newName); + duplicateMat.modelNode().setIdWithoutRefactoring(generateIdFromName(newName)); + + // sync properties + const QList<AbstractProperty> props = material.properties(); + for (const AbstractProperty &prop : props) { + if (prop.name() == "objectName") + continue; + + if (prop.isVariantProperty()) + duplicateMat.setVariantProperty(prop.name(), prop.toVariantProperty().value()); + else if (prop.isBindingProperty()) + duplicateMat.setBindingProperty(prop.name(), prop.toBindingProperty().expression()); + } + + m_materialLibrary.defaultNodeListProperty().reparentHere(duplicateMat); + }); +} + void MaterialEditorView::customNotification(const AbstractView *view, const QString &identifier, const QList<ModelNode> &nodeList, const QList<QVariant> &data) { @@ -758,6 +793,8 @@ void MaterialEditorView::customNotification(const AbstractView *view, const QStr renameMaterial(m_selectedMaterial, data.first().toString()); } else if (identifier == "add_new_material") { handleToolBarAction(MaterialEditorContextObject::AddNewMaterial); + } else if (identifier == "duplicate_material") { + duplicateMaterial(nodeList.first()); } } diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h index 9d096064bc..8ab30a63f4 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h @@ -106,6 +106,7 @@ private: void commitAuxValueToModel(const PropertyName &propertyName, const QVariant &value); void removePropertyFromModel(const PropertyName &propertyName); void renameMaterial(ModelNode &material, const QString &newName); + void duplicateMaterial(const ModelNode &material); bool noValidSelection() const; |