Mercurial > projects > dwt-addons
diff dwtx/jface/text/source/LineNumberRulerColumn.d @ 129:eb30df5ca28b
Added JFace Text sources
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sat, 23 Aug 2008 19:10:48 +0200 |
parents | |
children | c4fb132a086c |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/source/LineNumberRulerColumn.d Sat Aug 23 19:10:48 2008 +0200 @@ -0,0 +1,902 @@ +/******************************************************************************* + * Copyright (c) 2000, 2008 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + * Nikolay Botev <bono8106@hotmail.com> - [rulers] Shift clicking in line number column doesn't select range - https://bugs.eclipse.org/bugs/show_bug.cgi?id=32166 + * Nikolay Botev <bono8106@hotmail.com> - [rulers] Clicking in line number ruler should not trigger annotation ruler - https://bugs.eclipse.org/bugs/show_bug.cgi?id=40889 + * Port to the D programming language: + * Frank Benoit <benoit@tionex.de> + *******************************************************************************/ +module dwtx.jface.text.source.LineNumberRulerColumn; + +import dwt.dwthelper.utils; + +import java.util.Arrays; + +import dwt.DWT; +import dwt.custom.StyledText; +import dwt.events.DisposeEvent; +import dwt.events.DisposeListener; +import dwt.events.MouseEvent; +import dwt.events.MouseListener; +import dwt.events.MouseMoveListener; +import dwt.events.PaintEvent; +import dwt.events.PaintListener; +import dwt.graphics.Color; +import dwt.graphics.Font; +import dwt.graphics.FontMetrics; +import dwt.graphics.GC; +import dwt.graphics.Image; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.widgets.Canvas; +import dwt.widgets.Composite; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwt.widgets.TypedListener; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITextListener; +import dwtx.jface.text.ITextViewer; +import dwtx.jface.text.ITextViewerExtension; +import dwtx.jface.text.ITextViewerExtension5; +import dwtx.jface.text.IViewportListener; +import dwtx.jface.text.JFaceTextUtil; +import dwtx.jface.text.TextEvent; + + +/** + * A vertical ruler column displaying line numbers. + * Clients usually instantiate and configure object of this class. + * + * @since 2.0 + */ +public class LineNumberRulerColumn : IVerticalRulerColumn { + + /** + * Internal listener class. + */ + class InternalListener : IViewportListener, ITextListener { + + /** + * @since 3.1 + */ + private bool fCachedRedrawState= true; + + /* + * @see IViewportListener#viewportChanged(int) + */ + public void viewportChanged(int verticalPosition) { + if (fCachedRedrawState && verticalPosition !is fScrollPos) + redraw(); + } + + /* + * @see ITextListener#textChanged(TextEvent) + */ + public void textChanged(TextEvent event) { + + fCachedRedrawState= event.getViewerRedrawState(); + if (!fCachedRedrawState) + return; + + if (updateNumberOfDigits()) { + computeIndentations(); + layout(event.getViewerRedrawState()); + return; + } + + bool viewerCompletelyShown= isViewerCompletelyShown(); + if (viewerCompletelyShown || fSensitiveToTextChanges || event.getDocumentEvent() is null) + postRedraw(); + fSensitiveToTextChanges= viewerCompletelyShown; + } + } + + /** + * Handles all the mouse interaction in this line number ruler column. + */ + class MouseHandler : MouseListener, MouseMoveListener { + + /** The cached view port size. */ + private int fCachedViewportSize; + /** The area of the line at which line selection started. */ + private int fStartLineOffset; + /** The number of the line at which line selection started. */ + private int fStartLineNumber; + /** The auto scroll direction. */ + private int fAutoScrollDirection; + /* @since 3.2 */ + private bool fIsListeningForMove= false; + + /* + * @see dwt.events.MouseListener#mouseUp(dwt.events.MouseEvent) + */ + public void mouseUp(MouseEvent event) { + // see bug 45700 + if (event.button is 1) { + stopSelecting(); + stopAutoScroll(); + } + } + + /* + * @see dwt.events.MouseListener#mouseDown(dwt.events.MouseEvent) + */ + public void mouseDown(MouseEvent event) { + fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y); + // see bug 45700 + if (event.button is 1) { + startSelecting((event.stateMask & DWT.SHIFT) !is 0); + } + } + + /* + * @see dwt.events.MouseListener#mouseDoubleClick(dwt.events.MouseEvent) + */ + public void mouseDoubleClick(MouseEvent event) { + fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y); + stopSelecting(); + stopAutoScroll(); + } + + /* + * @see dwt.events.MouseMoveListener#mouseMove(dwt.events.MouseEvent) + */ + public void mouseMove(MouseEvent event) { + if (fIsListeningForMove && !autoScroll(event)) { + int newLine= fParentRuler.toDocumentLineNumber(event.y); + expandSelection(newLine); + } + fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y); + } + + /** + * Called when line drag selection started. Adds mouse move and track + * listeners to this column's control. + * + * @param expandExistingSelection if <code>true</code> the existing selection will be expanded, + * otherwise a new selection is started + */ + private void startSelecting(bool expandExistingSelection) { + try { + + // select line + IDocument document= fCachedTextViewer.getDocument(); + int lineNumber= fParentRuler.getLineOfLastMouseButtonActivity(); + if (expandExistingSelection && fCachedTextViewer instanceof ITextViewerExtension5 + && fCachedTextViewer.getTextWidget() !is null) { + ITextViewerExtension5 extension5= ((ITextViewerExtension5)fCachedTextViewer); + // Find model curosr position + int widgetCaret= fCachedTextViewer.getTextWidget().getCaretOffset(); + int modelCaret= extension5.widgetOffset2ModelOffset(widgetCaret); + // Find model selection range + Point selection= fCachedTextViewer.getSelectedRange(); + // Start from tail of selection range (opposite of cursor position) + int startOffset= modelCaret is selection.x ? selection.x + selection.y : selection.x; + + fStartLineNumber= document.getLineOfOffset(startOffset); + fStartLineOffset= startOffset; + + expandSelection(lineNumber); + } else { + fStartLineNumber= lineNumber; + fStartLineOffset= document.getLineInformation(fStartLineNumber).getOffset(); + fCachedTextViewer.setSelectedRange(fStartLineOffset, 0); + } + fCachedViewportSize= getVisibleLinesInViewport(); + + // prepare for drag selection + fIsListeningForMove= true; + + } catch (BadLocationException x) { + } + } + + /** + * Called when line drag selection stopped. Removes all previously + * installed listeners from this column's control. + */ + private void stopSelecting() { + // drag selection stopped + fIsListeningForMove= false; + } + + /** + * Expands the line selection from the remembered start line to the + * given line. + * + * @param lineNumber the line to which to expand the selection + */ + private void expandSelection(int lineNumber) { + try { + + IDocument document= fCachedTextViewer.getDocument(); + IRegion lineInfo= document.getLineInformation(lineNumber); + + Display display= fCachedTextWidget.getDisplay(); + Point absolutePosition= display.getCursorLocation(); + Point relativePosition= fCachedTextWidget.toControl(absolutePosition); + + int offset; + + if (relativePosition.x < 0) + offset= lineInfo.getOffset(); + else { + try { + int widgetOffset= fCachedTextWidget.getOffsetAtLocation(relativePosition); + Point p= fCachedTextWidget.getLocationAtOffset(widgetOffset); + if (p.x > relativePosition.x) + widgetOffset--; + + // Convert to model offset + if (fCachedTextViewer instanceof ITextViewerExtension5) { + ITextViewerExtension5 extension= (ITextViewerExtension5)fCachedTextViewer; + offset= extension.widgetOffset2ModelOffset(widgetOffset); + } else + offset= widgetOffset + fCachedTextViewer.getVisibleRegion().getOffset(); + + } catch (IllegalArgumentException ex) { + int lineEndOffset= lineInfo.getOffset() + lineInfo.getLength(); + + // Convert to widget offset + int lineEndWidgetOffset; + if (fCachedTextViewer instanceof ITextViewerExtension5) { + ITextViewerExtension5 extension= (ITextViewerExtension5)fCachedTextViewer; + lineEndWidgetOffset= extension.modelOffset2WidgetOffset(lineEndOffset); + } else + lineEndWidgetOffset= lineEndOffset - fCachedTextViewer.getVisibleRegion().getOffset(); + + Point p= fCachedTextWidget.getLocationAtOffset(lineEndWidgetOffset); + if (p.x < relativePosition.x) + offset= lineEndOffset; + else + offset= lineInfo.getOffset(); + } + } + + int start= Math.min(fStartLineOffset, offset); + int end= Math.max(fStartLineOffset, offset); + + if (lineNumber < fStartLineNumber) + fCachedTextViewer.setSelectedRange(end, start - end); + else + fCachedTextViewer.setSelectedRange(start, end - start); + + } catch (BadLocationException x) { + } + } + + /** + * Called when auto scrolling stopped. Clears the auto scroll direction. + */ + private void stopAutoScroll() { + fAutoScrollDirection= DWT.NULL; + } + + /** + * Called on drag selection. + * + * @param event the mouse event caught by the mouse move listener + * @return <code>true</code> if scrolling happened, <code>false</code> otherwise + */ + private bool autoScroll(MouseEvent event) { + Rectangle area= fCanvas.getClientArea(); + + if (event.y > area.height) { + autoScroll(DWT.DOWN); + return true; + } + + if (event.y < 0) { + autoScroll(DWT.UP); + return true; + } + + stopAutoScroll(); + return false; + } + + /** + * Scrolls the viewer into the given direction. + * + * @param direction the scroll direction + */ + private void autoScroll(int direction) { + + if (fAutoScrollDirection is direction) + return; + + final int TIMER_INTERVAL= 5; + final Display display= fCanvas.getDisplay(); + Runnable timer= null; + switch (direction) { + case DWT.UP: + timer= new Runnable() { + public void run() { + if (fAutoScrollDirection is DWT.UP) { + int top= getInclusiveTopIndex(); + if (top > 0) { + fCachedTextViewer.setTopIndex(top -1); + expandSelection(top -1); + display.timerExec(TIMER_INTERVAL, this); + } + } + } + }; + break; + case DWT.DOWN: + timer= new Runnable() { + public void run() { + if (fAutoScrollDirection is DWT.DOWN) { + int top= getInclusiveTopIndex(); + fCachedTextViewer.setTopIndex(top +1); + expandSelection(top +1 + fCachedViewportSize); + display.timerExec(TIMER_INTERVAL, this); + } + } + }; + break; + } + + if (timer !is null) { + fAutoScrollDirection= direction; + display.timerExec(TIMER_INTERVAL, timer); + } + } + + /** + * Returns the viewer's first visible line, even if only partially visible. + * + * @return the viewer's first visible line + */ + private int getInclusiveTopIndex() { + if (fCachedTextWidget !is null && !fCachedTextWidget.isDisposed()) { + return JFaceTextUtil.getPartialTopIndex(fCachedTextViewer); + } + return -1; + } + } + + /** This column's parent ruler */ + private CompositeRuler fParentRuler; + /** Cached text viewer */ + private ITextViewer fCachedTextViewer; + /** Cached text widget */ + private StyledText fCachedTextWidget; + /** The columns canvas */ + private Canvas fCanvas; + /** Cache for the actual scroll position in pixels */ + private int fScrollPos; + /** The drawable for double buffering */ + private Image fBuffer; + /** The internal listener */ + private InternalListener fInternalListener= new InternalListener(); + /** The font of this column */ + private Font fFont; + /** The indentation cache */ + private int[] fIndentation; + /** Indicates whether this column reacts on text change events */ + private bool fSensitiveToTextChanges= false; + /** The foreground color */ + private Color fForeground; + /** The background color */ + private Color fBackground; + /** Cached number of displayed digits */ + private int fCachedNumberOfDigits= -1; + /** Flag indicating whether a relayout is required */ + private bool fRelayoutRequired= false; + /** + * Redraw runnable lock + * @since 3.0 + */ + private Object fRunnableLock= new Object(); + /** + * Redraw runnable state + * @since 3.0 + */ + private bool fIsRunnablePosted= false; + /** + * Redraw runnable + * @since 3.0 + */ + private Runnable fRunnable= new Runnable() { + public void run() { + synchronized (fRunnableLock) { + fIsRunnablePosted= false; + } + redraw(); + } + }; + /* @since 3.2 */ + private MouseHandler fMouseHandler; + + + /** + * Constructs a new vertical ruler column. + */ + public LineNumberRulerColumn() { + } + + /** + * Sets the foreground color of this column. + * + * @param foreground the foreground color + */ + public void setForeground(Color foreground) { + fForeground= foreground; + } + + /** + * Returns the foreground color being used to print the line numbers. + * + * @return the configured foreground color + * @since 3.0 + */ + protected Color getForeground() { + return fForeground; + } + + /** + * Sets the background color of this column. + * + * @param background the background color + */ + public void setBackground(Color background) { + fBackground= background; + if (fCanvas !is null && !fCanvas.isDisposed()) + fCanvas.setBackground(getBackground(fCanvas.getDisplay())); + } + + /** + * Returns the System background color for list widgets. + * + * @param display the display + * @return the System background color for list widgets + */ + protected Color getBackground(Display display) { + if (fBackground is null) + return display.getSystemColor(DWT.COLOR_LIST_BACKGROUND); + return fBackground; + } + + /* + * @see IVerticalRulerColumn#getControl() + */ + public Control getControl() { + return fCanvas; + } + + /* + * @see IVerticalRuleColumnr#getWidth + */ + public int getWidth() { + return fIndentation[0]; + } + + /** + * Computes the number of digits to be displayed. Returns + * <code>true</code> if the number of digits changed compared + * to the previous call of this method. If the method is called + * for the first time, the return value is also <code>true</code>. + * + * @return whether the number of digits has been changed + * @since 3.0 + */ + protected bool updateNumberOfDigits() { + if (fCachedTextViewer is null) + return false; + + int digits= computeNumberOfDigits(); + + if (fCachedNumberOfDigits !is digits) { + fCachedNumberOfDigits= digits; + return true; + } + + return false; + } + + /** + * Does the real computation of the number of digits. Subclasses may override this method if + * they need extra space on the line number ruler. + * + * @return the number of digits to be displayed on the line number ruler. + */ + protected int computeNumberOfDigits() { + IDocument document= fCachedTextViewer.getDocument(); + int lines= document is null ? 0 : document.getNumberOfLines(); + + int digits= 2; + while (lines > Math.pow(10, digits) -1) { + ++digits; + } + return digits; + } + + /** + * Layouts the enclosing viewer to adapt the layout to changes of the + * size of the individual components. + * + * @param redraw <code>true</code> if this column can be redrawn + */ + protected void layout(bool redraw) { + if (!redraw) { + fRelayoutRequired= true; + return; + } + + fRelayoutRequired= false; + if (fCachedTextViewer instanceof ITextViewerExtension) { + ITextViewerExtension extension= (ITextViewerExtension) fCachedTextViewer; + Control control= extension.getControl(); + if (control instanceof Composite && !control.isDisposed()) { + Composite composite= (Composite) control; + composite.layout(true); + } + } + } + + /** + * Computes the indentations for the given font and stores them in + * <code>fIndentation</code>. + */ + protected void computeIndentations() { + if (fCanvas is null || fCanvas.isDisposed()) + return; + + GC gc= new GC(fCanvas); + try { + + gc.setFont(fCanvas.getFont()); + + fIndentation= new int[fCachedNumberOfDigits + 1]; + + char[] nines= new char[fCachedNumberOfDigits]; + Arrays.fill(nines, '9'); + String nineString= new String(nines); + Point p= gc.stringExtent(nineString); + fIndentation[0]= p.x; + + for (int i= 1; i <= fCachedNumberOfDigits; i++) { + p= gc.stringExtent(nineString.substring(0, i)); + fIndentation[i]= fIndentation[0] - p.x; + } + + } finally { + gc.dispose(); + } + } + + /* + * @see IVerticalRulerColumn#createControl(CompositeRuler, Composite) + */ + public Control createControl(CompositeRuler parentRuler, Composite parentControl) { + + fParentRuler= parentRuler; + fCachedTextViewer= parentRuler.getTextViewer(); + fCachedTextWidget= fCachedTextViewer.getTextWidget(); + + fCanvas= new Canvas(parentControl, DWT.NO_FOCUS ) { + /* + * @see dwt.widgets.Control#addMouseListener(dwt.events.MouseListener) + * @since 3.4 + */ + public void addMouseListener(MouseListener listener) { + // see bug 40889, bug 230073 and AnnotationRulerColumn#isPropagatingMouseListener() + if (listener is fMouseHandler) + super.addMouseListener(listener); + else { + TypedListener typedListener= null; + if (listener !is null) + typedListener= new TypedListener(listener); + addListener(DWT.MouseDoubleClick, typedListener); + } + } + }; + fCanvas.setBackground(getBackground(fCanvas.getDisplay())); + fCanvas.setForeground(fForeground); + + fCanvas.addPaintListener(new PaintListener() { + public void paintControl(PaintEvent event) { + if (fCachedTextViewer !is null) + doubleBufferPaint(event.gc); + } + }); + + fCanvas.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + handleDispose(); + fCachedTextViewer= null; + fCachedTextWidget= null; + } + }); + + fMouseHandler= new MouseHandler(); + fCanvas.addMouseListener(fMouseHandler); + fCanvas.addMouseMoveListener(fMouseHandler); + + if (fCachedTextViewer !is null) { + + fCachedTextViewer.addViewportListener(fInternalListener); + fCachedTextViewer.addTextListener(fInternalListener); + + if (fFont is null) { + if (fCachedTextWidget !is null && !fCachedTextWidget.isDisposed()) + fFont= fCachedTextWidget.getFont(); + } + } + + if (fFont !is null) + fCanvas.setFont(fFont); + + updateNumberOfDigits(); + computeIndentations(); + return fCanvas; + } + + /** + * Disposes the column's resources. + */ + protected void handleDispose() { + + if (fCachedTextViewer !is null) { + fCachedTextViewer.removeViewportListener(fInternalListener); + fCachedTextViewer.removeTextListener(fInternalListener); + } + + if (fBuffer !is null) { + fBuffer.dispose(); + fBuffer= null; + } + } + + /** + * Double buffer drawing. + * + * @param dest the GC to draw into + */ + private void doubleBufferPaint(GC dest) { + + Point size= fCanvas.getSize(); + + if (size.x <= 0 || size.y <= 0) + return; + + if (fBuffer !is null) { + Rectangle r= fBuffer.getBounds(); + if (r.width !is size.x || r.height !is size.y) { + fBuffer.dispose(); + fBuffer= null; + } + } + if (fBuffer is null) + fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y); + + GC gc= new GC(fBuffer); + gc.setFont(fCanvas.getFont()); + if (fForeground !is null) + gc.setForeground(fForeground); + + try { + gc.setBackground(getBackground(fCanvas.getDisplay())); + gc.fillRectangle(0, 0, size.x, size.y); + + ILineRange visibleLines= JFaceTextUtil.getVisibleModelLines(fCachedTextViewer); + if (visibleLines is null) + return; + fScrollPos= fCachedTextWidget.getTopPixel(); + doPaint(gc, visibleLines); + } finally { + gc.dispose(); + } + + dest.drawImage(fBuffer, 0, 0); + } + + /** + * Returns the view port height in lines. + * + * @return the view port height in lines + * @deprecated as of 3.2 the number of lines in the viewport cannot be computed because + * StyledText supports variable line heights + */ + protected int getVisibleLinesInViewport() { + return getVisibleLinesInViewport(fCachedTextWidget); + } + + + /** + * Returns <code>true</code> if the viewport displays the entire viewer contents, i.e. the + * viewer is not vertically scrollable. + * + * @return <code>true</code> if the viewport displays the entire contents, <code>false</code> otherwise + * @since 3.2 + */ + protected final bool isViewerCompletelyShown() { + return JFaceTextUtil.isShowingEntireContents(fCachedTextWidget); + } + + /** + * Draws the ruler column. + * + * @param gc the GC to draw into + * @param visibleLines the visible model lines + * @since 3.2 + */ + void doPaint(GC gc, ILineRange visibleLines) { + Display display= fCachedTextWidget.getDisplay(); + + // draw diff info + int y= -JFaceTextUtil.getHiddenTopLinePixels(fCachedTextWidget); + + int lastLine= end(visibleLines); + for (int line= visibleLines.getStartLine(); line < lastLine; line++) { + int widgetLine= JFaceTextUtil.modelLineToWidgetLine(fCachedTextViewer, line); + if (widgetLine is -1) + continue; + + int lineHeight= fCachedTextWidget.getLineHeight(fCachedTextWidget.getOffsetAtLine(widgetLine)); + paintLine(line, y, lineHeight, gc, display); + y += lineHeight; + } + } + + /* @since 3.2 */ + private static int end(ILineRange range) { + return range.getStartLine() + range.getNumberOfLines(); + } + + /** + * Computes the string to be printed for <code>line</code>. The default implementation returns + * <code>Integer.toString(line + 1)</code>. + * + * @param line the line number for which the line number string is generated + * @return the string to be printed on the line number bar for <code>line</code> + * @since 3.0 + */ + protected String createDisplayString(int line) { + return Integer.toString(line + 1); + } + + /** + * Returns the difference between the baseline of the widget and the + * baseline as specified by the font for <code>gc</code>. When drawing + * line numbers, the returned bias should be added to obtain text lined up + * on the correct base line of the text widget. + * + * @param gc the <code>GC</code> to get the font metrics from + * @param widgetLine the widget line + * @return the baseline bias to use when drawing text that is lined up with + * <code>fCachedTextWidget</code> + * @since 3.2 + */ + private int getBaselineBias(GC gc, int widgetLine) { + /* + * https://bugs.eclipse.org/bugs/show_bug.cgi?id=62951 + * widget line height may be more than the font height used for the + * line numbers, since font styles (bold, italics...) can have larger + * font metrics than the simple font used for the numbers. + */ + int offset= fCachedTextWidget.getOffsetAtLine(widgetLine); + int widgetBaseline= fCachedTextWidget.getBaseline(offset); + + FontMetrics fm= gc.getFontMetrics(); + int fontBaseline= fm.getAscent() + fm.getLeading(); + int baselineBias= widgetBaseline - fontBaseline; + return Math.max(0, baselineBias); + } + + /** + * Paints the line. After this method is called the line numbers are painted on top + * of the result of this method. + * + * @param line the line of the document which the ruler is painted for + * @param y the y-coordinate of the box being painted for <code>line</code>, relative to <code>gc</code> + * @param lineheight the height of one line (and therefore of the box being painted) + * @param gc the drawing context the client may choose to draw on. + * @param display the display the drawing occurs on + * @since 3.0 + */ + protected void paintLine(int line, int y, int lineheight, GC gc, Display display) { + int widgetLine= JFaceTextUtil.modelLineToWidgetLine(fCachedTextViewer, line); + + String s= createDisplayString(line); + int indentation= fIndentation[s.length()]; + int baselineBias= getBaselineBias(gc, widgetLine); + gc.drawString(s, indentation, y + baselineBias, true); + } + + /** + * Triggers a redraw in the display thread. + * + * @since 3.0 + */ + protected final void postRedraw() { + if (fCanvas !is null && !fCanvas.isDisposed()) { + Display d= fCanvas.getDisplay(); + if (d !is null) { + synchronized (fRunnableLock) { + if (fIsRunnablePosted) + return; + fIsRunnablePosted= true; + } + d.asyncExec(fRunnable); + } + } + } + + /* + * @see IVerticalRulerColumn#redraw() + */ + public void redraw() { + + if (fRelayoutRequired) { + layout(true); + return; + } + + if (fCachedTextViewer !is null && fCanvas !is null && !fCanvas.isDisposed()) { + GC gc= new GC(fCanvas); + doubleBufferPaint(gc); + gc.dispose(); + } + } + + /* + * @see IVerticalRulerColumn#setModel(IAnnotationModel) + */ + public void setModel(IAnnotationModel model) { + } + + /* + * @see IVerticalRulerColumn#setFont(Font) + */ + public void setFont(Font font) { + fFont= font; + if (fCanvas !is null && !fCanvas.isDisposed()) { + fCanvas.setFont(fFont); + updateNumberOfDigits(); + computeIndentations(); + } + } + + /** + * Returns the parent (composite) ruler of this ruler column. + * + * @return the parent ruler + * @since 3.0 + */ + protected CompositeRuler getParentRuler() { + return fParentRuler; + } + + + /** + * Returns the number of lines in the view port. + * + * @param textWidget + * @return the number of lines visible in the view port <code>-1</code> if there's no client area + * @deprecated this method should not be used - it relies on the widget using a uniform line height + */ + static int getVisibleLinesInViewport(StyledText textWidget) { + if (textWidget !is null) { + Rectangle clArea= textWidget.getClientArea(); + if (!clArea.isEmpty()) { + int firstPixel= 0; + int lastPixel= clArea.height - 1; // XXX what about margins? don't take trims as they include scrollbars + int first= JFaceTextUtil.getLineIndex(textWidget, firstPixel); + int last= JFaceTextUtil.getLineIndex(textWidget, lastPixel); + return last - first; + } + } + return -1; + } + +}