private int selectionSpan(SelectionModel sm, int orientation) { if (orientation == SwingConstants.VERTICAL) { return sm.getLastSelectedRow() - sm.getFirstSelectedRow() + 1; } else { return sm.getLastSelectedColumn() - sm.getFirstSelectedColumn() + 1; } }
public void actionPerformed(ActionEvent e) { JGrid grid = (JGrid) e.getSource(); SelectionModel sm = grid.getSelectionModel(); anchorRow = sm.getAnchorRow(); leadRow = sm.getLeadRow(); anchorColumn = sm.getAnchorColumn(); leadColumn = sm.getLeadColumn(); int oldAnchorRow = anchorRow; int oldAnchorColumn = anchorColumn; if (grid.isEditing() && !grid.getCurrentCellEditor().stopCellEditing()) { return; } if (!inSelection) { moveWithinGridRange(grid, dx, dy, extend); if (!extend) { grid.changeSelection(anchorRow, anchorColumn, false, extend); } else { grid.changeSelection(leadRow, leadColumn, false, extend); } } else { if (moveWithinSelectedRange(grid, dx, dy, false)) { grid.changeSelection(anchorRow, anchorColumn, true, true); } else { grid.changeSelection(anchorRow, anchorColumn, false, false); } } }
private void updateCursorHighlighting(boolean scroll) { hideBalloon(); if (myCursorHighlighter != null) { HighlightManager.getInstance(mySearchResults.getProject()) .removeSegmentHighlighter(mySearchResults.getEditor(), myCursorHighlighter); myCursorHighlighter = null; } final FindResult cursor = mySearchResults.getCursor(); Editor editor = mySearchResults.getEditor(); SelectionModel selection = editor.getSelectionModel(); if (cursor != null) { Set<RangeHighlighter> dummy = new HashSet<RangeHighlighter>(); highlightRange( cursor, new TextAttributes(null, null, Color.BLACK, EffectType.ROUNDED_BOX, 0), dummy); if (!dummy.isEmpty()) { myCursorHighlighter = dummy.iterator().next(); } if (scroll) { if (mySearchResults.getFindModel().isGlobal()) { FoldingModel foldingModel = editor.getFoldingModel(); final FoldRegion[] allRegions = editor.getFoldingModel().getAllFoldRegions(); foldingModel.runBatchFoldingOperation( new Runnable() { @Override public void run() { for (FoldRegion region : allRegions) { if (!region.isValid()) continue; if (cursor.intersects(TextRange.create(region))) { region.setExpanded(true); } } } }); selection.setSelection(cursor.getStartOffset(), cursor.getEndOffset()); editor.getCaretModel().moveToOffset(cursor.getEndOffset()); editor.getScrollingModel().scrollToCaret(ScrollType.CENTER); } else { if (!SearchResults.insideVisibleArea(editor, cursor)) { LogicalPosition pos = editor.offsetToLogicalPosition(cursor.getStartOffset()); editor.getScrollingModel().scrollTo(pos, ScrollType.CENTER); } } } editor .getScrollingModel() .runActionOnScrollingFinished( new Runnable() { @Override public void run() { showReplacementPreview(); } }); } }
private int compare(int i, SelectionModel sm, int orientation) { int min = 0; int max = 0; if (orientation == SwingConstants.VERTICAL) { min = sm.getFirstSelectedRow(); max = sm.getLastSelectedRow(); } else { min = sm.getFirstSelectedColumn(); max = sm.getLastSelectedColumn(); } return compare(i, min, max + 1); }
public static void pasteTransferableAsBlock( Editor editor, @Nullable Producer<Transferable> producer) { String text = getStringContent(producer); if (text == null) return; int caretLine = editor.getCaretModel().getLogicalPosition().line; int originalCaretLine = caretLine; int selectedLinesCount = 0; final SelectionModel selectionModel = editor.getSelectionModel(); if (selectionModel.hasBlockSelection()) { final LogicalPosition start = selectionModel.getBlockStart(); final LogicalPosition end = selectionModel.getBlockEnd(); assert start != null; assert end != null; LogicalPosition caret = new LogicalPosition(Math.min(start.line, end.line), Math.min(start.column, end.column)); selectedLinesCount = Math.abs(end.line - start.line); caretLine = caret.line; deleteSelectedText(editor); editor.getCaretModel().moveToLogicalPosition(caret); } LogicalPosition caretToRestore = editor.getCaretModel().getLogicalPosition(); String[] lines = LineTokenizer.tokenize(text.toCharArray(), false); if (lines.length > 1 || selectedLinesCount == 0) { int longestLineLength = 0; for (int i = 0; i < lines.length; i++) { String line = lines[i]; longestLineLength = Math.max(longestLineLength, line.length()); editor .getCaretModel() .moveToLogicalPosition(new LogicalPosition(caretLine + i, caretToRestore.column)); insertStringAtCaret(editor, line, false, true); } caretToRestore = new LogicalPosition(originalCaretLine, caretToRestore.column + longestLineLength); } else { for (int i = 0; i <= selectedLinesCount; i++) { editor .getCaretModel() .moveToLogicalPosition(new LogicalPosition(caretLine + i, caretToRestore.column)); insertStringAtCaret(editor, text, false, true); } caretToRestore = new LogicalPosition(originalCaretLine, caretToRestore.column + text.length()); } editor.getCaretModel().moveToLogicalPosition(caretToRestore); zeroWidthBlockSelectionAtCaretColumn(editor, caretLine, caretLine + selectedLinesCount); }
public void actionPerformed(ActionEvent e) { JGrid grid = (JGrid) e.getSource(); if (toLimit) { if (vertically) { int rowCount = grid.getRowCount(); this.dx = 0; this.dy = forwards ? rowCount : -rowCount; } else { int colCount = grid.getColumnCount(); this.dx = forwards ? colCount : -colCount; this.dy = 0; } } else { if (!(grid.getParent().getParent() instanceof JScrollPane)) { return; } Dimension delta = grid.getParent().getSize(); SelectionModel sm = grid.getSelectionModel(); int start = 0; if (vertically) { start = (extend) ? sm.getLeadRow() : sm.getAnchorRow(); } else { start = (extend) ? sm.getLeadColumn() : sm.getAnchorColumn(); } if (vertically) { Rectangle r = grid.getCellBounds(start, 0); r.y += forwards ? delta.height : -delta.height; this.dx = 0; int newRow = grid.rowAtPoint(r.getLocation()); if (newRow == -1 && forwards) { newRow = grid.getRowCount(); } this.dy = newRow - start; } else { Rectangle r = grid.getCellBounds(0, start); r.x += forwards ? delta.width : -delta.width; int newColumn = grid.columnAtPoint(r.getLocation()); if (newColumn == -1 && forwards) { newColumn = grid.getColumnCount(); } this.dx = newColumn - start; this.dy = 0; } } super.actionPerformed(e); }
@Test public void ensureValueIsUpdatedByCorrectSelectionModelWhenSelectionModelIsChanged() { box.getItems().addAll("Apple", "Orange", "Banana"); SelectionModel sm1 = box.getSelectionModel(); sm1.select(1); assertEquals("Orange", box.getValue()); SingleSelectionModel sm2 = new ChoiceBox.ChoiceBoxSelectionModel(box); box.setSelectionModel(sm2); sm1.select(2); // value should not change as we are using old SM assertEquals("Orange", box.getValue()); sm2.select(0); // value should change, as we are using new SM assertEquals("Apple", box.getValue()); }
private void updateInSelectionHighlighters() { if (mySearchResults.getEditor() == null) return; final SelectionModel selectionModel = mySearchResults.getEditor().getSelectionModel(); int[] starts = selectionModel.getBlockSelectionStarts(); int[] ends = selectionModel.getBlockSelectionEnds(); final HashSet<RangeHighlighter> toRemove = new HashSet<RangeHighlighter>(); Set<RangeHighlighter> toAdd = new HashSet<RangeHighlighter>(); for (RangeHighlighter highlighter : myHighlighters) { boolean intersectsWithSelection = false; for (int i = 0; i < starts.length; ++i) { TextRange selectionRange = new TextRange(starts[i], ends[i]); intersectsWithSelection = selectionRange.intersects(highlighter.getStartOffset(), highlighter.getEndOffset()) && selectionRange.getEndOffset() != highlighter.getStartOffset() && highlighter.getEndOffset() != selectionRange.getStartOffset(); if (intersectsWithSelection) break; } final Object userData = highlighter.getUserData(IN_SELECTION_KEY); if (userData != null) { if (!intersectsWithSelection) { if (userData == IN_SELECTION2) { HighlightManager.getInstance(mySearchResults.getProject()) .removeSegmentHighlighter(mySearchResults.getEditor(), highlighter); toRemove.add(highlighter); } else { highlighter.putUserData(IN_SELECTION_KEY, null); } } } else if (intersectsWithSelection) { TextRange cursor = mySearchResults.getCursor(); if (cursor != null && highlighter.getStartOffset() == cursor.getStartOffset() && highlighter.getEndOffset() == cursor.getEndOffset()) continue; final RangeHighlighter toAnnotate = highlightRange( new TextRange(highlighter.getStartOffset(), highlighter.getEndOffset()), new TextAttributes(null, null, Color.WHITE, EffectType.ROUNDED_BOX, 0), toAdd); highlighter.putUserData(IN_SELECTION_KEY, IN_SELECTION1); toAnnotate.putUserData(IN_SELECTION_KEY, IN_SELECTION2); } } myHighlighters.removeAll(toRemove); myHighlighters.addAll(toAdd); }
public void actionPerformed(ActionEvent e) { JGrid grid = (JGrid) e.getSource(); if (!grid.hasFocus()) { CellEditor cellEditor = grid.getCurrentCellEditor(); if (cellEditor != null && !cellEditor.stopCellEditing()) { return; } grid.requestFocus(); } SelectionModel selectionModel = grid.getSelectionModel(); int anchorRow = selectionModel.getAnchorRow(); int anchorColumn = selectionModel.getAnchorColumn(); grid.editCellAt(anchorRow, anchorColumn, null); Component editorComp = grid.getEditorComponent(); if (editorComp != null) { editorComp.requestFocus(); } }
public static int insertStringAtCaret( Editor editor, @NotNull String s, boolean toProcessOverwriteMode, boolean toMoveCaret, int caretShift) { final SelectionModel selectionModel = editor.getSelectionModel(); if (selectionModel.hasSelection()) { editor.getCaretModel().moveToOffset(selectionModel.getSelectionStart(), true); } // There is a possible case that particular soft wraps become hard wraps if the caret is located // at soft wrap-introduced virtual // space, hence, we need to give editor a chance to react accordingly. editor.getSoftWrapModel().beforeDocumentChangeAtCaret(); int oldOffset = editor.getCaretModel().getOffset(); String filler = calcStringToFillVirtualSpace(editor); if (filler.length() > 0) { s = filler + s; } Document document = editor.getDocument(); if (editor.isInsertMode() || !toProcessOverwriteMode) { if (selectionModel.hasSelection()) { oldOffset = selectionModel.getSelectionStart(); document.replaceString( selectionModel.getSelectionStart(), selectionModel.getSelectionEnd(), s); } else { document.insertString(oldOffset, s); } } else { deleteSelectedText(editor); int lineNumber = editor.getCaretModel().getLogicalPosition().line; if (lineNumber >= document.getLineCount()) { return insertStringAtCaret(editor, s, false, toMoveCaret); } int endOffset = document.getLineEndOffset(lineNumber); document.replaceString(oldOffset, Math.min(endOffset, oldOffset + s.length()), s); } int offset = oldOffset + filler.length() + caretShift; if (toMoveCaret) { editor.getCaretModel().moveToOffset(offset, true); editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); selectionModel.removeSelection(); } else if (editor.getCaretModel().getOffset() != oldOffset) { // handling the case when caret model tracks document changes editor.getCaretModel().moveToOffset(oldOffset); } return offset; }
/** * Instantiates a new Decision Theory selection model. * * @param model the underlying model * @param sampleSize the sample size */ public DTSelectionModel( Model model, double sampleSize, BIC bic, TreeDistancesCache distancesCache) { super(model, sampleSize); double minBIC = bic.get(bic.getBestModel()).getValue(); double sum = 0.0; for (SelectionModel selectionModel : bic.getSelectionModels()) { double distance = distancesCache.getDistance(model.getTree(), selectionModel.getModel().getTree()); if (distance > 0) { double power = Math.log(distance) - selectionModel.getValue() + minBIC; if (power > -30) { sum += Math.exp(power); } } } this.value = sum; }
public void performReplaceAll(Editor e) { if (!ReadonlyStatusHandler.ensureDocumentWritable(e.getProject(), e.getDocument())) return; if (mySearchResults.getFindModel() != null) { final FindModel copy = new FindModel(); copy.copyFrom(mySearchResults.getFindModel()); final SelectionModel selectionModel = mySearchResults.getEditor().getSelectionModel(); final int offset; if ((!selectionModel.hasSelection() && !selectionModel.hasBlockSelection()) || copy.isGlobal()) { copy.setGlobal(true); offset = 0; } else { offset = selectionModel.getBlockSelectionStarts()[0]; } FindUtil.replace(e.getProject(), e, offset, copy, this); } }
public static void typeInStringAtCaretHonorBlockSelection( final Editor editor, final String str, final boolean toProcessOverwriteMode) throws ReadOnlyFragmentModificationException { Document doc = editor.getDocument(); final SelectionModel selectionModel = editor.getSelectionModel(); if (selectionModel.hasBlockSelection()) { RangeMarker guard = selectionModel.getBlockSelectionGuard(); if (guard != null) { DocumentEvent evt = new MockDocumentEvent(doc, editor.getCaretModel().getOffset()); ReadOnlyFragmentModificationException e = new ReadOnlyFragmentModificationException(evt, guard); EditorActionManager.getInstance().getReadonlyFragmentModificationHandler(doc).handle(e); } else { final LogicalPosition start = selectionModel.getBlockStart(); final LogicalPosition end = selectionModel.getBlockEnd(); assert start != null; assert end != null; int column = Math.min(start.column, end.column); int startLine = Math.min(start.line, end.line); int endLine = Math.max(start.line, end.line); deleteBlockSelection(editor); for (int i = startLine; i <= endLine; i++) { editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(i, column)); insertStringAtCaret(editor, str, toProcessOverwriteMode, true); } selectionModel.setBlockSelection( new LogicalPosition(startLine, column + str.length()), new LogicalPosition(endLine, column + str.length())); } } else { insertStringAtCaret(editor, str, toProcessOverwriteMode, true); } }
private void makeSelectionForTaskDetailsTree( Set<PlotNameDto> plotTempSet, SelectionModel<PlotNameDto> plotNameSelectionModel, List<TaskDataDto> result) { if (!plotTempSet.isEmpty()) { for (PlotNameDto plotName : plotTempSet) { for (TaskDataDto td : result) { if (plotName.getTest().getTaskName().equals(td.getTaskName())) { plotNameSelectionModel.setSelected(new PlotNameDto(td, plotName.getPlotName()), true); } } } } }
/** Tests select responses to ctrl clicks that should result in select toggling */ public void testCtrlSelectToggle() { FileTreeNode root = mockTree.getModel().getRoot(); // Render the tree. mockTree.renderTree(-1); SignalEvent ctrlSignalEvent = new MockSignalEvent(true, false); // Select a bunch of nodes at the same tier. FileTreeNode AD1 = getNodeByPath(0); assertNotNull("Node did not get rendered!", AD1.getRenderedTreeNode()); assertFalse(AD1.getRenderedTreeNode().isSelected(resources.treeCss())); JsoArray<FileTreeNode> expectedSelects = JsoArray.create(); // Select the first top level dir. mockSelectionModel.selectNode(AD1, ctrlSignalEvent); expectedSelects.add(AD1); checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes()); assertTrue(AD1.getRenderedTreeNode().isSelected(resources.treeCss())); // Select the second top level dir FileTreeNode BD1 = getNodeByPath(1); mockSelectionModel.selectNode(BD1, ctrlSignalEvent); expectedSelects.add(BD1); checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes()); assertTrue(BD1.getRenderedTreeNode().isSelected(resources.treeCss())); // Select the first file. FileTreeNode AF1 = getNodeByPath(3); assertNotNull("Node did not get rendered!", AF1.getRenderedTreeNode()); assertFalse(AF1.getRenderedTreeNode().isSelected(resources.treeCss())); // Change the select. mockSelectionModel.selectNode(AF1, ctrlSignalEvent); expectedSelects.add(AF1); checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes()); assertTrue(AF1.getRenderedTreeNode().isSelected(resources.treeCss())); // Now toggle the second dir. mockSelectionModel.selectNode(BD1, ctrlSignalEvent); expectedSelects.remove(BD1); checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes()); assertFalse(BD1.getRenderedTreeNode().isSelected(resources.treeCss())); }
/** * Emulates pressing <code>Enter</code> at current caret position. * * @param editor target editor * @param project target project * @param shifts two-elements array which is expected to be filled with the following info: 1. The * first element holds added lines number; 2. The second element holds added symbols number; */ private static void emulateEnter( @NotNull final Editor editor, @NotNull Project project, int[] shifts) { final DataContext dataContext = prepareContext(editor.getComponent(), project); int caretOffset = editor.getCaretModel().getOffset(); Document document = editor.getDocument(); SelectionModel selectionModel = editor.getSelectionModel(); int startSelectionOffset = 0; int endSelectionOffset = 0; boolean restoreSelection = selectionModel.hasSelection(); if (restoreSelection) { startSelectionOffset = selectionModel.getSelectionStart(); endSelectionOffset = selectionModel.getSelectionEnd(); selectionModel.removeSelection(); } int textLengthBeforeWrap = document.getTextLength(); int lineCountBeforeWrap = document.getLineCount(); DataManager.getInstance() .saveInDataContext(dataContext, WRAP_LONG_LINE_DURING_FORMATTING_IN_PROGRESS_KEY, true); CommandProcessor commandProcessor = CommandProcessor.getInstance(); try { Runnable command = new Runnable() { @Override public void run() { EditorActionManager.getInstance() .getActionHandler(IdeActions.ACTION_EDITOR_ENTER) .execute(editor, dataContext); } }; if (commandProcessor.getCurrentCommand() == null) { commandProcessor.executeCommand(editor.getProject(), command, WRAP_LINE_COMMAND_NAME, null); } else { command.run(); } } finally { DataManager.getInstance() .saveInDataContext(dataContext, WRAP_LONG_LINE_DURING_FORMATTING_IN_PROGRESS_KEY, null); } int symbolsDiff = document.getTextLength() - textLengthBeforeWrap; if (restoreSelection) { int newSelectionStart = startSelectionOffset; int newSelectionEnd = endSelectionOffset; if (startSelectionOffset >= caretOffset) { newSelectionStart += symbolsDiff; } if (endSelectionOffset >= caretOffset) { newSelectionEnd += symbolsDiff; } selectionModel.setSelection(newSelectionStart, newSelectionEnd); } shifts[0] = document.getLineCount() - lineCountBeforeWrap; shifts[1] = symbolsDiff; }
public static void deleteSelectedText(Editor editor) { SelectionModel selectionModel = editor.getSelectionModel(); if (selectionModel.hasBlockSelection()) deleteBlockSelection(editor); if (!selectionModel.hasSelection()) return; int selectionStart = selectionModel.getSelectionStart(); int selectionEnd = selectionModel.getSelectionEnd(); editor.getCaretModel().moveToOffset(selectionStart); selectionModel.removeSelection(); editor.getDocument().deleteString(selectionStart, selectionEnd); editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); }
public static void deleteBlockSelection(Editor editor) { SelectionModel selectionModel = editor.getSelectionModel(); if (!selectionModel.hasBlockSelection()) return; LogicalPosition blockStart = selectionModel.getBlockStart(); LogicalPosition blockEnd = selectionModel.getBlockEnd(); if (blockStart == null || blockEnd == null) { return; } int startLine = blockStart.line; int endLine = blockEnd.line; int[] starts = selectionModel.getBlockSelectionStarts(); int[] ends = selectionModel.getBlockSelectionEnds(); for (int i = starts.length - 1; i >= 0; i--) { editor.getDocument().deleteString(starts[i], ends[i]); } editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); zeroWidthBlockSelectionAtCaretColumn(editor, startLine, endLine); }
/** Tests select responses to ctrl clicks across tiers in the tree. */ public void testCtrlSelectAcrossTiers() { FileTreeNode root = mockTree.getModel().getRoot(); // Render the tree. mockTree.renderTree(-1); SignalEvent ctrlSignalEvent = new MockSignalEvent(true, false); // Select a bunch of nodes at the same tier. FileTreeNode AD1 = getNodeByPath(0); assertNotNull("Node did not get rendered!", AD1.getRenderedTreeNode()); assertFalse(AD1.getRenderedTreeNode().isSelected(resources.treeCss())); JsoArray<FileTreeNode> expectedSelects = JsoArray.create(); // Select the first top level dir. mockSelectionModel.selectNode(AD1, ctrlSignalEvent); expectedSelects.add(AD1); checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes()); assertTrue(AD1.getRenderedTreeNode().isSelected(resources.treeCss())); // Select the second top level dir FileTreeNode BD1 = getNodeByPath(1); mockSelectionModel.selectNode(BD1, ctrlSignalEvent); expectedSelects.add(BD1); checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes()); assertTrue(BD1.getRenderedTreeNode().isSelected(resources.treeCss())); // Select deeper. We should not allow cross depth selecting and should // replace it with just the new select. FileTreeNode AF2 = getNodeByPath(0, 0); assertNotNull("Node did not get rendered!", AF2.getRenderedTreeNode()); assertFalse(AF2.getRenderedTreeNode().isSelected(resources.treeCss())); // Change the select. mockSelectionModel.selectNode(AF2, ctrlSignalEvent); expectedSelects.clear(); expectedSelects.add(AF2); checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes()); assertTrue(AF2.getRenderedTreeNode().isSelected(resources.treeCss())); assertFalse(AD1.getRenderedTreeNode().isSelected(resources.treeCss())); // Select another peer node. FileTreeNode CF2 = getNodeByPath(0, 2); assertNotNull("Node did not get rendered!", CF2.getRenderedTreeNode()); assertFalse(CF2.getRenderedTreeNode().isSelected(resources.treeCss())); // Change the select. mockSelectionModel.selectNode(CF2, ctrlSignalEvent); expectedSelects.add(CF2); checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes()); assertTrue(AF2.getRenderedTreeNode().isSelected(resources.treeCss())); assertTrue(CF2.getRenderedTreeNode().isSelected(resources.treeCss())); // Select another peer node. FileTreeNode BF2 = getNodeByPath(0, 1); assertNotNull("Node did not get rendered!", BF2.getRenderedTreeNode()); assertFalse(BF2.getRenderedTreeNode().isSelected(resources.treeCss())); // Change the select. mockSelectionModel.selectNode(BF2, ctrlSignalEvent); // We need to enforce sort order. AF2, BF2, CF2. expectedSelects.splice(1, 0, BF2); checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes()); assertTrue(AF2.getRenderedTreeNode().isSelected(resources.treeCss())); assertTrue(BF2.getRenderedTreeNode().isSelected(resources.treeCss())); assertTrue(CF2.getRenderedTreeNode().isSelected(resources.treeCss())); // Ensure that if we ctrl click back higher in the stack that we clear the // selected list. FileTreeNode AF1 = getNodeByPath(3); assertNotNull("Node did not get rendered!", AF1.getRenderedTreeNode()); assertFalse(AF1.getRenderedTreeNode().isSelected(resources.treeCss())); // Change the select. mockSelectionModel.selectNode(AF1, ctrlSignalEvent); expectedSelects.clear(); expectedSelects.add(AF1); checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes()); assertTrue(AF1.getRenderedTreeNode().isSelected(resources.treeCss())); assertFalse(AF2.getRenderedTreeNode().isSelected(resources.treeCss())); assertFalse(BF2.getRenderedTreeNode().isSelected(resources.treeCss())); assertFalse(CF2.getRenderedTreeNode().isSelected(resources.treeCss())); }
/** Tests select responses to shift clicks that should do range selects. */ public void testShiftSelect() { FileTreeNode root = mockTree.getModel().getRoot(); // Render the tree. mockTree.renderTree(-1); SignalEvent shiftSignalEvent = new MockSignalEvent(false, true); FileTreeNode AD1 = getNodeByPath(0); assertNotNull("Node did not get rendered!", AD1.getRenderedTreeNode()); assertFalse(AD1.getRenderedTreeNode().isSelected(resources.treeCss())); JsoArray<FileTreeNode> expectedSelects = JsoArray.create(); // Select the first top level dir. mockSelectionModel.selectNode(AD1, shiftSignalEvent); expectedSelects.add(AD1); checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes()); assertTrue(AD1.getRenderedTreeNode().isSelected(resources.treeCss())); // Shift select the last top level file. FileTreeNode BF1 = getNodeByPath(4); mockSelectionModel.selectNode(BF1, shiftSignalEvent); expectedSelects.add(getNodeByPath(1)); expectedSelects.add(getNodeByPath(2)); expectedSelects.add(getNodeByPath(3)); expectedSelects.add(getNodeByPath(4)); checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes()); assertTrue(BF1.getRenderedTreeNode().isSelected(resources.treeCss())); assertTrue(getNodeByPath(2).getRenderedTreeNode().isSelected(resources.treeCss())); assertTrue(getNodeByPath(3).getRenderedTreeNode().isSelected(resources.treeCss())); // Select the last file. It should zero the shift selection. mockSelectionModel.selectNode(BF1, shiftSignalEvent); expectedSelects.clear(); expectedSelects.add(BF1); checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes()); assertTrue(BF1.getRenderedTreeNode().isSelected(resources.treeCss())); assertFalse(getNodeByPath(0).getRenderedTreeNode().isSelected(resources.treeCss())); assertFalse(getNodeByPath(1).getRenderedTreeNode().isSelected(resources.treeCss())); assertFalse(getNodeByPath(2).getRenderedTreeNode().isSelected(resources.treeCss())); assertFalse(getNodeByPath(3).getRenderedTreeNode().isSelected(resources.treeCss())); // Select deeper. We should not allow cross depth selecting and // should replace it with just the new select. FileTreeNode AF2 = getNodeByPath(0, 0); assertNotNull("Node did not get rendered!", AF2.getRenderedTreeNode()); assertFalse(AF2.getRenderedTreeNode().isSelected(resources.treeCss())); // Change the select. mockSelectionModel.selectNode(AF2, shiftSignalEvent); expectedSelects.clear(); expectedSelects.add(AF2); checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes()); assertTrue(AF2.getRenderedTreeNode().isSelected(resources.treeCss())); assertFalse(BF1.getRenderedTreeNode().isSelected(resources.treeCss())); // Select the adjacent peer node. FileTreeNode BF2 = getNodeByPath(0, 1); assertNotNull("Node did not get rendered!", BF2.getRenderedTreeNode()); assertFalse(BF2.getRenderedTreeNode().isSelected(resources.treeCss())); // Change the select. mockSelectionModel.selectNode(BF2, shiftSignalEvent); expectedSelects.add(BF2); checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes()); assertTrue(AF2.getRenderedTreeNode().isSelected(resources.treeCss())); assertTrue(BF2.getRenderedTreeNode().isSelected(resources.treeCss())); // Select the last peer node. FileTreeNode DF2 = getNodeByPath(0, 3); assertNotNull("Node did not get rendered!", DF2.getRenderedTreeNode()); assertFalse(DF2.getRenderedTreeNode().isSelected(resources.treeCss())); // Change the select. mockSelectionModel.selectNode(DF2, shiftSignalEvent); expectedSelects.add(getNodeByPath(0, 2)); expectedSelects.add(getNodeByPath(0, 3)); checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes()); assertTrue(DF2.getRenderedTreeNode().isSelected(resources.treeCss())); assertTrue(getNodeByPath(0, 2).getRenderedTreeNode().isSelected(resources.treeCss())); // Ensure that if we shift click the last one we clear the selected list. mockSelectionModel.selectNode(DF2, shiftSignalEvent); expectedSelects.clear(); expectedSelects.add(DF2); checkNodeArray(expectedSelects, mockSelectionModel.getSelectedNodes()); assertTrue(DF2.getRenderedTreeNode().isSelected(resources.treeCss())); assertFalse(AF2.getRenderedTreeNode().isSelected(resources.treeCss())); assertFalse(BF2.getRenderedTreeNode().isSelected(resources.treeCss())); assertFalse(getNodeByPath(0, 2).getRenderedTreeNode().isSelected(resources.treeCss())); }
public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) { myProject = project; myFile = file.getViewProvider().getPsi(file.getViewProvider().getBaseLanguage()); myEditor = editor; PsiElement context = myFile.getContext(); if (context != null && (context.textContains('\'') || context.textContains('\"'))) { String s = context.getText(); if (StringUtil.startsWith(s, "\"") || StringUtil.startsWith(s, "\'")) { myFile = context.getContainingFile(); myEditor = editor instanceof EditorWindow ? ((EditorWindow) editor).getDelegate() : editor; } } myDocument = myEditor.getDocument(); if (!FileDocumentManager.getInstance().requestWriting(myDocument, project)) { return; } PsiDocumentManager.getInstance(project).commitDocument(myDocument); FeatureUsageTracker.getInstance().triggerFeatureUsed("codeassists.comment.line"); myCodeStyleManager = CodeStyleManager.getInstance(myProject); final SelectionModel selectionModel = myEditor.getSelectionModel(); boolean hasSelection = selectionModel.hasSelection(); myStartOffset = selectionModel.getSelectionStart(); myEndOffset = selectionModel.getSelectionEnd(); FoldRegion fold = myEditor.getFoldingModel().getCollapsedRegionAtOffset(myStartOffset); if (fold != null && fold.shouldNeverExpand() && fold.getStartOffset() == myStartOffset && fold.getEndOffset() == myEndOffset) { // Foldings that never expand are automatically selected, so the fact it is selected must not // interfer with commenter's logic hasSelection = false; } if (myDocument.getTextLength() == 0) return; while (true) { int lastLineEnd = myDocument.getLineEndOffset(myDocument.getLineNumber(myEndOffset)); FoldRegion collapsedAt = myEditor.getFoldingModel().getCollapsedRegionAtOffset(lastLineEnd); if (collapsedAt != null) { final int endOffset = collapsedAt.getEndOffset(); if (endOffset <= myEndOffset) { break; } myEndOffset = endOffset; } else { break; } } boolean wholeLinesSelected = !hasSelection || myStartOffset == myDocument.getLineStartOffset(myDocument.getLineNumber(myStartOffset)) && myEndOffset == myDocument.getLineEndOffset(myDocument.getLineNumber(myEndOffset - 1)) + 1; boolean startingNewLineComment = !hasSelection && isLineEmpty(myDocument.getLineNumber(myStartOffset)) && !Comparing.equal( IdeActions.ACTION_COMMENT_LINE, ActionManagerEx.getInstanceEx().getPrevPreformedActionId()); doComment(); if (startingNewLineComment) { final Commenter commenter = myCommenters[0]; if (commenter != null) { String prefix; if (commenter instanceof SelfManagingCommenter) { prefix = ((SelfManagingCommenter) commenter) .getCommentPrefix( myStartLine, myDocument, myCommenterStateMap.get((SelfManagingCommenter) commenter)); if (prefix == null) prefix = ""; // TODO } else { prefix = commenter.getLineCommentPrefix(); if (prefix == null) prefix = commenter.getBlockCommentPrefix(); } int lineStart = myDocument.getLineStartOffset(myStartLine); lineStart = CharArrayUtil.shiftForward(myDocument.getCharsSequence(), lineStart, " \t"); lineStart += prefix.length(); lineStart = CharArrayUtil.shiftForward(myDocument.getCharsSequence(), lineStart, " \t"); if (lineStart > myDocument.getTextLength()) lineStart = myDocument.getTextLength(); myEditor.getCaretModel().moveToOffset(lineStart); myEditor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); } } else { if (!hasSelection) { // Don't tweak caret position if we're already located on the last document line. LogicalPosition position = myEditor.getCaretModel().getLogicalPosition(); if (position.line < myDocument.getLineCount() - 1) { int verticalShift = 1 + myEditor.getSoftWrapModel().getSoftWrapsForLine(position.line).size() - position.softWrapLinesOnCurrentLogicalLine; myEditor.getCaretModel().moveCaretRelatively(0, verticalShift, false, false, true); } } else { if (wholeLinesSelected) { selectionModel.setSelection(myStartOffset, selectionModel.getSelectionEnd()); } } } }
public void moveCaretRelatively( int columnShift, int lineShift, boolean withSelection, boolean blockSelection, boolean scrollToCaret) { assertIsDispatchThread(); SelectionModel selectionModel = myEditor.getSelectionModel(); int selectionStart = selectionModel.getLeadSelectionOffset(); LogicalPosition blockSelectionStart = selectionModel.hasBlockSelection() ? selectionModel.getBlockStart() : getLogicalPosition(); EditorSettings editorSettings = myEditor.getSettings(); VisualPosition visualCaret = getVisualPosition(); int desiredX = myDesiredX; if (columnShift == 0) { if (myDesiredX < 0) { desiredX = myEditor.visualPositionToXY(visualCaret).x; } } else { myDesiredX = desiredX = -1; } int newLineNumber = visualCaret.line + lineShift; int newColumnNumber = visualCaret.column + columnShift; if (desiredX >= 0 && !ApplicationManager.getApplication().isUnitTestMode()) { newColumnNumber = myEditor.xyToVisualPosition( new Point(desiredX, Math.max(0, newLineNumber) * myEditor.getLineHeight())) .column; } Document document = myEditor.getDocument(); if (!editorSettings.isVirtualSpace() && columnShift == 0 && getLogicalPosition().softWrapLinesOnCurrentLogicalLine <= 0) { newColumnNumber = myEditor.getLastColumnNumber(); } else if (!editorSettings.isVirtualSpace() && lineShift == 0 && columnShift == 1) { int lastLine = document.getLineCount() - 1; if (lastLine < 0) lastLine = 0; if (EditorModificationUtil.calcAfterLineEnd(myEditor) >= 0 && newLineNumber < myEditor.logicalToVisualPosition(new LogicalPosition(lastLine, 0)).line) { newColumnNumber = 0; newLineNumber++; } } else if (!editorSettings.isVirtualSpace() && lineShift == 0 && columnShift == -1) { if (newColumnNumber < 0 && newLineNumber > 0) { newLineNumber--; newColumnNumber = EditorUtil.getLastVisualLineColumnNumber(myEditor, newLineNumber); } } if (newColumnNumber < 0) newColumnNumber = 0; // There is a possible case that caret is located at the first line and user presses 'Shift+Up'. // We want to select all text // from the document start to the current caret position then. So, we have a dedicated flag for // tracking that. boolean selectToDocumentStart = false; if (newLineNumber < 0) { selectToDocumentStart = true; newLineNumber = 0; // We want to move caret to the first column if it's already located at the first line and // 'Up' is pressed. newColumnNumber = 0; desiredX = -1; } VisualPosition pos = new VisualPosition(newLineNumber, newColumnNumber); int lastColumnNumber = newColumnNumber; if (!editorSettings.isCaretInsideTabs() && !myEditor.getSoftWrapModel().isInsideSoftWrap(pos)) { LogicalPosition log = myEditor.visualToLogicalPosition(new VisualPosition(newLineNumber, newColumnNumber)); int offset = myEditor.logicalPositionToOffset(log); if (offset >= document.getTextLength()) { int lastOffsetColumn = myEditor.offsetToVisualPosition(document.getTextLength()).column; // We want to move caret to the last column if if it's located at the last line and 'Down' // is pressed. newColumnNumber = lastColumnNumber = Math.max(lastOffsetColumn, newColumnNumber); desiredX = -1; } CharSequence text = document.getCharsSequence(); if (offset >= 0 && offset < document.getTextLength()) { if (text.charAt(offset) == '\t' && (columnShift <= 0 || offset == myOffset)) { if (columnShift <= 0) { newColumnNumber = myEditor.offsetToVisualPosition(offset).column; } else { SoftWrap softWrap = myEditor.getSoftWrapModel().getSoftWrap(offset + 1); // There is a possible case that tabulation symbol is the last document symbol // represented on a visual line before // soft wrap. We can't just use column from 'offset + 1' because it would point on a // next visual line. if (softWrap == null) { newColumnNumber = myEditor.offsetToVisualPosition(offset + 1).column; } else { newColumnNumber = EditorUtil.getLastVisualLineColumnNumber(myEditor, newLineNumber); } } } } } pos = new VisualPosition(newLineNumber, newColumnNumber); if (columnShift != 0 && lineShift == 0 && myEditor.getSoftWrapModel().isInsideSoftWrap(pos)) { LogicalPosition logical = myEditor.visualToLogicalPosition(pos); int softWrapOffset = myEditor.logicalPositionToOffset(logical); if (columnShift >= 0) { moveToOffset(softWrapOffset); } else { int line = myEditor.offsetToVisualLine(softWrapOffset - 1); moveToVisualPosition( new VisualPosition(line, EditorUtil.getLastVisualLineColumnNumber(myEditor, line))); } } else { moveToVisualPosition(pos); if (!editorSettings.isVirtualSpace() && columnShift == 0) { myEditor.setLastColumnNumber(lastColumnNumber); } } if (withSelection) { if (blockSelection) { selectionModel.setBlockSelection(blockSelectionStart, getLogicalPosition()); } else { if (selectToDocumentStart) { selectionModel.setSelection(selectionStart, 0); } else if (pos.line >= myEditor.getVisibleLineCount()) { if (selectionStart < document.getTextLength()) { selectionModel.setSelection(selectionStart, document.getTextLength()); } } else { selectionModel.setSelection(selectionStart, getVisualPosition(), getOffset()); } } } else { selectionModel.removeSelection(); } if (scrollToCaret) { myEditor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); } if (desiredX >= 0) { myDesiredX = desiredX; } EditorActionUtil.selectNonexpandableFold(myEditor); }
private void dumpEditorMarkupAndSelection(PrintStream dumpStream) { dumpStream.println(mySearchResults.getFindModel()); if (myReplacementPreviewText != null) { dumpStream.println("--"); dumpStream.println("Replacement Preview: " + myReplacementPreviewText); } dumpStream.println("--"); Editor editor = mySearchResults.getEditor(); RangeHighlighter[] highlighters = editor.getMarkupModel().getAllHighlighters(); List<Pair<Integer, Character>> ranges = new ArrayList<Pair<Integer, Character>>(); for (RangeHighlighter highlighter : highlighters) { ranges.add(new Pair<Integer, Character>(highlighter.getStartOffset(), '[')); ranges.add(new Pair<Integer, Character>(highlighter.getEndOffset(), ']')); } SelectionModel selectionModel = editor.getSelectionModel(); if (selectionModel.getSelectionStart() != selectionModel.getSelectionEnd()) { ranges.add(new Pair<Integer, Character>(selectionModel.getSelectionStart(), '<')); ranges.add(new Pair<Integer, Character>(selectionModel.getSelectionEnd(), '>')); } ranges.add(new Pair<Integer, Character>(-1, '\n')); ranges.add(new Pair<Integer, Character>(editor.getDocument().getTextLength() + 1, '\n')); ContainerUtil.sort( ranges, new Comparator<Pair<Integer, Character>>() { @Override public int compare(Pair<Integer, Character> pair, Pair<Integer, Character> pair2) { int res = pair.first - pair2.first; if (res == 0) { Character c1 = pair.second; Character c2 = pair2.second; if (c1 == '<' && c2 == '[') { return 1; } else if (c1 == '[' && c2 == '<') { return -1; } return c1.compareTo(c2); } return res; } }); Document document = editor.getDocument(); for (int i = 0; i < ranges.size() - 1; ++i) { Pair<Integer, Character> pair = ranges.get(i); Pair<Integer, Character> pair1 = ranges.get(i + 1); dumpStream.print( pair.second + document.getText( TextRange.create( Math.max(pair.first, 0), Math.min(pair1.first, document.getTextLength())))); } dumpStream.println("\n--"); if (NotFound) { dumpStream.println("Not Found"); dumpStream.println("--"); NotFound = false; } for (RangeHighlighter highlighter : highlighters) { dumpStream.println(highlighter + " : " + highlighter.getTextAttributes()); } dumpStream.println("------------"); }
public final void move(Editor editor, final PsiFile file) { myMover.beforeMove(editor, myInfo, myIsDown); final Document document = editor.getDocument(); final int start = StatementUpDownMover.getLineStartSafeOffset(document, myInfo.toMove.startLine); final int end = StatementUpDownMover.getLineStartSafeOffset(document, myInfo.toMove.endLine); myInfo.range1 = document.createRangeMarker(start, end); String textToInsert = document.getCharsSequence().subSequence(start, end).toString(); if (!StringUtil.endsWithChar(textToInsert, '\n')) textToInsert += '\n'; final int start2 = document.getLineStartOffset(myInfo.toMove2.startLine); final int end2 = StatementUpDownMover.getLineStartSafeOffset(document, myInfo.toMove2.endLine); String textToInsert2 = document.getCharsSequence().subSequence(start2, end2).toString(); if (!StringUtil.endsWithChar(textToInsert2, '\n')) textToInsert2 += '\n'; myInfo.range2 = document.createRangeMarker(start2, end2); if (myInfo.range1.getStartOffset() < myInfo.range2.getStartOffset()) { myInfo.range1.setGreedyToLeft(true); myInfo.range1.setGreedyToRight(false); myInfo.range2.setGreedyToLeft(true); myInfo.range2.setGreedyToRight(true); } else { myInfo.range1.setGreedyToLeft(true); myInfo.range1.setGreedyToRight(true); myInfo.range2.setGreedyToLeft(true); myInfo.range2.setGreedyToRight(false); } final CaretModel caretModel = editor.getCaretModel(); final int caretRelativePos = caretModel.getOffset() - start; final SelectionModel selectionModel = editor.getSelectionModel(); final int selectionStart = selectionModel.getSelectionStart(); final int selectionEnd = selectionModel.getSelectionEnd(); final boolean hasSelection = selectionModel.hasSelection(); // to prevent flicker caretModel.moveToOffset(0); // There is a possible case that the user performs, say, method move. It's also possible that // one (or both) of moved methods // are folded. We want to preserve their states then. The problem is that folding processing is // based on PSI element pointers // and the pointers behave as following during move up/down: // method1() {} // method2() {} // Pointer for the fold region from method1 points to 'method2()' now and vice versa (check // range markers processing on // document change for further information). I.e. information about fold regions statuses holds // the data swapped for // 'method1' and 'method2'. Hence, we want to apply correct 'collapsed' status. FoldRegion topRegion = null; FoldRegion bottomRegion = null; for (FoldRegion foldRegion : editor.getFoldingModel().getAllFoldRegions()) { if (!foldRegion.isValid() || (!contains(myInfo.range1, foldRegion) && !contains(myInfo.range2, foldRegion))) { continue; } if (contains(myInfo.range1, foldRegion) && !contains(topRegion, foldRegion)) { topRegion = foldRegion; } else if (contains(myInfo.range2, foldRegion) && !contains(bottomRegion, foldRegion)) { bottomRegion = foldRegion; } } document.insertString(myInfo.range1.getStartOffset(), textToInsert2); document.deleteString( myInfo.range1.getStartOffset() + textToInsert2.length(), myInfo.range1.getEndOffset()); document.insertString(myInfo.range2.getStartOffset(), textToInsert); int s = myInfo.range2.getStartOffset() + textToInsert.length(); int e = myInfo.range2.getEndOffset(); if (e > s) { document.deleteString(s, e); } final Project project = file.getProject(); PsiDocumentManager.getInstance(project).commitAllDocuments(); // Swap fold regions status if necessary. if (topRegion != null && bottomRegion != null) { final FoldRegion finalTopRegion = topRegion; final FoldRegion finalBottomRegion = bottomRegion; editor .getFoldingModel() .runBatchFoldingOperation( new Runnable() { @Override public void run() { boolean topExpanded = finalTopRegion.isExpanded(); finalTopRegion.setExpanded(finalBottomRegion.isExpanded()); finalBottomRegion.setExpanded(topExpanded); } }); } CodeFoldingManager.getInstance(project).allowFoldingOnCaretLine(editor); if (hasSelection) { restoreSelection(editor, selectionStart, selectionEnd, start, myInfo.range2.getStartOffset()); } caretModel.moveToOffset(myInfo.range2.getStartOffset() + caretRelativePos); if (myInfo.indentTarget) { indentLinesIn(editor, file, document, project, myInfo.range2); } if (myInfo.indentSource) { indentLinesIn(editor, file, document, project, myInfo.range1); } myMover.afterMove(editor, file, myInfo, myIsDown); editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); }
private static void doPaste( final Editor editor, final Project project, final PsiFile file, final Document document, final Producer<Transferable> producer) { Transferable content = null; if (producer != null) { content = producer.produce(); } else { CopyPasteManager manager = CopyPasteManager.getInstance(); if (manager.areDataFlavorsAvailable(DataFlavor.stringFlavor)) { content = manager.getContents(); if (content != null) { manager.stopKillRings(); } } } if (content != null) { String text = null; try { text = (String) content.getTransferData(DataFlavor.stringFlavor); } catch (Exception e) { editor.getComponent().getToolkit().beep(); } if (text == null) return; final CodeInsightSettings settings = CodeInsightSettings.getInstance(); final Map<CopyPastePostProcessor, TextBlockTransferableData> extraData = new HashMap<CopyPastePostProcessor, TextBlockTransferableData>(); for (CopyPastePostProcessor processor : Extensions.getExtensions(CopyPastePostProcessor.EP_NAME)) { TextBlockTransferableData data = processor.extractTransferableData(content); if (data != null) { extraData.put(processor, data); } } text = TextBlockTransferable.convertLineSeparators(text, "\n", extraData.values()); final CaretModel caretModel = editor.getCaretModel(); final SelectionModel selectionModel = editor.getSelectionModel(); final int col = caretModel.getLogicalPosition().column; // There is a possible case that we want to perform paste while there is an active selection // at the editor and caret is located // inside it (e.g. Ctrl+A is pressed while caret is not at the zero column). We want to insert // the text at selection start column // then, hence, inserted block of text should be indented according to the selection start as // well. final int blockIndentAnchorColumn; final int caretOffset = caretModel.getOffset(); if (selectionModel.hasSelection() && caretOffset >= selectionModel.getSelectionStart()) { blockIndentAnchorColumn = editor.offsetToLogicalPosition(selectionModel.getSelectionStart()).column; } else { blockIndentAnchorColumn = col; } // We assume that EditorModificationUtil.insertStringAtCaret() is smart enough to remove // currently selected text (if any). RawText rawText = RawText.fromTransferable(content); String newText = text; for (CopyPastePreProcessor preProcessor : Extensions.getExtensions(CopyPastePreProcessor.EP_NAME)) { newText = preProcessor.preprocessOnPaste(project, file, editor, newText, rawText); } int indentOptions = text.equals(newText) ? settings.REFORMAT_ON_PASTE : CodeInsightSettings.REFORMAT_BLOCK; text = newText; if (LanguageFormatting.INSTANCE.forContext(file) == null && indentOptions != CodeInsightSettings.NO_REFORMAT) { indentOptions = CodeInsightSettings.INDENT_BLOCK; } final String _text = text; ApplicationManager.getApplication() .runWriteAction( new Runnable() { @Override public void run() { EditorModificationUtil.insertStringAtCaret(editor, _text, false, true); } }); int length = text.length(); int offset = caretModel.getOffset() - length; if (offset < 0) { length += offset; offset = 0; } final RangeMarker bounds = document.createRangeMarker(offset, offset + length); caretModel.moveToOffset(bounds.getEndOffset()); editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); selectionModel.removeSelection(); final Ref<Boolean> indented = new Ref<Boolean>(Boolean.FALSE); for (Map.Entry<CopyPastePostProcessor, TextBlockTransferableData> e : extraData.entrySet()) { //noinspection unchecked e.getKey() .processTransferableData(project, editor, bounds, caretOffset, indented, e.getValue()); } boolean pastedTextContainsWhiteSpacesOnly = CharArrayUtil.shiftForward(document.getCharsSequence(), bounds.getStartOffset(), " \n\t") >= bounds.getEndOffset(); VirtualFile virtualFile = file.getVirtualFile(); if (!pastedTextContainsWhiteSpacesOnly && (virtualFile == null || !SingleRootFileViewProvider.isTooLargeForIntelligence(virtualFile))) { final int indentOptions1 = indentOptions; ApplicationManager.getApplication() .runWriteAction( new Runnable() { @Override public void run() { switch (indentOptions1) { case CodeInsightSettings.INDENT_BLOCK: if (!indented.get()) { indentBlock( project, editor, bounds.getStartOffset(), bounds.getEndOffset(), blockIndentAnchorColumn); } break; case CodeInsightSettings.INDENT_EACH_LINE: if (!indented.get()) { indentEachLine( project, editor, bounds.getStartOffset(), bounds.getEndOffset()); } break; case CodeInsightSettings.REFORMAT_BLOCK: indentEachLine( project, editor, bounds.getStartOffset(), bounds .getEndOffset()); // this is needed for example when inserting a // comment before method reformatBlock( project, editor, bounds.getStartOffset(), bounds.getEndOffset()); break; } } }); } if (bounds.isValid()) { caretModel.moveToOffset(bounds.getEndOffset()); editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); selectionModel.removeSelection(); editor.putUserData(EditorEx.LAST_PASTED_REGION, TextRange.create(bounds)); } } }
@Nullable @Override public TextBlockTransferableData collectTransferableData( PsiFile file, Editor editor, int[] startOffsets, int[] endOffsets) { if (!Registry.is("editor.richcopy.enable")) { return null; } try { for (TextWithMarkupBuilder builder : myBuilders) { builder.reset(); } SelectionModel selectionModel = editor.getSelectionModel(); if (selectionModel.hasBlockSelection()) { return null; // unsupported legacy mode } RichCopySettings settings = RichCopySettings.getInstance(); List<Caret> carets = editor.getCaretModel().getAllCarets(); Caret firstCaret = carets.get(0); final int indentSymbolsToStrip; final int firstLineStartOffset; if (settings.isStripIndents() && carets.size() == 1) { Pair<Integer, Integer> p = calcIndentSymbolsToStrip( editor.getDocument(), firstCaret.getSelectionStart(), firstCaret.getSelectionEnd()); firstLineStartOffset = p.first; indentSymbolsToStrip = p.second; } else { firstLineStartOffset = firstCaret.getSelectionStart(); indentSymbolsToStrip = 0; } logInitial(editor, startOffsets, endOffsets, indentSymbolsToStrip, firstLineStartOffset); CharSequence text = editor.getDocument().getCharsSequence(); EditorColorsScheme schemeToUse = settings.getColorsScheme(editor.getColorsScheme()); EditorHighlighter highlighter = HighlighterFactory.createHighlighter( file.getVirtualFile(), schemeToUse, file.getProject()); highlighter.setText(text); MarkupModel markupModel = DocumentMarkupModel.forDocument(editor.getDocument(), file.getProject(), false); Context context = new Context(text, schemeToUse, indentSymbolsToStrip); int shift = 0; int endOffset = 0; Caret prevCaret = null; for (Caret caret : carets) { int caretSelectionStart = caret.getSelectionStart(); int caretSelectionEnd = caret.getSelectionEnd(); int startOffsetToUse; if (caret == firstCaret) { startOffsetToUse = firstLineStartOffset; } else { startOffsetToUse = caretSelectionStart; assert prevCaret != null; String prevCaretSelectedText = prevCaret.getSelectedText(); // Block selection fills short lines by white spaces. int fillStringLength = prevCaretSelectedText == null ? 0 : prevCaretSelectedText.length() - (prevCaret.getSelectionEnd() - prevCaret.getSelectionStart()); int endLineOffset = endOffset + shift + fillStringLength; context.builder.addText(endLineOffset, endLineOffset + 1); shift++; // Block selection ends '\n' at line end shift += fillStringLength; } shift += endOffset - caretSelectionStart; endOffset = caretSelectionEnd; context.reset(shift); prevCaret = caret; if (endOffset <= startOffsetToUse) { continue; } MarkupIterator markupIterator = new MarkupIterator( text, new CompositeRangeIterator( schemeToUse, new HighlighterRangeIterator(highlighter, startOffsetToUse, endOffset), new MarkupModelRangeIterator( markupModel, schemeToUse, startOffsetToUse, endOffset)), schemeToUse); try { context.iterate(markupIterator, endOffset); } finally { markupIterator.dispose(); } } SyntaxInfo syntaxInfo = context.finish(); logSyntaxInfo(syntaxInfo); for (TextWithMarkupBuilder builder : myBuilders) { builder.build(syntaxInfo); } } catch (Exception e) { // catching the exception so that the rest of copy/paste functionality can still work fine LOG.error(e); } return null; }