Bug 529011 - Better handle folding when using TextPresentation

Some editors rely on TextPresentation, when those are combined with
folding, code minings could draw spaces at wrong locations, because the
widget coordinates (expected by widget) were not translated for usage in
TextPresentation (which expects model coordinate).

Change-Id: I6cb17b30b269ebd60eb0253987a99cd4c62e5624
Signed-off-by: Mickael Istria <mistria@redhat.com>
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 4641866..8bc3c31 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
@@ -131,15 +131,15 @@
 	 * Draw the inlined annotation. By default it draw the text of the annotation with gray color.
 	 * User can override this method to draw anything.
 	 *
-	 * @param gc         the graphics context
+	 * @param gc the graphics context
 	 * @param textWidget the text widget to draw on
-	 * @param offset     the offset of the line
-	 * @param length     the length of the line
-	 * @param color      the color of the line
-	 * @param x          the x position of the annotation
-	 * @param y          the y position of the annotation
+	 * @param widgetOffset the offset
+	 * @param length the length of the line
+	 * @param color the color of the line
+	 * @param x the x position of the annotation
+	 * @param y the y position of the annotation
 	 */
-	public void draw(GC gc, StyledText textWidget, int offset, int length, Color color, int x, int y) {
+	public void draw(GC gc, StyledText textWidget, int widgetOffset, int length, Color color, int x, int y) {
 		gc.setForeground(color);
 		gc.setBackground(textWidget.getBackground());
 		gc.drawString(getText(), x, y, true);
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 c29c633..07e37bd 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
@@ -138,10 +138,10 @@
 		}
 	}
 
-	protected static void drawAsLeftOf1stCharacter(LineContentAnnotation annotation, GC gc, StyledText textWidget, int offset, int length, Color color) {
+	protected static void drawAsLeftOf1stCharacter(LineContentAnnotation annotation, GC gc, StyledText textWidget, int widgetOffset, int length, Color color) {
 		StyleRange style= null;
 		try {
-			style= textWidget.getStyleRangeAtOffset(offset);
+			style= textWidget.getStyleRangeAtOffset(widgetOffset);
 		} catch (Exception e) {
 			return;
 		}
@@ -154,11 +154,11 @@
 			return;
 		}
 		if (gc != null) {
-			String s= textWidget.getText(offset, offset);
+			String s= textWidget.getText(widgetOffset, widgetOffset);
 			boolean isEndOfLine= ("\r".equals(s) || "\n".equals(s)); //$NON-NLS-1$ //$NON-NLS-2$
 
 			// Compute the location of the annotation
-			Rectangle bounds= textWidget.getTextBounds(offset, offset);
+			Rectangle bounds= textWidget.getTextBounds(widgetOffset, widgetOffset);
 			int x= bounds.x + (isEndOfLine ? bounds.width * 2 : 0);
 			int y= bounds.y;
 
@@ -167,7 +167,7 @@
 
 			// Draw the line content annotation
 			annotation.setLocation(x, y);
-			annotation.draw(gc, textWidget, offset, length, color, x, y);
+			annotation.draw(gc, textWidget, widgetOffset, length, color, x, y);
 			int width= annotation.getWidth();
 			if (width != 0) {
 				if (isEndOfLine) {
@@ -222,7 +222,7 @@
 				textWidget.setStyleRange(style);
 			}
 		} else {
-			textWidget.redrawRange(offset, length, true);
+			textWidget.redrawRange(widgetOffset, length, true);
 		}
 	}
 
@@ -264,6 +264,7 @@
 				StyleRange newStyle= annotation.updateStyle(style);
 				if (newStyle != null) {
 					textWidget.setStyleRange(newStyle);
+					System.err.println(newStyle);
 					return;
 				}
 
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationSupport.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationSupport.java
index 0f0000c..69aa435 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationSupport.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationSupport.java
@@ -48,9 +48,11 @@
 import org.eclipse.jface.text.ISynchronizable;
 import org.eclipse.jface.text.ITextPresentationListener;
 import org.eclipse.jface.text.ITextViewerExtension4;
+import org.eclipse.jface.text.ITextViewerExtension5;
 import org.eclipse.jface.text.IViewportListener;
 import org.eclipse.jface.text.JFaceTextUtil;
 import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.Region;
 import org.eclipse.jface.text.TextPresentation;
 import org.eclipse.jface.text.source.Annotation;
 import org.eclipse.jface.text.source.AnnotationPainter;
@@ -109,6 +111,12 @@
 							LineContentAnnotation ann= (LineContentAnnotation) annotation;
 							StyleRange style= ann.updateStyle(null);
 							if (style != null) {
+								if (fViewer instanceof ITextViewerExtension5) {
+									ITextViewerExtension5 projectionViewer= (ITextViewerExtension5) fViewer;
+									IRegion annotationRegion= projectionViewer.widgetRange2ModelRange(new Region(style.start, style.length));
+									style.start= annotationRegion.getOffset();
+									style.length= annotationRegion.getLength();
+								}
 								textPresentation.mergeStyleRange(style);
 							}
 						}
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 332a8a5..23d4f70 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
@@ -19,7 +19,9 @@
 import org.eclipse.swt.graphics.GC;

 import org.eclipse.swt.graphics.GlyphMetrics;

 

+import org.eclipse.jface.text.ITextViewerExtension5;

 import org.eclipse.jface.text.Position;

+import org.eclipse.jface.text.TextPresentation;

 import org.eclipse.jface.text.source.ISourceViewer;

 

 /**

@@ -102,10 +104,14 @@
 	/**

 	 * Returns the style to apply with GlyphMetrics width only if needed.

 	 *

-	 * @param annotation the line content annotation

-	 * @param usePreviousChar whether to attach the metrics to the offset char or previous one

+	 * As it's using Widget position, the results can be passed directly to

+	 * {@link StyledText#setStyleRange(StyleRange)} and family. However, in case of a Viewer

+	 * providing project/folder with {@link ITextViewerExtension5}, the range must be transformed to

+	 * model position before passing it to a {@link TextPresentation}.

+	 *

 	 * @param style the current style and null otherwise.

-	 * @return the style to apply with GlyphMetrics width only if needed.

+	 * @return the style to apply with GlyphMetrics width only if needed. It uses widget position,

+	 *         not model position.

 	 */

 	StyleRange updateStyle(StyleRange style) {

 		Position widgetPosition= computeWidgetPosition();