Search in sources :

Example 6 with ILineRange

use of org.eclipse.jface.text.source.ILineRange in project eclipse.platform.text by eclipse.

the class FocusedInformationPresenter method openFocusedAnnotationHover.

/**
 * Tries show a focused ("sticky") annotation hover.
 *
 * @param annotationHover the annotation hover to show
 * @param line the line for which to show the hover
 * @return <code>true</code> if successful, <code>false</code> otherwise
 */
public boolean openFocusedAnnotationHover(IAnnotationHover annotationHover, int line) {
    try {
        // compute the hover information
        Object hoverInfo;
        if (annotationHover instanceof IAnnotationHoverExtension) {
            IAnnotationHoverExtension extension = (IAnnotationHoverExtension) annotationHover;
            ILineRange hoverLineRange = extension.getHoverLineRange(fSourceViewer, line);
            if (hoverLineRange == null)
                return false;
            // allow any number of lines being displayed, as we support scrolling
            final int maxVisibleLines = Integer.MAX_VALUE;
            hoverInfo = extension.getHoverInfo(fSourceViewer, hoverLineRange, maxVisibleLines);
        } else {
            hoverInfo = annotationHover.getHoverInfo(fSourceViewer, line);
        }
        // hover region: the beginning of the concerned line to place the control right over the line
        IDocument document = fSourceViewer.getDocument();
        int offset = document.getLineOffset(line);
        String contentType = TextUtilities.getContentType(document, fSourceViewerConfiguration.getConfiguredDocumentPartitioning(fSourceViewer), offset, true);
        IInformationControlCreator controlCreator = null;
        if (// this is undocumented, but left here for backwards compatibility
        annotationHover instanceof IInformationProviderExtension2)
            controlCreator = ((IInformationProviderExtension2) annotationHover).getInformationPresenterControlCreator();
        else if (annotationHover instanceof IAnnotationHoverExtension)
            controlCreator = ((IAnnotationHoverExtension) annotationHover).getHoverControlCreator();
        IInformationProvider informationProvider = new InformationProvider(new Region(offset, 0), hoverInfo, controlCreator);
        setOffset(offset);
        setAnchor(AbstractInformationControlManager.ANCHOR_RIGHT);
        // AnnotationBarHoverManager sets (5,0), minus SourceViewer.GAP_SIZE_1
        setMargins(4, 0);
        setInformationProvider(informationProvider, contentType);
        showInformation();
        return true;
    } catch (BadLocationException e) {
        return false;
    }
}
Also used : IInformationControlCreator(org.eclipse.jface.text.IInformationControlCreator) IInformationProviderExtension2(org.eclipse.jface.text.information.IInformationProviderExtension2) ILineRange(org.eclipse.jface.text.source.ILineRange) IInformationProvider(org.eclipse.jface.text.information.IInformationProvider) Region(org.eclipse.jface.text.Region) IRegion(org.eclipse.jface.text.IRegion) IInformationProvider(org.eclipse.jface.text.information.IInformationProvider) IAnnotationHoverExtension(org.eclipse.jface.text.source.IAnnotationHoverExtension) IDocument(org.eclipse.jface.text.IDocument) BadLocationException(org.eclipse.jface.text.BadLocationException)

Example 7 with ILineRange

use of org.eclipse.jface.text.source.ILineRange in project eclipse.platform.text by eclipse.

the class DocumentLineDiffer method handleChanged.

/**
 * Implementation of documentChanged, non synchronized.
 *
 * @param event the document event
 * @throws BadLocationException if document access fails somewhere
 */
void handleChanged(DocumentEvent event) throws BadLocationException {
    Assert.isTrue(fThread == null || fThread == Thread.currentThread());
    fThread = null;
    // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=132125
    IDocument left = fLeftDocument;
    DocumentEquivalenceClass leftEquivalent = fLeftEquivalent;
    DocumentEquivalenceClass rightEquivalent = fRightEquivalent;
    if (left == null || leftEquivalent == null || rightEquivalent == null)
        return;
    // documents: left, right; modified and unchanged are either of both
    // TODO two-side
    IDocument right = event.getDocument();
    IDocument modified = event.getDocument();
    if (modified != left && modified != right)
        Assert.isTrue(false);
    boolean leftToRight = modified == left;
    String insertion = event.getText();
    int added = insertion == null ? 1 : modified.computeNumberOfLines(insertion) + 1;
    // put an upper bound to the delay we can afford
    if (added > 50 || fNLines > 50) {
        initialize();
        return;
    }
    int size = Math.max(fNLines, added) + 1;
    int lineDelta = added - fNLines;
    int lastLine = fFirstLine + fNLines - 1;
    int repetitionField;
    if (leftToRight) {
        int originalLine = getRightLine(lastLine + 1);
        repetitionField = searchForRepetitionField(size - 1, right, originalLine);
    } else {
        int originalLine = getLeftLine(lastLine + 1);
        repetitionField = searchForRepetitionField(size - 1, left, originalLine);
    }
    lastLine += repetitionField;
    // get enclosing range: search for a consistent block of at least the size of our
    // change before and after the change.
    final QuickDiffRangeDifference consistentBefore, consistentAfter;
    if (leftToRight) {
        consistentBefore = findConsistentRangeBeforeLeft(fFirstLine, size);
        consistentAfter = findConsistentRangeAfterLeft(lastLine, size);
    } else {
        consistentBefore = findConsistentRangeBeforeRight(fFirstLine, size);
        consistentAfter = findConsistentRangeAfterRight(lastLine, size);
    }
    // optimize unchanged blocks: if the consistent blocks around the change are larger than
    // size, we redimension them (especially important when there are only few changes.
    int shiftBefore = 0;
    if (consistentBefore.kind() == RangeDifference.NOCHANGE) {
        int unchanged;
        if (leftToRight)
            unchanged = Math.min(fFirstLine, consistentBefore.leftEnd()) - consistentBefore.leftStart();
        else
            unchanged = Math.min(fFirstLine, consistentBefore.rightEnd()) - consistentBefore.rightStart();
        shiftBefore = Math.max(0, unchanged - size);
    }
    int shiftAfter = 0;
    if (consistentAfter.kind() == RangeDifference.NOCHANGE) {
        int unchanged;
        if (leftToRight)
            unchanged = consistentAfter.leftEnd() - Math.max(lastLine + 1, consistentAfter.leftStart());
        else
            unchanged = consistentAfter.rightEnd() - Math.max(lastLine + 1, consistentAfter.rightStart());
        shiftAfter = Math.max(0, unchanged - size);
    }
    // get the document regions that will be rediffed, take into account that on the
    // document, the change has already happened.
    // left (reference) document
    int leftStartLine = consistentBefore.leftStart() + shiftBefore;
    int leftLine = consistentAfter.leftEnd();
    if (leftToRight)
        leftLine += lineDelta;
    int leftEndLine = leftLine - shiftAfter;
    ILineRange leftRange = new LineRange(leftStartLine, leftEndLine - leftStartLine);
    IRangeComparator reference = new DocEquivalenceComparator(leftEquivalent, leftRange);
    // right (actual) document
    int rightStartLine = consistentBefore.rightStart() + shiftBefore;
    int rightLine = consistentAfter.rightEnd();
    if (!leftToRight)
        rightLine += lineDelta;
    int rightEndLine = rightLine - shiftAfter;
    ILineRange rightRange = new LineRange(rightStartLine, rightEndLine - rightStartLine);
    IRangeComparator change = new DocEquivalenceComparator(rightEquivalent, rightRange);
    // put an upper bound to the delay we can afford
    if (leftLine - shiftAfter - leftStartLine > 50 || rightLine - shiftAfter - rightStartLine > 50) {
        initialize();
        return;
    }
    // debug
    // System.out.println("compare window: "+size+"\n\n<" + left.get(leftRegion.getOffset(), leftRegion.getLength()) +  //$NON-NLS-1$//$NON-NLS-2$
    // ">\n\n<" + right.get(rightRegion.getOffset(), rightRegion.getLength()) + ">\n"); //$NON-NLS-1$ //$NON-NLS-2$
    // compare
    List<QuickDiffRangeDifference> diffs = asQuickDiffRangeDifference(RangeDifferencer.findRanges(fRangeDiffFactory, null, reference, change));
    if (diffs.size() == 0) {
        diffs.add(new QuickDiffRangeDifference(RangeDifference.CHANGE, 0, 0, 0, 0));
    }
    // shift the partial diffs to the absolute document positions
    for (Iterator<QuickDiffRangeDifference> it = diffs.iterator(); it.hasNext(); ) {
        QuickDiffRangeDifference d = it.next();
        d.shiftLeft(leftStartLine);
        d.shiftRight(rightStartLine);
    }
    // undo optimization shifting
    if (shiftBefore > 0) {
        QuickDiffRangeDifference first = diffs.get(0);
        if (first.kind() == RangeDifference.NOCHANGE)
            first.extendStart(-shiftBefore);
        else
            diffs.add(0, new QuickDiffRangeDifference(RangeDifference.NOCHANGE, first.rightStart() - shiftBefore, shiftBefore, first.leftStart() - shiftBefore, shiftBefore));
    }
    QuickDiffRangeDifference last = diffs.get(diffs.size() - 1);
    if (shiftAfter > 0) {
        if (last.kind() == RangeDifference.NOCHANGE)
            last.extendEnd(shiftAfter);
        else
            diffs.add(new QuickDiffRangeDifference(RangeDifference.NOCHANGE, last.rightEnd(), shiftAfter, last.leftEnd(), shiftAfter));
    }
    // replace changed diff range
    synchronized (fDifferences) {
        final ListIterator<QuickDiffRangeDifference> it = fDifferences.listIterator();
        Iterator<QuickDiffRangeDifference> newIt = diffs.iterator();
        QuickDiffRangeDifference current;
        boolean changed = false;
        // search for consistentBefore
        do {
            Assert.isTrue(it.hasNext());
            current = it.next();
        } while (current != consistentBefore);
        Assert.isTrue(current == consistentBefore);
        fChanged.clear();
        fRemoved.clear();
        fAdded.clear();
        // replace until consistentAfter
        while (current != consistentAfter) {
            if (newIt.hasNext()) {
                QuickDiffRangeDifference o = newIt.next();
                if (!current.equals(o)) {
                    fRemoved.add(current);
                    fAdded.add(o);
                    changed = true;
                    it.set(o);
                }
            } else {
                fRemoved.add(current);
                it.remove();
                changed = true;
            }
            Assert.isTrue(it.hasNext());
            current = it.next();
        }
        // replace consistentAfter
        Assert.isTrue(current == consistentAfter);
        if (newIt.hasNext()) {
            QuickDiffRangeDifference o = newIt.next();
            if (!current.equals(o)) {
                fRemoved.add(current);
                fAdded.add(o);
                changed = true;
                it.set(o);
            }
        } else {
            fRemoved.add(current);
            it.remove();
            changed = true;
        }
        // add remaining new diffs
        while (newIt.hasNext()) {
            QuickDiffRangeDifference next = newIt.next();
            fAdded.add(next);
            it.add(next);
            changed = true;
        }
        // shift the old remaining diffs
        boolean init = true;
        int leftShift = 0;
        int rightShift = 0;
        while (it.hasNext()) {
            current = it.next();
            if (init) {
                init = false;
                leftShift = last.leftEnd() - current.leftStart();
                rightShift = last.rightEnd() - current.rightStart();
                if (leftShift != 0 || rightShift != 0)
                    changed = true;
                else
                    break;
            }
            // fChanged.add(current); // not needed since positional shifting is not handled by an annotation model
            current.shiftLeft(leftShift);
            current.shiftRight(rightShift);
        }
        fUpdateNeeded = changed;
    }
    fLastDifference = null;
}
Also used : DocumentEquivalenceClass(org.eclipse.ui.internal.texteditor.quickdiff.compare.equivalence.DocumentEquivalenceClass) IRangeComparator(org.eclipse.compare.rangedifferencer.IRangeComparator) LineRange(org.eclipse.jface.text.source.LineRange) ILineRange(org.eclipse.jface.text.source.ILineRange) ILineRange(org.eclipse.jface.text.source.ILineRange) DocEquivalenceComparator(org.eclipse.ui.internal.texteditor.quickdiff.compare.equivalence.DocEquivalenceComparator) IDocument(org.eclipse.jface.text.IDocument)

Example 8 with ILineRange

use of org.eclipse.jface.text.source.ILineRange in project eclipse.platform.text by eclipse.

the class ChangeRegion method getAdjustedCoverage.

/**
 * Returns the line coverage of the adjusted ranges, an empty range if the coverage is empty.
 *
 * @return the line coverage of the adjusted ranges
 */
public ILineRange getAdjustedCoverage() {
    if (fAdjusted.isEmpty())
        return new LineRange(fLines.getStartLine(), 0);
    Range first = fAdjusted.get(0);
    Range last = fAdjusted.get(fAdjusted.size() - 1);
    return Range.createAbsolute(first.start(), last.end());
}
Also used : ILineRange(org.eclipse.jface.text.source.ILineRange) LineRange(org.eclipse.jface.text.source.LineRange) ILineRange(org.eclipse.jface.text.source.ILineRange) LineRange(org.eclipse.jface.text.source.LineRange)

Example 9 with ILineRange

use of org.eclipse.jface.text.source.ILineRange in project eclipse.platform.text by eclipse.

the class RevisionPainter method paintRange.

/**
 * Paints a single change region onto <code>gc</code>.
 *
 * @param range the range to paint
 * @param gc the {@link GC} to paint on
 */
private void paintRange(RevisionRange range, GC gc) {
    ILineRange widgetRange = modelLinesToWidgetLines(range);
    if (widgetRange == null)
        return;
    Revision revision = range.getRevision();
    boolean drawArmedFocus = range == fMouseHandler.fMouseDownRegion;
    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);
        // highlight box
        gc.drawRectangle(box.x, box.y, box.width - 1, box.height - 1);
        // inner highlight box
        gc.drawRectangle(box.x + 1, box.y + 1, box.width - 3, box.height - 3);
        gc.setForeground(foreground);
    } else if (drawFocus || drawSelection) {
        Color foreground = gc.getForeground();
        Color focusColor = lookupColor(revision, true);
        gc.setForeground(focusColor);
        gc.fillRectangle(box);
        // highlight box
        gc.drawRectangle(box.x, box.y, box.width - 1, box.height - 1);
        gc.setForeground(foreground);
    } else {
        gc.fillRectangle(box);
    }
    if ((fShowAuthor || fShowRevision)) {
        int indentation = 1;
        int baselineBias = getBaselineBias(gc, widgetRange.getStartLine());
        if (fShowAuthor && fShowRevision) {
            gc.drawString(revision.getId(), indentation, box.y + baselineBias, true);
            gc.drawString(revision.getAuthor(), fAuthorInset, box.y + baselineBias, true);
        } else if (fShowAuthor) {
            gc.drawString(revision.getAuthor(), indentation, box.y + baselineBias, true);
        } else if (fShowRevision) {
            gc.drawString(revision.getId(), indentation, box.y + baselineBias, true);
        }
    }
}
Also used : Revision(org.eclipse.jface.text.revisions.Revision) ILineRange(org.eclipse.jface.text.source.ILineRange) Color(org.eclipse.swt.graphics.Color) Rectangle(org.eclipse.swt.graphics.Rectangle) Point(org.eclipse.swt.graphics.Point)

Example 10 with ILineRange

use of org.eclipse.jface.text.source.ILineRange in project eclipse.platform.text by eclipse.

the class JFaceTextUtil method getVisibleModelLines.

/**
 * Returns the range of lines that is visible in the viewer, including any partially visible
 * lines.
 *
 * @param viewer the viewer
 * @return the range of lines that is visible in the viewer, <code>null</code> if no lines are
 *         visible
 */
public static ILineRange getVisibleModelLines(ITextViewer viewer) {
    int top = getPartialTopIndex(viewer);
    int bottom = getPartialBottomIndex(viewer);
    if (top == -1 || bottom == -1)
        return null;
    return new LineRange(top, bottom - top + 1);
}
Also used : ILineRange(org.eclipse.jface.text.source.ILineRange) LineRange(org.eclipse.jface.text.source.LineRange) Point(org.eclipse.swt.graphics.Point)

Aggregations

ILineRange (org.eclipse.jface.text.source.ILineRange)10 LineRange (org.eclipse.jface.text.source.LineRange)5 Point (org.eclipse.swt.graphics.Point)4 IDocument (org.eclipse.jface.text.IDocument)3 ArrayList (java.util.ArrayList)2 Range (org.eclipse.jface.internal.text.revisions.Range)2 BadLocationException (org.eclipse.jface.text.BadLocationException)2 IRegion (org.eclipse.jface.text.IRegion)2 IRangeComparator (org.eclipse.compare.rangedifferencer.IRangeComparator)1 ChangeRegion (org.eclipse.jface.internal.text.revisions.ChangeRegion)1 IInformationControlCreator (org.eclipse.jface.text.IInformationControlCreator)1 ITextViewerExtension5 (org.eclipse.jface.text.ITextViewerExtension5)1 Region (org.eclipse.jface.text.Region)1 IInformationProvider (org.eclipse.jface.text.information.IInformationProvider)1 IInformationProviderExtension2 (org.eclipse.jface.text.information.IInformationProviderExtension2)1 Revision (org.eclipse.jface.text.revisions.Revision)1 RevisionRange (org.eclipse.jface.text.revisions.RevisionRange)1 IAnnotationHoverExtension (org.eclipse.jface.text.source.IAnnotationHoverExtension)1 Color (org.eclipse.swt.graphics.Color)1 Rectangle (org.eclipse.swt.graphics.Rectangle)1