diff --git a/src/plugins/qmldesigner/components/integration/designdocument.cpp b/src/plugins/qmldesigner/components/integration/designdocument.cpp index 0e78864c140..2235e984a1d 100644 --- a/src/plugins/qmldesigner/components/integration/designdocument.cpp +++ b/src/plugins/qmldesigner/components/integration/designdocument.cpp @@ -382,60 +382,11 @@ void DesignDocument::deleteSelected() void DesignDocument::copySelected() { - QScopedPointer copyModel(Model::create("QtQuick.Rectangle", 1, 0, currentModel())); - copyModel->setFileUrl(currentModel()->fileUrl()); - copyModel->changeImports(currentModel()->imports(), {}); - - Q_ASSERT(copyModel); - DesignDocumentView view; currentModel()->attachView(&view); - if (view.selectedModelNodes().isEmpty()) - return; - - QList selectedNodes(view.selectedModelNodes()); - - foreach (const ModelNode &node, selectedNodes) { - foreach (const ModelNode &node2, selectedNodes) { - if (node.isAncestorOf(node2)) - selectedNodes.removeAll(node2); - } - } - - if (selectedNodes.count() == 1) { - ModelNode selectedNode(selectedNodes.first()); - - if (!selectedNode.isValid()) - return; - - currentModel()->detachView(&view); - - copyModel->attachView(&view); - view.replaceModel(selectedNode); - - Q_ASSERT(view.rootModelNode().isValid()); - Q_ASSERT(view.rootModelNode().type() != "empty"); - - view.toClipboard(); - } else { //multi items selected - currentModel()->detachView(&view); - copyModel->attachView(&view); - - foreach (ModelNode node, view.rootModelNode().directSubModelNodes()) { - node.destroy(); - } - view.changeRootNodeType("QtQuick.Rectangle", 1, 0); - view.rootModelNode().setIdWithRefactoring(QLatin1String("designer__Selection")); - - foreach (const ModelNode &selectedNode, selectedNodes) { - ModelNode newNode(view.insertModel(selectedNode)); - view.rootModelNode().nodeListProperty("data").reparentHere(newNode); - } - - view.toClipboard(); - } + DesignDocumentView::copyModelNodes(view.selectedModelNodes()); } void DesignDocument::cutSelected() @@ -479,28 +430,21 @@ static void scatterItem(const ModelNode &pastedNode, const ModelNode &targetNode void DesignDocument::paste() { - QScopedPointer pasteModel(Model::create("empty", 1, 0, currentModel())); - pasteModel->setFileUrl(currentModel()->fileUrl()); - pasteModel->changeImports(currentModel()->imports(), {}); - - Q_ASSERT(pasteModel); + QScopedPointer pasteModel(DesignDocumentView::pasteToModel()); if (!pasteModel) return; DesignDocumentView view; pasteModel->attachView(&view); - - view.fromClipboard(); - ModelNode rootNode(view.rootModelNode()); + QList selectedNodes = rootNode.directSubModelNodes(); + pasteModel->detachView(&view); if (rootNode.type() == "empty") return; - if (rootNode.id() == QLatin1String("designer__Selection")) { - QList selectedNodes = rootNode.directSubModelNodes(); - pasteModel->detachView(&view); + if (rootNode.id() == "designer__Selection") { currentModel()->attachView(&view); ModelNode targetNode; @@ -546,7 +490,6 @@ void DesignDocument::paste() try { RewriterTransaction transaction(rewriterView(), QByteArrayLiteral("DesignDocument::paste2")); - pasteModel->detachView(&view); currentModel()->attachView(&view); ModelNode pastedNode(view.insertModel(rootNode)); ModelNode targetNode; diff --git a/src/plugins/qmldesigner/components/integration/designdocumentview.cpp b/src/plugins/qmldesigner/components/integration/designdocumentview.cpp index a4178e615cc..b371fe3fe6e 100644 --- a/src/plugins/qmldesigner/components/integration/designdocumentview.cpp +++ b/src/plugins/qmldesigner/components/integration/designdocumentview.cpp @@ -28,12 +28,18 @@ #include #include +#include "designdocument.h" +#include +#include + #include #include #include #include #include +#include + namespace QmlDesigner { DesignDocumentView::DesignDocumentView(QObject *parent) @@ -151,4 +157,95 @@ void DesignDocumentView::fromText(QString text) } } +static Model *currentModel() +{ + DesignDocument *document = QmlDesignerPlugin::instance()->viewManager().currentDesignDocument(); + if (document) + return document->currentModel(); + + return 0; +} + +Model *DesignDocumentView::pasteToModel() +{ + Model *parentModel = currentModel(); + + QTC_ASSERT(parentModel, return 0); + + Model *pasteModel(Model::create("empty", 1, 0, parentModel)); + + pasteModel->setFileUrl(parentModel->fileUrl()); + pasteModel->changeImports(parentModel->imports(), {}); + + Q_ASSERT(pasteModel); + + if (!pasteModel) + return 0; + + DesignDocumentView view; + pasteModel->attachView(&view); + + view.fromClipboard(); + + return pasteModel; +} + +void DesignDocumentView::copyModelNodes(const QList &nodesToCopy) +{ + Model *parentModel = currentModel(); + + QTC_ASSERT(parentModel, return); + + QScopedPointer copyModel(Model::create("QtQuick.Rectangle", 1, 0, parentModel)); + + copyModel->setFileUrl(parentModel->fileUrl()); + copyModel->changeImports(parentModel->imports(), {}); + + Q_ASSERT(copyModel); + + QList selectedNodes = nodesToCopy; + + if (selectedNodes.isEmpty()) + return; + + foreach (const ModelNode &node, selectedNodes) { + foreach (const ModelNode &node2, selectedNodes) { + if (node.isAncestorOf(node2)) + selectedNodes.removeAll(node2); + } + } + + DesignDocumentView view; + copyModel->attachView(&view); + + if (selectedNodes.count() == 1) { + ModelNode selectedNode(selectedNodes.first()); + + if (!selectedNode.isValid()) + return; + + view.replaceModel(selectedNode); + + Q_ASSERT(view.rootModelNode().isValid()); + Q_ASSERT(view.rootModelNode().type() != "empty"); + + view.toClipboard(); + } else { //multi items selected + + foreach (ModelNode node, view.rootModelNode().directSubModelNodes()) { + node.destroy(); + } + view.changeRootNodeType("QtQuick.Rectangle", 2, 0); + view.rootModelNode().setIdWithRefactoring("designer__Selection"); + + foreach (const ModelNode &selectedNode, selectedNodes) { + ModelNode newNode(view.insertModel(selectedNode)); + view.rootModelNode().nodeListProperty("data").reparentHere(newNode); + } + + view.toClipboard(); + } + +} + }// namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/integration/designdocumentview.h b/src/plugins/qmldesigner/components/integration/designdocumentview.h index 41fbfd5626e..6abc92df09b 100644 --- a/src/plugins/qmldesigner/components/integration/designdocumentview.h +++ b/src/plugins/qmldesigner/components/integration/designdocumentview.h @@ -33,7 +33,7 @@ namespace QmlDesigner { class ModelMerger; -class DesignDocumentView : public AbstractView +class QMLDESIGNERCORE_EXPORT DesignDocumentView : public AbstractView { Q_OBJECT public: @@ -49,6 +49,9 @@ public: QString toText() const; void fromText(QString text); + static Model *pasteToModel(); + static void copyModelNodes(const QList &nodesToCopy); + private: std::unique_ptr m_modelMerger; }; diff --git a/src/plugins/qmldesigner/designercore/include/viewmanager.h b/src/plugins/qmldesigner/designercore/include/viewmanager.h index f69f714f0a7..b1a8077202e 100644 --- a/src/plugins/qmldesigner/designercore/include/viewmanager.h +++ b/src/plugins/qmldesigner/designercore/include/viewmanager.h @@ -96,6 +96,7 @@ public: void toggleStatesViewExpanded(); QString qmlJSEditorHelpId() const; + DesignDocument *currentDesignDocument() const; private: // functions Q_DISABLE_COPY(ViewManager) @@ -107,7 +108,6 @@ private: // functions Model *currentModel() const; Model *documentModel() const; - DesignDocument *currentDesignDocument() const; QString pathToQt() const; void switchStateEditorViewToBaseState();