--- CLabel.java 2012-02-01 15:39:40.000000000 +0100 +++ CLabel.ellipsis.java 2012-05-31 10:25:31.620676907 +0200 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 IBM Corporation and others. + * Copyright (c) 2000, 2012 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 @@ -50,7 +50,7 @@ /** Left and right margins */ private static final int DEFAULT_MARGIN = 3; /** a string inserted in the middle of text that has been shortened */ - private static final String ELLIPSIS = "..."; //$NON-NLS-1$ // could use the ellipsis glyph on some platforms "\u2026" + private static final String DEFAULT_ELLIPSIS = "..."; //$NON-NLS-1$ // could use the ellipsis glyph on some platforms "\u2026" /** the alignment. Either CENTER, RIGHT, LEFT. Default is LEFT*/ private int align = SWT.LEFT; private int leftMargin = DEFAULT_MARGIN; @@ -75,6 +75,9 @@ private boolean gradientVertical; private Color background; + private String ellipsis = DEFAULT_ELLIPSIS; + private int ellipsisAlign = SWT.CENTER; + private static int DRAW_FLAGS = SWT.DRAW_MNEMONIC | SWT.DRAW_TAB | SWT.DRAW_TRANSPARENT | SWT.DRAW_DELIMITER; /** @@ -222,6 +225,26 @@ return bottomMargin; } /** + * Return the CLabel's ellipsis. + * + * @return the current ellipsis + * + * @since TDB + */ +public String getEllipsis() { + return ellipsis; +} +/** + * Return the CLabel's ellipsis alignment. + * + * @return the current ellipsis alignment + * + * @since TDB + */ +public int getEllipsisAligment() { + return ellipsisAlign; +} +/** * Return the CLabel's image or null. * * @return the image of the label or null @@ -800,6 +823,58 @@ this.bottomMargin = bottomMargin; redraw(); } +/** + * Set the label's ellipsis + * + * @param ellipsis the ellipsis to use instead of the {@link #DEFAULT_ELLIPSIS} + * + * @exception SWTException + * + * @since TBD + */ +public void setEllipsis (String ellipsis) { + checkWidget (); + this.ellipsis = ellipsis; + redraw(); +} +/** + * Set the alignment of the ellipsis. + *

Use the values LEFT, CENTER, RIGHT, BEGINNING or END to align the ellipsis in the text.

+ *

BEGINNING and END are mapped to LEFT and RIGHT according to the current LEFT_TO_RIGHT and RIGHT_TO_LEFT style.

+ * + * @param align the alignment style of LEFT, RIGHT, CENTER, BEGINNING or END + * + * @exception SWTException + * + * @since TBD + */ +public void setEllipsisAlignment(int ellipsisAlign) { + checkWidget(); + if (ellipsisAlign != SWT.LEFT && ellipsisAlign != SWT.RIGHT && ellipsisAlign != SWT.CENTER && ellipsisAlign != SWT.BEGINNING && ellipsisAlign != SWT.END) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + + // correct left/right + if ( ellipsisAlign == SWT.BEGINNING ) { + ellipsisAlign = ( getStyle () & SWT.RIGHT_TO_LEFT ) != 0 ? SWT.RIGHT : SWT.LEFT; + } + else if ( ellipsisAlign == SWT.END ) { + ellipsisAlign = ( getStyle () & SWT.RIGHT_TO_LEFT ) != 0 ? SWT.LEFT : SWT.RIGHT; + } + + if (this.ellipsisAlign != ellipsisAlign) { + this.ellipsisAlign = ellipsisAlign; + redraw(); + } +} public void setFont(Font font) { super.setFont(font); redraw(); @@ -944,40 +1019,83 @@ */ protected String shortenText(GC gc, String t, int width) { if (t == null) return null; - int w = gc.textExtent(ELLIPSIS, DRAW_FLAGS).x; + int w = gc.textExtent(this.ellipsis, DRAW_FLAGS).x; if (width<=w) return t; - int l = t.length(); - int max = l/2; - int min = 0; - int mid = (max+min)/2 - 1; - if (mid <= 0) return t; - TextLayout layout = new TextLayout (getDisplay()); - layout.setText(t); - mid = validateOffset(layout, mid); - while (min < mid && mid < max) { - String s1 = t.substring(0, mid); - String s2 = t.substring(validateOffset(layout, l-mid), l); - int l1 = gc.textExtent(s1, DRAW_FLAGS).x; - int l2 = gc.textExtent(s2, DRAW_FLAGS).x; - if (l1+w+l2 > width) { - max = mid; - mid = validateOffset(layout, (max+min)/2); - } else if (l1+w+l2 < width) { - min = mid; - mid = validateOffset(layout, (max+min)/2); - } else { - min = max; - } - } - String result = mid == 0 ? t : t.substring(0, mid) + ELLIPSIS + t.substring(validateOffset(layout, l-mid), l); - layout.dispose(); - return result; + switch ( ellipsisAlign ) { + case SWT.LEFT: + return beginShortenText(gc, t, width, w); + case SWT.RIGHT: + return endShortenText(gc, t, width, w); + case SWT.CENTER: + //$FALL-THROUGH$ + default: + return centerShortenText(gc, t, width, w); + } +} +protected String beginShortenText(GC gc, String t, int width, int w) { + TextLayout layout = new TextLayout (getDisplay()); + layout.setText(t); + + String result = t; + int len = gc.textExtent(result, DRAW_FLAGS).x; + while ( len + w > width && result.length () > 0 ) { + result = result.substring ( validateOffsetInverse ( layout, 1 ) ); + len = gc.textExtent(result, DRAW_FLAGS).x; + } + layout.dispose(); + return ellipsis + result; +} +protected String endShortenText(GC gc, String t, int width, int w) { + TextLayout layout = new TextLayout (getDisplay()); + layout.setText(t); + + String result = t; + int len = gc.textExtent(result, DRAW_FLAGS).x; + while ( len + w > width && result.length () > 0 ) { + result = result.substring ( 0, validateOffset ( layout, result.length () - 1 ) ); + len = gc.textExtent(result, DRAW_FLAGS).x; + } + layout.dispose(); + return result + ellipsis; +} +protected String centerShortenText(GC gc, String t, int width, int w) { + int l = t.length(); + int max = l/2; + int min = 0; + int mid = (max+min)/2 - 1; + if (mid <= 0) return t; + TextLayout layout = new TextLayout (getDisplay()); + layout.setText(t); + mid = validateOffset(layout, mid); + while (min < mid && mid < max) { + String s1 = t.substring(0, mid); + String s2 = t.substring(validateOffset(layout, l-mid), l); + int l1 = gc.textExtent(s1, DRAW_FLAGS).x; + int l2 = gc.textExtent(s2, DRAW_FLAGS).x; + if (l1+w+l2 > width) { + max = mid; + mid = validateOffset(layout, (max+min)/2); + } else if (l1+w+l2 < width) { + min = mid; + mid = validateOffset(layout, (max+min)/2); + } else { + min = max; + } + } + String result = mid == 0 ? t : t.substring(0, mid) + this.ellipsis + t.substring(validateOffset(layout, l-mid), l); + layout.dispose(); + return result; } int validateOffset(TextLayout layout, int offset) { int nextOffset = layout.getNextOffset(offset, SWT.MOVEMENT_CLUSTER); if (nextOffset != offset) return layout.getPreviousOffset(nextOffset, SWT.MOVEMENT_CLUSTER); return offset; } +int validateOffsetInverse(TextLayout layout, int offset) { + int previousOffset = layout.getPreviousOffset(offset, SWT.MOVEMENT_CLUSTER); + if (previousOffset != offset) return layout.getNextOffset(previousOffset, SWT.MOVEMENT_CLUSTER); + return offset; +} private String[] splitString(String text) { String[] lines = new String[1]; int start = 0, pos;