X-Git-Url: http://secure.phpeclipse.com 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 index e59e385..0000000 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/OverviewRuler.java +++ /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 -1 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; - } -}