@Override public void run() { // Should be executed inside read action PasteNodeData nodeData = CopyPasteUtil.getPasteNodeDataFromClipboard(myModel); IOperationContext operationContext = new ModuleContext(myModel.getModelDescriptor().getModule(), myProject); SwingUtilities.invokeLater(getAddImportsRunnable(nodeData, operationContext)); }
@Override public void execute(EditorContext context) { LOG.assertInCommand(); EditorComponent editorComponent = (EditorComponent) context.getEditorComponent(); EditorCell selectedCell = editorComponent.getSelectedCell(); SNode anchorNode = selectedCell.getSNode(); PasteNodeData pasteNodeData = CopyPasteUtil.getPasteNodeDataFromClipboard(anchorNode.getModel()); if (pasteNodeData == null || pasteNodeData.getNodes().isEmpty()) { pasteNodeData = CopyPasteUtil.getConvertedFromClipboard( anchorNode.getModel(), context.getOperationContext().getProject()); if (pasteNodeData == null) return; } List<SNode> pasteNodes = pasteNodeData.getNodes(); Set<SReference> requireResolveReferences = pasteNodeData.getRequireResolveReferences(); new NodePaster(pasteNodes).pasteRelative(anchorNode, myPastePlaceHint); ResolverComponent.getInstance() .resolveScopesOnly(requireResolveReferences, context.getOperationContext()); // set selection editorComponent.flushEvents(); EditorCell nodeCell = editorComponent.findNodeCell(pasteNodes.get(0)); if (nodeCell == null) return; // after 'set reference'? EditorCell_Label labelCell = CellFinderUtil.findChildByClass(nodeCell, EditorCell_Label.class, true); if (labelCell != null) { editorComponent.changeSelection(labelCell); } if (pasteNodes.size() == 1) { editorComponent.pushSelection(nodeCell); } else { SelectionManager selectionManager = editorComponent.getSelectionManager(); selectionManager.pushSelection( selectionManager.createRangeSelection( pasteNodes.get(0), pasteNodes.get(pasteNodes.size() - 1))); } }
public void execute(final EditorContext context) { LOG.assertInCommand(); final EditorComponent editorComponent = (EditorComponent) context.getEditorComponent(); EditorCell pasteTargetCell = getCellToPasteTo(editorComponent.getSelectedCell()); final CellInfo pasteTargetCellInfo = pasteTargetCell.getCellInfo(); final SNode nodeSelected = pasteTargetCell.getSNode(); final SNodePointer selectedNodePointer = new SNodePointer(nodeSelected); final SModel model = nodeSelected.getModel(); // sometimes model is not in repository (paste in merge dialog) final boolean inRepository = model.getModelDescriptor() == selectedNodePointer.getModel(); PasteNodeData data = CopyPasteUtil.getPasteNodeDataFromClipboard(model); if (data == null || data.getNodes().isEmpty()) { data = CopyPasteUtil.getConvertedFromClipboard( model, context.getOperationContext().getProject()); if (data == null || data.getNodes().isEmpty()) return; } final PasteNodeData pasteNodeData = data; SwingUtilities.invokeLater( new Runnable() { public void run() { final Runnable addImportsRunnable = CopyPasteUtil.addImportsWithDialog( pasteNodeData, model, context.getOperationContext()); ModelAccess.instance() .runCommandInEDT( new Runnable() { public void run() { if (addImportsRunnable != null) { addImportsRunnable.run(); } SNode selectedNode = inRepository ? selectedNodePointer.getNode() : nodeSelected; if (jetbrains.mps.util.SNodeOperations.isDisposed(selectedNode)) { StringBuilder errorText = new StringBuilder( "Selected node is disposed: " + selectedNode.toString()); SModelReference modelReference = selectedNodePointer.getModelReference(); if (modelReference != null) { SModelDescriptor modelDescriptor = SModelRepository.getInstance().getModelDescriptor(modelReference); if (modelDescriptor != null) { SModel sModel = modelDescriptor.getSModel(); errorText.append(", sModel.isDisposed(): " + sModel.isDisposed()); SNode node = sModel.getNodeById(selectedNodePointer.getNodeId()); if (node != null) { errorText.append( ", node != null, node.isDisposed(): " + jetbrains.mps.util.SNodeOperations.isDisposed(node)); } else { errorText.append(", node == null"); } } } LOG.error(errorText.toString()); return; } EditorCell selectedCell = pasteTargetCellInfo.findCell(editorComponent); assert selectedCell != null; List<SNode> pasteNodes = pasteNodeData.getNodes(); if (canPasteBefore(selectedCell, pasteNodes)) { new NodePaster(pasteNodes) .pasteRelative(selectedNode, PastePlaceHint.BEFORE_ANCHOR); } else { new NodePaster(pasteNodes).paste(selectedCell); } Set<SReference> requireResolveReferences = new HashSet<SReference>(); for (SReference ref : pasteNodeData.getRequireResolveReferences()) { // ref can be detached from model while using copy/paste handlers if (ref.getSourceNode() == null || ref.getSourceNode().getModel() == null) continue; requireResolveReferences.add(ref); } ResolverComponent.getInstance() .resolveScopesOnly( requireResolveReferences, context.getOperationContext()); // set selection editorComponent.flushEvents(); EditorCell nodeCell = editorComponent.findNodeCell(pasteNodes.get(0)); if (nodeCell == null) return; // after 'set reference'? EditorCell_Label labelCell = nodeCell.findChild(CellFinders.byClass(EditorCell_Label.class, true)); if (labelCell != null) { editorComponent.changeSelection(labelCell); } if (pasteNodes.size() == 1) { editorComponent.pushSelection(nodeCell); } else { SNode firstNodeToSelect = pasteNodes.get(0); SNode lastNodeToSelect = null; for (int i = pasteNodes.size() - 1; i > 0 && lastNodeToSelect == null; i--) { if (pasteNodes.get(i).getParent() == firstNodeToSelect.getParent()) { lastNodeToSelect = pasteNodes.get(i); } } if (lastNodeToSelect != null) { SelectionManager selectionManager = editorComponent.getSelectionManager(); selectionManager.pushSelection( selectionManager.createRangeSelection( firstNodeToSelect, lastNodeToSelect)); } } } }, context.getOperationContext().getProject()); } }); }
@Override public void execute(final EditorContext context) { LOG.assertLog( context.getRepository().getModelAccess().isCommandAction(), "This action must be performed in command"); final EditorComponent editorComponent = (EditorComponent) context.getEditorComponent(); final Selection selection = editorComponent.getSelectionManager().getSelection(); final List<SNode> selectedNodes = selection.getSelectedNodes(); // this is used in case node is in repo to pass it into invokeLater final List<SNodeReference> selectedReferences = new ArrayList<SNodeReference>(); for (SNode node : selectedNodes) { selectedReferences.add(node.getReference()); } final CellInfo pasteTargetCellInfo; final SNode cellNodeSelected; final SNodeReference selectedCellReference; if (selection instanceof SingularSelection) { EditorCell pasteTargetCell = getCellToPasteTo(context.getSelectedCell()); if (pasteTargetCell == null) { return; } pasteTargetCellInfo = APICellAdapter.getCellInfo(pasteTargetCell); cellNodeSelected = pasteTargetCell.getSNode(); selectedCellReference = cellNodeSelected.getReference(); } else { pasteTargetCellInfo = null; cellNodeSelected = null; selectedCellReference = null; } final SModel modelToPaste = selectedNodes.get(0).getModel(); // sometimes model is not in repository (paste in merge dialog) final boolean inRepository = modelToPaste.getReference().resolve(context.getRepository()) != null; // FIXME relationship between Project and Editor needs attention, it's bad to extract final Project mpsProject = ProjectHelper.getProject(context.getRepository()); if (mpsProject == null) { LOG.warning("Paste needs a project to show a dialog for additional imports"); return; } final PasteNodeData pasteNodeData = CopyPasteUtil.getPasteNodeDataFromClipboard(modelToPaste); // FIXME why SwingUtlities? Is it necessary to execute in EDT thread? If yes, use ThreadUtils. // If not, use any other thread than UI, e.g. app's pooled one. SwingUtilities.invokeLater( new Runnable() { @Override public void run() { final Runnable addImportsRunnable = CopyPasteUtil.addImportsWithDialog(pasteNodeData, modelToPaste, mpsProject); context .getRepository() .getModelAccess() .executeCommandInEDT( new Runnable() { @Override public void run() { if (addImportsRunnable != null) { addImportsRunnable.run(); } List<SNode> pasteNodes = pasteNodeData.getNodes(); List<SNode> currentSelectedNodes; if (!inRepository) { currentSelectedNodes = selectedNodes; } else { currentSelectedNodes = new ArrayList<SNode>(); for (SNodeReference ref : selectedReferences) { currentSelectedNodes.add( ref.resolve(MPSModuleRepository.getInstance())); } } NodePaster nodePaster = new NodePaster(pasteNodes); boolean disposed = checkDisposedSelectedNodes(currentSelectedNodes, selectedReferences); boolean canPasteWithRemove = !disposed && nodePaster.canPasteWithRemove(currentSelectedNodes); if (selection instanceof SingularSelection && (selection instanceof EditorCellLabelSelection && !isCompletelySelected((EditorCellLabelSelection) selection) || (selection instanceof EditorCellSelection && !canPasteWithRemove))) { EditorCell selectedCell = pasteTargetCellInfo.findCell(editorComponent); assert selectedCell != null; if (canPasteBefore(selectedCell, pasteNodes)) { SNode selectedNode = inRepository ? selectedCellReference.resolve( MPSModuleRepository.getInstance()) : cellNodeSelected; if (checkDisposed(selectedCellReference, cellNodeSelected)) { return; } new NodePaster(pasteNodes) .pasteRelative(selectedNode, PastePlaceHint.BEFORE_ANCHOR); } else { new NodePaster(pasteNodes).paste(selectedCell); } } else if ((selection instanceof MultipleSelection || selection instanceof EditorCellSelection) && canPasteWithRemove) { nodePaster.pasteWithRemove(currentSelectedNodes); } else { return; } Set<SReference> requireResolveReferences = new HashSet<SReference>(); for (SReference ref : pasteNodeData.getRequireResolveReferences()) { // ref can be detached from modeltoPaste while using copy/paste handlers if (ref.getSourceNode() == null || ref.getSourceNode().getModel() == null) continue; requireResolveReferences.add(ref); } ResolverComponent.getInstance() .resolveScopesOnly(requireResolveReferences, context.getRepository()); // set selection editorComponent.getUpdater().flushModelEvents(); SNode lastNode = pasteNodes.get(pasteNodes.size() - 1); editorComponent .getSelectionManager() .setSelection(lastNode, SelectionManager.LAST_CELL, -1); } }); } }); }