+++ /dev/null
-/**********************************************************************
- Copyright (c) 2000, 2002 IBM Corp. and others.
- All rights reserved. This program and the accompanying materials
- are made available under the terms of the Common Public License v1.0
- which accompanies this distribution, and is available at
- http://www.eclipse.org/legal/cpl-v10.html
-
- Contributors:
- IBM Corporation - Initial implementation
- **********************************************************************/
-
-package net.sourceforge.phpeclipse.phpeditor;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import net.sourceforge.phpeclipse.PHPeclipsePlugin;
-import net.sourceforge.phpeclipse.ui.WebUI;
-
-import org.eclipse.jface.text.BadLocationException;
-import org.eclipse.jface.text.IDocument;
-import org.eclipse.jface.text.IRegion;
-import org.eclipse.jface.text.ITextViewerExtension5;
-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.IAnnotationModel;
-import org.eclipse.jface.text.source.IAnnotationModelListener;
-import org.eclipse.jface.text.source.ISourceViewer;
-import org.eclipse.swt.custom.StyledText;
-import org.eclipse.swt.events.PaintEvent;
-import org.eclipse.swt.events.PaintListener;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.ui.texteditor.IDocumentProvider;
-import org.eclipse.ui.texteditor.ITextEditor;
-
-/**
- * Highlights the temporary problems.
- */
-public class ProblemPainter implements IPainter, PaintListener,
- IAnnotationModelListener {
-
- private static class ProblemPosition {
- Position fPosition;
-
- Color fColor;
-
- boolean fMultiLine;
- };
-
- private boolean fIsActive = false;
-
- private boolean fIsPainting = false;
-
- private boolean fIsSettingModel = false;
-
- private ITextEditor fTextEditor;
-
- private ISourceViewer fSourceViewer;
-
- private StyledText fTextWidget;
-
- private IAnnotationModel fModel;
-
- private List fProblemPositions = new ArrayList();
-
- private Map fColorTable = new HashMap();
-
- private Set fAnnotationSet = new HashSet();
-
- public ProblemPainter(ITextEditor textEditor, ISourceViewer sourceViewer) {
- fTextEditor = textEditor;
- fSourceViewer = sourceViewer;
- fTextWidget = sourceViewer.getTextWidget();
- }
-
- private boolean hasProblems() {
- return !fProblemPositions.isEmpty();
- }
-
- private void enablePainting() {
- if (!fIsPainting && hasProblems()) {
- fIsPainting = true;
- fTextWidget.addPaintListener(this);
- handleDrawRequest(null);
- }
- }
-
- private void disablePainting(boolean redraw) {
- if (fIsPainting) {
- fIsPainting = false;
- fTextWidget.removePaintListener(this);
- if (redraw && hasProblems())
- handleDrawRequest(null);
- }
- }
-
- private void setModel(IAnnotationModel model) {
- if (fModel != model) {
- if (fModel != null)
- fModel.removeAnnotationModelListener(this);
- fModel = model;
- if (fModel != null) {
- try {
- fIsSettingModel = true;
- fModel.addAnnotationModelListener(this);
- } finally {
- fIsSettingModel = false;
- }
- }
- }
- }
-
- private void catchupWithModel() {
- if (fProblemPositions != null) {
- fProblemPositions.clear();
- if (fModel != null) {
-
- Iterator e = new ProblemAnnotationIterator(fModel, true);
- while (e.hasNext()) {
- IProblemAnnotation pa = (IProblemAnnotation) e.next();
- Annotation a = (Annotation) pa;
-
- Color color = null;
- AnnotationType type = pa.getAnnotationType();
- if (fAnnotationSet.contains(type))
- color = (Color) fColorTable.get(type);
-
- if (color != null) {
- ProblemPosition pp = new ProblemPosition();
- pp.fPosition = fModel.getPosition(a);
- pp.fColor = color;
- pp.fMultiLine = true;
- fProblemPositions.add(pp);
- }
- }
- }
- }
- }
-
- private void updatePainting() {
- disablePainting(true);
- catchupWithModel();
- enablePainting();
- }
-
- /*
- * @see IAnnotationModelListener#modelChanged(IAnnotationModel)
- */
- public void modelChanged(final IAnnotationModel model) {
- if (fTextWidget != null && !fTextWidget.isDisposed()) {
- if (fIsSettingModel) {
- // inside the ui thread -> no need for posting
- updatePainting();
- } else {
- Display d = fTextWidget.getDisplay();
- if (d != null) {
- d.asyncExec(new Runnable() {
- public void run() {
- if (fTextWidget != null
- && !fTextWidget.isDisposed())
- updatePainting();
- }
- });
- }
- }
- }
- }
-
- public void setColor(AnnotationType annotationType, Color color) {
- if (color != null)
- fColorTable.put(annotationType, color);
- else
- fColorTable.remove(annotationType);
- }
-
- public void paintAnnotations(AnnotationType annotationType, boolean paint) {
- if (paint)
- fAnnotationSet.add(annotationType);
- else
- fAnnotationSet.remove(annotationType);
- }
-
- public boolean isPaintingAnnotations() {
- return !fAnnotationSet.isEmpty();
- }
-
- /*
- * @see IPainter#dispose()
- */
- public void dispose() {
-
- if (fColorTable != null)
- fColorTable.clear();
- fColorTable = null;
-
- if (fAnnotationSet != null)
- fAnnotationSet.clear();
- fAnnotationSet = null;
-
- fTextWidget = null;
- fModel = null;
- fProblemPositions = null;
- }
-
- /*
- * Returns the document offset of the upper left corner of the widgets
- * viewport, possibly including partially visible lines.
- */
- private int getInclusiveTopIndexStartOffset() {
-
- if (fTextWidget != null && !fTextWidget.isDisposed()) {
- int top = fSourceViewer.getTopIndex();
- if ((fTextWidget.getTopPixel() % fTextWidget.getLineHeight()) != 0)
- top--;
- try {
- IDocument document = fSourceViewer.getDocument();
- return document.getLineOffset(top);
- } catch (BadLocationException ex) {
- }
- }
-
- return -1;
- }
-
- /*
- * @see PaintListener#paintControl(PaintEvent)
- */
- public void paintControl(PaintEvent event) {
- if (fTextWidget != null)
- handleDrawRequest(event.gc);
- }
-
- private void handleDrawRequest(GC gc) {
-
- int vOffset = getInclusiveTopIndexStartOffset();
- // http://bugs.eclipse.org/bugs/show_bug.cgi?id=17147
- int vLength = fSourceViewer.getBottomIndexEndOffset() + 1;
-
- for (Iterator e = fProblemPositions.iterator(); e.hasNext();) {
- ProblemPosition pp = (ProblemPosition) e.next();
- Position p = pp.fPosition;
- if (p.overlapsWith(vOffset, vLength)) {
-
- if (!pp.fMultiLine) {
-
- IRegion widgetRange = getWidgetRange(p);
- if (widgetRange != null)
- draw(gc, widgetRange.getOffset(), widgetRange
- .getLength(), pp.fColor);
-
- } else {
-
- IDocument document = fSourceViewer.getDocument();
- try {
-
- int startLine = document.getLineOfOffset(p.getOffset());
- int lastInclusive = Math.max(p.getOffset(), p
- .getOffset()
- + p.getLength() - 1);
- int endLine = document.getLineOfOffset(lastInclusive);
-
- for (int i = startLine; i <= endLine; i++) {
- IRegion line = document.getLineInformation(i);
- int paintStart = Math.max(line.getOffset(), p
- .getOffset());
- int paintEnd = Math.min(line.getOffset()
- + line.getLength(), p.getOffset()
- + p.getLength());
- if (paintEnd > paintStart) {
- // otherwise inside a line delimiter
- IRegion widgetRange = getWidgetRange(new Position(
- paintStart, paintEnd - paintStart));
- if (widgetRange != null)
- draw(gc, widgetRange.getOffset(),
- widgetRange.getLength(), pp.fColor);
- }
- }
-
- } catch (BadLocationException x) {
- }
- }
- }
- }
- }
-
- private IRegion getWidgetRange(Position p) {
- if (fSourceViewer instanceof ITextViewerExtension5) {
- ITextViewerExtension5 extension = (ITextViewerExtension5) fSourceViewer;
- return extension.modelRange2WidgetRange(new Region(p.getOffset(), p
- .getLength()));
-
- } else {
-
- IRegion region = fSourceViewer.getVisibleRegion();
- int offset = region.getOffset();
- int length = region.getLength();
-
- if (p.overlapsWith(offset, length)) {
- int p1 = Math.max(offset, p.getOffset());
- int p2 = Math.min(offset + length, p.getOffset()
- + p.getLength());
- return new Region(p1 - offset, p2 - p1);
- }
- }
-
- return null;
- }
-
- private int[] computePolyline(Point left, Point right, int height) {
-
- final int WIDTH = 4; // must be even
- final int HEIGHT = 2; // can be any number
- // final int MINPEEKS= 2; // minimal number of peeks
-
- int peeks = (right.x - left.x) / WIDTH;
- // if (peeks < MINPEEKS) {
- // int missing= (MINPEEKS - peeks) * WIDTH;
- // left.x= Math.max(0, left.x - missing/2);
- // peeks= MINPEEKS;
- // }
-
- int leftX = left.x;
-
- // compute (number of point) * 2
- int length = ((2 * peeks) + 1) * 2;
- if (length < 0)
- return new int[0];
-
- int[] coordinates = new int[length];
-
- // cache peeks' y-coordinates
- int bottom = left.y + height - 1;
- int top = bottom - HEIGHT;
-
- // populate array with peek coordinates
- for (int i = 0; i < peeks; i++) {
- int index = 4 * i;
- coordinates[index] = leftX + (WIDTH * i);
- coordinates[index + 1] = bottom;
- coordinates[index + 2] = coordinates[index] + WIDTH / 2;
- coordinates[index + 3] = top;
- }
-
- // the last down flank is missing
- coordinates[length - 2] = left.x + (WIDTH * peeks);
- coordinates[length - 1] = bottom;
-
- return coordinates;
- }
-
- private void draw(GC gc, int offset, int length, Color color) {
- if (gc != null) {
-
- Point left = fTextWidget.getLocationAtOffset(offset);
- Point right = fTextWidget.getLocationAtOffset(offset + length);
-
- gc.setForeground(color);
- int[] polyline = computePolyline(left, right, gc.getFontMetrics()
- .getHeight());
- gc.drawPolyline(polyline);
-
- } else {
- fTextWidget.redrawRange(offset, length, true);
- }
- }
-
- /*
- * @see IPainter#deactivate(boolean)
- */
- public void deactivate(boolean redraw) {
- if (fIsActive) {
- fIsActive = false;
- disablePainting(redraw);
- setModel(null);
- catchupWithModel();
- }
- }
-
- /*
- * @see IPainter#paint(int)
- */
- public void paint(int reason) {
- if (!fIsActive) {
- fIsActive = true;
- IDocumentProvider provider = WebUI.getDefault()
- .getCompilationUnitDocumentProvider();
- setModel(provider.getAnnotationModel(fTextEditor.getEditorInput()));
- } else if (CONFIGURATION == reason || INTERNAL == reason)
- updatePainting();
- }
-
- /*
- * @see IPainter#setPositionManager(IPositionManager)
- */
- public void setPositionManager(IPositionManager manager) {
- }
-}