org.eclipse.jface.text.JFaceTextUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.eclipse.jface.text Show documentation
Show all versions of org.eclipse.jface.text Show documentation
This is org.eclipse.jface.text jar used by Scout SDK
The newest version!
/*******************************************************************************
* Copyright (c) 2006, 2016 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Tom Eicher (Avaloq Evolution AG) - block selection mode
*******************************************************************************/
package org.eclipse.jface.text;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.jface.internal.text.SelectionProcessor;
import org.eclipse.jface.text.source.ILineRange;
import org.eclipse.jface.text.source.LineRange;
/**
* A collection of JFace Text functions.
*
* This class is neither intended to be instantiated nor subclassed.
*
*
* @since 3.3
* @noinstantiate This class is not intended to be instantiated by clients.
*/
public final class JFaceTextUtil {
private JFaceTextUtil() {
// Do not instantiate
}
/**
* Computes the full line height for the text line corresponding to the given widget line,
* considering the possible line wrapping.
*
* @param styledText the widget
* @param widgetLine the widget line
* @return the full real height of the corresponding line of text (which might wrap to multiple
* widget lines) in the widget
* @since 3.11
*/
public static int computeLineHeight(StyledText styledText, int widgetLine) {
boolean isWrapActive= styledText.getWordWrap();
int lineHeight;
int offset= styledText.getOffsetAtLine(widgetLine);
if (!isWrapActive) {
lineHeight= styledText.getLineHeight(offset);
} else {
int offsetEnd= offset + styledText.getLine(widgetLine).length();
if (offsetEnd == styledText.getCharCount()) {
lineHeight= styledText.getLineHeight(offset);
} else {
Rectangle textBounds= styledText.getTextBounds(offset, offsetEnd);
lineHeight= textBounds.height;
}
}
return lineHeight;
}
/**
* Computes the line height for the given line range.
*
* @param textWidget the StyledText
widget
* @param startLine the start line
* @param endLine the end line (exclusive)
* @param lineCount the line count used by the old API
* @return the height of all lines starting with startLine
and ending above endLime
*/
public static int computeLineHeight(StyledText textWidget, int startLine, int endLine, int lineCount) {
return getLinePixel(textWidget, endLine) - getLinePixel(textWidget, startLine);
}
/**
* Returns the last fully visible line of the widget. The exact semantics of "last fully visible
* line" are:
*
* - the last line of which the last pixel is visible, if any
*
- otherwise, the only line that is partially visible
*
*
* @param widget the widget
* @return the last fully visible line
*/
public static int getBottomIndex(StyledText widget) {
int lastPixel= computeLastVisiblePixel(widget);
// bottom is in [0 .. lineCount - 1]
int bottom= widget.getLineIndex(lastPixel);
// bottom is the first line - no more checking
if (bottom == 0)
return bottom;
int pixel= widget.getLinePixel(bottom);
// bottom starts on or before the client area start - bottom is the only visible line
if (pixel <= 0)
return bottom;
int height= computeLineHeight(widget, bottom);
// bottom is not showing entirely - use the previous line
if (pixel + height - 1 > lastPixel)
return bottom - 1;
// bottom is fully visible and its last line is exactly the last pixel
return bottom;
}
/**
* Returns the index of the first (possibly only partially) visible line of the widget
*
* @param widget the widget
* @return the index of the first line of which a pixel is visible
*/
public static int getPartialTopIndex(StyledText widget) {
// see StyledText#getPartialTopIndex()
int top= widget.getTopIndex();
int pixels= widget.getLinePixel(top);
if (pixels > 0)
top--;
return top;
}
/**
* Returns the index of the last (possibly only partially) visible line of the widget
*
* @param widget the text widget
* @return the index of the last line of which a pixel is visible
*/
public static int getPartialBottomIndex(StyledText widget) {
// @see StyledText#getPartialBottomIndex()
int lastPixel= computeLastVisiblePixel(widget);
int bottom= widget.getLineIndex(lastPixel);
return bottom;
}
/**
* Returns the last visible pixel in the widget's client area.
*
* @param widget the widget
* @return the last visible pixel in the widget's client area
*/
private static int computeLastVisiblePixel(StyledText widget) {
int caHeight= widget.getClientArea().height;
int lastPixel= caHeight - 1;
// XXX: what if there is a margin? can't take trim as this includes the scrollbars which are not part of the client area
// if ((textWidget.getStyle() & SWT.BORDER) != 0)
// lastPixel -= 4;
return lastPixel;
}
/**
* Returns the line index of the first visible model line in the viewer. The line may be only
* partially visible.
*
* @param viewer the text viewer
* @return the first line of which a pixel is visible, or -1 for no line
*/
public static int getPartialTopIndex(ITextViewer viewer) {
StyledText widget= viewer.getTextWidget();
int widgetTop= getPartialTopIndex(widget);
return widgetLine2ModelLine(viewer, widgetTop);
}
/**
* Returns the last, possibly partially, visible line in the view port.
*
* @param viewer the text viewer
* @return the last, possibly partially, visible line in the view port
*/
public static int getPartialBottomIndex(ITextViewer viewer) {
StyledText textWidget= viewer.getTextWidget();
int widgetBottom= getPartialBottomIndex(textWidget);
return widgetLine2ModelLine(viewer, widgetBottom);
}
/**
* 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, null
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);
}
/**
* Converts a widget line into a model (i.e. {@link IDocument}) line using the
* {@link ITextViewerExtension5} if available, otherwise by adapting the widget line to the
* viewer's {@link ITextViewer#getVisibleRegion() visible region}.
*
* @param viewer the viewer
* @param widgetLine the widget line to convert.
* @return the model line corresponding to widgetLine
or -1 to signal that there
* is no corresponding model line
*/
public static int widgetLine2ModelLine(ITextViewer viewer, int widgetLine) {
int modelLine;
if (viewer instanceof ITextViewerExtension5) {
ITextViewerExtension5 extension= (ITextViewerExtension5) viewer;
modelLine= extension.widgetLine2ModelLine(widgetLine);
} else {
try {
IRegion r= viewer.getVisibleRegion();
IDocument d= viewer.getDocument();
if (d == null)
return -1;
modelLine= widgetLine + d.getLineOfOffset(r.getOffset());
} catch (BadLocationException x) {
modelLine= widgetLine;
}
}
return modelLine;
}
/**
* Converts a model (i.e. {@link IDocument}) line into a widget line using the
* {@link ITextViewerExtension5} if available, otherwise by adapting the model line to the
* viewer's {@link ITextViewer#getVisibleRegion() visible region}.
*
* @param viewer the viewer
* @param modelLine the model line to convert.
* @return the widget line corresponding to modelLine
or -1 to signal that there
* is no corresponding widget line
*/
public static int modelLineToWidgetLine(ITextViewer viewer, final int modelLine) {
int widgetLine;
if (viewer instanceof ITextViewerExtension5) {
ITextViewerExtension5 extension= (ITextViewerExtension5) viewer;
widgetLine= extension.modelLine2WidgetLine(modelLine);
} else {
IRegion region= viewer.getVisibleRegion();
IDocument document= viewer.getDocument();
if (document == null)
return -1;
try {
int visibleStartLine= document.getLineOfOffset(region.getOffset());
int visibleEndLine= document.getLineOfOffset(region.getOffset() + region.getLength());
if (modelLine < visibleStartLine || modelLine > visibleEndLine)
widgetLine= -1;
else
widgetLine= modelLine - visibleStartLine;
} catch (BadLocationException x) {
// ignore and return -1
widgetLine= -1;
}
}
return widgetLine;
}
/**
* Returns the number of hidden pixels of the first partially visible line. If there is no
* partially visible line, zero is returned.
*
* @param textWidget the widget
* @return the number of hidden pixels of the first partial line, always >= 0
*/
public static int getHiddenTopLinePixels(StyledText textWidget) {
int top= getPartialTopIndex(textWidget);
return -textWidget.getLinePixel(top);
}
/*
* @see StyledText#getLinePixel(int)
*/
public static int getLinePixel(StyledText textWidget, int line) {
return textWidget.getLinePixel(line);
}
/*
* @see StyledText#getLineIndex(int)
*/
public static int getLineIndex(StyledText textWidget, int y) {
int lineIndex= textWidget.getLineIndex(y);
return lineIndex;
}
/**
* Returns true
if the widget displays the entire contents, i.e. it cannot
* be vertically scrolled.
*
* @param widget the widget
* @return true
if the widget displays the entire contents, i.e. it cannot
* be vertically scrolled, false
otherwise
*/
public static boolean isShowingEntireContents(StyledText widget) {
if (widget.getTopPixel() != 0) // more efficient shortcut
return false;
int lastVisiblePixel= computeLastVisiblePixel(widget);
int lastPossiblePixel= widget.getLinePixel(widget.getLineCount());
return lastPossiblePixel <= lastVisiblePixel;
}
/**
* Determines the graphical area covered by the given text region in
* the given viewer.
*
* @param region the region whose graphical extend must be computed
* @param textViewer the text viewer containing the region
* @return the graphical extend of the given region in the given viewer
*
* @since 3.4
*/
public static Rectangle computeArea(IRegion region, ITextViewer textViewer) {
int start= 0;
int end= 0;
IRegion widgetRegion= modelRange2WidgetRange(region, textViewer);
if (widgetRegion != null) {
start= widgetRegion.getOffset();
end= start + widgetRegion.getLength();
}
StyledText styledText= textViewer.getTextWidget();
Rectangle bounds;
if (end > 0 && start < end)
bounds= styledText.getTextBounds(start, end - 1);
else {
Point loc= styledText.getLocationAtOffset(start);
bounds= new Rectangle(loc.x, loc.y, getAverageCharWidth(textViewer.getTextWidget()),
computeLineHeight(styledText, styledText.getLineAtOffset(start)));
}
return new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height);
}
/**
* Translates a given region of the text viewer's document into
* the corresponding region of the viewer's widget.
*
* @param region the document region
* @param textViewer the viewer containing the region
* @return the corresponding widget region
*
* @since 3.4
*/
private static IRegion modelRange2WidgetRange(IRegion region, ITextViewer textViewer) {
if (textViewer instanceof ITextViewerExtension5) {
ITextViewerExtension5 extension= (ITextViewerExtension5) textViewer;
return extension.modelRange2WidgetRange(region);
}
IRegion visibleRegion= textViewer.getVisibleRegion();
int start= region.getOffset() - visibleRegion.getOffset();
int end= start + region.getLength();
if (end > visibleRegion.getLength())
end= visibleRegion.getLength();
return new Region(start, end - start);
}
/**
* Returns the average character width of the given control's font.
*
* @param control the control to calculate the average char width for
* @return the average character width of the controls font
*
* @since 3.4
*/
public static int getAverageCharWidth(Control control) {
GC gc= new GC(control);
gc.setFont(control.getFont());
int increment= gc.getFontMetrics().getAverageCharWidth();
gc.dispose();
return increment;
}
/**
* Returns true
if the text covered by selection
does not contain any
* characters in the given viewer. Note the difference to {@link ITextSelection#isEmpty()},
* which returns true
only for invalid selections.
*
* @param viewer the viewer
* @param selection the selection
* @return true
if selection
does not contain any text,
* false
otherwise
* @throws BadLocationException if accessing the document failed
* @since 3.5
*/
public static boolean isEmpty(ITextViewer viewer, ITextSelection selection) throws BadLocationException {
return new SelectionProcessor(viewer).isEmpty(selection);
}
/**
* Returns the text regions covered by the given selection in the given viewer.
*
* @param viewer the viewer
* @param selection the selection
* @return the text regions corresponding to selection
* @throws BadLocationException if accessing the document failed
* @since 3.5
*/
public static IRegion[] getCoveredRanges(ITextViewer viewer, ITextSelection selection) throws BadLocationException {
return new SelectionProcessor(viewer).getRanges(selection);
}
/**
* Returns the offset in the given viewer that corresponds to the current cursor location.
*
* @param viewer the viewer
* @return the offset for the current cursor location or -1 if not available
* @since 3.5
*/
public static int getOffsetForCursorLocation(ITextViewer viewer) {
try {
StyledText text= viewer.getTextWidget();
if (text == null || text.isDisposed())
return -1;
Display display= text.getDisplay();
Point absolutePosition= display.getCursorLocation();
Point relativePosition= text.toControl(absolutePosition);
int widgetOffset= text.getOffsetAtLocation(relativePosition);
Point p= text.getLocationAtOffset(widgetOffset);
if (p.x > relativePosition.x)
widgetOffset--;
if (viewer instanceof ITextViewerExtension5) {
ITextViewerExtension5 extension= (ITextViewerExtension5)viewer;
return extension.widgetOffset2ModelOffset(widgetOffset);
}
return widgetOffset + viewer.getVisibleRegion().getOffset();
} catch (IllegalArgumentException e) {
return -1;
}
}
}