### Eclipse Workspace Patch 1.0 #P org.eclipse.jface.snippets Index: Eclipse JFace Snippets/org/eclipse/jface/snippets/viewers/Snippet049StyledCellLabelProvider.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jface.snippets/Eclipse JFace Snippets/org/eclipse/jface/snippets/viewers/Snippet049StyledCellLabelProvider.java,v retrieving revision 1.4 diff -u -r1.4 Snippet049StyledCellLabelProvider.java --- Eclipse JFace Snippets/org/eclipse/jface/snippets/viewers/Snippet049StyledCellLabelProvider.java 24 Apr 2008 16:24:14 -0000 1.4 +++ Eclipse JFace Snippets/org/eclipse/jface/snippets/viewers/Snippet049StyledCellLabelProvider.java 27 Nov 2008 18:09:50 -0000 @@ -22,14 +22,19 @@ import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerCell; +import org.eclipse.jface.viewers.StyledString.Styler; import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.graphics.TextStyle; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; @@ -41,14 +46,12 @@ private static final int SHELL_WIDTH= 400; - private static final Display DISPLAY= Display.getDefault(); - public static void main(String[] args) { - + Display display = new Display(); JFaceResources.getColorRegistry().put(JFacePreferences.COUNTER_COLOR, new RGB(0,127,174)); - Shell shell= new Shell(DISPLAY, SWT.CLOSE | SWT.RESIZE); + Shell shell= new Shell(display, SWT.CLOSE | SWT.RESIZE); shell.setSize(SHELL_WIDTH, 400); shell.setLayout(new GridLayout(1, false)); @@ -59,11 +62,11 @@ shell.open(); while (!shell.isDisposed()) { - if (!DISPLAY.readAndDispatch()) { - DISPLAY.sleep(); + if (!display.readAndDispatch()) { + display.sleep(); } } - DISPLAY.dispose(); + display.dispose(); } public Snippet049StyledCellLabelProvider() { @@ -77,12 +80,15 @@ Label label= new Label(composite, SWT.NONE); label.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); label.setText("Viewer with a StyledCellLabelProvider:"); //$NON-NLS-1$ - - ExampleLabelProvider labelProvider= new ExampleLabelProvider(); - FileSystemContentProvider contentProvider= new FileSystemContentProvider(); final TableViewer tableViewer= new TableViewer(composite, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); + FontData[] boldFontData= getModifiedFontData(tableViewer.getTable().getFont().getFontData(), SWT.BOLD); + + Font boldFont = new Font(Display.getCurrent(), boldFontData); + ExampleLabelProvider labelProvider= new ExampleLabelProvider(boldFont); + FileSystemContentProvider contentProvider= new FileSystemContentProvider(); + tableViewer.setContentProvider(contentProvider); tableViewer.setLabelProvider(labelProvider); @@ -93,14 +99,29 @@ return composite; } + private static FontData[] getModifiedFontData(FontData[] originalData, int additionalStyle) { + FontData[] styleData = new FontData[originalData.length]; + for (int i = 0; i < styleData.length; i++) { + FontData base = originalData[i]; + styleData[i] = new FontData(base.getName(), base.getHeight(), base.getStyle() | additionalStyle); + } + return styleData; + } + private static class ExampleLabelProvider extends StyledCellLabelProvider { private static int IMAGE_SIZE= 16; - private static final Image IMAGE1= new Image(DISPLAY, DISPLAY.getSystemImage(SWT.ICON_WARNING).getImageData().scaledTo(IMAGE_SIZE, IMAGE_SIZE)); - private static final Image IMAGE2= new Image(DISPLAY, DISPLAY.getSystemImage(SWT.ICON_ERROR).getImageData().scaledTo(IMAGE_SIZE, IMAGE_SIZE)); + private static final Image IMAGE1= new Image(Display.getCurrent(), Display.getCurrent().getSystemImage(SWT.ICON_WARNING).getImageData().scaledTo(IMAGE_SIZE, IMAGE_SIZE)); + private static final Image IMAGE2= new Image(Display.getCurrent(), Display.getCurrent().getSystemImage(SWT.ICON_ERROR).getImageData().scaledTo(IMAGE_SIZE, IMAGE_SIZE)); + private final Styler fBoldStyler; - public ExampleLabelProvider() { + public ExampleLabelProvider(final Font boldFont) { + fBoldStyler= new Styler() { + public void applyStyles(TextStyle textStyle) { + textStyle.font= boldFont; + } + }; } public void update(ViewerCell cell) { @@ -109,7 +130,8 @@ if (element instanceof File) { File file= (File) element; - StyledString styledString= new StyledString(file.getName()); + Styler style= file.isDirectory() ? fBoldStyler: null; + StyledString styledString= new StyledString(file.getName(), style); String decoration = MessageFormat.format(" ({0} bytes)", new Object[] { new Long(file.length()) }); //$NON-NLS-1$ styledString.append(decoration, StyledString.COUNTER_STYLER); @@ -127,6 +149,12 @@ super.update(cell); } + + protected void measure(Event event, Object element) { + System.out.println("measure native: " + event.width); + super.measure(event, element); + System.out.println("measure custom: " + event.width); + } } private static class FileSystemContentProvider implements IStructuredContentProvider { #P org.eclipse.jface Index: src/org/eclipse/jface/viewers/StyledCellLabelProvider.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jface/src/org/eclipse/jface/viewers/StyledCellLabelProvider.java,v retrieving revision 1.4 diff -u -r1.4 StyledCellLabelProvider.java --- src/org/eclipse/jface/viewers/StyledCellLabelProvider.java 24 Apr 2008 16:24:13 -0000 1.4 +++ src/org/eclipse/jface/viewers/StyledCellLabelProvider.java 27 Nov 2008 18:09:51 -0000 @@ -21,6 +21,7 @@ import org.eclipse.swt.graphics.TextLayout; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Widget; /** * A {@link StyledCellLabelProvider} supports styled labels by using owner @@ -37,14 +38,6 @@ * {@link ViewerCell#setStyleRanges(StyleRange[])} to set style ranges * on the label. *

- *

- * The current version of the {@link StyledCellLabelProvider} will ignore all font settings on - * {@link StyleRange}. Different fonts would make labels wider, and the native - * selection drawing could not be reused. - *

- * - *

NOTE: This API is experimental and may be deleted or - * changed before 3.4 is released.

* * @since 3.4 */ @@ -75,6 +68,9 @@ private ColumnViewer viewer; private ViewerColumn column; + + private Widget itemOfLastMeasure; + private int deltaOfLastMeasure; /** * Creates a new StyledCellLabelProvider. By default, owner draw is enabled, focus is drawn and no @@ -200,8 +196,6 @@ int orientation = viewer.getControl().getStyle() & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT); cachedTextLayout = new TextLayout(display); cachedTextLayout.setOrientation(orientation); - } else { - cachedTextLayout.setText(""); // make sure no previous ranges are cleared //$NON-NLS-1$ } return cachedTextLayout; } @@ -215,37 +209,6 @@ return (event.detail & SWT.FOCUSED) != 0 && (this.style & NO_FOCUS) == 0; } - - /** - * Returns a {@link TextLayout} instance for the given cell - * configured with the style ranges. The text layout instance is managed by - * the label provider. Caller of the method must not dispose the text - * layout. - * - * @param diplay - * the current display - * @param applyColors - * if set, create colors in the result - * @param cell - * the viewer cell - * @return a TextLayout instance - */ - private TextLayout getTextLayoutForInfo(Display display, ViewerCell cell, boolean applyColors) { - TextLayout layout = getSharedTextLayout(display); - - layout.setText(cell.getText()); - layout.setFont(cell.getFont()); // set also if null to clear previous usages - - StyleRange[] styleRanges = cell.getStyleRanges(); - if (styleRanges != null) { // user didn't fill styled ranges - for (int i = 0; i < styleRanges.length; i++) { - StyleRange curr = prepareStyleRange(styleRanges[i], applyColors); - layout.setStyle(curr, curr.start, curr.start + curr.length - 1); - } - } - - return layout; - } /** * Prepares the given style range before it is applied to the label. This method makes sure that @@ -263,10 +226,8 @@ protected StyleRange prepareStyleRange(StyleRange styleRange, boolean applyColors) { // if no colors apply or font is set, create a clone and clear the // colors and font - if (styleRange.font != null || !applyColors - && (styleRange.foreground != null || styleRange.background != null)) { + if (!applyColors && (styleRange.foreground != null || styleRange.background != null)) { styleRange = (StyleRange) styleRange.clone(); - styleRange.font = null; // ignore font settings until bug 168807 is resolved if (!applyColors) { styleRange.foreground = null; styleRange.background = null; @@ -305,7 +266,53 @@ * java.lang.Object) */ protected void measure(Event event, Object element) { - // use native measuring + if (!isOwnerDrawEnabled()) + return; + + ViewerCell cell= getViewerCell(event, element); + boolean applyColors = useColors(event); // returns false because of bug 228376 + + TextLayout layout = getSharedTextLayout(event.display); + + int textWidthDelta = deltaOfLastMeasure = updateTextLayout(layout, cell, applyColors); + /* remove-begin if bug 228695 fixed */ + itemOfLastMeasure = event.item; + /* remove-end if bug 228695 fixed */ + + event.width += textWidthDelta; + } + + /** + * @param layout + * @param cell + * @param applyColors + * @return the text width delta (0 if the text layout contains no other font) + */ + private int updateTextLayout(TextLayout layout, ViewerCell cell, + boolean applyColors) { + layout.setText(""); //$NON-NLS-1$ //make sure all previous ranges are cleared (see bug 226090) + + layout.setText(cell.getText()); + layout.setFont(cell.getFont()); // set also if null to clear previous usages + + int originalTextWidth = layout.getBounds().width; // text width without any styles + boolean containsOtherFont= false; + + StyleRange[] styleRanges = cell.getStyleRanges(); + if (styleRanges != null) { // user didn't fill styled ranges + for (int i = 0; i < styleRanges.length; i++) { + StyleRange curr = prepareStyleRange(styleRanges[i], applyColors); + layout.setStyle(curr, curr.start, curr.start + curr.length - 1); + if (curr.font != null) { + containsOtherFont= true; + } + } + } + int textWidthDelta = 0; + if (containsOtherFont) { + textWidthDelta = layout.getBounds().width - originalTextWidth; + } + return textWidthDelta; } /* @@ -321,6 +328,7 @@ ViewerCell cell= getViewerCell(event, element); boolean applyColors = useColors(event); + GC gc = event.gc; // remember colors to restore the GC later Color oldForeground = gc.getForeground(); @@ -337,7 +345,6 @@ gc.setBackground(background); } } - Image image = cell.getImage(); if (image != null) { Rectangle imageBounds = cell.getImageBounds(); @@ -353,10 +360,31 @@ } } - TextLayout textLayout = getTextLayoutForInfo(event.display, cell, applyColors); - Rectangle textBounds = cell.getTextBounds(); if (textBounds != null) { + TextLayout textLayout= getSharedTextLayout(event.display); + + /* remove-begin if bug 228695 fixed */ + if (event.item != itemOfLastMeasure) { + // fLayout has not been configured in 'measure()' + deltaOfLastMeasure = updateTextLayout(textLayout, cell, applyColors); + itemOfLastMeasure = event.item; + } + /* remove-end if bug 228695 fixed */ + + /* remove-begin if bug 228376 fixed */ + if (!applyColors) { + // need to remove colors for selected elements: measure doesn't provide that information, see bug 228376 + StyleRange[] styleRanges= cell.getStyleRanges(); + if (styleRanges != null) { + for (int i= 0; i < styleRanges.length; i++) { + StyleRange curr = prepareStyleRange(styleRanges[i], applyColors); + textLayout.setStyle(curr, curr.start, curr.start + curr.length - 1); + } + } + } + /* remove-end if bug 228376 fixed */ + Rectangle layoutBounds = textLayout.getBounds(); int x = textBounds.x; @@ -368,7 +396,7 @@ if (drawFocus(event)) { Rectangle focusBounds = cell.getViewerRow().getBounds(); - gc.drawFocus(focusBounds.x, focusBounds.y, focusBounds.width, + gc.drawFocus(focusBounds.x, focusBounds.y, focusBounds.width + deltaOfLastMeasure, focusBounds.height); } Index: src/org/eclipse/jface/preference/PreferenceManager.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jface/src/org/eclipse/jface/preference/PreferenceManager.java,v retrieving revision 1.15 diff -u -r1.15 PreferenceManager.java --- src/org/eclipse/jface/preference/PreferenceManager.java 10 Mar 2008 03:47:54 -0000 1.15 +++ src/org/eclipse/jface/preference/PreferenceManager.java 27 Nov 2008 18:09:51 -0000 @@ -12,6 +12,8 @@ package org.eclipse.jface.preference; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; import java.util.List; import java.util.StringTokenizer; @@ -129,6 +131,7 @@ sequence.add(node); } IPreferenceNode[] subnodes = node.getSubNodes(); + sort(subnodes); for (int i = 0; i < subnodes.length; i++) { buildSequence(subnodes[i], sequence, order); } @@ -189,6 +192,8 @@ "invalid traversal order");//$NON-NLS-1$ ArrayList sequence = new ArrayList(); IPreferenceNode[] subnodes = getRoot().getSubNodes(); + sort(subnodes); + for (int i = 0; i < subnodes.length; i++) { buildSequence(subnodes[i], sequence, order); } @@ -196,6 +201,26 @@ } /** + * Sorts the given nodes by ID. This is required because we no longer + * populate this manager with a sorted list of elements. This is to provide + * backwards compatability in {@link #getElements(int)}. + * + * @param nodes + * the nodes to sort. + * @since 3.4 + */ + private void sort(IPreferenceNode[] nodes) { + Arrays.sort(nodes, new Comparator() { + + public int compare(Object o1, Object o2) { + IPreferenceNode n1 = (IPreferenceNode) o1; + IPreferenceNode n2 = (IPreferenceNode) o2; + return n1.getLabelText().compareTo(n2.getLabelText()); + } + }); + } + + /** * Returns the root node. * Note that the root node is a special internal node * that is used to collect together all the nodes that