public static Color getBackgroundColor(Editor editor) { EditorColorsScheme colorsScheme = editor.getColorsScheme(); Color color = colorsScheme.getColor(EditorColors.CARET_ROW_COLOR); if (color == null) { color = colorsScheme.getDefaultBackground(); } return color; }
@Nullable public Color getPolygonColor(Editor editor) { if (isApplied()) { return getLegendColor(editor.getColorsScheme()); } else if (isInlineWrapper()) { return getBgColorForFragmentContainingInlines((EditorEx) editor); } else { TextAttributes attributes = getTextAttributes(editor); return attributes == null ? null : attributes.getBackgroundColor(); } }
@NotNull public static RangeHighlighter highlightMatch(@NotNull Editor editor, int start, int end) { TextAttributes color = editor.getColorsScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES); return editor .getMarkupModel() .addRangeHighlighter( start, end, HighlighterLayer.ADDITIONAL_SYNTAX + 1, color, HighlighterTargetArea.EXACT_RANGE); }
@Nullable public TextAttributes getTextAttributes(@NotNull Editor editor) { TextAttributes originalAttrs = getTextAttributes(editor.getColorsScheme()); if (originalAttrs == null) { return null; } TextAttributes overridingAttributes = new TextAttributes(); if (myApplied) { overridingAttributes.setBackgroundColor(((EditorEx) editor).getBackgroundColor()); } else if (myInlineWrapper) { overridingAttributes.setBackgroundColor( getBgColorForFragmentContainingInlines((EditorEx) editor)); } return TextAttributes.merge(originalAttrs, overridingAttributes); }
@Override public void paint(Graphics gfx) { Graphics2D g = (Graphics2D) gfx; g.setColor(editor.getColorsScheme().getDefaultBackground()); g.fillRect(0, 0, getWidth(), getHeight()); logger.debug(String.format("Rendering to buffer: %d", activeBuffer)); if (activeBuffer >= 0) { paintSelection(g); Minimap minimap = minimaps[activeBuffer]; Rectangle visibleArea = editor.getScrollingModel().getVisibleArea(); double documentEndY = editor .logicalPositionToXY( editor.offsetToLogicalPosition(editor.getDocument().getTextLength() - 1)) .getY(); coords .setMinimap(minimap) .setPanelHeight(getHeight()) .setPanelWidth(getWidth()) .setPercentageComplete( visibleArea.getMinY() / (documentEndY - (visibleArea.getMaxY() - visibleArea.getMinY()))) .setHidpiScale(getHidpiScale()); Rectangle src = coords.getImageSource(); Rectangle dest = coords.getImageDestination(); // Draw the image and scale it to stretch vertically. g.drawImage( minimap.img, // source image dest.x, dest.y, dest.width, dest.height, src.x, src.y, src.width, src.height, null); paintVisibleWindow(g); } }
protected static void processMagnification(IdeFrame frame, double magnification) { Point mouse = MouseInfo.getPointerInfo().getLocation(); SwingUtilities.convertPointFromScreen(mouse, frame.getComponent()); Component componentAt = SwingUtilities.getDeepestComponentAt(frame.getComponent(), mouse.x, mouse.y); if (componentAt != null) { Editor editor = PlatformDataKeys.EDITOR.getData(DataManager.getInstance().getDataContext(componentAt)); if (editor != null) { double currentSize = editor.getColorsScheme().getEditorFontSize(); int defaultFontSize = EditorColorsManager.getInstance().getGlobalScheme().getEditorFontSize(); ((EditorEx) editor) .setFontSize((int) (Math.max(currentSize + magnification * 3, defaultFontSize))); } } }
@NotNull private RangeHighlighter highlightConfirm(@NotNull Editor editor, int start, int end) { TextAttributes color = new TextAttributes( editor.getColorsScheme().getColor(EditorColors.SELECTION_FOREGROUND_COLOR), editor.getColorsScheme().getColor(EditorColors.SELECTION_BACKGROUND_COLOR), null, null, 0); return editor .getMarkupModel() .addRangeHighlighter( start, end, HighlighterLayer.ADDITIONAL_SYNTAX + 2, color, HighlighterTargetArea.EXACT_RANGE); }
public static Editor createEditor(boolean isReadOnly, final CharSequence text) { EditorFactory editorFactory = EditorFactory.getInstance(); Document doc = editorFactory.createDocument(text); Editor editor = (isReadOnly ? editorFactory.createViewer(doc) : editorFactory.createEditor(doc)); EditorSettings editorSettings = editor.getSettings(); editorSettings.setVirtualSpace(false); editorSettings.setLineMarkerAreaShown(false); editorSettings.setIndentGuidesShown(false); editorSettings.setLineNumbersShown(false); editorSettings.setFoldingOutlineShown(false); EditorColorsScheme scheme = editor.getColorsScheme(); scheme.setColor(EditorColors.CARET_ROW_COLOR, null); return editor; }
private void paintSelection(Graphics2D g) { int selectionStartOffset = editor.getSelectionModel().getSelectionStart(); int selectionEndOffset = editor.getSelectionModel().getSelectionEnd(); int firstSelectedLine = coords.offsetToScreenSpace(selectionStartOffset); int firstSelectedCharacter = coords.offsetToCharacterInLine(selectionStartOffset); int lastSelectedLine = coords.offsetToScreenSpace(selectionEndOffset); int lastSelectedCharacter = coords.offsetToCharacterInLine(selectionEndOffset); g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.90f)); g.setColor( editor .getColorsScheme() .getColor(ColorKey.createColorKey("SELECTION_BACKGROUND", JBColor.BLUE))); if (firstSelectedLine == lastSelectedLine) { // Single line is easy g.fillRect( firstSelectedCharacter, firstSelectedLine, lastSelectedCharacter - firstSelectedCharacter, config.pixelsPerLine); } else { // Draw the line leading in g.fillRect( firstSelectedCharacter, firstSelectedLine, getWidth() - firstSelectedCharacter, config.pixelsPerLine); // Then the line at the end g.fillRect(0, lastSelectedLine, lastSelectedCharacter, config.pixelsPerLine); if (firstSelectedLine + 1 != lastSelectedLine) { // And if there is anything in between, fill it in g.fillRect( 0, firstSelectedLine + config.pixelsPerLine, getWidth(), lastSelectedLine - firstSelectedLine - config.pixelsPerLine); } } }
/** Fires off a new task to the worker thread. This should only be called from the ui thread. */ private void updateImage() { if (config.disabled) return; if (project.isDisposed()) return; PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); if (file == null) { return; } synchronized (this) { // If we have already sent a rendering job off to get processed then first we need to wait for // it to finish. // see updateComplete for dirty handling. The is that there will be fast updates plus one // final update to // ensure accuracy, dropping any requests in the middle. if (updatePending) { dirty = true; return; } updatePending = true; } SyntaxHighlighter hl = SyntaxHighlighterFactory.getSyntaxHighlighter( file.getLanguage(), project, file.getVirtualFile()); nextBuffer = activeBuffer == 0 ? 1 : 0; runner.add( new RenderTask( minimaps[nextBuffer], editor.getDocument().getText(), editor.getColorsScheme(), hl, editor.getFoldingModel().getAllFoldRegions(), new Runnable() { @Override public void run() { updateComplete(); } })); }
private static void highlightSearchLines( @NotNull Editor editor, @NotNull String pattern, int startLine, int endLine, boolean ignoreCase) { final TextAttributes color = editor.getColorsScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES); Collection<RangeHighlighter> highlighters = EditorData.getLastHighlights(editor); if (highlighters == null) { highlighters = new ArrayList<RangeHighlighter>(); EditorData.setLastHighlights(editor, highlighters); } for (TextRange range : findAll(editor, pattern, startLine, endLine, ignoreCase)) { final RangeHighlighter highlighter = highlightMatch(editor, range.getStartOffset(), range.getEndOffset()); highlighter.setErrorStripeMarkColor(color.getBackgroundColor()); highlighter.setErrorStripeTooltip(pattern); highlighters.add(highlighter); } }
private Editor createEditor() { EditorFactory editorFactory = EditorFactory.getInstance(); Document doc = myFile == null ? editorFactory.createDocument(myTemplate == null ? "" : myTemplate.getText()) : PsiDocumentManager.getInstance(myFile.getProject()).getDocument(myFile); Editor editor = myProject == null ? editorFactory.createEditor(doc) : editorFactory.createEditor(doc, myProject); EditorSettings editorSettings = editor.getSettings(); editorSettings.setVirtualSpace(false); editorSettings.setLineMarkerAreaShown(false); editorSettings.setIndentGuidesShown(false); editorSettings.setLineNumbersShown(false); editorSettings.setFoldingOutlineShown(false); editorSettings.setAdditionalColumnsCount(3); editorSettings.setAdditionalLinesCount(3); EditorColorsScheme scheme = editor.getColorsScheme(); scheme.setColor(EditorColors.CARET_ROW_COLOR, null); editor .getDocument() .addDocumentListener( new DocumentAdapter() { @Override public void documentChanged(DocumentEvent e) { onTextChanged(); } }); ((EditorEx) editor).setHighlighter(createHighlighter()); mySplitter.setFirstComponent(editor.getComponent()); return editor; }
@Override @SuppressWarnings({"AssignmentToForLoopParameter"}) public void paint( @NotNull Editor editor, @NotNull RangeHighlighter highlighter, @NotNull Graphics g) { int startOffset = highlighter.getStartOffset(); final Document doc = highlighter.getDocument(); if (startOffset >= doc.getTextLength()) return; final int endOffset = highlighter.getEndOffset(); final int endLine = doc.getLineNumber(endOffset); int off; int startLine = doc.getLineNumber(startOffset); IndentGuideDescriptor descriptor = editor.getIndentsModel().getDescriptor(startLine, endLine); final CharSequence chars = doc.getCharsSequence(); do { int start = doc.getLineStartOffset(startLine); int end = doc.getLineEndOffset(startLine); off = CharArrayUtil.shiftForward(chars, start, end, " \t"); startLine--; } while (startLine > 1 && off < doc.getTextLength() && chars.charAt(off) == '\n'); final VisualPosition startPosition = editor.offsetToVisualPosition(off); int indentColumn = startPosition.column; // It's considered that indent guide can cross not only white space but comments, javadocs // etc. Hence, there is a possible // case that the first indent guide line is, say, single-line comment where comment // symbols ('//') are located at the first // visual column. We need to calculate correct indent guide column then. int lineShift = 1; if (indentColumn <= 0 && descriptor != null) { indentColumn = descriptor.indentLevel; lineShift = 0; } if (indentColumn <= 0) return; final FoldingModel foldingModel = editor.getFoldingModel(); if (foldingModel.isOffsetCollapsed(off)) return; final FoldRegion headerRegion = foldingModel.getCollapsedRegionAtOffset(doc.getLineEndOffset(doc.getLineNumber(off))); final FoldRegion tailRegion = foldingModel.getCollapsedRegionAtOffset( doc.getLineStartOffset(doc.getLineNumber(endOffset))); if (tailRegion != null && tailRegion == headerRegion) return; final boolean selected; final IndentGuideDescriptor guide = editor.getIndentsModel().getCaretIndentGuide(); if (guide != null) { final CaretModel caretModel = editor.getCaretModel(); final int caretOffset = caretModel.getOffset(); selected = caretOffset >= off && caretOffset < endOffset && caretModel.getLogicalPosition().column == indentColumn; } else { selected = false; } Point start = editor.visualPositionToXY( new VisualPosition(startPosition.line + lineShift, indentColumn)); final VisualPosition endPosition = editor.offsetToVisualPosition(endOffset); Point end = editor.visualPositionToXY(new VisualPosition(endPosition.line, endPosition.column)); int maxY = end.y; if (endPosition.line == editor.offsetToVisualPosition(doc.getTextLength()).line) { maxY += editor.getLineHeight(); } Rectangle clip = g.getClipBounds(); if (clip != null) { if (clip.y >= maxY || clip.y + clip.height <= start.y) { return; } maxY = Math.min(maxY, clip.y + clip.height); } final EditorColorsScheme scheme = editor.getColorsScheme(); g.setColor( selected ? scheme.getColor(EditorColors.SELECTED_INDENT_GUIDE_COLOR) : scheme.getColor(EditorColors.INDENT_GUIDE_COLOR)); // There is a possible case that indent line intersects soft wrap-introduced text. // Example: // this is a long line <soft-wrap> // that| is soft-wrapped // | // | <- vertical indent // // Also it's possible that no additional intersections are added because of soft wrap: // this is a long line <soft-wrap> // | that is soft-wrapped // | // | <- vertical indent // We want to use the following approach then: // 1. Show only active indent if it crosses soft wrap-introduced text; // 2. Show indent as is if it doesn't intersect with soft wrap-introduced text; if (selected) { g.drawLine(start.x + 2, start.y, start.x + 2, maxY); } else { int y = start.y; int newY = start.y; SoftWrapModel softWrapModel = editor.getSoftWrapModel(); int lineHeight = editor.getLineHeight(); for (int i = Math.max(0, startLine + lineShift); i < endLine && newY < maxY; i++) { List<? extends SoftWrap> softWraps = softWrapModel.getSoftWrapsForLine(i); int logicalLineHeight = softWraps.size() * lineHeight; if (i > startLine + lineShift) { logicalLineHeight += lineHeight; // We assume that initial 'y' value points just below the target // line. } if (!softWraps.isEmpty() && softWraps.get(0).getIndentInColumns() < indentColumn) { if (y < newY || i > startLine + lineShift) { // There is a possible case that soft wrap is located on // indent start line. g.drawLine(start.x + 2, y, start.x + 2, newY + lineHeight); } newY += logicalLineHeight; y = newY; } else { newY += logicalLineHeight; } FoldRegion foldRegion = foldingModel.getCollapsedRegionAtOffset(doc.getLineEndOffset(i)); if (foldRegion != null && foldRegion.getEndOffset() < doc.getTextLength()) { i = doc.getLineNumber(foldRegion.getEndOffset()); } } if (y < maxY) { g.drawLine(start.x + 2, y, start.x + 2, maxY); } } }
@NotNull private static EditorColorsScheme getColorScheme(@Nullable Editor editor) { return editor != null ? editor.getColorsScheme() : EditorColorsManager.getInstance().getGlobalScheme(); }
@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; }