/** * Creates a new instance. * * @param sharedColors the shared colors provider to use */ public LineNumberChangeRulerColumn(ISharedTextColors sharedColors) { Assert.isNotNull(sharedColors); fRevisionPainter= new RevisionPainter(this, sharedColors); fDiffPainter= new DiffPainter(this, sharedColors); }
@Override public void addRevisionListener(IRevisionListener listener) { fRevisionPainter.addRevisionListener(listener); }
/** * Sets the revision information to be drawn and triggers a redraw. * * @param info the revision information to show, <code>null</code> to draw none */ public void setRevisionInformation(RevisionInformation info) { if (fRevisionInfo != info) { fRequiredWidth= -1; fRevisionIdChars= 0; fRevisionInfo= info; clearRangeCache(); updateFocusRange(null); handleRevisionSelected((Revision) null); fColorTool.setInfo(info); postRedraw(); informListeners(); } }
/** * Handles a changing focus line. * * @param previousLine the old focus line (-1 for no focus) * @param nextLine the new focus line (-1 for no focus) */ private void onFocusLineChanged(int previousLine, int nextLine) { if (DEBUG) System.out.println("line: " + previousLine + " > " + nextLine); //$NON-NLS-1$ //$NON-NLS-2$ fFocusLine= nextLine; RevisionRange region= getRange(nextLine); updateFocusRange(region); }
/** * Returns the revision range that contains the given line, or * <code>null</code> if there is none. * * @param line the line of interest * @return the corresponding <code>RevisionRange</code> or <code>null</code> */ private RevisionRange getRange(int line) { List<RevisionRange> ranges= getRangeCache(); if (ranges.isEmpty() || line == -1) return null; for (RevisionRange range : ranges) { if (contains(range, line)) return range; } // line may be right after the last region RevisionRange lastRegion= ranges.get(ranges.size() - 1); if (line == end(lastRegion)) return lastRegion; return null; }
connectIfNeeded(); if (!isConnected()) return; int width= getWidth(); if (width != fLastWidth) { fColorTool.setInfo(fRevisionInfo); List<RevisionRange> ranges= getRanges(visibleLines); for (RevisionRange region : ranges) { paintRange(region, gc);
for (Iterator<RevisionRange> it= ranges.iterator(); it.hasNext();) { RevisionRange range= it.next(); ILineRange widgetRange= modelLinesToWidgetLines(range); if (contains(range, documentHoverLine)) { nextWidgetRange= last; break; for (ListIterator<RevisionRange> it= ranges.listIterator(ranges.size()); it.hasPrevious();) { RevisionRange range= it.previous(); ILineRange widgetRange= modelLinesToWidgetLines(range); if (contains(range, documentHoverLine)) { nextWidgetRange= last; break; return; int widgetCurrentFocusLine= modelLinesToWidgetLines(new LineRange(documentHoverLine, 1)).getStartLine(); int widgetNextFocusLine= nextWidgetRange.getStartLine(); int newTopPixel= fWidget.getTopPixel() + JFaceTextUtil.computeLineHeight(fWidget, widgetCurrentFocusLine, widgetNextFocusLine, widgetNextFocusLine - widgetCurrentFocusLine); updateFocusLine(toDocumentLineNumber(fWidget.toControl(fWidget.getDisplay().getCursorLocation()).y)); immediateUpdate();
ILineRange widgetRange= modelLinesToWidgetLines(range); if (widgetRange == null) return; boolean drawSelection= !drawArmedFocus && revision == fSelectedRevision; boolean drawFocus= !drawSelection && !drawArmedFocus && revision == fFocusRevision; Rectangle box= computeBoxBounds(widgetRange); gc.setBackground(lookupColor(revision, false)); if (drawArmedFocus) { Color foreground= gc.getForeground(); Color focusColor= lookupColor(revision, true); gc.setForeground(focusColor); gc.fillRectangle(box); } else if (drawFocus || drawSelection) { Color foreground= gc.getForeground(); Color focusColor= lookupColor(revision, true); gc.setForeground(focusColor); gc.fillRectangle(box); int baselineBias= getBaselineBias(gc, widgetRange.getStartLine()); if (fShowAuthor && fShowRevision) { gc.drawString(revision.getId(), indentation, box.y + baselineBias, true);
/** * Returns the sublist of all <code>RevisionRange</code>s that intersect with the given lines. * * @param lines the model based lines of interest * @return elementType: RevisionRange */ private List<RevisionRange> getRanges(ILineRange lines) { List<RevisionRange> ranges= getRangeCache(); // return the interesting subset int end= end(lines); int first= -1, last= -1; for (int i= 0; i < ranges.size(); i++) { RevisionRange range= ranges.get(i); int rangeEnd= end(range); if (first == -1 && rangeEnd > lines.getStartLine()) first= i; if (first != -1 && rangeEnd > end) { last= i; break; } } if (first == -1) return Collections.emptyList(); if (last == -1) last= ranges.size() - 1; // bottom index may be one too much return ranges.subList(first, last + 1); }
/** * Returns <code>true</code> if <code>range</code> contains <code>line</code>. A line is * not contained in a range if it is the range's exclusive end line. * * @param range the range to check whether it contains <code>line</code> * @param line the line the line * @return <code>true</code> if <code>range</code> contains <code>line</code>, * <code>false</code> if not */ private static boolean contains(ILineRange range, int line) { return range.getStartLine() <= line && end(range) > line; }
/** * Returns the revision at a certain document offset, or <code>null</code> for none. * * @param offset the document offset * @return the revision at offset, or <code>null</code> for none */ Revision getRevision(int offset) { IDocument document= fViewer.getDocument(); int line; try { line= document.getLineOfOffset(offset); } catch (BadLocationException x) { return null; } if (line != -1) { RevisionRange range= getRange(line); if (range != null) return range.getRevision(); } return null; }
connectIfNeeded(); if (!isConnected()) return; int width= getWidth(); if (width != fLastWidth) { fColorTool.setInfo(fRevisionInfo); List<RevisionRange> ranges= getRanges(visibleLines); for (Iterator<RevisionRange> it= ranges.iterator(); it.hasNext();) { RevisionRange region= it.next(); paintRange(region, gc);
if (up) { for (RevisionRange range : ranges) { ILineRange widgetRange= modelLinesToWidgetLines(range); if (contains(range, documentHoverLine)) { nextWidgetRange= last; break; for (ListIterator<RevisionRange> it= ranges.listIterator(ranges.size()); it.hasPrevious();) { RevisionRange range= it.previous(); ILineRange widgetRange= modelLinesToWidgetLines(range); if (contains(range, documentHoverLine)) { nextWidgetRange= last; break; return; int widgetCurrentFocusLine= modelLinesToWidgetLines(new LineRange(documentHoverLine, 1)).getStartLine(); int widgetNextFocusLine= nextWidgetRange.getStartLine(); int newTopPixel= fWidget.getTopPixel() + JFaceTextUtil.computeLineHeight(fWidget, widgetCurrentFocusLine, widgetNextFocusLine, widgetNextFocusLine - widgetCurrentFocusLine); updateFocusLine(toDocumentLineNumber(fWidget.toControl(fWidget.getDisplay().getCursorLocation()).y)); immediateUpdate();
ILineRange widgetRange= modelLinesToWidgetLines(range); if (widgetRange == null) return; boolean drawSelection= !drawArmedFocus && revision == fSelectedRevision; boolean drawFocus= !drawSelection && !drawArmedFocus && revision == fFocusRevision; Rectangle box= computeBoxBounds(widgetRange); gc.setBackground(lookupColor(revision, false)); if (drawArmedFocus) { Color foreground= gc.getForeground(); Color focusColor= lookupColor(revision, true); gc.setForeground(focusColor); gc.fillRectangle(box); } else if (drawFocus || drawSelection) { Color foreground= gc.getForeground(); Color focusColor= lookupColor(revision, true); gc.setForeground(focusColor); gc.fillRectangle(box); int baselineBias= getBaselineBias(gc, widgetRange.getStartLine()); if (fShowAuthor && fShowRevision) { gc.drawString(revision.getId(), indentation, box.y + baselineBias, true);
/** * Returns the revision range that contains the given line, or * <code>null</code> if there is none. * * @param line the line of interest * @return the corresponding <code>RevisionRange</code> or <code>null</code> */ private RevisionRange getRange(int line) { List<RevisionRange> ranges= getRangeCache(); if (ranges.isEmpty() || line == -1) return null; for (Iterator<RevisionRange> it= ranges.iterator(); it.hasNext();) { RevisionRange range= it.next(); if (contains(range, line)) return range; } // line may be right after the last region RevisionRange lastRegion= ranges.get(ranges.size() - 1); if (line == end(lastRegion)) return lastRegion; return null; }
/** * Handles a changing focus line. * * @param previousLine the old focus line (-1 for no focus) * @param nextLine the new focus line (-1 for no focus) */ private void onFocusLineChanged(int previousLine, int nextLine) { if (DEBUG) System.out.println("line: " + previousLine + " > " + nextLine); //$NON-NLS-1$ //$NON-NLS-2$ fFocusLine= nextLine; RevisionRange region= getRange(nextLine); updateFocusRange(region); }
/** * Returns the sublist of all <code>RevisionRange</code>s that intersect with the given lines. * * @param lines the model based lines of interest * @return elementType: RevisionRange */ private List<RevisionRange> getRanges(ILineRange lines) { List<RevisionRange> ranges= getRangeCache(); // return the interesting subset int end= end(lines); int first= -1, last= -1; for (int i= 0; i < ranges.size(); i++) { RevisionRange range= ranges.get(i); int rangeEnd= end(range); if (first == -1 && rangeEnd > lines.getStartLine()) first= i; if (first != -1 && rangeEnd > end) { last= i; break; } } if (first == -1) return Collections.emptyList(); if (last == -1) last= ranges.size() - 1; // bottom index may be one too much return ranges.subList(first, last + 1); }
/** * Returns <code>true</code> if <code>range</code> contains <code>line</code>. A line is * not contained in a range if it is the range's exclusive end line. * * @param range the range to check whether it contains <code>line</code> * @param line the line the line * @return <code>true</code> if <code>range</code> contains <code>line</code>, * <code>false</code> if not */ private static boolean contains(ILineRange range, int line) { return range.getStartLine() <= line && end(range) > line; }