Changes:
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / phpeditor / OverviewRuler.java
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/OverviewRuler.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/OverviewRuler.java
deleted file mode 100644 (file)
index e59e385..0000000
+++ /dev/null
@@ -1,760 +0,0 @@
-/**********************************************************************
-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.Collections;
-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.phpdt.ui.text.JavaTextTools;
-import net.sourceforge.phpeclipse.PHPeclipsePlugin;
-
-import org.eclipse.jface.text.BadLocationException;
-import org.eclipse.jface.text.IDocument;
-import org.eclipse.jface.text.IRegion;
-import org.eclipse.jface.text.ITextListener;
-import org.eclipse.jface.text.ITextViewer;
-import org.eclipse.jface.text.ITextViewerExtension3;
-import org.eclipse.jface.text.Position;
-import org.eclipse.jface.text.Region;
-import org.eclipse.jface.text.TextEvent;
-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.IVerticalRulerInfo;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.StyledText;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseMoveListener;
-import org.eclipse.swt.events.PaintEvent;
-import org.eclipse.swt.events.PaintListener;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Cursor;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.RGB;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.widgets.Canvas;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-
-/**
- * 
- */
-public class OverviewRuler implements IVerticalRulerInfo {
-
-  /**
-   * Internal listener class.
-   */
-  class InternalListener implements ITextListener, IAnnotationModelListener {
-
-    /*
-     * @see ITextListener#textChanged
-     */
-    public void textChanged(TextEvent e) {
-      if (fTextViewer != null && e.getDocumentEvent() == null && e.getViewerRedrawState()) {
-        // handle only changes of visible document
-        redraw();
-      }
-    }
-
-    /*
-     * @see IAnnotationModelListener#modelChanged(IAnnotationModel)
-     */
-    public void modelChanged(IAnnotationModel model) {
-      update();
-    }
-  }
-
-  /**
-   * Filters problems based on their types.
-   */
-  class FilterIterator implements Iterator {
-
-    private final static int IGNORE = 0;
-    private final static int TEMPORARY = 1;
-    private final static int PERSISTENT = 2;
-
-    private Iterator fIterator;
-    private AnnotationType fType;
-    private IProblemAnnotation fNext;
-    private int fTemporary;
-
-    public FilterIterator(AnnotationType type) {
-      this(type, IGNORE);
-    }
-
-    public FilterIterator(AnnotationType type, boolean temporary) {
-      this(type, temporary ? TEMPORARY : PERSISTENT);
-    }
-
-    private FilterIterator(AnnotationType type, int temporary) {
-      fType = type;
-      fTemporary = temporary;
-      if (fModel != null) {
-        fIterator = fModel.getAnnotationIterator();
-        skip();
-      }
-    }
-
-    private void skip() {
-      while (fIterator.hasNext()) {
-        Object next = fIterator.next();
-        if (next instanceof IProblemAnnotation) {
-          fNext = (IProblemAnnotation) next;
-          AnnotationType type = fNext.getAnnotationType();
-          if (fType == AnnotationType.ALL || fType == type) {
-            if (fTemporary == IGNORE)
-              return;
-            if (fTemporary == TEMPORARY && fNext.isTemporary())
-              return;
-            if (fTemporary == PERSISTENT && !fNext.isTemporary())
-              return;
-          }
-        }
-      }
-      fNext = null;
-    }
-
-    /*
-     * @see Iterator#hasNext()
-     */
-    public boolean hasNext() {
-      return fNext != null;
-    }
-    /*
-     * @see Iterator#next()
-     */
-    public Object next() {
-      try {
-        return fNext;
-      } finally {
-        if (fModel != null)
-          skip();
-      }
-    }
-    /*
-     * @see Iterator#remove()
-     */
-    public void remove() {
-      throw new UnsupportedOperationException();
-    }
-  };
-
-  private static final int INSET = 2;
-  private static final int PROBLEM_HEIGHT_MIN = 4;
-  private static boolean PROBLEM_HEIGHT_SCALABLE = false;
-
-  /** The model of the overview ruler */
-  private IAnnotationModel fModel;
-  /** The view to which this ruler is connected */
-  private ITextViewer fTextViewer;
-  /** The ruler's canvas */
-  private Canvas fCanvas;
-  /** The drawable for double buffering */
-  private Image fBuffer;
-  /** The internal listener */
-  private InternalListener fInternalListener = new InternalListener();
-  /** The width of this vertical ruler */
-  private int fWidth;
-  /** The hit detection cursor */
-  private Cursor fHitDetectionCursor;
-  /** The last cursor */
-  private Cursor fLastCursor;
-  /** Cache for the actual scroll position in pixels */
-  private int fScrollPos;
-  /** The line of the last mouse button activity */
-  private int fLastMouseButtonActivityLine = -1;
-  /** The actual problem height */
-  private int fProblemHeight = -1;
-
-  private Set fAnnotationSet = new HashSet();
-  private Map fLayers = new HashMap();
-  private Map fColorTable = new HashMap();
-
-  /**
-   * Constructs a vertical ruler with the given width.
-   *
-   * @param width the width of the vertical ruler
-   */
-  public OverviewRuler(int width) {
-    fWidth = width;
-  }
-
-  public Control getControl() {
-    return fCanvas;
-  }
-
-  public int getWidth() {
-    return fWidth;
-  }
-
-  public void setModel(IAnnotationModel model) {
-    if (model != fModel || model != null) {
-
-      if (fModel != null)
-        fModel.removeAnnotationModelListener(fInternalListener);
-
-      fModel = model;
-
-      if (fModel != null)
-        fModel.addAnnotationModelListener(fInternalListener);
-
-      update();
-    }
-  }
-
-  public Control createControl(Composite parent, ITextViewer textViewer) {
-
-    fTextViewer = textViewer;
-
-    fHitDetectionCursor = new Cursor(parent.getDisplay(), SWT.CURSOR_HAND);
-    fCanvas = new Canvas(parent, SWT.NO_BACKGROUND);
-
-    fCanvas.addPaintListener(new PaintListener() {
-      public void paintControl(PaintEvent event) {
-        if (fTextViewer != null)
-          doubleBufferPaint(event.gc);
-      }
-    });
-
-    fCanvas.addDisposeListener(new DisposeListener() {
-      public void widgetDisposed(DisposeEvent event) {
-        handleDispose();
-        fTextViewer = null;
-      }
-    });
-
-    fCanvas.addMouseListener(new MouseAdapter() {
-      public void mouseDown(MouseEvent event) {
-        handleMouseDown(event);
-      }
-    });
-
-    fCanvas.addMouseMoveListener(new MouseMoveListener() {
-      public void mouseMove(MouseEvent event) {
-        handleMouseMove(event);
-      }
-    });
-
-    if (fTextViewer != null)
-      fTextViewer.addTextListener(fInternalListener);
-
-    return fCanvas;
-  }
-
-  /**
-   * Disposes the ruler's resources.
-   */
-  private void handleDispose() {
-
-    if (fTextViewer != null) {
-      fTextViewer.removeTextListener(fInternalListener);
-      fTextViewer = null;
-    }
-
-    if (fModel != null)
-      fModel.removeAnnotationModelListener(fInternalListener);
-
-    if (fBuffer != null) {
-      fBuffer.dispose();
-      fBuffer = null;
-    }
-
-    if (fHitDetectionCursor != null) {
-      fHitDetectionCursor.dispose();
-      fHitDetectionCursor = null;
-    }
-
-    fAnnotationSet.clear();
-    fLayers.clear();
-    fColorTable.clear();
-  }
-
-  /**
-   * Double buffer drawing.
-   */
-  private void doubleBufferPaint(GC dest) {
-
-    Point size = fCanvas.getSize();
-
-    if (size.x <= 0 || size.y <= 0)
-      return;
-
-    if (fBuffer != null) {
-      Rectangle r = fBuffer.getBounds();
-      if (r.width != size.x || r.height != size.y) {
-        fBuffer.dispose();
-        fBuffer = null;
-      }
-    }
-    if (fBuffer == null)
-      fBuffer = new Image(fCanvas.getDisplay(), size.x, size.y);
-
-    GC gc = new GC(fBuffer);
-    try {
-      gc.setBackground(fCanvas.getBackground());
-      gc.fillRectangle(0, 0, size.x, size.y);
-
-      if (fTextViewer instanceof ITextViewerExtension3)
-        doPaint1(gc);
-      else
-        doPaint(gc);
-
-    } finally {
-      gc.dispose();
-    }
-
-    dest.drawImage(fBuffer, 0, 0);
-  }
-
-  private void doPaint(GC gc) {
-
-    if (fTextViewer == null)
-      return;
-
-    Rectangle r = new Rectangle(0, 0, 0, 0);
-    int yy, hh = PROBLEM_HEIGHT_MIN;
-
-    IDocument document = fTextViewer.getDocument();
-    IRegion visible = fTextViewer.getVisibleRegion();
-
-    StyledText textWidget = fTextViewer.getTextWidget();
-    int maxLines = textWidget.getLineCount();
-    fScrollPos = textWidget.getTopPixel();
-
-    Point size = fCanvas.getSize();
-    int writable = maxLines * textWidget.getLineHeight();
-    if (size.y > writable)
-      size.y = writable;
-
-    List indices = new ArrayList(fLayers.keySet());
-    Collections.sort(indices);
-
-    for (Iterator iterator = indices.iterator(); iterator.hasNext();) {
-      Object layer = iterator.next();
-      AnnotationType annotationType = (AnnotationType) fLayers.get(layer);
-
-      if (skip(annotationType))
-        continue;
-
-      boolean[] temporary = new boolean[] { false, true };
-      for (int t = 0; t < temporary.length; t++) {
-
-        Iterator e = new FilterIterator(annotationType, temporary[t]);
-        Color fill = getFillColor(annotationType, temporary[t]);
-        Color stroke = getStrokeColor(annotationType, temporary[t]);
-
-        for (int i = 0; e.hasNext(); i++) {
-
-          Annotation a = (Annotation) e.next();
-          Position p = fModel.getPosition(a);
-
-          if (p == null || !p.overlapsWith(visible.getOffset(), visible.getLength()))
-            continue;
-
-          int problemOffset = Math.max(p.getOffset(), visible.getOffset());
-          int problemEnd = Math.min(p.getOffset() + p.getLength(), visible.getOffset() + visible.getLength());
-          int problemLength = problemEnd - problemOffset;
-
-          try {
-            if (PROBLEM_HEIGHT_SCALABLE) {
-              int numbersOfLines = document.getNumberOfLines(problemOffset, problemLength);
-              hh = (numbersOfLines * size.y) / maxLines;
-              if (hh < PROBLEM_HEIGHT_MIN)
-                hh = PROBLEM_HEIGHT_MIN;
-            }
-            fProblemHeight = hh;
-
-            int startLine = textWidget.getLineAtOffset(problemOffset - visible.getOffset());
-            yy = Math.min((startLine * size.y) / maxLines, size.y - hh);
-
-            if (fill != null) {
-              gc.setBackground(fill);
-              gc.fillRectangle(INSET, yy, size.x - (2 * INSET), hh);
-            }
-
-            if (stroke != null) {
-              gc.setForeground(stroke);
-              r.x = INSET;
-              r.y = yy;
-              r.width = size.x - (2 * INSET) - 1;
-              r.height = hh;
-              gc.setLineWidth(1);
-              gc.drawRectangle(r);
-            }
-          } catch (BadLocationException x) {
-          }
-        }
-      }
-    }
-  }
-
-  private void doPaint1(GC gc) {
-
-    if (fTextViewer == null)
-      return;
-
-    Rectangle r = new Rectangle(0, 0, 0, 0);
-    int yy, hh = PROBLEM_HEIGHT_MIN;
-
-    ITextViewerExtension3 extension = (ITextViewerExtension3) fTextViewer;
-    IDocument document = fTextViewer.getDocument();
-    StyledText textWidget = fTextViewer.getTextWidget();
-    fScrollPos = textWidget.getTopPixel();
-
-    int maxLines = textWidget.getLineCount();
-    Point size = fCanvas.getSize();
-    int writable = maxLines * textWidget.getLineHeight();
-    if (size.y > writable)
-      size.y = writable;
-
-    List indices = new ArrayList(fLayers.keySet());
-    Collections.sort(indices);
-
-    for (Iterator iterator = indices.iterator(); iterator.hasNext();) {
-      Object layer = iterator.next();
-      AnnotationType annotationType = (AnnotationType) fLayers.get(layer);
-
-      if (skip(annotationType))
-        continue;
-
-      boolean[] temporary = new boolean[] { false, true };
-      for (int t = 0; t < temporary.length; t++) {
-
-        Iterator e = new FilterIterator(annotationType, temporary[t]);
-        Color fill = getFillColor(annotationType, temporary[t]);
-        Color stroke = getStrokeColor(annotationType, temporary[t]);
-
-        for (int i = 0; e.hasNext(); i++) {
-
-          Annotation a = (Annotation) e.next();
-          Position p = fModel.getPosition(a);
-
-          if (p == null)
-            continue;
-
-          IRegion widgetRegion = extension.modelRange2WidgetRange(new Region(p.getOffset(), p.getLength()));
-          if (widgetRegion == null)
-            continue;
-
-          try {
-            if (PROBLEM_HEIGHT_SCALABLE) {
-              int numbersOfLines = document.getNumberOfLines(p.getOffset(), p.getLength());
-              hh = (numbersOfLines * size.y) / maxLines;
-              if (hh < PROBLEM_HEIGHT_MIN)
-                hh = PROBLEM_HEIGHT_MIN;
-            }
-            fProblemHeight = hh;
-
-            int startLine = textWidget.getLineAtOffset(widgetRegion.getOffset());
-            yy = Math.min((startLine * size.y) / maxLines, size.y - hh);
-
-            if (fill != null) {
-              gc.setBackground(fill);
-              gc.fillRectangle(INSET, yy, size.x - (2 * INSET), hh);
-            }
-
-            if (stroke != null) {
-              gc.setForeground(stroke);
-              r.x = INSET;
-              r.y = yy;
-              r.width = size.x - (2 * INSET) - 1;
-              r.height = hh;
-              gc.setLineWidth(1);
-              gc.drawRectangle(r);
-            }
-          } catch (BadLocationException x) {
-          }
-        }
-      }
-    }
-  }
-
-  /**
-   * Thread-safe implementation.
-   * Can be called from any thread.
-   */
-  public void update() {
-    if (fCanvas != null && !fCanvas.isDisposed()) {
-      Display d = fCanvas.getDisplay();
-      if (d != null) {
-        d.asyncExec(new Runnable() {
-          public void run() {
-            redraw();
-          }
-        });
-      }
-    }
-  }
-
-  /**
-   * Redraws the overview ruler.
-   */
-  private void redraw() {
-    if (fCanvas != null && !fCanvas.isDisposed()) {
-      GC gc = new GC(fCanvas);
-      doubleBufferPaint(gc);
-      gc.dispose();
-    }
-  }
-
-  private int[] toLineNumbers(int y_coordinate) {
-
-    StyledText textWidget = fTextViewer.getTextWidget();
-    int maxLines = textWidget.getContent().getLineCount();
-
-    int rulerLength = fCanvas.getSize().y;
-    int writable = maxLines * textWidget.getLineHeight();
-
-    if (rulerLength > writable)
-      rulerLength = writable;
-
-    if (y_coordinate >= writable)
-      return new int[] { -1, -1 };
-
-    int[] lines = new int[2];
-
-    int pixel = Math.max(y_coordinate - 1, 0);
-    lines[0] = (pixel * maxLines) / rulerLength;
-
-    pixel = Math.min(rulerLength, y_coordinate + 1);
-    lines[1] = (pixel * maxLines) / rulerLength;
-
-    if (fTextViewer instanceof ITextViewerExtension3) {
-      ITextViewerExtension3 extension = (ITextViewerExtension3) fTextViewer;
-      lines[0] = extension.widgetlLine2ModelLine(lines[0]);
-      lines[1] = extension.widgetlLine2ModelLine(lines[1]);
-    } else {
-      try {
-        IRegion visible = fTextViewer.getVisibleRegion();
-        int lineNumber = fTextViewer.getDocument().getLineOfOffset(visible.getOffset());
-        lines[0] += lineNumber;
-        lines[1] += lineNumber;
-      } catch (BadLocationException x) {
-      }
-    }
-
-    return lines;
-  }
-
-  boolean hasAnnotationAt(int y_coordinate) {
-    return findBestMatchingLineNumber(toLineNumbers(y_coordinate)) != -1;
-  }
-
-  private Position getProblemPositionAt(int[] lineNumbers) {
-    if (lineNumbers[0] == -1)
-      return null;
-
-    Position found = null;
-
-    try {
-      IDocument d = fTextViewer.getDocument();
-      IRegion line = d.getLineInformation(lineNumbers[0]);
-
-      int start = line.getOffset();
-
-      line = d.getLineInformation(lineNumbers[lineNumbers.length - 1]);
-      int end = line.getOffset() + line.getLength();
-
-      Iterator e = new FilterIterator(AnnotationType.ALL);
-      while (e.hasNext()) {
-        Annotation a = (Annotation) e.next();
-        Position p = fModel.getPosition(a);
-        if (start <= p.getOffset() && p.getOffset() < end) {
-          if (found == null || p.getOffset() < found.getOffset())
-            found = p;
-        }
-      }
-
-    } catch (BadLocationException x) {
-    }
-
-    return found;
-  }
-
-  /**
-   * Returns the line which best corresponds to one of
-   * the underlying problem annotations at the given
-   * y ruler coordinate.
-   * 
-   * @return the best matching line or <code>-1</code> if no such line can be found
-   * @since 2.1
-   */
-  private int findBestMatchingLineNumber(int[] lineNumbers) {
-    if (lineNumbers == null || lineNumbers.length < 1)
-      return -1;
-
-    try {
-      Position pos = getProblemPositionAt(lineNumbers);
-      if (pos == null)
-        return -1;
-      return fTextViewer.getDocument().getLineOfOffset(pos.getOffset());
-    } catch (BadLocationException ex) {
-      return -1;
-    }
-  }
-
-  private void handleMouseDown(MouseEvent event) {
-    if (fTextViewer != null) {
-      int[] lines = toLineNumbers(event.y);
-      Position p = getProblemPositionAt(lines);
-      if (p != null) {
-        fTextViewer.revealRange(p.getOffset(), p.getLength());
-        fTextViewer.setSelectedRange(p.getOffset(), p.getLength());
-      }
-      fTextViewer.getTextWidget().setFocus();
-    }
-    fLastMouseButtonActivityLine = toDocumentLineNumber(event.y);
-  }
-
-  private void handleMouseMove(MouseEvent event) {
-    if (fTextViewer != null) {
-      int[] lines = toLineNumbers(event.y);
-      Position p = getProblemPositionAt(lines);
-      Cursor cursor = (p != null ? fHitDetectionCursor : null);
-      if (cursor != fLastCursor) {
-        fCanvas.setCursor(cursor);
-        fLastCursor = cursor;
-      }
-    }
-  }
-
-  private void handleMouseDoubleClick(MouseEvent event) {
-    fLastMouseButtonActivityLine = toDocumentLineNumber(event.y);
-  }
-
-  public void showAnnotation(AnnotationType annotationType, boolean show) {
-    if (show)
-      fAnnotationSet.add(annotationType);
-    else
-      fAnnotationSet.remove(annotationType);
-  }
-
-  public void setLayer(AnnotationType annotationType, int layer) {
-    if (layer >= 0)
-      fLayers.put(new Integer(layer), annotationType);
-    else {
-      Iterator e = fLayers.keySet().iterator();
-      while (e.hasNext()) {
-        Object key = e.next();
-        if (annotationType.equals(fLayers.get(key))) {
-          fLayers.remove(key);
-          return;
-        }
-      }
-    }
-  }
-
-  public void setColor(AnnotationType annotationType, Color color) {
-    if (color != null)
-      fColorTable.put(annotationType, color);
-    else
-      fColorTable.remove(annotationType);
-  }
-
-  private boolean skip(AnnotationType annotationType) {
-    return !fAnnotationSet.contains(annotationType);
-  }
-
-  private static RGB interpolate(RGB fg, RGB bg, double scale) {
-    return new RGB(
-      (int) ((1.0 - scale) * fg.red + scale * bg.red),
-      (int) ((1.0 - scale) * fg.green + scale * bg.green),
-      (int) ((1.0 - scale) * fg.blue + scale * bg.blue));
-  }
-
-  private static double greyLevel(RGB rgb) {
-    if (rgb.red == rgb.green && rgb.green == rgb.blue)
-      return rgb.red;
-    return (0.299 * rgb.red + 0.587 * rgb.green + 0.114 * rgb.blue + 0.5);
-  }
-
-  private static boolean isDark(RGB rgb) {
-    return greyLevel(rgb) > 128;
-  }
-
-  private static Color getColor(RGB rgb) {
-    JavaTextTools textTools = PHPeclipsePlugin.getDefault().getJavaTextTools();
-    return textTools.getColorManager().getColor(rgb);
-  }
-
-  private Color getColor(AnnotationType annotationType, double scale) {
-    Color base = (Color) fColorTable.get(annotationType);
-    if (base == null)
-      return null;
-
-    RGB baseRGB = base.getRGB();
-    RGB background = fCanvas.getBackground().getRGB();
-
-    boolean darkBase = isDark(baseRGB);
-    boolean darkBackground = isDark(background);
-    if (darkBase && darkBackground)
-      background = new RGB(255, 255, 255);
-    else if (!darkBase && !darkBackground)
-      background = new RGB(0, 0, 0);
-
-    return getColor(interpolate(baseRGB, background, scale));
-  }
-
-  private Color getStrokeColor(AnnotationType annotationType, boolean temporary) {
-    return getColor(annotationType, temporary ? 0.5 : 0.2);
-  }
-
-  private Color getFillColor(AnnotationType annotationType, boolean temporary) {
-    return getColor(annotationType, temporary ? 0.9 : 0.6);
-  }
-
-  /**
-   * @see IVerticalRulerInfo#getLineOfLastMouseButtonActivity()
-   * @since 2.1
-   */
-  public int getLineOfLastMouseButtonActivity() {
-    return fLastMouseButtonActivityLine;
-  }
-
-  /**
-   * @see IVerticalRulerInfo#toDocumentLineNumber(int)
-   * @since 2.1
-   */
-  public int toDocumentLineNumber(int y_coordinate) {
-
-    if (fTextViewer == null || y_coordinate == -1)
-      return -1;
-
-    int[] lineNumbers = toLineNumbers(y_coordinate);
-    int bestLine = findBestMatchingLineNumber(lineNumbers);
-    if (bestLine == -1 && lineNumbers.length > 0)
-      return lineNumbers[0];
-    return bestLine;
-  }
-
-  /**
-   * Returns the height of the problem rectangle.
-   * 
-   * @return the height of the problem rectangle
-   * @since 2.1
-   */
-  int getAnnotationHeight() {
-    return fProblemHeight;
-  }
-}