From e0060fef201da35b08d4d4db2eb85163146c1da0 Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Tue, 16 May 2017 11:06:52 +0300 Subject: [PATCH] EA-83987 - IOOBE: CharSequenceSubSequence. This includes two fixes: 1) Correct model-to-view translation in JTextComponent wrapper for editor (avoids exception when target position is at the end of the document) 2) Avoid wrapping editor component into TextComponentEditor (could happen previously if editor was in renderer mode) --- .../actions/TextComponentEditorAction.java | 7 ++++- .../editor/impl/EditorComponentImpl.java | 29 ++++++++++++------- 2 files changed, 24 insertions(+), 12 deletions(-) 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