aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMahmoud Badri <mahmoud.badri@qt.io>2022-05-25 21:42:15 +0300
committerMahmoud Badri <mahmoud.badri@qt.io>2022-05-27 11:20:48 +0000
commit0b51afe21d6aa72b4b9faafc14f759d77f428e32 (patch)
treef2c7f0bde07a66ce7dca11d8c7a8f94ecfa8ea3e
parente2f20ddcd5f515d39d1eb5ae0d13b766ddfa73b6 (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>
-rw-r--r--share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml8
-rw-r--r--src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp11
-rw-r--r--src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h2
-rw-r--r--src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp62
-rw-r--r--src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h6
-rw-r--r--src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp37
-rw-r--r--src/plugins/qmldesigner/components/materialeditor/materialeditorview.h1
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;