diff options
author | Mahmoud Badri <mahmoud.badri@qt.io> | 2020-03-12 15:55:30 +0200 |
---|---|---|
committer | Mahmoud Badri <mahmoud.badri@qt.io> | 2020-03-13 13:25:58 +0000 |
commit | 11bd2f8debc512cc263b03ccce2186435048f3ba (patch) | |
tree | db8ca287d877009a74e5cc4284aca5f579229676 | |
parent | 38458c3e401d5fcafca6fa5b97fae7dd7c1865f4 (diff) |
Enable Copy, Cut, and Paste in the Editor 3D
Task-number: QDS-1563
Change-Id: I22c3017b8c158d8bc084f050baef89fa8fffd365
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
13 files changed, 108 insertions, 23 deletions
diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp index eeaa5c48f8..3687ba362d 100644 --- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp +++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp @@ -112,16 +112,17 @@ void DesignerActionManager::polishActions() const [](ActionInterface *action) { return action->type() != ActionInterface::ContextMenu; }); Core::Context qmlDesignerFormEditorContext(Constants::C_QMLFORMEDITOR); + Core::Context qmlDesignerEditor3DContext(Constants::C_QMLEDITOR3D); Core::Context qmlDesignerNavigatorContext(Constants::C_QMLNAVIGATOR); Core::Context qmlDesignerUIContext; qmlDesignerUIContext.add(qmlDesignerFormEditorContext); + qmlDesignerUIContext.add(qmlDesignerEditor3DContext); qmlDesignerUIContext.add(qmlDesignerNavigatorContext); for (auto *action : actions) { if (!action->menuId().isEmpty()) { - const QString id = - QString("QmlDesigner.%1").arg(QString::fromLatin1(action->menuId())); + const QString id = QString("QmlDesigner.%1").arg(QString::fromLatin1(action->menuId())); Core::Command *cmd = Core::ActionManager::registerAction(action->action(), id.toLatin1().constData(), qmlDesignerUIContext); diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.h b/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.h index 2243a466dd..df9ab26be8 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.h @@ -45,6 +45,8 @@ public: void updateRenderImage(const QImage &img); void updateActiveScene(qint32 activeScene); + qint32 activeScene() const { return m_activeScene; } + protected: void mousePressEvent(QMouseEvent *e) override; void mouseReleaseEvent(QMouseEvent *e) override; diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp index 34bb770be0..5e203026d3 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp @@ -37,6 +37,8 @@ #include <viewmanager.h> #include <qmldesignericons.h> #include <utils/utilsicons.h> +#include <coreplugin/icore.h> +#include <designmodecontext.h> #include <QDebug> @@ -55,6 +57,9 @@ void Edit3DView::createEdit3DWidget() { createEdit3DActions(); m_edit3DWidget = new Edit3DWidget(this); + + auto editor3DContext = new Internal::Editor3DContext(m_edit3DWidget.data()); + Core::ICore::addContextObject(editor3DContext); } WidgetInfo Edit3DView::widgetInfo() @@ -88,8 +93,11 @@ void Edit3DView::updateActiveScene3D(const QVariantMap &sceneState) const QString orientationKey = QStringLiteral("globalOrientation"); const QString editLightKey = QStringLiteral("showEditLight"); - if (sceneState.contains(sceneKey)) - edit3DWidget()->canvas()->updateActiveScene(sceneState[sceneKey].value<qint32>()); + if (sceneState.contains(sceneKey)) { + qint32 newActiveScene = sceneState[sceneKey].value<qint32>(); + edit3DWidget()->canvas()->updateActiveScene(newActiveScene); + rootModelNode().setAuxiliaryData("3d-active-scene", newActiveScene); + } if (sceneState.contains(selectKey)) m_selectionModeAction->action()->setChecked(sceneState[selectKey].toInt() == 0); diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp index b21bb3d46e..461613e476 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp @@ -33,6 +33,7 @@ #include "qmldesignerconstants.h" #include "viewmanager.h" +#include <coreplugin/icore.h> #include <toolbox.h> #include <utils/utilsicons.h> #include <QVBoxLayout> @@ -42,6 +43,11 @@ namespace QmlDesigner { Edit3DWidget::Edit3DWidget(Edit3DView *view) : m_view(view) { + Core::Context context(Constants::C_QMLEDITOR3D); + m_context = new Core::IContext(this); + m_context->setContext(context); + m_context->setWidget(this); + setMouseTracking(true); setFocusPolicy(Qt::WheelFocus); @@ -93,6 +99,14 @@ Edit3DWidget::Edit3DWidget(Edit3DView *view) : fillLayout->addWidget(m_canvas.data()); } +void Edit3DWidget::contextHelp(const Core::IContext::HelpCallback &callback) const +{ + if (m_view) + m_view->contextHelp(callback); + + callback({}); +} + Edit3DCanvas *Edit3DWidget::canvas() const { return m_canvas.data(); diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h index 967713930e..c5cea8836c 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h @@ -26,6 +26,7 @@ #include <QtWidgets/qwidget.h> #include <QtCore/qpointer.h> +#include <coreplugin/icontext.h> namespace QmlDesigner { @@ -42,12 +43,14 @@ public: Edit3DCanvas *canvas() const; Edit3DView *view() const; + void contextHelp(const Core::IContext::HelpCallback &callback) const; private: QPointer<Edit3DView> m_edit3DView; QPointer<Edit3DView> m_view; QPointer<Edit3DCanvas> m_canvas; QPointer<ToolBox> m_toolBox; + Core::IContext *m_context = nullptr; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp index 7cdae618b7..c9a98580a7 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp @@ -342,7 +342,6 @@ double FormEditorWidget::containerPadding() const return DesignerSettings::getValue(DesignerSettingsKey::CONTAINERPADDING).toDouble(); } - void FormEditorWidget::contextHelp(const Core::IContext::HelpCallback &callback) const { if (m_formEditorView) diff --git a/src/plugins/qmldesigner/components/integration/designdocument.cpp b/src/plugins/qmldesigner/components/integration/designdocument.cpp index 75b45fedb8..e5d7e8978d 100644 --- a/src/plugins/qmldesigner/components/integration/designdocument.cpp +++ b/src/plugins/qmldesigner/components/integration/designdocument.cpp @@ -35,6 +35,8 @@ #include <qmldesignerplugin.h> #include <viewmanager.h> #include <nodeinstanceview.h> +#include "qmldesignerconstants.h" +#include "qmlvisualnode.h" #include <projectexplorer/projecttree.h> #include <projectexplorer/project.h> @@ -44,6 +46,7 @@ #include <qtsupport/qtkitinformation.h> #include <qtsupport/qtsupportconstants.h> #include <qtsupport/qtversionmanager.h> +#include <coreplugin/icore.h> #include <coreplugin/idocument.h> #include <coreplugin/editormanager/editormanager.h> @@ -449,7 +452,7 @@ void DesignDocument::paste() if (rootNode.type() == "empty") return; - if (rootNode.id() == "designer__Selection") { + if (rootNode.id() == "designer__Selection") { // pasting multiple objects currentModel()->attachView(&view); ModelNode targetNode; @@ -458,8 +461,22 @@ void DesignDocument::paste() targetNode = view.selectedModelNodes().constFirst(); //In case we copy and paste a selection we paste in the parent item - if ((view.selectedModelNodes().count() == selectedNodes.count()) && targetNode.isValid() && targetNode.hasParentProperty()) + if ((view.selectedModelNodes().count() == selectedNodes.count()) && targetNode.isValid() && targetNode.hasParentProperty()) { targetNode = targetNode.parentProperty().parentModelNode(); + } else { + // if selection is empty and copied nodes are all 3D nodes, paste them under the active scene + bool all3DNodes = std::find_if(selectedNodes.begin(), selectedNodes.end(), + [](const ModelNode &node) { return !node.isSubclassOf("QtQuick3D.Node"); }) + == selectedNodes.end(); + if (all3DNodes) { + int activeSceneId = rootModelNode().auxiliaryData("3d-active-scene").toInt(); + if (activeSceneId != -1) { + NodeListProperty sceneNodeProperty + = QmlVisualNode::findSceneNodeProperty(rootModelNode().view(), activeSceneId); + targetNode = sceneNodeProperty.parentModelNode(); + } + } + } if (!targetNode.isValid()) targetNode = view.rootModelNode(); @@ -487,24 +504,35 @@ void DesignDocument::paste() view.setSelectedModelNodes(pastedNodeList); }); - } else { - rewriterView()->executeInTransaction("DesignDocument::paste1", [this, &view, selectedNodes, rootNode](){ + } else { // pasting single object + rewriterView()->executeInTransaction("DesignDocument::paste1", [this, &view, selectedNodes, rootNode]() { currentModel()->attachView(&view); ModelNode pastedNode(view.insertModel(rootNode)); ModelNode targetNode; - if (!view.selectedModelNodes().isEmpty()) + if (!view.selectedModelNodes().isEmpty()) { targetNode = view.selectedModelNodes().constFirst(); + } else { + // if selection is empty and this is a 3D Node, paste it under the active scene + if (pastedNode.isSubclassOf("QtQuick3D.Node")) { + int activeSceneId = rootModelNode().auxiliaryData("3d-active-scene").toInt(); + if (activeSceneId != -1) { + NodeListProperty sceneNodeProperty + = QmlVisualNode::findSceneNodeProperty(rootModelNode().view(), activeSceneId); + targetNode = sceneNodeProperty.parentModelNode(); + } + } + } if (!targetNode.isValid()) targetNode = view.rootModelNode(); if (targetNode.hasParentProperty() && - (pastedNode.simplifiedTypeName() == targetNode.simplifiedTypeName()) && - (pastedNode.variantProperty("width").value() == targetNode.variantProperty("width").value()) && - (pastedNode.variantProperty("height").value() == targetNode.variantProperty("height").value())) - + pastedNode.simplifiedTypeName() == targetNode.simplifiedTypeName() && + pastedNode.variantProperty("width").value() == targetNode.variantProperty("width").value() && + pastedNode.variantProperty("height").value() == targetNode.variantProperty("height").value()) { targetNode = targetNode.parentProperty().parentModelNode(); + } PropertyName defaultProperty(targetNode.metaInfo().defaultPropertyName()); diff --git a/src/plugins/qmldesigner/designmodecontext.cpp b/src/plugins/qmldesigner/designmodecontext.cpp index 298fe6d07f..a0cb0cf407 100644 --- a/src/plugins/qmldesigner/designmodecontext.cpp +++ b/src/plugins/qmldesigner/designmodecontext.cpp @@ -27,6 +27,7 @@ #include "qmldesignerconstants.h" #include "designmodewidget.h" #include "formeditorwidget.h" +#include "edit3dwidget.h" #include "navigatorwidget.h" #include "texteditorwidget.h" @@ -57,6 +58,18 @@ void FormEditorContext::contextHelp(const HelpCallback &callback) const qobject_cast<FormEditorWidget *>(m_widget)->contextHelp(callback); } +Editor3DContext::Editor3DContext(QWidget *widget) + : IContext(widget) +{ + setWidget(widget); + setContext(Core::Context(Constants::C_QMLEDITOR3D, Constants::C_QT_QUICK_TOOLS_MENU)); +} + +void Editor3DContext::contextHelp(const HelpCallback &callback) const +{ + qobject_cast<Edit3DWidget *>(m_widget)->contextHelp(callback); +} + NavigatorContext::NavigatorContext(QWidget *widget) : IContext(widget) { diff --git a/src/plugins/qmldesigner/designmodecontext.h b/src/plugins/qmldesigner/designmodecontext.h index 0417f62921..b30430b5ee 100644 --- a/src/plugins/qmldesigner/designmodecontext.h +++ b/src/plugins/qmldesigner/designmodecontext.h @@ -51,6 +51,15 @@ public: void contextHelp(const Core::IContext::HelpCallback &callback) const override; }; +class Editor3DContext : public Core::IContext +{ + Q_OBJECT + +public: + Editor3DContext(QWidget *widget); + void contextHelp(const Core::IContext::HelpCallback &callback) const override; +}; + class NavigatorContext : public Core::IContext { Q_OBJECT diff --git a/src/plugins/qmldesigner/qmldesignerconstants.h b/src/plugins/qmldesigner/qmldesignerconstants.h index 89c5b64396..132f31d2ff 100644 --- a/src/plugins/qmldesigner/qmldesignerconstants.h +++ b/src/plugins/qmldesigner/qmldesignerconstants.h @@ -28,14 +28,15 @@ namespace QmlDesigner { namespace Constants { -const char C_BACKSPACE[] = "QmlDesigner.Backspace"; -const char C_DELETE[] = "QmlDesigner.Delete"; +const char C_BACKSPACE[] = "QmlDesigner.Backspace"; +const char C_DELETE[] = "QmlDesigner.Delete"; // Context -const char C_QMLDESIGNER[] = "QmlDesigner::QmlDesignerMain"; -const char C_QMLFORMEDITOR[] = "QmlDesigner::FormEditor"; -const char C_QMLNAVIGATOR[] = "QmlDesigner::Navigator"; -const char C_QMLTEXTEDITOR[] = "QmlDesigner::TextEditor"; +const char C_QMLDESIGNER[] = "QmlDesigner::QmlDesignerMain"; +const char C_QMLFORMEDITOR[] = "QmlDesigner::FormEditor"; +const char C_QMLEDITOR3D[] = "QmlDesigner::Editor3D"; +const char C_QMLNAVIGATOR[] = "QmlDesigner::Navigator"; +const char C_QMLTEXTEDITOR[] = "QmlDesigner::TextEditor"; // Special context for preview menu, shared b/w designer and text editor const char C_QT_QUICK_TOOLS_MENU[] = "QmlDesigner::ToolsMenu"; diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp index 1a2f3c8c27..a65ff3600b 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.cpp +++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp @@ -287,14 +287,17 @@ void QmlDesignerPlugin::integrateIntoQtCreator(QWidget *modeWidget) Core::ICore::addContextObject(d->context); Core::Context qmlDesignerMainContext(Constants::C_QMLDESIGNER); Core::Context qmlDesignerFormEditorContext(Constants::C_QMLFORMEDITOR); + Core::Context qmlDesignerEditor3dContext(Constants::C_QMLEDITOR3D); Core::Context qmlDesignerNavigatorContext(Constants::C_QMLNAVIGATOR); d->context->context().add(qmlDesignerMainContext); d->context->context().add(qmlDesignerFormEditorContext); + d->context->context().add(qmlDesignerEditor3dContext); d->context->context().add(qmlDesignerNavigatorContext); d->context->context().add(ProjectExplorer::Constants::QMLJS_LANGUAGE_ID); - d->shortCutManager.registerActions(qmlDesignerMainContext, qmlDesignerFormEditorContext, qmlDesignerNavigatorContext); + d->shortCutManager.registerActions(qmlDesignerMainContext, qmlDesignerFormEditorContext, + qmlDesignerEditor3dContext, qmlDesignerNavigatorContext); const QStringList mimeTypes = { QmlJSTools::Constants::QML_MIMETYPE, QmlJSTools::Constants::QMLUI_MIMETYPE }; diff --git a/src/plugins/qmldesigner/shortcutmanager.cpp b/src/plugins/qmldesigner/shortcutmanager.cpp index d4dac41cf4..72f79a8810 100644 --- a/src/plugins/qmldesigner/shortcutmanager.cpp +++ b/src/plugins/qmldesigner/shortcutmanager.cpp @@ -77,6 +77,7 @@ ShortCutManager::ShortCutManager() void ShortCutManager::registerActions(const Core::Context &qmlDesignerMainContext, const Core::Context &qmlDesignerFormEditorContext, + const Core::Context &qmlDesignerEditor3DContext, const Core::Context &qmlDesignerNavigatorContext) { Core::ActionContainer *editMenu = Core::ActionManager::actionContainer(Core::Constants::M_EDIT); @@ -166,18 +167,21 @@ void ShortCutManager::registerActions(const Core::Context &qmlDesignerMainContex designerActionManager.addCreatorCommand(command, ComponentCoreConstants::editCategory, 280); Core::ActionManager::registerAction(&m_cutAction, Core::Constants::CUT, qmlDesignerFormEditorContext); + Core::ActionManager::registerAction(&m_cutAction, Core::Constants::CUT, qmlDesignerEditor3DContext); command = Core::ActionManager::registerAction(&m_cutAction, Core::Constants::CUT, qmlDesignerNavigatorContext); command->setDefaultKeySequence(QKeySequence::Cut); editMenu->addAction(command, Core::Constants::G_EDIT_COPYPASTE); designerActionManager.addCreatorCommand(command, ComponentCoreConstants::editCategory, 260, Utils::Icons::CUT_TOOLBAR.icon()); Core::ActionManager::registerAction(&m_copyAction, Core::Constants::COPY, qmlDesignerFormEditorContext); + Core::ActionManager::registerAction(&m_copyAction, Core::Constants::COPY, qmlDesignerEditor3DContext); command = Core::ActionManager::registerAction(&m_copyAction, Core::Constants::COPY, qmlDesignerNavigatorContext); command->setDefaultKeySequence(QKeySequence::Copy); editMenu->addAction(command, Core::Constants::G_EDIT_COPYPASTE); designerActionManager.addCreatorCommand(command, ComponentCoreConstants::editCategory, 250, Utils::Icons::COPY_TOOLBAR.icon()); Core::ActionManager::registerAction(&m_pasteAction, Core::Constants::PASTE, qmlDesignerFormEditorContext); + Core::ActionManager::registerAction(&m_pasteAction, Core::Constants::PASTE, qmlDesignerEditor3DContext); command = Core::ActionManager::registerAction(&m_pasteAction, Core::Constants::PASTE, qmlDesignerNavigatorContext); command->setDefaultKeySequence(QKeySequence::Paste); editMenu->addAction(command, Core::Constants::G_EDIT_COPYPASTE); @@ -209,14 +213,13 @@ void ShortCutManager::registerActions(const Core::Context &qmlDesignerMainContex }); connect(Core::ICore::instance(), &Core::ICore::contextChanged, this, [&designerActionManager, this](const Core::Context &context){ - if (!context.contains(Constants::C_QMLFORMEDITOR) && !context.contains(Constants::C_QMLNAVIGATOR)) { + if (!context.contains(Constants::C_QMLFORMEDITOR) && !context.contains(Constants::C_QMLEDITOR3D) && !context.contains(Constants::C_QMLNAVIGATOR)) { m_deleteAction.setEnabled(false); m_cutAction.setEnabled(false); m_copyAction.setEnabled(false); m_pasteAction.setEnabled(false); } else { designerActionManager.view()->emitSelectionChanged(); - } }); } diff --git a/src/plugins/qmldesigner/shortcutmanager.h b/src/plugins/qmldesigner/shortcutmanager.h index 102448f430..6e5b5ec23b 100644 --- a/src/plugins/qmldesigner/shortcutmanager.h +++ b/src/plugins/qmldesigner/shortcutmanager.h @@ -46,6 +46,7 @@ public: void registerActions(const Core::Context &qmlDesignerMainContext, const Core::Context &qmlDesignerFormEditorContext, + const Core::Context &qmlDesignerEditor3DContext, const Core::Context &qmlDesignerNavigatorContext); void connectUndoActions(DesignDocument *designDocument); |