Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMickael Istria2019-04-29 08:50:05 -0400
committerMickael Istria - away until Apr 22nd2019-04-29 10:51:37 -0400
commitb26b8782569616fcace8dcbd47a61c13ae694513 (patch)
tree84fd60f11a0c7debe839f9da112df36572b987ca
parent54ad465f841c2c09437070d0234d1e3166301b89 (diff)
downloadeclipse.platform.text-b26b8782569616fcace8dcbd47a61c13ae694513.tar.gz
eclipse.platform.text-b26b8782569616fcace8dcbd47a61c13ae694513.tar.xz
eclipse.platform.text-b26b8782569616fcace8dcbd47a61c13ae694513.zip
Bug 546706 - multi-line code minings rendered erroneouslyI20190429-1800
Change-Id: I1a89962176d2583551e4fcd28b2511a69b62aa23 Signed-off-by: Mickael Istria <mistria@redhat.com>
-rw-r--r--org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/codemining/CodeMiningTest.java66
-rw-r--r--org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/codemining/StaticContentLineCodeMining.java5
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/AbstractInlinedAnnotation.java10
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationDrawingStrategy.java11
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/LineContentAnnotation.java2
5 files changed, 87 insertions, 7 deletions
diff --git a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/codemining/CodeMiningTest.java b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/codemining/CodeMiningTest.java
index cac5fde14..dbb7c0962 100644
--- a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/codemining/CodeMiningTest.java
+++ b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/codemining/CodeMiningTest.java
@@ -13,6 +13,9 @@
*******************************************************************************/
package org.eclipse.jface.text.tests.codemining;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.After;
@@ -24,16 +27,25 @@ import org.junit.Test;
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.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
+import org.eclipse.core.runtime.IProgressMonitor;
+
import org.eclipse.jface.util.Util;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+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.reconciler.DirtyRegion;
import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
@@ -49,6 +61,7 @@ public class CodeMiningTest {
private SourceViewer fViewer;
private Shell fShell;
+ private int defaultCharWidth;
@Rule public ScreenshotOnFailureRule rule = new ScreenshotOnFailureRule();
@@ -59,6 +72,9 @@ public class CodeMiningTest {
fShell.setLayout(new FillLayout());
fViewer= new SourceViewer(fShell, null, SWT.NONE);
final StyledText textWidget= fViewer.getTextWidget();
+ textWidget.setText("a");
+ defaultCharWidth = textWidget.getTextBounds(0, 0).width;
+ textWidget.setText("");
MonoReconciler reconciler = new MonoReconciler(new IReconcilingStrategy() {
@Override
public void setDocument(IDocument document) {
@@ -180,4 +196,54 @@ public class CodeMiningTest {
}.waitForCondition(fViewer.getControl().getDisplay(), 3000));
}
+ @Test
+ public void testCodeMiningMultiLine() throws BadLocationException {
+ fViewer.getDocument().set("a\nbc");
+ fViewer.setCodeMiningProviders(new ICodeMiningProvider[] { new ICodeMiningProvider() {
+ @Override
+ public CompletableFuture<List<? extends ICodeMining>> provideCodeMinings(ITextViewer viewer, IProgressMonitor monitor) {
+ return CompletableFuture.completedFuture(Collections.singletonList(new StaticContentLineCodeMining(new Position(0, 3), "long enough code mining to be wider than actual text", this)));
+ }
+
+ @Override
+ public void dispose() {
+ }
+ } });
+ StyledText widget = fViewer.getTextWidget();
+ Assert.assertFalse("Code mining is visible on 2nd line", new DisplayHelper() {
+ @Override
+ protected boolean condition() {
+ try {
+ return widget.getStyleRangeAtOffset(0) != null && widget.getStyleRangeAtOffset(0).metrics != null
+ && hasCodeMiningPrintedAfterTextOnLine(fViewer, 1);
+ } catch (BadLocationException e) {
+ e.printStackTrace();
+ return true;
+ }
+ }
+ }.waitForCondition(fViewer.getTextWidget().getDisplay(), 1000));
+ }
+
+ private static boolean hasCodeMiningPrintedAfterTextOnLine(ITextViewer viewer, int line) throws BadLocationException {
+ StyledText widget = viewer.getTextWidget();
+ IDocument document= viewer.getDocument();
+ Rectangle secondLineBounds = widget.getTextBounds(document.getLineOffset(1), document.getLineOffset(line) + document.getLineLength(line) - 1);
+ Image image = new Image(widget.getDisplay(), widget.getSize().x, widget.getSize().y);
+ GC gc = new GC(widget);
+ gc.copyArea(image, 0, 0);
+ gc.dispose();
+ ImageData imageData = image.getImageData();
+ secondLineBounds.x += secondLineBounds.width; // look only area after text
+ for (int x = secondLineBounds.x + 1; x < image.getBounds().width && x < imageData.width; x++) {
+ for (int y = secondLineBounds.y; y < secondLineBounds.y + secondLineBounds.height && y < imageData.height; y++) {
+ if (!imageData.palette.getRGB(imageData.getPixel(x, y)).equals(widget.getBackground().getRGB())) {
+ // code mining printed
+ image.dispose();
+ return true;
+ }
+ }
+ }
+ image.dispose();
+ return false;
+ }
}
diff --git a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/codemining/StaticContentLineCodeMining.java b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/codemining/StaticContentLineCodeMining.java
index 59ef8f6e6..726b7a698 100644
--- a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/codemining/StaticContentLineCodeMining.java
+++ b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/codemining/StaticContentLineCodeMining.java
@@ -19,6 +19,11 @@ import org.eclipse.jface.text.codemining.LineContentCodeMining;
public class StaticContentLineCodeMining extends LineContentCodeMining {
+ public StaticContentLineCodeMining(Position position, String message, ICodeMiningProvider provider) {
+ super(position, provider);
+ setLabel(message);
+ }
+
public StaticContentLineCodeMining(int i, char c, ICodeMiningProvider repeatLettersCodeMiningProvider) {
super(new Position(i, 1), repeatLettersCodeMiningProvider);
setLabel(Character.toString(c));
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/AbstractInlinedAnnotation.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/AbstractInlinedAnnotation.java
index 8bc3c312b..28e80553d 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/AbstractInlinedAnnotation.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/AbstractInlinedAnnotation.java
@@ -28,6 +28,7 @@ import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.projection.ProjectionViewer;
/**
* Abstract class for inlined annotation.
@@ -188,6 +189,15 @@ public abstract class AbstractInlinedAnnotation extends Annotation {
return support.isInVisibleLines(getPosition().getOffset());
}
+ boolean isFirstVisibleOffset(int widgetOffset) {
+ if (fViewer instanceof ProjectionViewer) {
+ IRegion widgetRange= ((ProjectionViewer) fViewer).modelRange2WidgetRange(new Region(position.getOffset(), position.getLength()));
+ return widgetOffset == widgetRange.getOffset();
+ } else {
+ return position.getOffset() == widgetOffset;
+ }
+ }
+
/**
* Return whether the given offset is in visible lines.
*
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationDrawingStrategy.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationDrawingStrategy.java
index 5deaad5c5..719ff79de 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationDrawingStrategy.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationDrawingStrategy.java
@@ -32,16 +32,15 @@ import org.eclipse.jface.text.source.AnnotationPainter.IDrawingStrategy;
class InlinedAnnotationDrawingStrategy implements IDrawingStrategy {
@Override
- public void draw(Annotation annotation, GC gc, StyledText textWidget, int widgetoffset, int length, Color color) {
+ public void draw(Annotation annotation, GC gc, StyledText textWidget, int widgetOffset, int length, Color color) {
if (!(annotation instanceof AbstractInlinedAnnotation)) {
return;
}
- if (!((AbstractInlinedAnnotation) annotation).isInVisibleLines()) {
- // The annotation is not in visible lines, don't draw it.
- return;
+ AbstractInlinedAnnotation inlinedAnnotation= (AbstractInlinedAnnotation) annotation;
+ if (inlinedAnnotation.isInVisibleLines() && inlinedAnnotation.isFirstVisibleOffset(widgetOffset)) {
+ draw((AbstractInlinedAnnotation) annotation, gc, textWidget, widgetOffset, length,
+ color);
}
- draw((AbstractInlinedAnnotation) annotation, gc, textWidget, widgetoffset, length,
- color);
}
/**
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 23d4f7068..a7a898b7d 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,7 @@ public class LineContentAnnotation extends AbstractInlinedAnnotation {
}
boolean drawRightToPreviousChar(int widgetOffset) {
- return getTextWidget().getLineAtOffset(widgetOffset) == getTextWidget().getLineAtOffset(widgetOffset - 1);
+ return widgetOffset > 0 && getTextWidget().getLineAtOffset(widgetOffset) == getTextWidget().getLineAtOffset(widgetOffset - 1);
}
}

Back to the top