diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/TextComponentEditorAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/TextComponentEditorAction.java index b237d50be34b..1396bb4ec9e7 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/TextComponentEditorAction.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/TextComponentEditorAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.actionSystem.EditorAction; import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.editor.impl.EditorComponentImpl; import com.intellij.openapi.editor.textarea.TextComponentEditorImpl; import com.intellij.openapi.project.Project; import com.intellij.ui.SpeedSearchBase; @@ -52,6 +53,10 @@ public abstract class TextComponentEditorAction extends EditorAction { if (editor != null) return editor; final Project project = CommonDataKeys.PROJECT.getData(dataContext); final Object data = PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext); + if (data instanceof EditorComponentImpl) { + // can happen if editor is already disposed, or if it's in renderer mode + return null; + } if (data instanceof JTextComponent) { return new TextComponentEditorImpl(project, (JTextComponent)data); } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorComponentImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorComponentImpl.java index b5fa3a89c751..fb0cd6ec441d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorComponentImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorComponentImpl.java @@ -132,7 +132,14 @@ public class EditorComponentImpl extends JTextComponent implements Scrollable, D @Override public Object getData(String dataId) { - if (myEditor.isDisposed() || myEditor.isRendererMode()) return null; + if (myEditor.isDisposed()) return null; + + if (PlatformDataKeys.COPY_PROVIDER.is(dataId)) { + // enable copying from editor in renderer mode + return myEditor.getCopyProvider(); + } + + if (myEditor.isRendererMode()) return null; if (CommonDataKeys.EDITOR.is(dataId)) { return myEditor; @@ -146,9 +153,6 @@ public class EditorComponentImpl extends JTextComponent implements Scrollable, D if (PlatformDataKeys.CUT_PROVIDER.is(dataId)) { return myEditor.getCutProvider(); } - if (PlatformDataKeys.COPY_PROVIDER.is(dataId)) { - return myEditor.getCopyProvider(); - } if (PlatformDataKeys.PASTE_PROVIDER.is(dataId)) { return myEditor.getPasteProvider(); } @@ -814,11 +818,7 @@ public class EditorComponentImpl extends JTextComponent implements Scrollable, D @Nullable @Override public Rectangle modelToView(JTextComponent tc, int offset) throws BadLocationException { - LogicalPosition pos = myEditor.offsetToLogicalPosition(offset); - Point point = myEditor.logicalPositionToXY(pos); - FontMetrics fontMetrics = myEditor.getFontMetrics(Font.PLAIN); - char c = myEditor.getDocument().getCharsSequence().subSequence(offset, offset + 1).charAt(0); - return new Rectangle(point.x, point.y, fontMetrics.charWidth(c), fontMetrics.getHeight()); + return modelToView(tc, offset, Position.Bias.Forward); } @Override @@ -829,8 +829,15 @@ public class EditorComponentImpl extends JTextComponent implements Scrollable, D @Nullable @Override - public Rectangle modelToView(JTextComponent tc, int pos, Position.Bias ignored) throws BadLocationException { - return modelToView(tc, pos); + public Rectangle modelToView(JTextComponent tc, int offset, Position.Bias bias) throws BadLocationException { + LogicalPosition pos = myEditor.offsetToLogicalPosition(offset).leanForward(bias == Position.Bias.Forward); + LogicalPosition posNext = myEditor.offsetToLogicalPosition(bias == Position.Bias.Forward ? offset + 1 : offset - 1) + .leanForward(bias != Position.Bias.Forward); + Point point = myEditor.logicalPositionToXY(pos); + Point pointNext = myEditor.logicalPositionToXY(posNext); + return point.y == pointNext.y + ? new Rectangle(Math.min(point.x, pointNext.x), point.y, Math.abs(point.x - pointNext.x), myEditor.getLineHeight()) + : new Rectangle(point.x, point.y, 0, myEditor.getLineHeight()); } @Override