Mercurial > projects > dwt-addons
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 * <html> section). | 391 * <html> 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; |