/*package*/ static EditorCell getEditorCellToInsert(EditorComponent editorComponent) { Selection selection = editorComponent.getSelectionManager().getSelection(); // TODO: remove this limitation if (!(selection instanceof SingularSelection)) { return null; } Iterator<jetbrains.mps.nodeEditor.cells.EditorCell> iterator = selection.getSelectedCells().iterator(); if (!(iterator.hasNext())) { return null; } EditorCell editorCell = iterator.next(); return (editorCell instanceof EditorCell_Component ? null : editorCell); }
@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))); } }
/*package*/ static boolean isReadonlyActionEnabled(EditorComponent editorComponent) { return editorComponent.isFocusOwner() && !(editorComponent.getNodeSubstituteChooser().isVisible()) && editorComponent.getSelectionManager().getSelection() != null; }
@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); } }); } }); }