comparison dwtx/jface/internal/text/revisions/RevisionPainter.d @ 150:5cf141e43417

...
author Frank Benoit <benoit@tionex.de>
date Sun, 24 Aug 2008 23:05:26 +0200
parents 000f9136b8f7
children f70d9508c95c
comparison
equal deleted inserted replaced
149:b411f1c62131 150:5cf141e43417
96 96
97 97
98 /** 98 /**
99 * A strategy for painting the live annotate colors onto the vertical ruler column. It also manages 99 * A strategy for painting the live annotate colors onto the vertical ruler column. It also manages
100 * the revision hover. 100 * the revision hover.
101 * 101 *
102 * @since 3.2 102 * @since 3.2
103 */ 103 */
104 public final class RevisionPainter { 104 public final class RevisionPainter {
105 /** Tells whether this class is in debug mode. */ 105 /** Tells whether this class is in debug mode. */
106 private static bool DEBUG= "true".equalsIgnoreCase(Platform.getDebugOption("dwtx.jface.text.source/debug/RevisionRulerColumn")); //$NON-NLS-1$//$NON-NLS-2$ 106 private static bool DEBUG= "true".equalsIgnoreCase(Platform.getDebugOption("dwtx.jface.text.source/debug/RevisionRulerColumn")); //$NON-NLS-1$//$NON-NLS-2$
107 107
108 // RGBs provided by UI Designer 108 // RGBs provided by UI Designer
109 private static const RGB BY_DATE_START_COLOR= new RGB(199, 134, 57); 109 private static const RGB BY_DATE_START_COLOR= new RGB(199, 134, 57);
110 private static const RGB BY_DATE_END_COLOR= new RGB(241, 225, 206); 110 private static const RGB BY_DATE_END_COLOR= new RGB(241, 225, 206);
111 111
112 112
113 /** 113 /**
114 * The annotations created to show a revision in the overview ruler. 114 * The annotations created to show a revision in the overview ruler.
115 */ 115 */
116 private static final class RevisionAnnotation : Annotation { 116 private static final class RevisionAnnotation : Annotation {
117 public this(String text) { 117 public this(String text) {
158 */ 158 */
159 private const Map fFocusColors= new HashMap(); 159 private const Map fFocusColors= new HashMap();
160 160
161 /** 161 /**
162 * Sets the revision information, which is needed to compute the relative age of a revision. 162 * Sets the revision information, which is needed to compute the relative age of a revision.
163 * 163 *
164 * @param info the new revision info, <code>null</code> for none. 164 * @param info the new revision info, <code>null</code> for none.
165 */ 165 */
166 public void setInfo(RevisionInformation info) { 166 public void setInfo(RevisionInformation info) {
167 fRevisions= null; 167 fRevisions= null;
168 fColors.clear(); 168 fColors.clear();
169 fFocusColors.clear(); 169 fFocusColors.clear();
170 170
171 if (info is null) 171 if (info is null)
172 return; 172 return;
173 List revisions= new ArrayList(); 173 List revisions= new ArrayList();
174 for (Iterator it= info.getRevisions().iterator(); it.hasNext();) { 174 for (Iterator it= info.getRevisions().iterator(); it.hasNext();) {
175 Revision revision= cast(Revision) it.next(); 175 Revision revision= cast(Revision) it.next();
218 private int computeAgeIndex(Revision revision) { 218 private int computeAgeIndex(Revision revision) {
219 long age= computeAge(revision); 219 long age= computeAge(revision);
220 int index= fRevisions.indexOf(new Long(age)); 220 int index= fRevisions.indexOf(new Long(age));
221 return index; 221 return index;
222 } 222 }
223 223
224 private RGB getShadedColor(RGB color, float scale, bool focus) { 224 private RGB getShadedColor(RGB color, float scale, bool focus) {
225 Assert.isLegal(scale >= 0.0); 225 Assert.isLegal(scale >= 0.0);
226 Assert.isLegal(scale <= 1.0); 226 Assert.isLegal(scale <= 1.0);
227 RGB background= getBackground().getRGB(); 227 RGB background= getBackground().getRGB();
228 228
250 return revision.getDate().getTime(); 250 return revision.getDate().getTime();
251 } 251 }
252 252
253 /** 253 /**
254 * Returns the color for a revision based on relative age and author. 254 * Returns the color for a revision based on relative age and author.
255 * 255 *
256 * @param revision the revision 256 * @param revision the revision
257 * @param focus <code>true</code> to return the focus color 257 * @param focus <code>true</code> to return the focus color
258 * @return the color for a revision 258 * @return the color for a revision
259 */ 259 */
260 public RGB getColor(Revision revision, bool focus) { 260 public RGB getColor(Revision revision, bool focus) {
261 Map map= focus ? fFocusColors : fColors; 261 Map map= focus ? fFocusColors : fColors;
262 RGB color= cast(RGB) map.get(revision); 262 RGB color= cast(RGB) map.get(revision);
263 if (color !is null) 263 if (color !is null)
264 return color; 264 return color;
265 265
266 color= adaptColor(revision, focus); 266 color= adaptColor(revision, focus);
267 map.put(revision, color); 267 map.put(revision, color);
268 return color; 268 return color;
269 } 269 }
270 } 270 }
273 * Handles all the mouse interaction in this line number ruler column. 273 * Handles all the mouse interaction in this line number ruler column.
274 */ 274 */
275 private class MouseHandler : MouseMoveListener, MouseTrackListener, Listener { 275 private class MouseHandler : MouseMoveListener, MouseTrackListener, Listener {
276 276
277 private RevisionRange fMouseDownRegion; 277 private RevisionRange fMouseDownRegion;
278 278
279 private void handleMouseUp(Event e) { 279 private void handleMouseUp(Event e) {
280 if (e.button is 1) { 280 if (e.button is 1) {
281 RevisionRange upRegion= fFocusRange; 281 RevisionRange upRegion= fFocusRange;
282 RevisionRange downRegion= fMouseDownRegion; 282 RevisionRange downRegion= fMouseDownRegion;
283 fMouseDownRegion= null; 283 fMouseDownRegion= null;
364 /** 364 /**
365 * The information control creator. 365 * The information control creator.
366 */ 366 */
367 private static final class HoverInformationControlCreator : AbstractReusableInformationControlCreator { 367 private static final class HoverInformationControlCreator : AbstractReusableInformationControlCreator {
368 private bool fIsFocusable; 368 private bool fIsFocusable;
369 369
370 public this(bool isFocusable) { 370 public this(bool isFocusable) {
371 fIsFocusable= isFocusable; 371 fIsFocusable= isFocusable;
372 } 372 }
373 373
374 /* 374 /*
383 */ 383 */
384 public void setInformation(String content) { 384 public void setInformation(String content) {
385 content= addCSSToHTMLFragment(content); 385 content= addCSSToHTMLFragment(content);
386 super.setInformation(content); 386 super.setInformation(content);
387 } 387 }
388 388
389 /** 389 /**
390 * Adds a HTML header and CSS info if <code>html</code> is only an HTML fragment (has no 390 * Adds a HTML header and CSS info if <code>html</code> is only an HTML fragment (has no
391 * &lt;html&gt; section). 391 * &lt;html&gt; section).
392 * 392 *
393 * @param html the html / text produced by a revision 393 * @param html the html / text produced by a revision
394 * @return modified html 394 * @return modified html
395 */ 395 */
396 private String addCSSToHTMLFragment(String html) { 396 private String addCSSToHTMLFragment(String html) {
397 int max= Math.min(100, html.length()); 397 int max= Math.min(100, html.length());
398 if (html.substring(0, max).indexOf("<html>") !is -1) //$NON-NLS-1$ 398 if (html.substring(0, max).indexOf("<html>") !is -1) //$NON-NLS-1$
399 // there is already a header 399 // there is already a header
400 return html; 400 return html;
401 401
402 StringBuffer info= new StringBuffer(512 + html.length()); 402 StringBuffer info= new StringBuffer(512 + html.length());
403 HTMLPrinter.insertPageProlog(info, 0, fgStyleSheet); 403 HTMLPrinter.insertPageProlog(info, 0, fgStyleSheet);
404 info.append(html); 404 info.append(html);
405 HTMLPrinter.addPageEpilog(info); 405 HTMLPrinter.addPageEpilog(info);
406 return info.toString(); 406 return info.toString();
407 } 407 }
408 408
409 }; 409 };
410 } 410 }
411 return new DefaultInformationControl(parent, fIsFocusable); 411 return new DefaultInformationControl(parent, fIsFocusable);
412 } 412 }
413 413
449 "strong { font-weight: bold }\n" + //$NON-NLS-1$ 449 "strong { font-weight: bold }\n" + //$NON-NLS-1$
450 "em { font-style: italic }\n" + //$NON-NLS-1$ 450 "em { font-style: italic }\n" + //$NON-NLS-1$
451 "var { font-style: italic }\n" + //$NON-NLS-1$ 451 "var { font-style: italic }\n" + //$NON-NLS-1$
452 "th { font-weight: bold }\n" + //$NON-NLS-1$ 452 "th { font-weight: bold }\n" + //$NON-NLS-1$
453 ""; //$NON-NLS-1$ 453 ""; //$NON-NLS-1$
454 454
455 /** 455 /**
456 * The revision hover displays information about the currently selected revision. 456 * The revision hover displays information about the currently selected revision.
457 */ 457 */
458 private final class RevisionHover : IAnnotationHover, IAnnotationHoverExtension, IAnnotationHoverExtension2, IInformationProviderExtension2 { 458 private final class RevisionHover : IAnnotationHover, IAnnotationHoverExtension, IAnnotationHoverExtension2, IInformationProviderExtension2 {
459 459
460 /* 460 /*
461 * @see dwtx.jface.text.source.IAnnotationHover#getHoverInfo(dwtx.jface.text.source.ISourceViewer, 461 * @see dwtx.jface.text.source.IAnnotationHover#getHoverInfo(dwtx.jface.text.source.ISourceViewer,
462 * int) 462 * int)
463 */ 463 */
464 public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) { 464 public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) {
631 */ 631 */
632 private int fLastWidth= -1; 632 private int fLastWidth= -1;
633 633
634 /** 634 /**
635 * Creates a new revision painter for a vertical ruler column. 635 * Creates a new revision painter for a vertical ruler column.
636 * 636 *
637 * @param column the column that will delegate{@link #paint(GC, ILineRange) painting} to the 637 * @param column the column that will delegate{@link #paint(GC, ILineRange) painting} to the
638 * newly created painter. 638 * newly created painter.
639 * @param sharedColors a shared colors object to store shaded colors in 639 * @param sharedColors a shared colors object to store shaded colors in
640 */ 640 */
641 public this(IVerticalRulerColumn column, ISharedTextColors sharedColors) { 641 public this(IVerticalRulerColumn column, ISharedTextColors sharedColors) {
645 fSharedColors= sharedColors; 645 fSharedColors= sharedColors;
646 } 646 }
647 647
648 /** 648 /**
649 * Sets the revision information to be drawn and triggers a redraw. 649 * Sets the revision information to be drawn and triggers a redraw.
650 * 650 *
651 * @param info the revision information to show, <code>null</code> to draw none 651 * @param info the revision information to show, <code>null</code> to draw none
652 */ 652 */
653 public void setRevisionInformation(RevisionInformation info) { 653 public void setRevisionInformation(RevisionInformation info) {
654 if (fRevisionInfo !is info) { 654 if (fRevisionInfo !is info) {
655 fRequiredWidth= -1; 655 fRequiredWidth= -1;
664 } 664 }
665 } 665 }
666 666
667 /** 667 /**
668 * Changes the rendering mode and triggers redrawing if needed. 668 * Changes the rendering mode and triggers redrawing if needed.
669 * 669 *
670 * @param renderingMode the rendering mode 670 * @param renderingMode the rendering mode
671 * @since 3.3 671 * @since 3.3
672 */ 672 */
673 public void setRenderingMode(RenderingMode renderingMode) { 673 public void setRenderingMode(RenderingMode renderingMode) {
674 Assert.isLegal(renderingMode !is null); 674 Assert.isLegal(renderingMode !is null);
679 } 679 }
680 } 680 }
681 681
682 /** 682 /**
683 * Sets the background color. 683 * Sets the background color.
684 * 684 *
685 * @param background the background color, <code>null</code> for the platform's list 685 * @param background the background color, <code>null</code> for the platform's list
686 * background 686 * background
687 */ 687 */
688 public void setBackground(Color background) { 688 public void setBackground(Color background) {
689 fBackground= background; 689 fBackground= background;
690 } 690 }
691 691
692 /** 692 /**
693 * Sets the parent ruler - the delegating column must call this method as soon as it creates its 693 * Sets the parent ruler - the delegating column must call this method as soon as it creates its
694 * control. 694 * control.
695 * 695 *
696 * @param parentRuler the parent ruler 696 * @param parentRuler the parent ruler
697 */ 697 */
698 public void setParentRuler(CompositeRuler parentRuler) { 698 public void setParentRuler(CompositeRuler parentRuler) {
699 fParentRuler= parentRuler; 699 fParentRuler= parentRuler;
700 } 700 }
701 701
702 /** 702 /**
703 * Delegates the painting of the quick diff colors to this painter. The painter will draw the 703 * Delegates the painting of the quick diff colors to this painter. The painter will draw the
704 * color boxes onto the passed {@link GC} for all model (document) lines in 704 * color boxes onto the passed {@link GC} for all model (document) lines in
705 * <code>visibleModelLines</code>. 705 * <code>visibleModelLines</code>.
706 * 706 *
707 * @param gc the {@link GC} to draw onto 707 * @param gc the {@link GC} to draw onto
708 * @param visibleLines the lines (in document offsets) that are currently (perhaps only 708 * @param visibleLines the lines (in document offsets) that are currently (perhaps only
709 * partially) visible 709 * partially) visible
710 */ 710 */
711 public void paint(GC gc, ILineRange visibleLines) { 711 public void paint(GC gc, ILineRange visibleLines) {
722 string[0]= '.'; 722 string[0]= '.';
723 string[1]= ' '; 723 string[1]= ' ';
724 } 724 }
725 fAuthorInset= gc.stringExtent(new String(string)).x; 725 fAuthorInset= gc.stringExtent(new String(string)).x;
726 } 726 }
727 727
728 // recompute colors (show intense colors if ruler is narrow) 728 // recompute colors (show intense colors if ruler is narrow)
729 int width= getWidth(); 729 int width= getWidth();
730 if (width !is fLastWidth) { 730 if (width !is fLastWidth) {
731 fColorTool.setInfo(fRevisionInfo); 731 fColorTool.setInfo(fRevisionInfo);
732 fLastWidth= width; 732 fLastWidth= width;
733 } 733 }
734 734
735 // draw change regions 735 // draw change regions
736 List/* <RevisionRange> */ranges= getRanges(visibleLines); 736 List/* <RevisionRange> */ranges= getRanges(visibleLines);
737 for (Iterator it= ranges.iterator(); it.hasNext();) { 737 for (Iterator it= ranges.iterator(); it.hasNext();) {
738 RevisionRange region= cast(RevisionRange) it.next(); 738 RevisionRange region= cast(RevisionRange) it.next();
739 paintRange(region, gc); 739 paintRange(region, gc);
770 */ 770 */
771 public void widgetDisposed(DisposeEvent e) { 771 public void widgetDisposed(DisposeEvent e) {
772 handleDispose(); 772 handleDispose();
773 } 773 }
774 }); 774 });
775 775
776 fRevisionSelectionProvider.install(fViewer); 776 fRevisionSelectionProvider.install(fViewer);
777 } 777 }
778 778
779 /** 779 /**
780 * Returns <code>true</code> if the column is fully connected. 780 * Returns <code>true</code> if the column is fully connected.
781 * 781 *
782 * @return <code>true</code> if the column is fully connected, false otherwise 782 * @return <code>true</code> if the column is fully connected, false otherwise
783 */ 783 */
784 private bool isConnected() { 784 private bool isConnected() {
785 return fControl !is null; 785 return fControl !is null;
786 } 786 }
787 787
788 /** 788 /**
789 * Sets the annotation model. 789 * Sets the annotation model.
790 * 790 *
791 * @param model the annotation model, possibly <code>null</code> 791 * @param model the annotation model, possibly <code>null</code>
792 * @see IVerticalRulerColumn#setModel(IAnnotationModel) 792 * @see IVerticalRulerColumn#setModel(IAnnotationModel)
793 */ 793 */
794 public void setModel(IAnnotationModel model) { 794 public void setModel(IAnnotationModel model) {
795 IAnnotationModel diffModel; 795 IAnnotationModel diffModel;
802 setAnnotationModel(model); 802 setAnnotationModel(model);
803 } 803 }
804 804
805 /** 805 /**
806 * Sets the annotation model. 806 * Sets the annotation model.
807 * 807 *
808 * @param model the annotation model. 808 * @param model the annotation model.
809 */ 809 */
810 private void setAnnotationModel(IAnnotationModel model) { 810 private void setAnnotationModel(IAnnotationModel model) {
811 if (fAnnotationModel !is model) 811 if (fAnnotationModel !is model)
812 fAnnotationModel= model; 812 fAnnotationModel= model;
813 } 813 }
814 814
815 /** 815 /**
816 * Sets the line differ. 816 * Sets the line differ.
817 * 817 *
818 * @param differ the line differ or <code>null</code> if none 818 * @param differ the line differ or <code>null</code> if none
819 */ 819 */
820 private void setDiffer(IAnnotationModel differ) { 820 private void setDiffer(IAnnotationModel differ) {
821 if ( cast(ILineDiffer)differ || differ is null) { 821 if ( cast(ILineDiffer)differ || differ is null) {
822 if (fLineDiffer !is differ) { 822 if (fLineDiffer !is differ) {
837 837
838 if (fLineDiffer !is null) { 838 if (fLineDiffer !is null) {
839 (cast(IAnnotationModel) fLineDiffer).removeAnnotationModelListener(fAnnotationListener); 839 (cast(IAnnotationModel) fLineDiffer).removeAnnotationModelListener(fAnnotationListener);
840 fLineDiffer= null; 840 fLineDiffer= null;
841 } 841 }
842 842
843 fRevisionSelectionProvider.uninstall(); 843 fRevisionSelectionProvider.uninstall();
844 } 844 }
845 845
846 /** 846 /**
847 * Paints a single change region onto <code>gc</code>. 847 * Paints a single change region onto <code>gc</code>.
848 * 848 *
849 * @param range the range to paint 849 * @param range the range to paint
850 * @param gc the {@link GC} to paint on 850 * @param gc the {@link GC} to paint on
851 */ 851 */
852 private void paintRange(RevisionRange range, GC gc) { 852 private void paintRange(RevisionRange range, GC gc) {
853 ILineRange widgetRange= modelLinesToWidgetLines(range); 853 ILineRange widgetRange= modelLinesToWidgetLines(range);
913 * line numbers, since font styles (bold, italics...) can have larger 913 * line numbers, since font styles (bold, italics...) can have larger
914 * font metrics than the simple font used for the numbers. 914 * font metrics than the simple font used for the numbers.
915 */ 915 */
916 int offset= fWidget.getOffsetAtLine(widgetLine); 916 int offset= fWidget.getOffsetAtLine(widgetLine);
917 int widgetBaseline= fWidget.getBaseline(offset); 917 int widgetBaseline= fWidget.getBaseline(offset);
918 918
919 FontMetrics fm = gc.getFontMetrics(); 919 FontMetrics fm = gc.getFontMetrics();
920 int fontBaseline = fm.getAscent() + fm.getLeading(); 920 int fontBaseline = fm.getAscent() + fm.getLeading();
921 int baselineBias= widgetBaseline - fontBaseline; 921 int baselineBias= widgetBaseline - fontBaseline;
922 return Math.max(0, baselineBias); 922 return Math.max(0, baselineBias);
923 } 923 }
924 924
925 /** 925 /**
926 * Looks up the color for a certain revision. 926 * Looks up the color for a certain revision.
927 * 927 *
928 * @param revision the revision to get the color for 928 * @param revision the revision to get the color for
929 * @param focus <code>true</code> if it is the focus revision 929 * @param focus <code>true</code> if it is the focus revision
930 * @return the color for the revision 930 * @return the color for the revision
931 */ 931 */
932 private Color lookupColor(Revision revision, bool focus) { 932 private Color lookupColor(Revision revision, bool focus) {
934 } 934 }
935 935
936 /** 936 /**
937 * Returns the revision range that contains the given line, or 937 * Returns the revision range that contains the given line, or
938 * <code>null</code> if there is none. 938 * <code>null</code> if there is none.
939 * 939 *
940 * @param line the line of interest 940 * @param line the line of interest
941 * @return the corresponding <code>RevisionRange</code> or <code>null</code> 941 * @return the corresponding <code>RevisionRange</code> or <code>null</code>
942 */ 942 */
943 private RevisionRange getRange(int line) { 943 private RevisionRange getRange(int line) {
944 List ranges= getRangeCache(); 944 List ranges= getRangeCache();
959 return null; 959 return null;
960 } 960 }
961 961
962 /** 962 /**
963 * Returns the sublist of all <code>RevisionRange</code>s that intersect with the given lines. 963 * Returns the sublist of all <code>RevisionRange</code>s that intersect with the given lines.
964 * 964 *
965 * @param lines the model based lines of interest 965 * @param lines the model based lines of interest
966 * @return elementType: RevisionRange 966 * @return elementType: RevisionRange
967 */ 967 */
968 private List getRanges(ILineRange lines) { 968 private List getRanges(ILineRange lines) {
969 List ranges= getRangeCache(); 969 List ranges= getRangeCache();
990 } 990 }
991 991
992 /** 992 /**
993 * Gets all change ranges of the revisions in the revision model and adapts them to the current 993 * Gets all change ranges of the revisions in the revision model and adapts them to the current
994 * quick diff information. The list is cached. 994 * quick diff information. The list is cached.
995 * 995 *
996 * @return the list of all change regions, with diff information applied 996 * @return the list of all change regions, with diff information applied
997 */ 997 */
998 private List getRangeCache() { 998 private List getRangeCache() {
999 if (fRevisionRanges is null) { 999 if (fRevisionRanges is null) {
1000 if (fRevisionInfo is null) { 1000 if (fRevisionInfo is null) {
1017 * @since 3.3 1017 * @since 3.3
1018 */ 1018 */
1019 private void clearRangeCache() { 1019 private void clearRangeCache() {
1020 fRevisionRanges= null; 1020 fRevisionRanges= null;
1021 } 1021 }
1022 1022
1023 /** 1023 /**
1024 * Returns <code>true</code> if <code>range</code> contains <code>line</code>. A line is 1024 * Returns <code>true</code> if <code>range</code> contains <code>line</code>. A line is
1025 * not contained in a range if it is the range's exclusive end line. 1025 * not contained in a range if it is the range's exclusive end line.
1026 * 1026 *
1027 * @param range the range to check whether it contains <code>line</code> 1027 * @param range the range to check whether it contains <code>line</code>
1028 * @param line the line the line 1028 * @param line the line the line
1029 * @return <code>true</code> if <code>range</code> contains <code>line</code>, 1029 * @return <code>true</code> if <code>range</code> contains <code>line</code>,
1030 * <code>false</code> if not 1030 * <code>false</code> if not
1031 */ 1031 */
1033 return range.getStartLine() <= line && end(range) > line; 1033 return range.getStartLine() <= line && end(range) > line;
1034 } 1034 }
1035 1035
1036 /** 1036 /**
1037 * Computes the end index of a line range. 1037 * Computes the end index of a line range.
1038 * 1038 *
1039 * @param range a line range 1039 * @param range a line range
1040 * @return the last line (exclusive) of <code>range</code> 1040 * @return the last line (exclusive) of <code>range</code>
1041 */ 1041 */
1042 private static int end(ILineRange range) { 1042 private static int end(ILineRange range) {
1043 return range.getStartLine() + range.getNumberOfLines(); 1043 return range.getStartLine() + range.getNumberOfLines();
1044 } 1044 }
1045 1045
1046 /** 1046 /**
1047 * Returns the visible extent of a document line range in widget lines. 1047 * Returns the visible extent of a document line range in widget lines.
1048 * 1048 *
1049 * @param range the document line range 1049 * @param range the document line range
1050 * @return the visible extent of <code>range</code> in widget lines 1050 * @return the visible extent of <code>range</code> in widget lines
1051 */ 1051 */
1052 private ILineRange modelLinesToWidgetLines(ILineRange range) { 1052 private ILineRange modelLinesToWidgetLines(ILineRange range) {
1053 int widgetStartLine= -1; 1053 int widgetStartLine= -1;
1081 return new LineRange(widgetStartLine, widgetEndLine - widgetStartLine + 1); 1081 return new LineRange(widgetStartLine, widgetEndLine - widgetStartLine + 1);
1082 } 1082 }
1083 1083
1084 /** 1084 /**
1085 * Returns the revision hover. 1085 * Returns the revision hover.
1086 * 1086 *
1087 * @return the revision hover 1087 * @return the revision hover
1088 */ 1088 */
1089 public IAnnotationHover getHover() { 1089 public IAnnotationHover getHover() {
1090 return fHover; 1090 return fHover;
1091 } 1091 }
1092 1092
1093 /** 1093 /**
1094 * Computes and returns the bounds of the rectangle corresponding to a widget line range. The 1094 * Computes and returns the bounds of the rectangle corresponding to a widget line range. The
1095 * rectangle is in pixel coordinates relative to the text widget's 1095 * rectangle is in pixel coordinates relative to the text widget's
1096 * {@link StyledText#getClientArea() client area} and has the width of the ruler. 1096 * {@link StyledText#getClientArea() client area} and has the width of the ruler.
1097 * 1097 *
1098 * @param range the widget line range 1098 * @param range the widget line range
1099 * @return the box bounds corresponding to <code>range</code> 1099 * @return the box bounds corresponding to <code>range</code>
1100 */ 1100 */
1101 private Rectangle computeBoxBounds(ILineRange range) { 1101 private Rectangle computeBoxBounds(ILineRange range) {
1102 int y1= fWidget.getLinePixel(range.getStartLine()); 1102 int y1= fWidget.getLinePixel(range.getStartLine());
1109 * Shows (or hides) the overview annotations. 1109 * Shows (or hides) the overview annotations.
1110 */ 1110 */
1111 private void updateOverviewAnnotations() { 1111 private void updateOverviewAnnotations() {
1112 if (fAnnotationModel is null) 1112 if (fAnnotationModel is null)
1113 return; 1113 return;
1114 1114
1115 Revision revision= fFocusRevision !is null ? fFocusRevision : fSelectedRevision; 1115 Revision revision= fFocusRevision !is null ? fFocusRevision : fSelectedRevision;
1116 1116
1117 Map added= null; 1117 Map added= null;
1118 if (revision !is null) { 1118 if (revision !is null) {
1119 added= new HashMap(); 1119 added= new HashMap();
1151 1151
1152 } 1152 }
1153 1153
1154 /** 1154 /**
1155 * Returns the character offset based region of a line range. 1155 * Returns the character offset based region of a line range.
1156 * 1156 *
1157 * @param lines the line range to convert 1157 * @param lines the line range to convert
1158 * @return the character offset range corresponding to <code>range</code> 1158 * @return the character offset range corresponding to <code>range</code>
1159 * @throws BadLocationException if the line range is not within the document bounds 1159 * @throws BadLocationException if the line range is not within the document bounds
1160 */ 1160 */
1161 private IRegion toCharRegion(ILineRange lines) { 1161 private IRegion toCharRegion(ILineRange lines) {
1170 return new Region(offset, endOffset - offset); 1170 return new Region(offset, endOffset - offset);
1171 } 1171 }
1172 1172
1173 /** 1173 /**
1174 * Handles the selection of a revision and informs listeners. 1174 * Handles the selection of a revision and informs listeners.
1175 * 1175 *
1176 * @param revision the selected revision, <code>null</code> for none 1176 * @param revision the selected revision, <code>null</code> for none
1177 */ 1177 */
1178 void handleRevisionSelected(Revision revision) { 1178 void handleRevisionSelected(Revision revision) {
1179 fSelectedRevision= revision; 1179 fSelectedRevision= revision;
1180 fRevisionSelectionProvider.revisionSelected(revision); 1180 fRevisionSelectionProvider.revisionSelected(revision);
1182 postRedraw(); 1182 postRedraw();
1183 } 1183 }
1184 1184
1185 /** 1185 /**
1186 * Handles the selection of a revision id and informs listeners 1186 * Handles the selection of a revision id and informs listeners
1187 * 1187 *
1188 * @param id the selected revision id 1188 * @param id the selected revision id
1189 */ 1189 */
1190 void handleRevisionSelected(String id) { 1190 void handleRevisionSelected(String id) {
1191 Assert.isLegal(id !is null); 1191 Assert.isLegal(id !is null);
1192 if (fRevisionInfo is null) 1192 if (fRevisionInfo is null)
1204 handleRevisionSelected(cast(Revision) null); 1204 handleRevisionSelected(cast(Revision) null);
1205 } 1205 }
1206 1206
1207 /** 1207 /**
1208 * Returns the selection provider. 1208 * Returns the selection provider.
1209 * 1209 *
1210 * @return the selection provider 1210 * @return the selection provider
1211 */ 1211 */
1212 public RevisionSelectionProvider getRevisionSelectionProvider() { 1212 public RevisionSelectionProvider getRevisionSelectionProvider() {
1213 return fRevisionSelectionProvider; 1213 return fRevisionSelectionProvider;
1214 } 1214 }
1215 1215
1216 /** 1216 /**
1217 * Updates the focus line with a new line. 1217 * Updates the focus line with a new line.
1218 * 1218 *
1219 * @param line the new focus line, -1 for no focus 1219 * @param line the new focus line, -1 for no focus
1220 */ 1220 */
1221 private void updateFocusLine(int line) { 1221 private void updateFocusLine(int line) {
1222 if (fFocusLine !is line) 1222 if (fFocusLine !is line)
1223 onFocusLineChanged(fFocusLine, line); 1223 onFocusLineChanged(fFocusLine, line);
1224 } 1224 }
1225 1225
1226 /** 1226 /**
1227 * Handles a changing focus line. 1227 * Handles a changing focus line.
1228 * 1228 *
1229 * @param previousLine the old focus line (-1 for no focus) 1229 * @param previousLine the old focus line (-1 for no focus)
1230 * @param nextLine the new focus line (-1 for no focus) 1230 * @param nextLine the new focus line (-1 for no focus)
1231 */ 1231 */
1232 private void onFocusLineChanged(int previousLine, int nextLine) { 1232 private void onFocusLineChanged(int previousLine, int nextLine) {
1233 if cast(DEBUG) 1233 if (DEBUG)
1234 System.out_.println("line: " + previousLine + " > " + nextLine); //$NON-NLS-1$ //$NON-NLS-2$ 1234 System.out_.println("line: " ~ previousLine ~ " > " ~ nextLine); //$NON-NLS-1$ //$NON-NLS-2$
1235 fFocusLine= nextLine; 1235 fFocusLine= nextLine;
1236 RevisionRange region= getRange(nextLine); 1236 RevisionRange region= getRange(nextLine);
1237 updateFocusRange(region); 1237 updateFocusRange(region);
1238 } 1238 }
1239 1239
1240 /** 1240 /**
1241 * Updates the focus range. 1241 * Updates the focus range.
1242 * 1242 *
1243 * @param range the new focus range, <code>null</code> for no focus 1243 * @param range the new focus range, <code>null</code> for no focus
1244 */ 1244 */
1245 private void updateFocusRange(RevisionRange range) { 1245 private void updateFocusRange(RevisionRange range) {
1246 if (range !is fFocusRange) 1246 if (range !is fFocusRange)
1247 onFocusRangeChanged(fFocusRange, range); 1247 onFocusRangeChanged(fFocusRange, range);
1248 } 1248 }
1249 1249
1250 /** 1250 /**
1251 * Handles a changing focus range. 1251 * Handles a changing focus range.
1252 * 1252 *
1253 * @param previousRange the old focus range (<code>null</code> for no focus) 1253 * @param previousRange the old focus range (<code>null</code> for no focus)
1254 * @param nextRange the new focus range (<code>null</code> for no focus) 1254 * @param nextRange the new focus range (<code>null</code> for no focus)
1255 */ 1255 */
1256 private void onFocusRangeChanged(RevisionRange previousRange, RevisionRange nextRange) { 1256 private void onFocusRangeChanged(RevisionRange previousRange, RevisionRange nextRange) {
1257 if cast(DEBUG) 1257 if (DEBUG)
1258 System.out_.println("range: " + previousRange + " > " + nextRange); //$NON-NLS-1$ //$NON-NLS-2$ 1258 System.out_.println("range: " + previousRange + " > " + nextRange); //$NON-NLS-1$ //$NON-NLS-2$
1259 fFocusRange= nextRange; 1259 fFocusRange= nextRange;
1260 Revision revision= nextRange is null ? null : nextRange.getRevision(); 1260 Revision revision= nextRange is null ? null : nextRange.getRevision();
1261 updateFocusRevision(revision); 1261 updateFocusRevision(revision);
1262 } 1262 }
1266 onFocusRevisionChanged(fFocusRevision, revision); 1266 onFocusRevisionChanged(fFocusRevision, revision);
1267 } 1267 }
1268 1268
1269 /** 1269 /**
1270 * Handles a changing focus revision. 1270 * Handles a changing focus revision.
1271 * 1271 *
1272 * @param previousRevision the old focus revision (<code>null</code> for no focus) 1272 * @param previousRevision the old focus revision (<code>null</code> for no focus)
1273 * @param nextRevision the new focus revision (<code>null</code> for no focus) 1273 * @param nextRevision the new focus revision (<code>null</code> for no focus)
1274 */ 1274 */
1275 private void onFocusRevisionChanged(Revision previousRevision, Revision nextRevision) { 1275 private void onFocusRevisionChanged(Revision previousRevision, Revision nextRevision) {
1276 if cast(DEBUG) 1276 if (DEBUG)
1277 System.out_.println("revision: " + previousRevision + " > " + nextRevision); //$NON-NLS-1$ //$NON-NLS-2$ 1277 System.out_.println("revision: " + previousRevision + " > " + nextRevision); //$NON-NLS-1$ //$NON-NLS-2$
1278 fFocusRevision= nextRevision; 1278 fFocusRevision= nextRevision;
1279 uninstallWheelHandler(); 1279 uninstallWheelHandler();
1280 installWheelHandler(); 1280 installWheelHandler();
1281 updateOverviewAnnotations(); 1281 updateOverviewAnnotations();
1303 } 1303 }
1304 } 1304 }
1305 1305
1306 /** 1306 /**
1307 * Handles a mouse wheel event. 1307 * Handles a mouse wheel event.
1308 * 1308 *
1309 * @param event the mouse wheel event 1309 * @param event the mouse wheel event
1310 */ 1310 */
1311 private void handleMouseWheel(Event event) { 1311 private void handleMouseWheel(Event event) {
1312 bool up= event.count > 0; 1312 bool up= event.count > 0;
1313 int documentHoverLine= fFocusLine; 1313 int documentHoverLine= fFocusLine;
1379 } 1379 }
1380 1380
1381 /** 1381 /**
1382 * Translates a y coordinate in the pixel coordinates of the column's control to a document line 1382 * Translates a y coordinate in the pixel coordinates of the column's control to a document line
1383 * number. 1383 * number.
1384 * 1384 *
1385 * @param y the y coordinate 1385 * @param y the y coordinate
1386 * @return the corresponding document line, -1 for no line 1386 * @return the corresponding document line, -1 for no line
1387 * @see CompositeRuler#toDocumentLineNumber(int) 1387 * @see CompositeRuler#toDocumentLineNumber(int)
1388 */ 1388 */
1389 private int toDocumentLineNumber(int y) { 1389 private int toDocumentLineNumber(int y) {
1404 fParentRuler.immediateUpdate(); 1404 fParentRuler.immediateUpdate();
1405 } 1405 }
1406 1406
1407 /** 1407 /**
1408 * Returns the width of the column. 1408 * Returns the width of the column.
1409 * 1409 *
1410 * @return the width of the column 1410 * @return the width of the column
1411 */ 1411 */
1412 private int getWidth() { 1412 private int getWidth() {
1413 return fColumn.getWidth(); 1413 return fColumn.getWidth();
1414 } 1414 }
1415 1415
1416 /** 1416 /**
1417 * Returns the System background color for list widgets. 1417 * Returns the System background color for list widgets.
1418 * 1418 *
1419 * @return the System background color for list widgets 1419 * @return the System background color for list widgets
1420 */ 1420 */
1421 private Color getBackground() { 1421 private Color getBackground() {
1422 if (fBackground is null) 1422 if (fBackground is null)
1423 return fWidget.getDisplay().getSystemColor(DWT.COLOR_LIST_BACKGROUND); 1423 return fWidget.getDisplay().getSystemColor(DWT.COLOR_LIST_BACKGROUND);
1424 return fBackground; 1424 return fBackground;
1425 } 1425 }
1426 1426
1427 /** 1427 /**
1428 * Sets the hover later returned by {@link #getHover()}. 1428 * Sets the hover later returned by {@link #getHover()}.
1429 * 1429 *
1430 * @param hover the hover 1430 * @param hover the hover
1431 */ 1431 */
1432 public void setHover(IAnnotationHover hover) { 1432 public void setHover(IAnnotationHover hover) {
1433 // TODO ignore for now - must make revision hover settable from outside 1433 // TODO ignore for now - must make revision hover settable from outside
1434 } 1434 }
1435 1435
1436 /** 1436 /**
1437 * Returns <code>true</code> if the receiver can provide a hover for a certain document line. 1437 * Returns <code>true</code> if the receiver can provide a hover for a certain document line.
1438 * 1438 *
1439 * @param activeLine the document line of interest 1439 * @param activeLine the document line of interest
1440 * @return <code>true</code> if the receiver can provide a hover 1440 * @return <code>true</code> if the receiver can provide a hover
1441 */ 1441 */
1442 public bool hasHover(int activeLine) { 1442 public bool hasHover(int activeLine) {
1443 return cast(ISourceViewer)fViewer && fHover.getHoverLineRange(cast(ISourceViewer) fViewer, activeLine) !is null; 1443 return cast(ISourceViewer)fViewer && fHover.getHoverLineRange(cast(ISourceViewer) fViewer, activeLine) !is null;
1444 } 1444 }
1445 1445
1446 /** 1446 /**
1447 * Returns the revision at a certain document offset, or <code>null</code> for none. 1447 * Returns the revision at a certain document offset, or <code>null</code> for none.
1448 * 1448 *
1449 * @param offset the document offset 1449 * @param offset the document offset
1450 * @return the revision at offset, or <code>null</code> for none 1450 * @return the revision at offset, or <code>null</code> for none
1451 */ 1451 */
1452 Revision getRevision(int offset) { 1452 Revision getRevision(int offset) {
1453 IDocument document= fViewer.getDocument(); 1453 IDocument document= fViewer.getDocument();
1465 return null; 1465 return null;
1466 } 1466 }
1467 1467
1468 /** 1468 /**
1469 * Returns <code>true</code> if a revision model has been set, <code>false</code> otherwise. 1469 * Returns <code>true</code> if a revision model has been set, <code>false</code> otherwise.
1470 * 1470 *
1471 * @return <code>true</code> if a revision model has been set, <code>false</code> otherwise 1471 * @return <code>true</code> if a revision model has been set, <code>false</code> otherwise
1472 */ 1472 */
1473 public bool hasInformation() { 1473 public bool hasInformation() {
1474 return fRevisionInfo !is null; 1474 return fRevisionInfo !is null;
1475 } 1475 }
1476 1476
1477 /** 1477 /**
1478 * Returns the width in chars required to display information. 1478 * Returns the width in chars required to display information.
1479 * 1479 *
1480 * @return the width in chars required to display information 1480 * @return the width in chars required to display information
1481 * @since 3.3 1481 * @since 3.3
1482 */ 1482 */
1483 public int getRequiredWidth() { 1483 public int getRequiredWidth() {
1484 if (fRequiredWidth is -1) { 1484 if (fRequiredWidth is -1) {
1504 return fRequiredWidth; 1504 return fRequiredWidth;
1505 } 1505 }
1506 1506
1507 /** 1507 /**
1508 * Enables showing the revision id. 1508 * Enables showing the revision id.
1509 * 1509 *
1510 * @param show <code>true</code> to show the revision, <code>false</code> to hide it 1510 * @param show <code>true</code> to show the revision, <code>false</code> to hide it
1511 */ 1511 */
1512 public void showRevisionId(bool show) { 1512 public void showRevisionId(bool show) {
1513 if (fShowRevision !is show) { 1513 if (fShowRevision !is show) {
1514 fRequiredWidth= -1; 1514 fRequiredWidth= -1;
1515 fRevisionIdChars= 0; 1515 fRevisionIdChars= 0;
1516 fShowRevision= show; 1516 fShowRevision= show;
1517 postRedraw(); 1517 postRedraw();
1518 } 1518 }
1519 } 1519 }
1520 1520
1521 /** 1521 /**
1522 * Enables showing the revision author. 1522 * Enables showing the revision author.
1523 * 1523 *
1524 * @param show <code>true</code> to show the author, <code>false</code> to hide it 1524 * @param show <code>true</code> to show the author, <code>false</code> to hide it
1525 */ 1525 */
1526 public void showRevisionAuthor(bool show) { 1526 public void showRevisionAuthor(bool show) {
1527 if (fShowAuthor !is show) { 1527 if (fShowAuthor !is show) {
1528 fRequiredWidth= -1; 1528 fRequiredWidth= -1;
1532 } 1532 }
1533 } 1533 }
1534 1534
1535 /** 1535 /**
1536 * Adds a revision listener. 1536 * Adds a revision listener.
1537 * 1537 *
1538 * @param listener the listener 1538 * @param listener the listener
1539 * @since 3.3 1539 * @since 3.3
1540 */ 1540 */
1541 public void addRevisionListener(IRevisionListener listener) { 1541 public void addRevisionListener(IRevisionListener listener) {
1542 fRevisionListeners.add(listener); 1542 fRevisionListeners.add(listener);
1543 } 1543 }
1544 1544
1545 /** 1545 /**
1546 * Removes a revision listener. 1546 * Removes a revision listener.
1547 * 1547 *
1548 * @param listener the listener 1548 * @param listener the listener
1549 * @since 3.3 1549 * @since 3.3
1550 */ 1550 */
1551 public void removeRevisionListener(IRevisionListener listener) { 1551 public void removeRevisionListener(IRevisionListener listener) {
1552 fRevisionListeners.remove(listener); 1552 fRevisionListeners.remove(listener);
1553 } 1553 }
1554 1554
1555 /** 1555 /**
1556 * Informs the revision listeners about a change. 1556 * Informs the revision listeners about a change.
1557 * 1557 *
1558 * @since 3.3 1558 * @since 3.3
1559 */ 1559 */
1560 private void informListeners() { 1560 private void informListeners() {
1561 if (fRevisionInfo is null || fRevisionListeners.isEmpty()) 1561 if (fRevisionInfo is null || fRevisionListeners.isEmpty())
1562 return; 1562 return;