Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMickael Istria2019-06-26 10:56:05 -0400
committerMickael Istria2019-06-26 11:16:37 -0400
commitf6f861584d69ea66be304e03ece940a922bd717a (patch)
tree2dc3fbb2dbd549de9c2e7615966aa12ffb73e477
parentedcad2307a2bc04210522a763303aad951e7e327 (diff)
downloadeclipse.platform.text-f6f861584d69ea66be304e03ece940a922bd717a.tar.gz
eclipse.platform.text-f6f861584d69ea66be304e03ece940a922bd717a.tar.xz
eclipse.platform.text-f6f861584d69ea66be304e03ece940a922bd717a.zip
This is more a workaround as the solution is not optimal at usage (caret not properly placed), but the proposed state is still better than current one. This prevents from making a '\t' character "host" the annotation as it comes with a bunch of issues in the DrawingStrategy (that fails at properly computing the width of a tab) and in SWT (bug 547532). Change-Id: I897da06cd57aef80a862ba28dc75887c212d234a Signed-off-by: Mickael Istria <mistria@redhat.com>
-rw-r--r--org.eclipse.jface.text.tests/META-INF/MANIFEST.MF1
-rw-r--r--org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/JFaceTextTestSuite.java4
-rw-r--r--org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/codemining/CodeMiningProjectionViewerTest.java19
-rw-r--r--org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/source/inlined/InlineAnnotationTest.java164
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/LineContentAnnotation.java4
5 files changed, 173 insertions, 19 deletions
diff --git a/org.eclipse.jface.text.tests/META-INF/MANIFEST.MF b/org.eclipse.jface.text.tests/META-INF/MANIFEST.MF
index a86ce43a0..1a42f6042 100644
--- a/org.eclipse.jface.text.tests/META-INF/MANIFEST.MF
+++ b/org.eclipse.jface.text.tests/META-INF/MANIFEST.MF
@@ -12,6 +12,7 @@ Export-Package:
org.eclipse.jface.text.tests.reconciler,
org.eclipse.jface.text.tests.rules,
org.eclipse.jface.text.tests.source,
+ org.eclipse.jface.text.tests.source.inlined,
org.eclipse.jface.text.tests.templates.persistence,
org.eclipse.jface.text.tests.util
Require-Bundle:
diff --git a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/JFaceTextTestSuite.java b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/JFaceTextTestSuite.java
index d35ff7e74..5a492dad9 100644
--- a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/JFaceTextTestSuite.java
+++ b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/JFaceTextTestSuite.java
@@ -17,8 +17,8 @@ import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
-import org.eclipse.jface.text.tests.codemining.CodeMiningTest;
import org.eclipse.jface.text.tests.codemining.CodeMiningProjectionViewerTest;
+import org.eclipse.jface.text.tests.codemining.CodeMiningTest;
import org.eclipse.jface.text.tests.contentassist.AsyncContentAssistTest;
import org.eclipse.jface.text.tests.reconciler.AbstractReconcilerTest;
import org.eclipse.jface.text.tests.rules.DefaultPartitionerTest;
@@ -27,6 +27,7 @@ import org.eclipse.jface.text.tests.rules.FastPartitionerTest;
import org.eclipse.jface.text.tests.rules.ScannerColumnTest;
import org.eclipse.jface.text.tests.rules.WordRuleTest;
import org.eclipse.jface.text.tests.source.LineNumberRulerColumnTest;
+import org.eclipse.jface.text.tests.source.inlined.InlineAnnotationTest;
import org.eclipse.jface.text.tests.templates.persistence.TemplatePersistenceDataTest;
@@ -57,6 +58,7 @@ import org.eclipse.jface.text.tests.templates.persistence.TemplatePersistenceDat
WordRuleTest.class,
TemplatePersistenceDataTest.class,
+ InlineAnnotationTest.class,
CodeMiningTest.class,
CodeMiningProjectionViewerTest.class
})
diff --git a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/codemining/CodeMiningProjectionViewerTest.java b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/codemining/CodeMiningProjectionViewerTest.java
index 4fbb54ecf..88bf217ce 100644
--- a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/codemining/CodeMiningProjectionViewerTest.java
+++ b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/codemining/CodeMiningProjectionViewerTest.java
@@ -43,7 +43,6 @@ import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.codemining.ICodeMining;
import org.eclipse.jface.text.codemining.ICodeMiningProvider;
import org.eclipse.jface.text.codemining.LineContentCodeMining;
-import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.AnnotationPainter;
import org.eclipse.jface.text.source.IAnnotationAccess;
import org.eclipse.jface.text.source.ISharedTextColors;
@@ -51,6 +50,7 @@ import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;
import org.eclipse.jface.text.source.projection.ProjectionSupport;
import org.eclipse.jface.text.source.projection.ProjectionViewer;
+import org.eclipse.jface.text.tests.source.inlined.InlineAnnotationTest.AccessAllAnnoations;
import org.eclipse.jface.text.tests.util.DisplayHelper;
public class CodeMiningProjectionViewerTest {
@@ -86,22 +86,7 @@ public class CodeMiningProjectionViewerTest {
fParent.setSize(500, 200);
fParent.setLayout(new FillLayout());
fViewer= new ProjectionViewer(fParent, null, null, false, SWT.NONE);
- IAnnotationAccess annotationAccess = new IAnnotationAccess() {
- @Override
- public Object getType(Annotation annotation) {
- return annotation.getType();
- }
-
- @Override
- public boolean isMultiLine(Annotation annotation) {
- return true;
- }
-
- @Override
- public boolean isTemporary(Annotation annotation) {
- return true;
- }
- };
+ IAnnotationAccess annotationAccess = new AccessAllAnnoations();
// code minings
AnnotationPainter painter = new AnnotationPainter(fViewer, annotationAccess);
fViewer.addPainter(painter);
diff --git a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/source/inlined/InlineAnnotationTest.java b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/source/inlined/InlineAnnotationTest.java
new file mode 100644
index 000000000..75e924d28
--- /dev/null
+++ b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/source/inlined/InlineAnnotationTest.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Red Hat Inc. and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.jface.text.tests.source.inlined;
+
+import java.util.Collections;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Shell;
+
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.ITextViewerExtension2;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.AnnotationModel;
+import org.eclipse.jface.text.source.AnnotationPainter;
+import org.eclipse.jface.text.source.IAnnotationAccess;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.jface.text.source.inlined.InlinedAnnotationSupport;
+import org.eclipse.jface.text.source.inlined.LineContentAnnotation;
+import org.eclipse.jface.text.tests.util.DisplayHelper;
+
+@RunWith(Parameterized.class)
+public class InlineAnnotationTest {
+ @Parameters(name="{0}")
+ public static String[] contents() {
+ return new String[] {
+ "annotation inside text",
+ " annotation just after initial space",
+ "\tannoation just after initial tab"
+ };
+ }
+
+ private String text;
+
+ public InlineAnnotationTest(String text) {
+ this.text = text;
+ }
+
+ public static final class AccessAllAnnoations implements IAnnotationAccess {
+ @Override
+ public Object getType(Annotation annotation) {
+ return annotation.getType();
+ }
+
+ @Override
+ public boolean isMultiLine(Annotation annotation) {
+ return true;
+ }
+
+ @Override
+ public boolean isTemporary(Annotation annotation) {
+ return true;
+ }
+ }
+
+ private static final class TestAnnotationPainter extends AnnotationPainter {
+ private boolean painted;
+
+ private TestAnnotationPainter(ISourceViewer sourceViewer, IAnnotationAccess access) {
+ super(sourceViewer, access);
+ }
+
+ @Override
+ public void paint(int reason) {
+ this.painted = true;
+ super.paint(reason);
+ }
+
+ public boolean wasPainted() {
+ return this.painted;
+ }
+ }
+
+ private Shell fParent;
+
+ @Before
+ public void setUp() {
+ fParent= new Shell();
+ }
+
+ @After
+ public void tearDown() {
+ fParent.dispose();
+ fParent = null;
+ }
+
+ @Test
+ public void testTextBoundsMatchPaintedArea() {
+ fParent.setLayout(new FillLayout());
+
+ // Create source viewer and initialize the content
+ ISourceViewer sourceViewer = new SourceViewer(fParent,null,
+ SWT.V_SCROLL | SWT.BORDER);
+ sourceViewer.setDocument(new Document(this.text), new AnnotationModel());
+
+ // Initialize inlined annotations support
+ InlinedAnnotationSupport support = new InlinedAnnotationSupport();
+ IAnnotationAccess annotationAccess = new AccessAllAnnoations();
+ TestAnnotationPainter painter = new TestAnnotationPainter(sourceViewer, annotationAccess);
+ ((ITextViewerExtension2) sourceViewer).addPainter(painter);
+ support.install(sourceViewer, painter);
+
+ // add annotations
+ LineContentAnnotation annotation= new LineContentAnnotation(new Position(1, 1), sourceViewer);
+ annotation.setText("longAnnationToDisplayOnTab");
+ support.updateAnnotations(Collections.singleton(annotation));
+ fParent.open();
+ StyledText textWidget= sourceViewer.getTextWidget();
+ Assert.assertTrue(new DisplayHelper() {
+ @Override
+ protected boolean condition() {
+ return textWidget.isVisible() && painter.wasPainted();
+ }
+ }.waitForCondition(textWidget.getDisplay(), 2000));
+ DisplayHelper.sleep(textWidget.getDisplay(), 1000);
+ Rectangle textBounds= textWidget.getTextBounds(0, textWidget.getText().length() - 1);
+ int supposedMostRightPaintedPixel = textBounds.x + textBounds.width - 1;
+ int mostRightPaintedPixel= getMostRightPaintedPixel(textWidget);
+ Assert.assertEquals(supposedMostRightPaintedPixel, mostRightPaintedPixel, 1.5); // use double comparison with delta to tolerate variation from a system to the other
+ }
+
+ public int getMostRightPaintedPixel(StyledText widget) {
+ Image image = new Image(widget.getDisplay(), widget.getSize().x, widget.getSize().y);
+ GC gc = new GC(widget);
+ gc.copyArea(image, 0, 0);
+ gc.dispose();
+ RGB backgroundRgb = widget.getBackground().getRGB();
+ ImageData imageData = image.getImageData();
+ for (int x = imageData.width - 50 /* magic number to avoid rulers and other */; x >= 0; x--) {
+ for (int y = 3 /* magic number as well to avoid title bar */; y < imageData.height; y++) {
+ if (!imageData.palette.getRGB(imageData.getPixel(x, y)).equals(backgroundRgb)) {
+ image.dispose();
+ return x;
+ }
+ }
+ }
+ image.dispose();
+ return -1;
+ }
+}
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/LineContentAnnotation.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/LineContentAnnotation.java
index 6ec1ca33d..6a606360b 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/LineContentAnnotation.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/LineContentAnnotation.java
@@ -151,7 +151,9 @@ public class LineContentAnnotation extends AbstractInlinedAnnotation {
}
boolean drawRightToPreviousChar(int widgetOffset) {
- return widgetOffset > 0 && getTextWidget().getLineAtOffset(widgetOffset) == getTextWidget().getLineAtOffset(widgetOffset - 1);
+ return widgetOffset > 0 &&
+ getTextWidget().getLineAtOffset(widgetOffset) == getTextWidget().getLineAtOffset(widgetOffset - 1) &&
+ getTextWidget().getText().charAt(widgetOffset - 1) != '\t'; // \t workaround bug 547532
}
}

Back to the top