From 6efda0be081b3104a744e8fb2f3bebef64d922d2 Mon Sep 17 00:00:00 2001 From: angelozerr Date: Thu, 30 Nov 2017 09:39:29 +0100 Subject: Bug 527675 - [CodeMining] Provide inline annotations support Add Inlined annotation demo Change-Id: I445c00ec8b8a187bdb1e63a1c4fde1e3552250f3 Signed-off-by: angelozerr --- .../examples/sources/inlined/ColorAnnotation.java | 80 +++++++ .../sources/inlined/ColorStatusAnnotation.java | 31 +++ .../sources/inlined/InlinedAnnotationDemo.java | 233 +++++++++++++++++++++ 3 files changed, 344 insertions(+) create mode 100644 org.eclipse.jface.text.examples/src/org/eclipse/jface/text/examples/sources/inlined/ColorAnnotation.java create mode 100644 org.eclipse.jface.text.examples/src/org/eclipse/jface/text/examples/sources/inlined/ColorStatusAnnotation.java create mode 100644 org.eclipse.jface.text.examples/src/org/eclipse/jface/text/examples/sources/inlined/InlinedAnnotationDemo.java (limited to 'org.eclipse.jface.text.examples/src/org/eclipse/jface/text') diff --git a/org.eclipse.jface.text.examples/src/org/eclipse/jface/text/examples/sources/inlined/ColorAnnotation.java b/org.eclipse.jface.text.examples/src/org/eclipse/jface/text/examples/sources/inlined/ColorAnnotation.java new file mode 100644 index 00000000000..9af22ac48e1 --- /dev/null +++ b/org.eclipse.jface.text.examples/src/org/eclipse/jface/text/examples/sources/inlined/ColorAnnotation.java @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2017 Angelo ZERR. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Angelo Zerr - [CodeMining] Provide inline annotations support - Bug 527675 + */ +package org.eclipse.jface.text.examples.sources.inlined; + +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.source.inlined.LineContentAnnotation; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.FontMetrics; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Rectangle; + +/** + * Color annotation displays a colorized square before the rgb declaration. + */ +public class ColorAnnotation extends LineContentAnnotation { + + private Color color; + + public ColorAnnotation(Position pos, StyledText styledText) { + super(pos, styledText); + } + + @Override + public int getWidth() { + StyledText styledText = super.getTextWidget(); + return getSquareWidth(styledText); + } + + public void setColor(Color color) { + this.color = color; + } + + @Override + public void draw(GC gc, StyledText textWidget, int offset, int length, Color color, int x, int y) { + int size = getSquareSize(gc.getFontMetrics()); + Rectangle rect = new Rectangle(x, y, size, size); + + // Fill square + gc.setBackground(this.color); + gc.fillRectangle(rect); + + // Draw square box + gc.setForeground(textWidget.getForeground()); + gc.drawRectangle(rect); + } + + /** + * Returns the colorized square size. + * + * @param fontMetrics + * @return the colorized square size. + */ + public static int getSquareSize(FontMetrics fontMetrics) { + return fontMetrics.getHeight() - 2 * fontMetrics.getDescent(); + } + + /** + * Compute width of square + * + * @param styledText + * @return the width of square + */ + private static int getSquareWidth(StyledText styledText) { + GC gc = new GC(styledText); + FontMetrics fontMetrics = gc.getFontMetrics(); + // width = 2 spaces + size width of square + int width = 2 * fontMetrics.getAverageCharWidth() + getSquareSize(fontMetrics); + gc.dispose(); + return width; + } +} diff --git a/org.eclipse.jface.text.examples/src/org/eclipse/jface/text/examples/sources/inlined/ColorStatusAnnotation.java b/org.eclipse.jface.text.examples/src/org/eclipse/jface/text/examples/sources/inlined/ColorStatusAnnotation.java new file mode 100644 index 00000000000..63e14e36ace --- /dev/null +++ b/org.eclipse.jface.text.examples/src/org/eclipse/jface/text/examples/sources/inlined/ColorStatusAnnotation.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2017 Angelo ZERR. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Angelo Zerr - [CodeMining] Provide inline annotations support - Bug 527675 + */ +package org.eclipse.jface.text.examples.sources.inlined; + +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.source.inlined.LineHeaderAnnotation; +import org.eclipse.swt.custom.StyledText; + +/** + * Color status annotation shows the result of rgb parse before each line which + * defines 'color:'. + */ +public class ColorStatusAnnotation extends LineHeaderAnnotation { + + public ColorStatusAnnotation(Position position, StyledText styledText) { + super(position, styledText); + } + + public void setStatus(String status) { + super.setText(status); + } + +} diff --git a/org.eclipse.jface.text.examples/src/org/eclipse/jface/text/examples/sources/inlined/InlinedAnnotationDemo.java b/org.eclipse.jface.text.examples/src/org/eclipse/jface/text/examples/sources/inlined/InlinedAnnotationDemo.java new file mode 100644 index 00000000000..a911388248f --- /dev/null +++ b/org.eclipse.jface.text.examples/src/org/eclipse/jface/text/examples/sources/inlined/InlinedAnnotationDemo.java @@ -0,0 +1,233 @@ +/** + * Copyright (c) 2017 Angelo ZERR. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Angelo Zerr - [CodeMining] Provide inline annotations support - Bug 527675 + */ +package org.eclipse.jface.text.examples.sources.inlined; + +import java.util.HashSet; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +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.ITextViewerExtension2; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.reconciler.DirtyRegion; +import org.eclipse.jface.text.reconciler.IReconcilingStrategy; +import org.eclipse.jface.text.reconciler.MonoReconciler; +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.AbstractInlinedAnnotation; +import org.eclipse.jface.text.source.inlined.InlinedAnnotationSupport; +import org.eclipse.jface.text.source.inlined.LineContentAnnotation; +import org.eclipse.jface.text.source.inlined.LineHeaderAnnotation; +import org.eclipse.jface.text.source.inlined.Positions; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * An inlined demo with {@link LineHeaderAnnotation} and + * {@link LineContentAnnotation} annotations both: + * + *
    + *
  • a status OK, NOK is displayed before the line which starts with 'color:'. + * This status is the result of the content after 'color' which must be a rgb + * content. Here {@link ColorStatusAnnotation} is used.
  • + *
  • a colorized square is displayed before the rgb declaration (inside the + * line content). Here {@link ColorAnnotation} is used.
  • + *
+ * + */ +public class InlinedAnnotationDemo { + + public static void main(String[] args) throws Exception { + + Display display = new Display(); + Shell shell = new Shell(display); + shell.setLayout(new FillLayout()); + shell.setText("Inlined annotation demo"); + + // Create source viewer and initialize the content + ISourceViewer sourceViewer = new SourceViewer(shell, null, SWT.V_SCROLL | SWT.BORDER); + sourceViewer.setDocument(new Document("\ncolor:rgb(255, 255, 0)"), new AnnotationModel()); + + // Initialize inlined annotations support + InlinedAnnotationSupport support = new InlinedAnnotationSupport(); + support.install(sourceViewer, createAnnotationPainter(sourceViewer)); + + // Refresh inlined annotation in none UI Thread with reconciler. + MonoReconciler reconciler = new MonoReconciler(new IReconcilingStrategy() { + + @Override + public void setDocument(IDocument document) { + Set annotations = getInlinedAnnotation(sourceViewer, support); + support.updateAnnotations(annotations); + } + + @Override + public void reconcile(IRegion partition) { + Set anns = getInlinedAnnotation(sourceViewer, support); + support.updateAnnotations(anns); + } + + @Override + public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) { + + } + }, false); + reconciler.setDelay(1); + reconciler.install(sourceViewer); + + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) + display.sleep(); + } + display.dispose(); + } + + /** + * Create annotation painter. + * + * @param viewer + * the viewer. + * @return annotation painter. + */ + private static AnnotationPainter createAnnotationPainter(ISourceViewer viewer) { + 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; + } + + }; + AnnotationPainter painter = new AnnotationPainter(viewer, annotationAccess); + ((ITextViewerExtension2) viewer).addPainter(painter); + return painter; + } + + /** + * Returns the inlined annotations list to display in the given viewer. + * + * @param viewer + * the viewer + * @param support + * the inlined annotation suppor. + * @return the inlined annotations list to display in the given viewer. + */ + private static Set getInlinedAnnotation(ISourceViewer viewer, + InlinedAnnotationSupport support) { + IDocument document = viewer.getDocument(); + Set annotations = new HashSet<>(); + int lineCount = document.getNumberOfLines(); + for (int i = 0; i < lineCount; i++) { + String line = getLineText(document, i).trim(); + int index = line.indexOf("color:"); + if (index == 0) { + String rgb = line.substring(index + "color:".length(), line.length()).trim(); + try { + String status = "OK!"; + Color color = parse(rgb, viewer.getTextWidget().getDisplay()); + if (color != null) { + } else { + status = "ERROR!"; + } + // Status color annotation + Position pos = Positions.of(i, document, true); + ColorStatusAnnotation statusAnnotation = support.findExistingAnnotation(pos); + if (statusAnnotation == null) { + statusAnnotation = new ColorStatusAnnotation(pos, viewer.getTextWidget()); + } + statusAnnotation.setStatus(status); + annotations.add(statusAnnotation); + + // Color annotation + if (color != null) { + Position colorPos = new Position(pos.offset + index + "color:".length(), rgb.length()); + ColorAnnotation colorAnnotation = support.findExistingAnnotation(colorPos); + if (colorAnnotation == null) { + colorAnnotation = new ColorAnnotation(colorPos, viewer.getTextWidget()); + } + colorAnnotation.setColor(color); + annotations.add(colorAnnotation); + } + + } catch (BadLocationException e) { + e.printStackTrace(); + } + } + } + return annotations; + } + + /** + * Parse the given input rgb color and returns an instance of SWT Color and null + * otherwise. + * + * @param input + * the rgb string color + * @param device + * @return the created color and null otherwise. + */ + private static Color parse(String input, Device device) { + Pattern c = Pattern.compile("rgb *\\( *([0-9]+), *([0-9]+), *([0-9]+) *\\)"); + Matcher m = c.matcher(input); + if (m.matches()) { + try { + return new Color(device, Integer.valueOf(m.group(1)), // r + Integer.valueOf(m.group(2)), // g + Integer.valueOf(m.group(3))); // b + } catch (Exception e) { + + } + } + return null; + } + + /** + * Returns the line text. + * + * @param document + * the document. + * @param line + * the line index. + * @return the line text. + */ + private static String getLineText(IDocument document, int line) { + try { + int offset = document.getLineOffset(line); + int length = document.getLineLength(line); + return document.get(offset, length); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } +} -- cgit v1.2.3