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;
}
}
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;
}
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());
}
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);
}
}
}
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);
}
Aggregations