Mercurial > projects > dwt2
diff org.eclipse.jface.text/src/org/eclipse/jface/text/source/ChangeRulerColumn.d @ 12:bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sat, 14 Mar 2009 18:23:29 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/ChangeRulerColumn.d Sat Mar 14 18:23:29 2009 +0100 @@ -0,0 +1,632 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 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 + * Port to the D programming language: + * Frank Benoit <benoit@tionex.de> + *******************************************************************************/ +module org.eclipse.jface.text.source.ChangeRulerColumn; + +import org.eclipse.jface.text.source.ISharedTextColors; // packageimport +import org.eclipse.jface.text.source.ILineRange; // packageimport +import org.eclipse.jface.text.source.IAnnotationPresentation; // packageimport +import org.eclipse.jface.text.source.IVerticalRulerInfoExtension; // packageimport +import org.eclipse.jface.text.source.ICharacterPairMatcher; // packageimport +import org.eclipse.jface.text.source.TextInvocationContext; // packageimport +import org.eclipse.jface.text.source.LineChangeHover; // packageimport +import org.eclipse.jface.text.source.IChangeRulerColumn; // packageimport +import org.eclipse.jface.text.source.IAnnotationMap; // packageimport +import org.eclipse.jface.text.source.IAnnotationModelListenerExtension; // packageimport +import org.eclipse.jface.text.source.ISourceViewerExtension2; // packageimport +import org.eclipse.jface.text.source.IAnnotationHover; // packageimport +import org.eclipse.jface.text.source.ContentAssistantFacade; // packageimport +import org.eclipse.jface.text.source.IAnnotationAccess; // packageimport +import org.eclipse.jface.text.source.IVerticalRulerExtension; // packageimport +import org.eclipse.jface.text.source.IVerticalRulerColumn; // packageimport +import org.eclipse.jface.text.source.LineNumberRulerColumn; // packageimport +import org.eclipse.jface.text.source.MatchingCharacterPainter; // packageimport +import org.eclipse.jface.text.source.IAnnotationModelExtension; // packageimport +import org.eclipse.jface.text.source.ILineDifferExtension; // packageimport +import org.eclipse.jface.text.source.DefaultCharacterPairMatcher; // packageimport +import org.eclipse.jface.text.source.LineNumberChangeRulerColumn; // packageimport +import org.eclipse.jface.text.source.IAnnotationAccessExtension; // packageimport +import org.eclipse.jface.text.source.ISourceViewer; // packageimport +import org.eclipse.jface.text.source.AnnotationModel; // packageimport +import org.eclipse.jface.text.source.ILineDifferExtension2; // packageimport +import org.eclipse.jface.text.source.IAnnotationModelListener; // packageimport +import org.eclipse.jface.text.source.IVerticalRuler; // packageimport +import org.eclipse.jface.text.source.DefaultAnnotationHover; // packageimport +import org.eclipse.jface.text.source.SourceViewer; // packageimport +import org.eclipse.jface.text.source.SourceViewerConfiguration; // packageimport +import org.eclipse.jface.text.source.AnnotationBarHoverManager; // packageimport +import org.eclipse.jface.text.source.CompositeRuler; // packageimport +import org.eclipse.jface.text.source.ImageUtilities; // packageimport +import org.eclipse.jface.text.source.VisualAnnotationModel; // packageimport +import org.eclipse.jface.text.source.IAnnotationModel; // packageimport +import org.eclipse.jface.text.source.ISourceViewerExtension3; // packageimport +import org.eclipse.jface.text.source.ILineDiffInfo; // packageimport +import org.eclipse.jface.text.source.VerticalRulerEvent; // packageimport +import org.eclipse.jface.text.source.ILineDiffer; // packageimport +import org.eclipse.jface.text.source.AnnotationModelEvent; // packageimport +import org.eclipse.jface.text.source.AnnotationColumn; // packageimport +import org.eclipse.jface.text.source.AnnotationRulerColumn; // packageimport +import org.eclipse.jface.text.source.IAnnotationHoverExtension; // packageimport +import org.eclipse.jface.text.source.AbstractRulerColumn; // packageimport +import org.eclipse.jface.text.source.ISourceViewerExtension; // packageimport +import org.eclipse.jface.text.source.AnnotationMap; // packageimport +import org.eclipse.jface.text.source.IVerticalRulerInfo; // packageimport +import org.eclipse.jface.text.source.IAnnotationModelExtension2; // packageimport +import org.eclipse.jface.text.source.LineRange; // packageimport +import org.eclipse.jface.text.source.IAnnotationAccessExtension2; // packageimport +import org.eclipse.jface.text.source.VerticalRuler; // packageimport +import org.eclipse.jface.text.source.JFaceTextMessages; // packageimport +import org.eclipse.jface.text.source.IOverviewRuler; // packageimport +import org.eclipse.jface.text.source.Annotation; // packageimport +import org.eclipse.jface.text.source.IVerticalRulerListener; // packageimport +import org.eclipse.jface.text.source.ISourceViewerExtension4; // packageimport +import org.eclipse.jface.text.source.AnnotationPainter; // packageimport +import org.eclipse.jface.text.source.IAnnotationHoverExtension2; // packageimport +import org.eclipse.jface.text.source.OverviewRuler; // packageimport +import org.eclipse.jface.text.source.OverviewRulerHoverManager; // packageimport + + +import java.lang.all; +import java.util.Set; + + + + + +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.MouseEvent; +import org.eclipse.swt.events.MouseListener; +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.Font; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +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; +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.internal.text.revisions.RevisionPainter; +import org.eclipse.jface.internal.text.source.DiffPainter; +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.ITextViewerExtension5; +import org.eclipse.jface.text.IViewportListener; +import org.eclipse.jface.text.JFaceTextUtil; +import org.eclipse.jface.text.TextEvent; +import org.eclipse.jface.text.revisions.IRevisionRulerColumn; +import org.eclipse.jface.text.revisions.RevisionInformation; +import org.eclipse.jface.viewers.ISelectionProvider; + +/** + * A vertical ruler column displaying line numbers and serving as a UI for quick diff. + * Clients instantiate and configure object of this class. + * + * @since 3.0 + */ +public final class ChangeRulerColumn : IVerticalRulerColumn, IVerticalRulerInfo, IVerticalRulerInfoExtension, IChangeRulerColumn, IRevisionRulerColumn { + /** + * Handles all the mouse interaction in this line number ruler column. + */ + private class MouseHandler : MouseListener, MouseMoveListener { + + /* + * @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent) + */ + public void mouseUp(MouseEvent event) { + } + + /* + * @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent) + */ + public void mouseDown(MouseEvent event) { + fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y); + } + + /* + * @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent) + */ + public void mouseDoubleClick(MouseEvent event) { + fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y); + } + + /* + * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent) + */ + public void mouseMove(MouseEvent event) { + fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y); + } + } + + /** + * Internal listener class. + */ + private class InternalListener : IViewportListener, ITextListener { + + /* + * @see IViewportListener#viewportChanged(int) + */ + public void viewportChanged(int verticalPosition) { + if (verticalPosition !is fScrollPos) + redraw(); + } + + /* + * @see ITextListener#textChanged(TextEvent) + */ + public void textChanged(TextEvent event) { + + if (!event.getViewerRedrawState()) + return; + + if (fSensitiveToTextChanges || event.getDocumentEvent() is null) + postRedraw(); + + } + } + + /** + * The view(port) listener. + */ + private /+const+/ InternalListener fInternalListener; + /** + * The mouse handler. + * @since 3.2 + */ + private /+const+/ MouseHandler fMouseHandler; + /** + * The revision painter. + * @since 3.2 + */ + private const RevisionPainter fRevisionPainter; + /** + * The diff info painter. + * @since 3.2 + */ + private const DiffPainter fDiffPainter; + + /** 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; + /** The background color */ + private Color fBackground; + /** The ruler's annotation model. */ + private IAnnotationModel fAnnotationModel; + /** The width of the change ruler column. */ + private const int fWidth= 5; + + /** Cache for the actual scroll position in pixels */ + private int fScrollPos; + /** The buffer for double buffering */ + private Image fBuffer; + /** Indicates whether this column reacts on text change events */ + private bool fSensitiveToTextChanges= false; + + private void instanceInit(){ + fInternalListener= new InternalListener(); + fMouseHandler= new MouseHandler(); + } + /** + * Creates a new ruler column. + * + * @deprecated since 3.2 use {@link #ChangeRulerColumn(ISharedTextColors)} instead + */ + public this() { + instanceInit(); + fRevisionPainter= null; + fDiffPainter= new DiffPainter(this, null); + } + + /** + * Creates a new revision ruler column. + * + * @param sharedColors the colors to look up RGBs + * @since 3.2 + */ + public this(ISharedTextColors sharedColors) { + instanceInit(); + Assert.isNotNull(cast(Object)sharedColors); + fRevisionPainter= new RevisionPainter(this, sharedColors); + fDiffPainter= new DiffPainter(this, null); // no shading + } + + /** + * Returns the System background color for list widgets. + * + * @return the System background color for list widgets + */ + private Color getBackground() { + if (fBackground is null) + return fCachedTextWidget.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND); + return fBackground; + } + + /* + * @see IVerticalRulerColumn#createControl(CompositeRuler, Composite) + */ + public Control createControl(CompositeRuler parentRuler, Composite parentControl) { + + fParentRuler= parentRuler; + fCachedTextViewer= parentRuler.getTextViewer(); + fCachedTextWidget= fCachedTextViewer.getTextWidget(); + + fCanvas= new Canvas(parentControl, SWT.NONE); + fCanvas.setBackground(getBackground()); + + fCanvas.addPaintListener(new class() PaintListener { + public void paintControl(PaintEvent event) { + if (fCachedTextViewer !is null) + doubleBufferPaint(event.gc); + } + }); + + fCanvas.addDisposeListener(new class() DisposeListener { + public void widgetDisposed(DisposeEvent e) { + handleDispose(); + fCachedTextViewer= null; + fCachedTextWidget= null; + } + }); + + fCanvas.addMouseListener(fMouseHandler); + fCanvas.addMouseMoveListener(fMouseHandler); + + if (fCachedTextViewer !is null) { + + fCachedTextViewer.addViewportListener(fInternalListener); + fCachedTextViewer.addTextListener(fInternalListener); + } + + fRevisionPainter.setParentRuler(parentRuler); + fDiffPainter.setParentRuler(parentRuler); + + 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()); + + try { + gc.setBackground(getBackground()); + gc.fillRectangle(0, 0, size.x, size.y); + + doPaint(gc); + } 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() { + // Hack to reduce amount of copied code. + return LineNumberRulerColumn.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 + */ + private void doPaint(GC gc) { + ILineRange visibleModelLines= computeVisibleModelLines(); + if (visibleModelLines is null) + return; + + fSensitiveToTextChanges= isViewerCompletelyShown(); + + fScrollPos= fCachedTextWidget.getTopPixel(); + + fRevisionPainter.paint(gc, visibleModelLines); + if (!fRevisionPainter.hasInformation()) // don't paint quick diff colors if revisions are painted + fDiffPainter.paint(gc, visibleModelLines); + } + + /* + * @see IVerticalRulerColumn#redraw() + */ + public void redraw() { + + if (fCachedTextViewer !is null && fCanvas !is null && !fCanvas.isDisposed()) { + GC gc= new GC(fCanvas); + doubleBufferPaint(gc); + gc.dispose(); + } + } + + /* + * @see IVerticalRulerColumn#setFont(Font) + */ + public void setFont(Font font) { + } + + /** + * Returns the parent (composite) ruler of this ruler column. + * + * @return the parent ruler + * @since 3.0 + */ + private CompositeRuler getParentRuler() { + return fParentRuler; + } + + /* + * @see org.eclipse.jface.text.source.IVerticalRulerInfo#getLineOfLastMouseButtonActivity() + */ + public int getLineOfLastMouseButtonActivity() { + return getParentRuler().getLineOfLastMouseButtonActivity(); + } + + /* + * @see org.eclipse.jface.text.source.IVerticalRulerInfo#toDocumentLineNumber(int) + */ + public int toDocumentLineNumber(int y_coordinate) { + return getParentRuler().toDocumentLineNumber(y_coordinate); + } + + /* + * @see org.eclipse.jface.text.source.IVerticalRulerInfoExtension#getHover() + */ + public IAnnotationHover getHover() { + int activeLine= getParentRuler().getLineOfLastMouseButtonActivity(); + if (fRevisionPainter.hasHover(activeLine)) + return fRevisionPainter.getHover(); + if (fDiffPainter.hasHover(activeLine)) + return fDiffPainter.getHover(); + return null; + } + + /* + * @see org.eclipse.jface.text.source.IChangeRulerColumn#setHover(org.eclipse.jface.text.source.IAnnotationHover) + */ + public void setHover(IAnnotationHover hover) { + fRevisionPainter.setHover(hover); + fDiffPainter.setHover(hover); + } + + /* + * @see IVerticalRulerColumn#setModel(IAnnotationModel) + */ + public void setModel(IAnnotationModel model) { + setAnnotationModel(model); + fRevisionPainter.setModel(model); + fDiffPainter.setModel(model); + } + + private void setAnnotationModel(IAnnotationModel model) { + if (fAnnotationModel !is model) + fAnnotationModel= model; + } + + /* + * @see org.eclipse.jface.text.source.IChangeRulerColumn#setBackground(org.eclipse.swt.graphics.Color) + */ + public void setBackground(Color background) { + fBackground= background; + if (fCanvas !is null && !fCanvas.isDisposed()) + fCanvas.setBackground(getBackground()); + fRevisionPainter.setBackground(background); + fDiffPainter.setBackground(background); + } + + /* + * @see org.eclipse.jface.text.source.IChangeRulerColumn#setAddedColor(org.eclipse.swt.graphics.Color) + */ + public void setAddedColor(Color addedColor) { + fDiffPainter.setAddedColor(addedColor); + } + + /* + * @see org.eclipse.jface.text.source.IChangeRulerColumn#setChangedColor(org.eclipse.swt.graphics.Color) + */ + public void setChangedColor(Color changedColor) { + fDiffPainter.setChangedColor(changedColor); + } + + /* + * @see org.eclipse.jface.text.source.IChangeRulerColumn#setDeletedColor(org.eclipse.swt.graphics.Color) + */ + public void setDeletedColor(Color deletedColor) { + fDiffPainter.setDeletedColor(deletedColor); + } + + /* + * @see org.eclipse.jface.text.source.IVerticalRulerInfoExtension#getModel() + */ + public IAnnotationModel getModel() { + return fAnnotationModel; + } + + /* + * @see IVerticalRulerColumn#getControl() + */ + public Control getControl() { + return fCanvas; + } + + /* + * @see org.eclipse.jface.text.source.IVerticalRulerInfo#getWidth() + */ + public int getWidth() { + return fWidth; + } + + /** + * Triggers a redraw in the display thread. + */ + protected final void postRedraw() { + if (fCanvas !is null && !fCanvas.isDisposed()) { + Display d= fCanvas.getDisplay(); + if (d !is null) { + d.asyncExec(new class() Runnable { + public void run() { + redraw(); + } + }); + } + } + } + + /* + * @see org.eclipse.jface.text.source.IVerticalRulerInfoExtension#addVerticalRulerListener(org.eclipse.jface.text.source.IVerticalRulerListener) + */ + public void addVerticalRulerListener(IVerticalRulerListener listener) { + throw new UnsupportedOperationException(); + } + + /* + * @see org.eclipse.jface.text.source.IVerticalRulerInfoExtension#removeVerticalRulerListener(org.eclipse.jface.text.source.IVerticalRulerListener) + */ + public void removeVerticalRulerListener(IVerticalRulerListener listener) { + throw new UnsupportedOperationException(); + } + + /** + * Computes the document based line range visible in the text widget. + * + * @return the document based line range visible in the text widget + * @since 3.2 + */ + private final ILineRange computeVisibleModelLines() { + IDocument doc= fCachedTextViewer.getDocument(); + if (doc is null) + return null; + + int topLine; + IRegion coverage; + + if ( cast(ITextViewerExtension5)fCachedTextViewer ) { + ITextViewerExtension5 extension= cast(ITextViewerExtension5) fCachedTextViewer; + + // ITextViewer.getTopIndex returns the fully visible line, but we want the partially + // visible one + int widgetTopLine= JFaceTextUtil.getPartialTopIndex(fCachedTextWidget); + topLine= extension.widgetLine2ModelLine(widgetTopLine); + + coverage= extension.getModelCoverage(); + + } else { + topLine= JFaceTextUtil.getPartialTopIndex(fCachedTextViewer); + coverage= fCachedTextViewer.getVisibleRegion(); + } + + int bottomLine= fCachedTextViewer.getBottomIndex(); + if (bottomLine !is -1) + ++ bottomLine; + + // clip by coverage window + try { + int firstLine= doc.getLineOfOffset(coverage.getOffset()); + if (firstLine > topLine) + topLine= firstLine; + + int lastLine= doc.getLineOfOffset(coverage.getOffset() + coverage.getLength()); + if (lastLine < bottomLine || bottomLine is -1) + bottomLine= lastLine; + } catch (BadLocationException x) { + ExceptionPrintStackTrace(x); + return null; + } + + ILineRange visibleModelLines= new LineRange(topLine, bottomLine - topLine + 1); + return visibleModelLines; + } + + /* + * @see org.eclipse.jface.text.revisions.IRevisionRulerColumn#setRevisionInformation(org.eclipse.jface.text.revisions.RevisionInformation) + */ + public void setRevisionInformation(RevisionInformation info) { + fRevisionPainter.setRevisionInformation(info); + fRevisionPainter.setBackground(getBackground()); + } + + /** + * Returns the revision selection provider. + * + * @return the revision selection provider + * @since 3.2 + */ + public ISelectionProvider getRevisionSelectionProvider() { + return fRevisionPainter.getRevisionSelectionProvider(); + } +}