diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp index 10c91ff0a45..91ee59666d3 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp @@ -183,6 +183,10 @@ void Edit3DWidget::createContextMenu() m_contextMenu->addSeparator(); + m_duplicateAction = m_contextMenu->addAction(tr("Duplicate"), [&] { + QmlDesignerPlugin::instance()->currentDesignDocument()->duplicateSelected(); + }); + m_copyAction = m_contextMenu->addAction(tr("Copy"), [&] { QmlDesignerPlugin::instance()->currentDesignDocument()->copySelected(); }); @@ -374,6 +378,7 @@ void Edit3DWidget::showContextMenu(const QPoint &pos, const ModelNode &modelNode m_editComponentAction->setEnabled(isSingleComponent); m_editMaterialAction->setEnabled(isModel); + m_duplicateAction->setEnabled(isNotRoot); m_copyAction->setEnabled(isNotRoot); m_pasteAction->setEnabled(isPasteAvailable()); m_deleteAction->setEnabled(isNotRoot); diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h index 63aba37484b..38ff56e67ad 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h @@ -64,6 +64,7 @@ private: QPointer m_contextMenu; QPointer m_editComponentAction; QPointer m_editMaterialAction; + QPointer m_duplicateAction; QPointer m_copyAction; QPointer m_pasteAction; QPointer m_deleteAction; diff --git a/src/plugins/qmldesigner/components/integration/designdocument.cpp b/src/plugins/qmldesigner/components/integration/designdocument.cpp index e75c791a197..2b185f2bf0b 100644 --- a/src/plugins/qmldesigner/components/integration/designdocument.cpp +++ b/src/plugins/qmldesigner/components/integration/designdocument.cpp @@ -579,6 +579,18 @@ void DesignDocument::cutSelected() deleteSelected(); } +void DesignDocument::duplicateSelected() +{ + DesignDocumentView view{m_externalDependencies}; + currentModel()->attachView(&view); + const QList selectedNodes = view.selectedModelNodes(); + currentModel()->detachView(&view); + + rewriterView()->executeInTransaction("DesignDocument::duplicateSelected", [this, selectedNodes]() { + moveNodesToPosition(selectedNodes, {}); + }); +} + void DesignDocument::paste() { pasteToPosition({}); diff --git a/src/plugins/qmldesigner/components/integration/designdocument.h b/src/plugins/qmldesigner/components/integration/designdocument.h index 4750908f64a..043444159a8 100644 --- a/src/plugins/qmldesigner/components/integration/designdocument.h +++ b/src/plugins/qmldesigner/components/integration/designdocument.h @@ -98,6 +98,7 @@ public: void deleteSelected(); void copySelected(); void cutSelected(); + void duplicateSelected(); void paste(); void pasteToPosition(const std::optional &position); void selectAll();