### Eclipse Workspace Patch 1.0
#P org.eclipse.jface.snippets
Index: Eclipse JFace Snippets/org/eclipse/jface/snippets/viewers/Snippet042StyledMultiLineLabelSupport.java
===================================================================
RCS file: Eclipse JFace Snippets/org/eclipse/jface/snippets/viewers/Snippet042StyledMultiLineLabelSupport.java
diff -N Eclipse JFace Snippets/org/eclipse/jface/snippets/viewers/Snippet042StyledMultiLineLabelSupport.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Eclipse JFace Snippets/org/eclipse/jface/snippets/viewers/Snippet042StyledMultiLineLabelSupport.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,257 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Michael Krkoska 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:
+ * Michael Krkoska - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jface.snippets.viewers;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.ColumnPixelData;
+import org.eclipse.jface.viewers.ColumnViewer;
+import org.eclipse.jface.viewers.StyledCellLabelProvider;
+import org.eclipse.jface.viewers.StyledLabelSupport;
+import org.eclipse.jface.viewers.StyledMultiLineLabelSupport;
+import org.eclipse.jface.viewers.TableLayout;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyleRange;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+
+/**
+ * A TableViewer using a StyledMultiLineLabelSupport to show some of the
+ * posibilities:
+ *
+ * - placing the image provided by the label provider anywhere in the label
+ * - multi-line labels (currently only by placing line breaks in the label)
+ * - multi font labels
+ * - multi colored labels
+ *
+ *
+ * @author Michael Krkoska
+ */
+public class Snippet042StyledMultiLineLabelSupport {
+
+ private static final String[] TEXT = new String[] {
+ "TextStyle defines a set of styles that can be\n" + "applied to a range of text. The hashCode() method\n"
+ + "in this class uses the values of the public fields to",
+ "compute the hash value.\uFFFC When storing instances\n" + "of the class in hashed collections do not modify\n"
+ + "these fields after the object has been inserted.",
+ "Application code does not need to explicitly\n" + "release the resources managed and thus no\n" + "dispose() method is provided.\uFFFC", };
+ private static final Pattern METHODS = Pattern.compile("\\w+\\(\\)");
+ private static final int SHELL_WIDTH = 640;
+ private static final Display DISPLAY = Display.getDefault();
+ 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));
+
+ public static void main( String[] args ) {
+
+ Shell shell = new Shell(DISPLAY, SWT.CLOSE);
+ shell.setSize(SHELL_WIDTH, 300);
+ shell.setLayout(new GridLayout(2, false));
+
+ Snippet042StyledMultiLineLabelSupport example = new Snippet042StyledMultiLineLabelSupport();
+ example.createPartControl(shell);
+
+ shell.open();
+
+ while ( !shell.isDisposed() ) {
+ if ( !DISPLAY.readAndDispatch() ) {
+ DISPLAY.sleep();
+ }
+ }
+ DISPLAY.dispose();
+ }
+
+ private TableViewer viewer;
+
+ private Text text;
+
+ public Snippet042StyledMultiLineLabelSupport() {
+ int defaultSize = JFaceResources.getDefaultFontDescriptor().getFontData()[0].getHeight();
+ JFaceResources.getFontRegistry().put("Courier", new FontData[] { new FontData("Courier New", defaultSize, SWT.NORMAL) });
+ FontData[] fontData = JFaceResources.getFontRegistry().defaultFontDescriptor().getFontData();
+ fontData[0].setHeight(fontData[0].getHeight() + 2);
+ JFaceResources.getFontRegistry().put("BiggerDefault", fontData);
+ }
+
+ public void createPartControl( Composite parent ) {
+ Label label = new Label(parent, SWT.NONE);
+ label.setText("type something here:");
+
+ text = new Text(parent, SWT.NONE);
+ text.setText("hash");
+ text.setSelection(0, 4);
+ text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ text.addListener(SWT.Modify, new Listener() {
+
+ public void handleEvent( Event event ) {
+ viewer.refresh();
+ }
+ });
+
+ // SWT.FULL_SELECTION is needed on win32 as long as Bug 168807 exists
+ viewer = new TableViewer(parent, SWT.FULL_SELECTION);
+
+ GridData data = new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.FILL_BOTH);
+ data.horizontalSpan = 2;
+ viewer.getControl().setLayoutData(data);
+
+ viewer.setContentProvider(new ArrayContentProvider());
+ createColumns();
+
+ StyledMultiLineLabelSupport.setUpMultiLineLabelSupport(viewer);
+ viewer.setInput(TEXT);
+ }
+
+ private void createColumns() {
+ TableLayout layout = new TableLayout();
+ viewer.getTable().setLayout(layout);
+ viewer.getTable().setHeaderVisible(true);
+ viewer.getTable().setLinesVisible(true);
+
+ int width = SHELL_WIDTH - 2 * 5 - viewer.getTable().getShell().computeTrim(0, 0, 0, 0).width;
+ int width1 = width / 2;
+ int width2 = width - width1;
+
+ TableViewerColumn tc = new TableViewerColumn(viewer, SWT.NONE);
+ tc.getColumn().setText("col1");
+ layout.addColumnData(new ColumnPixelData(width1));
+ tc.setLabelProvider(new MyStyleRangeLabelProviderCol1(viewer, new MyStyledFontSupport()));
+
+ tc = new TableViewerColumn(viewer, SWT.NONE);
+ tc.getColumn().setText("col2");
+ layout.addColumnData(new ColumnPixelData(width2));
+ tc.setLabelProvider(new MyStyleRangeLabelProviderCol2(viewer, new MyStyledFontSupport()));
+ }
+
+ private class MyStyledFontSupport extends StyledMultiLineLabelSupport {
+
+ public MyStyledFontSupport() {
+ super(StyledLabelSupport.CENTER_ITEMS_VERTICALLY | StyledLabelSupport.CENTER_TEXT_VERTICALLY);
+ }
+
+ public StyleRange[] getStyleRanges( Object element, String label ) {
+ String searchText = text.getText();
+ TextPresentation tp = new TextPresentation();
+ if ( searchText.length() > 0 ) {
+ Color yellow = text.getDisplay().getSystemColor(SWT.COLOR_YELLOW);
+ int index = -1;
+ while ( (index = label.indexOf(searchText, index + 1)) >= 0 ) {
+ StyleRange styleRange = new StyleRange(index, searchText.length(), null, yellow);
+ tp.mergeStyleRange(styleRange);
+ }
+ }
+
+ Font courier = JFaceResources.getFont("Courier");
+ Matcher matcher = METHODS.matcher(label);
+ while ( matcher.find() ) {
+ StyleRange styleRange = new StyleRange(matcher.start(), matcher.end() - matcher.start(), null, null);
+ styleRange.font = courier;
+ tp.mergeStyleRange(styleRange);
+ }
+
+ List ranges = new ArrayList();
+ for ( Iterator iterator = tp.getAllStyleRangeIterator(); iterator.hasNext(); ) {
+ ranges.add(iterator.next());
+ }
+ return (StyleRange[])ranges.toArray(new StyleRange[ranges.size()]);
+ }
+
+ }
+
+ private final class MyStyleRangeLabelProviderCol1 extends StyledCellLabelProvider {
+
+ private MyStyleRangeLabelProviderCol1( ColumnViewer viewer, StyledLabelSupport fontSupport ) {
+ super(viewer, fontSupport);
+ }
+
+ public Color getBackground( Object element ) {
+ return null;
+ }
+
+ public Font getFont( Object element ) {
+ if ( element == TEXT[0] ) {
+ return JFaceResources.getFont("BiggerDefault");
+ }
+ return null;
+ }
+
+ public Color getForeground( Object element ) {
+ if ( element == TEXT[1] ) {
+ return DISPLAY.getSystemColor(SWT.COLOR_DARK_RED);
+ }
+ return null;
+ }
+
+ public Image getImage( Object element ) {
+ return IMAGE1;
+ }
+
+ public String getText( Object element ) {
+ return element.toString();
+ }
+ }
+
+ private final class MyStyleRangeLabelProviderCol2 extends StyledCellLabelProvider {
+
+ private MyStyleRangeLabelProviderCol2( ColumnViewer viewer, StyledLabelSupport fontSupport ) {
+ super(viewer, fontSupport);
+ }
+
+ public Color getBackground( Object element ) {
+ return null;
+ }
+
+ public Font getFont( Object element ) {
+ if ( element == TEXT[1] ) {
+ return JFaceResources.getFont("BiggerDefault");
+ }
+ return null;
+ }
+
+ public Color getForeground( Object element ) {
+ if ( element == TEXT[2] ) {
+ return DISPLAY.getSystemColor(SWT.COLOR_DARK_RED);
+ }
+ return null;
+ }
+
+ public Image getImage( Object element ) {
+ return IMAGE2;
+ }
+
+ public String getText( Object element ) {
+ return element.toString();
+ }
+ }
+
+}
Index: Eclipse JFace Snippets/org/eclipse/jface/snippets/viewers/Snippet041WrappedStyledCellLabelProvider.java
===================================================================
RCS file: Eclipse JFace Snippets/org/eclipse/jface/snippets/viewers/Snippet041WrappedStyledCellLabelProvider.java
diff -N Eclipse JFace Snippets/org/eclipse/jface/snippets/viewers/Snippet041WrappedStyledCellLabelProvider.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Eclipse JFace Snippets/org/eclipse/jface/snippets/viewers/Snippet041WrappedStyledCellLabelProvider.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Michael Krkoska 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:
+ * Michael Krkoska - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.snippets.viewers;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.ColumnPixelData;
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.OwnerDrawLabelProvider;
+import org.eclipse.jface.viewers.StyledLabelSupport;
+import org.eclipse.jface.viewers.TableLayout;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.jface.viewers.WrappedStyledCellLabelProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyleRange;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+
+/**
+ * A simple TableViewer using a StyledLabelSupport to color a part of the label.
+ * To show how to re-use existing label providers, a WrappedStyledCellLabelProvider
+ * is used instead of the preferable StyledCellLabelProviders.
+ *
+ * @author Michael Krkoska
+ */
+public class Snippet041WrappedStyledCellLabelProvider {
+
+ private static final Display DISPLAY = Display.getDefault();
+ private static final Color GREEN = DISPLAY.getSystemColor(SWT.COLOR_DARK_GREEN);
+ private static final Image IMAGE_BIG = DISPLAY.getSystemImage(SWT.ICON_WARNING);
+ private static final Image IMAGE = new Image(DISPLAY, IMAGE_BIG.getImageData().scaledTo(16, 16));
+ private static final Pattern BRACES = Pattern.compile("\\(.*\\)");
+
+ public static void main( String[] args ) {
+
+ Shell shell = new Shell(DISPLAY, SWT.CLOSE);
+ shell.setSize(300, 300);
+ shell.setLayout(new GridLayout());
+
+ Snippet041WrappedStyledCellLabelProvider example = new Snippet041WrappedStyledCellLabelProvider();
+ example.createPartControl(shell);
+
+ shell.open();
+
+ while ( !shell.isDisposed() ) {
+ if ( !DISPLAY.readAndDispatch() ) {
+ DISPLAY.sleep();
+ }
+ }
+ DISPLAY.dispose();
+ }
+
+ private TableViewer viewer;
+
+ public void createPartControl( Composite parent ) {
+ // SWT.FULL_SELECTION is needed on win32 as long as Bug 168807 exists
+ viewer = new TableViewer(parent, SWT.FULL_SELECTION);
+
+ GridData data = new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.FILL_BOTH);
+ viewer.getControl().setLayoutData(data);
+
+ viewer.setContentProvider(new ArrayContentProvider());
+ createColumns();
+
+ OwnerDrawLabelProvider.setUpOwnerDraw(viewer);
+
+ String[] s = new String[10];
+ for ( int i = 0; i < s.length; i++ ) {
+ s[i] = "row " + i + " (green)";
+ }
+ viewer.setInput(s);
+ }
+
+ private void createColumns() {
+ TableLayout layout = new TableLayout();
+ viewer.getTable().setLayout(layout);
+ viewer.getTable().setHeaderVisible(false);
+ viewer.getTable().setLinesVisible(true);
+
+ int width = 300 - 2 * 5 - viewer.getTable().getShell().computeTrim(0, 0, 0, 0).width;
+
+ IBaseLabelProvider labelProvider = new MyStyledLabelProvider();
+
+ TableViewerColumn tc = new TableViewerColumn(viewer, SWT.NONE);
+ tc.getColumn().setText("col1");
+ layout.addColumnData(new ColumnPixelData(width));
+ MyStyledLabelSupport support = new MyStyledLabelSupport();
+ tc.setLabelProvider(new WrappedStyledCellLabelProvider(viewer, support, labelProvider));
+ }
+
+ private final class MyStyledLabelProvider extends LabelProvider {
+
+ public Font getFont( Object element ) {
+ return JFaceResources.getFont("Font");
+ }
+
+ public Image getImage( Object element ) {
+// if(element.toString().startsWith("row 1"))
+// return IMAGE_BIG;
+ if ( !element.toString().startsWith("row 0") ) {
+ return IMAGE;
+ }
+ return null;
+ }
+
+ public String getText( Object element ) {
+ return element == null ? "" : element.toString(); //$NON-NLS-1$
+ }
+ }
+
+ private final class MyStyledLabelSupport extends StyledLabelSupport {
+
+ public MyStyledLabelSupport() {
+ super(StyledLabelSupport.CENTER_ITEMS_VERTICALLY | StyledLabelSupport.CENTER_TEXT_VERTICALLY);
+ }
+
+ public StyleRange[] getStyleRanges( Object element, String label ) {
+ Matcher matcher = BRACES.matcher(label);
+ if ( matcher.find() ) {
+ StyleRange styleRange = new StyleRange(matcher.start(), matcher.end() - matcher.start(), null, null);
+ styleRange.foreground = GREEN;
+ return new StyleRange[] { styleRange };
+ }
+ return null;
+ }
+
+ }
+
+}
#P org.eclipse.jface
Index: src/org/eclipse/jface/viewers/StyledLabelSupport.java
===================================================================
RCS file: src/org/eclipse/jface/viewers/StyledLabelSupport.java
diff -N src/org/eclipse/jface/viewers/StyledLabelSupport.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/jface/viewers/StyledLabelSupport.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,339 @@
+package org.eclipse.jface.viewers;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyleRange;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Device;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.FontMetrics;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.GlyphMetrics;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.graphics.TextLayout;
+import org.eclipse.swt.graphics.TextStyle;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+
+
+/**
+ * @since 3.4
+ *
+ */
+public abstract class StyledLabelSupport {
+
+ /**
+ * This is the char which can be used as placeholder for an image in the
+ * label.
+ */
+ public static final char IMAGE_PLACEHOLDER = '\uFFFC';
+
+ /**
+ * Style constant for centering the viewer's items vertically if their
+ * heights are less than the maximum vertical height.
+ */
+ public static final int CENTER_ITEMS_VERTICALLY = 1;
+ /**
+ * Style constant for centering the text of a viewer's item vertically if
+ * its height is less than the height of the item's image.
+ */
+ public static final int CENTER_TEXT_VERTICALLY = 2;
+
+ boolean centerItemsVertically = false;
+ boolean centerTextVertically = false;
+
+ private Map styledFonts = new HashMap();
+
+ /**
+ * Creates a new StyledLabelSupport.
+ *
+ * @param style
+ * the style bits
+ * @see StyledLabelSupport#CENTER_ITEMS_VERTICALLY
+ * @see StyledLabelSupport#CENTER_TEXT_VERTICALLY
+ */
+ public StyledLabelSupport( int style ) {
+ if ( (CENTER_ITEMS_VERTICALLY & style) != 0 ) {
+ centerItemsVertically = true;
+ }
+ if ( (CENTER_TEXT_VERTICALLY & style) != 0 ) {
+ centerTextVertically = true;
+ }
+ }
+
+ /**
+ * Dispose any resources acquired during usage. The instance stays usable.
+ *
+ * More specifically: Styled fonts are created if needed and these have to be disposed again.
+ *
+ * This method is called automatically if a StyledCellLabelProvider's viewer is disposed.
+ */
+ public void dispose() {
+ for ( Iterator iterator = styledFonts.values().iterator(); iterator.hasNext(); ) {
+ Font f = (Font)iterator.next();
+ f.dispose();
+ }
+ styledFonts.clear();
+ }
+
+ /**
+ * Returns an array of StyleRange instances which are to be applied to the
+ * label.
+ *
+ * @param element
+ * The element whose label is going to be displayed
+ * @param label
+ * The label for which to provide the StyleRanges
+ * @return An array of StyleRange instances, may be null if no styles are to
+ * be applied for this label.
+ */
+ public abstract StyleRange[] getStyleRanges( Object element, String label );
+
+ /**
+ * Creates a TextLayout instance for either measuring or painting the item,
+ * using the StyleRanges supplied by
+ * {@link StyledLabelSupport#getStyleRanges(Object, String)}.
+ *
+ * Adds an image at the first occurence of
+ * {@link StyledLabelSupport#IMAGE_PLACEHOLDER} or at the beginning of the
+ * label.
+ *
+ * @param event
+ * the measure or paint event for which a TextLayout is needed
+ * @param label
+ * the label to display.
+ * @param image
+ * the image to display. May be null.
+ * @param defaultFont
+ * the default font for the label. If null the system default
+ * font is used.
+ * @param defaultBackground
+ * the default background color. May be null.
+ * @param element
+ * the model element used to obtain label and styles.
+ * @return a TextLayout instance which must be disposed after use.
+ */
+ protected TextLayout createTextLayout( Event event, String label, Image image, Font defaultFont, Color defaultBackground, Object element ) {
+
+ Display display = event.display;
+ TextLayout layout = new TextLayout(display);
+
+ int maxFontHeight = 0;
+ if ( defaultFont != null ) {
+ layout.setFont(defaultFont);
+ maxFontHeight = getFontHeight(defaultFont);
+ }
+ else {
+ maxFontHeight = getFontHeight(display.getSystemFont());
+ }
+
+ int rangeOffset = 0, imageOffset = 0;
+ GlyphMetrics imageMetrics = null;
+ TextStyle imageStyle = null;
+ if ( image != null ) {
+ int index = label.indexOf(IMAGE_PLACEHOLDER);
+ String labelWithImage = label;
+ if ( index < 0 ) {
+ labelWithImage = IMAGE_PLACEHOLDER + " " + label; //$NON-NLS-1$
+ rangeOffset = 2;
+ }
+ layout.setText(labelWithImage);
+ imageOffset = Math.max(0, index);
+ Rectangle bounds = image.getBounds();
+ imageStyle = new TextStyle(null, null, null);
+ imageMetrics = new GlyphMetrics(bounds.height, 0, bounds.width);
+ imageStyle.metrics = imageMetrics;
+ }
+ else {
+ layout.setText(label);
+ }
+
+ StyleRange[] styleRanges = getStyleRanges(element, label);
+ if ( styleRanges != null ) {
+ for ( int i = 0; i < styleRanges.length; i++ ) {
+ StyleRange styleRange = styleRanges[i];
+ checkFont(display, styleRange);
+ layout.setStyle(styleRange, styleRange.start + rangeOffset, styleRange.start + rangeOffset + styleRange.length - 1);
+ if ( styleRange.font != null ) {
+ maxFontHeight = Math.max(maxFontHeight, getFontHeight(styleRange.font));
+ }
+ }
+ }
+
+ if ( imageStyle != null ) {
+ layout.setStyle(imageStyle, imageOffset, imageOffset);
+ }
+
+ if ( centerTextVertically && imageMetrics != null ) {
+ int lineCount = layout.getLineCount();
+ if ( lineCount == 1 && imageMetrics.ascent > maxFontHeight ) {
+ // vertically center the text if there is an image bigger than
+ // the text.
+ int height = imageMetrics.ascent;
+ int space = (height - maxFontHeight);
+ imageMetrics.ascent = (maxFontHeight) + Math.round(space / 2f);
+ // TODO why does it look better (at least on win xp) with this
+ // added pixel?
+ layout.setDescent(height - imageMetrics.ascent + 1);
+ }
+
+ }
+
+ if ( defaultBackground != null ) {
+ int[] ranges = layout.getRanges();
+ int oldEnd = -1;
+ TextStyle[] styles = layout.getStyles();
+ for ( int i = 0, length = ranges.length; i < length; i += 2 ) {
+ int start = ranges[i];
+ int end = ranges[i + 1];
+ if ( start > oldEnd + 1 ) {
+ TextStyle style = new TextStyle(null, null, defaultBackground);
+ layout.setStyle(style, oldEnd + 1, start - 1);
+ }
+
+ TextStyle style = styles[i >> 1];
+ if ( style.background == null ) {
+ style.background = defaultBackground;
+ layout.setStyle(style, start, end);
+ }
+
+ oldEnd = end;
+ }
+ if ( layout.getText().length() > oldEnd + 1 ) {
+ TextStyle style = new TextStyle(null, null, defaultBackground);
+ layout.setStyle(style, oldEnd + 1, layout.getText().length() - 1);
+ }
+ }
+
+ return layout;
+ }
+
+ /**
+ * Handle the erase event. The default implementation does nothing to ensure
+ * keep native selection highlighting working.
+ *
+ * @param event
+ * the erase event
+ * @param element
+ * the model object
+ * @see SWT#EraseItem
+ */
+ protected void erase( Event event, Object element ) {
+ event.detail &= ~SWT.FOREGROUND;
+ }
+
+ /**
+ * @param event
+ * @param element
+ * @param viewerLabel
+ */
+ protected void measure( Event event, Object element, ViewerLabel viewerLabel ) {
+ String label = viewerLabel.getText();
+ Image image = viewerLabel.getImage();
+ Font font = viewerLabel.getFont();
+ Color defaultBackground = viewerLabel.getBackground();
+ TextLayout textLayout = createTextLayout(event, label, image, font, defaultBackground, element);
+ Rectangle bounds = textLayout.getBounds();
+ event.setBounds(new Rectangle(0, 0, bounds.width, bounds.height));
+ textLayout.dispose();
+ }
+
+ /**
+ * @param event
+ * @param element
+ * @param viewerLabel
+ */
+ protected void paint( Event event, Object element, ViewerLabel viewerLabel ) {
+ String label = viewerLabel.getText();
+ Image image = viewerLabel.getImage();
+ Font font = viewerLabel.getFont();
+ Color defaultBackground = viewerLabel.getBackground();
+ TextLayout textLayout = createTextLayout(event, label, image, font, defaultBackground, element);
+ GC gc = event.gc;
+ Color oldForeground = gc.getForeground(), oldBackground = gc.getBackground();
+ Color foreground = viewerLabel.getForeground();
+ if ( foreground != null ) {
+ gc.setForeground(foreground);
+ }
+
+ if ( defaultBackground != null ) {
+ gc.setBackground(defaultBackground);
+ }
+
+ int heightOffset = 0;
+ if ( centerItemsVertically ) {
+ heightOffset = (event.height - textLayout.getBounds().height) / 2;
+ heightOffset = Math.max(0, heightOffset);
+ }
+
+ textLayout.draw(gc, event.x, event.y + heightOffset);
+
+ if ( image != null ) {
+ int imageOffset = Math.max(0, label.indexOf(IMAGE_PLACEHOLDER));
+ int lineIndex = textLayout.getLineIndex(imageOffset);
+ FontMetrics lineMetrics = textLayout.getLineMetrics(lineIndex);
+ Point point = textLayout.getLocation(imageOffset, false);
+ GlyphMetrics glyphMetrics = textLayout.getStyle(imageOffset).metrics;
+ int y = event.y + point.y + lineMetrics.getAscent() - glyphMetrics.ascent + heightOffset;
+ // Following line is because of a strange incorrect measurement of 3
+ // pixels under win32 in some cases.
+ y = Math.max(event.y, y);
+ gc.drawImage(image, event.x + point.x, y);
+ }
+ textLayout.dispose();
+
+ gc.setForeground(oldForeground);
+ gc.setBackground(oldBackground);
+ }
+
+ int getFontHeight( Font font ) {
+ int h = 0;
+ FontData[] fontData = font.getFontData();
+ for ( int i = 0; i < fontData.length; i++ ) {
+ h = Math.max(h, (int)fontData[i].height);
+ }
+ return h;
+ }
+
+ private void checkFont( Device device, StyleRange styleRange ) {
+ int fontStyle = styleRange.fontStyle;
+ if ( fontStyle != SWT.NORMAL ) {
+ Font font = styleRange.font;
+ if ( font == null ) {
+ font = JFaceResources.getDefaultFont();
+ }
+ boolean wrongStyle = false;
+ FontData[] fontData = font.getFontData();
+ for ( int i = 0, length = fontData.length; i < length && !wrongStyle; i++ ) {
+ if ( fontData[i].getStyle() != fontStyle ) {
+ wrongStyle = true;
+ }
+ }
+ if ( wrongStyle ) {
+ fontData = getFontData(font, fontStyle);
+ // TODO using fontData[0] as cache key might be wrong on motif
+ Font styledFont = (Font)styledFonts.get(fontData[0]);
+ if ( styledFont == null ) {
+ styledFont = new Font(device, fontData);
+ styledFonts.put(fontData[0], styledFont);
+ }
+ }
+ styleRange.font = font;
+ }
+ }
+
+ private FontData[] getFontData( Font font, int style ) {
+ FontData[] fontDatas = font.getFontData();
+ for ( int i = 0; i < fontDatas.length; i++ ) {
+ fontDatas[i].setStyle(style);
+ }
+ return fontDatas;
+ }
+}
Index: src/org/eclipse/jface/viewers/StyledCellLabelProvider.java
===================================================================
RCS file: src/org/eclipse/jface/viewers/StyledCellLabelProvider.java
diff -N src/org/eclipse/jface/viewers/StyledCellLabelProvider.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/jface/viewers/StyledCellLabelProvider.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,92 @@
+package org.eclipse.jface.viewers;
+
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Event;
+
+
+/**
+ * @since 3.4
+ */
+public class StyledCellLabelProvider extends OwnerDrawLabelProvider implements ILabelProvider, IFontProvider, IColorProvider {
+
+ private ColumnViewer viewer;
+
+ private StyledLabelSupport support;
+
+ /**
+ * @param viewer
+ * @param support
+ */
+ public StyledCellLabelProvider( ColumnViewer viewer, StyledLabelSupport support ) {
+ super();
+ this.viewer = viewer;
+ this.support = support;
+ }
+
+ public void dispose() {
+ super.dispose();
+ support.dispose();
+ }
+
+ public Color getBackground( Object element ) {
+ return null;
+ }
+
+ public Font getFont( Object element ) {
+ return null;
+ }
+
+ public Color getForeground( Object element ) {
+ return null;
+ }
+
+ public Image getImage( Object element ) {
+ return null;
+ }
+
+ public String getText( Object element ) {
+ return ""; //$NON-NLS-1$
+ }
+
+ protected void measure( Event event, Object element ) {
+ int height = event.height;
+ int width = event.width;
+
+ ViewerCell cell = viewer.getViewerRowFromItem(event.item).getCell(event.index);
+
+ ViewerLabel viewerLabel = new ViewerLabel(cell.getText(), cell.getImage());
+ viewerLabel.setImage(getImage(element));
+ viewerLabel.setText(getText(element));
+ viewerLabel.setFont(getFont(element));
+ viewerLabel.setBackground(getBackground(element));
+ viewerLabel.setForeground(getForeground(element));
+ support.measure(event, element, viewerLabel);
+
+ if ( event.height != height || event.width != width ) {
+ // On Carbon the first cell in a Table is not updated properly, if the size changes.
+ Rectangle rect = cell.getBounds();
+ viewer.getControl().redraw(rect.x, rect.y, rect.width, rect.height, true);
+ }
+ }
+
+ protected void paint( Event event, Object element ) {
+ ViewerCell cell = viewer.getViewerRowFromItem(event.item).getCell(event.index);
+
+ ViewerLabel viewerLabel = new ViewerLabel(cell.getText(), cell.getImage());
+ viewerLabel.setImage(getImage(element));
+ viewerLabel.setText(getText(element));
+ viewerLabel.setFont(getFont(element));
+ viewerLabel.setBackground(getBackground(element));
+ viewerLabel.setForeground(getForeground(element));
+
+ support.paint(event, element, viewerLabel);
+ }
+
+ StyledLabelSupport getStyledLabelSupport() {
+ return support;
+ }
+
+}
Index: src/org/eclipse/jface/viewers/WrappedStyledCellLabelProvider.java
===================================================================
RCS file: src/org/eclipse/jface/viewers/WrappedStyledCellLabelProvider.java
diff -N src/org/eclipse/jface/viewers/WrappedStyledCellLabelProvider.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/jface/viewers/WrappedStyledCellLabelProvider.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Michael Krkoska 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:
+ * Michael Krkoska - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jface.viewers;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+
+
+/**
+ * A wrapper for using {@link StyledLabelSupport} with classic label providers implementing any of ILabelProvider,
+ * IFontProvider, IColorProvider or the corresponding table variants.
+ *
+ * The provided color and font information is used as default style for the item.
+ *
+ * @since 3.4
+ * @author Michael Krkoska
+ */
+public class WrappedStyledCellLabelProvider extends StyledCellLabelProvider {
+
+ private ILabelProvider labelProvider;
+ private IFontProvider fontProvider = null;
+ private IColorProvider colorProvider = null;
+ private ITableLabelProvider tableLabelProvider = null;
+ private ITableFontProvider tableFontProvider = null;
+ private ITableColorProvider tableColorProvider = null;
+ private int columnIndex;
+
+ /**
+ * Creates a WrappedStyledCellLabelProvider for usage with a ViewerColumn.
+ *
+ * @param viewer the viewer for this CellLabelProvider
+ * @param support the StyledLabelSupport for providing the item's style
+ * @param labelProvider the label provider implementing ILabelProvider and optionally IFontProvider or IColorProvider
+ */
+ public WrappedStyledCellLabelProvider( ColumnViewer viewer, StyledLabelSupport support, IBaseLabelProvider labelProvider ) {
+ this(viewer, support, labelProvider, 0);
+ }
+
+ /**
+ * Creates a WrappedStyledCellLabelProvider for usage with a ViewerColumn.
+ *
+ * @param viewer the viewer for this CellLabelProvider
+ * @param support the StyledLabelSupport for providing the item's style
+ * @param labelProvider the label provider implementing ILabelProvider and optionally IFontProvider or IColorProvider
+ * @param columnIndex the column index to pass to a wrapped ITable*Provider
+ */
+ public WrappedStyledCellLabelProvider( ColumnViewer viewer, StyledLabelSupport support, IBaseLabelProvider labelProvider, int columnIndex ) {
+ super(viewer, support);
+ this.columnIndex = columnIndex;
+ setLabelProvider(labelProvider);
+ }
+
+ public Color getBackground( Object element ) {
+ if ( tableColorProvider != null ) {
+ return tableColorProvider.getBackground(element, columnIndex);
+ }
+ if ( colorProvider != null && columnIndex == 0 ) {
+ return colorProvider.getBackground(element);
+ }
+ return null;
+ }
+
+ public Font getFont( Object element ) {
+ if ( tableFontProvider != null ) {
+ return tableFontProvider.getFont(element, columnIndex);
+ }
+ if ( fontProvider != null && columnIndex == 0 ) {
+ return fontProvider.getFont(element);
+ }
+ return null;
+ }
+
+ public Color getForeground( Object element ) {
+ if ( tableColorProvider != null ) {
+ return tableColorProvider.getForeground(element, columnIndex);
+ }
+ if ( colorProvider != null && columnIndex == 0 ) {
+ return colorProvider.getForeground(element);
+ }
+ return null;
+ }
+
+ public Image getImage( Object element ) {
+ if ( tableLabelProvider != null ) {
+ return tableLabelProvider.getColumnImage(element, columnIndex);
+ }
+ if ( columnIndex == 0 ) {
+ return labelProvider.getImage(element);
+ }
+ return null;
+ }
+
+ public String getText( Object element ) {
+ if ( tableLabelProvider != null ) {
+ return tableLabelProvider.getColumnText(element, columnIndex);
+ }
+ if ( columnIndex == 0 ) {
+ return labelProvider.getText(element);
+ }
+ return ""; //$NON-NLS-1$
+ }
+
+ private void setLabelProvider( IBaseLabelProvider labelProvider ) {
+ Assert.isTrue(labelProvider instanceof ITableLabelProvider || labelProvider instanceof ILabelProvider);
+ if ( labelProvider instanceof ILabelProvider ) {
+ this.labelProvider = (ILabelProvider)labelProvider;
+ }
+ if ( labelProvider instanceof IFontProvider ) {
+ fontProvider = (IFontProvider)labelProvider;
+ }
+ if ( labelProvider instanceof IColorProvider ) {
+ colorProvider = (IColorProvider)labelProvider;
+ }
+ if ( labelProvider instanceof ITableLabelProvider ) {
+ tableLabelProvider = (ITableLabelProvider)labelProvider;
+ }
+ if ( labelProvider instanceof ITableFontProvider ) {
+ tableFontProvider = (ITableFontProvider)labelProvider;
+ }
+ if ( labelProvider instanceof ITableColorProvider ) {
+ tableColorProvider = (ITableColorProvider)labelProvider;
+ }
+ }
+
+}
Index: src/org/eclipse/jface/viewers/StyledMultiLineLabelSupport.java
===================================================================
RCS file: src/org/eclipse/jface/viewers/StyledMultiLineLabelSupport.java
diff -N src/org/eclipse/jface/viewers/StyledMultiLineLabelSupport.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/jface/viewers/StyledMultiLineLabelSupport.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,307 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Michael Krkoska 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:
+ * Michael Krkoska - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jface.viewers;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.GlyphMetrics;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.TextLayout;
+import org.eclipse.swt.graphics.TextStyle;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeColumn;
+import org.eclipse.swt.widgets.TreeItem;
+
+
+/**
+ * A StyledLabelSupport which supports multiple lines per label.
+ *
+ *
+ * To set up a StyledMultiLineLabelSupport for your viewer's control, you must call
+ * {@link StyledMultiLineLabelSupport#setUpMultiLineLabelSupport(ColumnViewer)}.
+ *
+ * @since 3.4
+ * @author Michael Krkoska
+ */
+public abstract class StyledMultiLineLabelSupport extends StyledLabelSupport {
+
+ /**
+ * Set up the owner draw callbacks for the viewer and enable multi line support for StyledCellLabelProviders.
+ * @param viewer
+ * the viewer the owner draw is set up
+ */
+ public static void setUpMultiLineLabelSupport( final ColumnViewer viewer ) {
+ OwnerDrawLabelProvider.setUpOwnerDraw(viewer);
+
+ Listener l = new Listener() {
+
+ public void handleEvent( Event event ) {
+ ViewerColumn column;
+ int i = 0;
+ while ( (column = viewer.getViewerColumn(i++)) != null ) {
+ CellLabelProvider provider = column.getLabelProvider();
+
+ if ( provider instanceof StyledCellLabelProvider ) {
+ StyledLabelSupport styledLabelSupport = ((StyledCellLabelProvider)provider).getStyledLabelSupport();
+ if ( styledLabelSupport instanceof StyledMultiLineLabelSupport ) {
+ ((StyledMultiLineLabelSupport)styledLabelSupport).columnsResized(event);
+ }
+ }
+ }
+ }
+
+ };
+ if ( viewer.getControl() instanceof Table ) {
+ Table table = (Table)viewer.getControl();
+ TableColumn[] cols = table.getColumns();
+ for ( int i = 0; i < cols.length; i++ ) {
+ cols[i].addListener(SWT.Resize, l);
+ }
+ }
+ else if ( viewer.getControl() instanceof Tree ) {
+ Tree tree = (Tree)viewer.getControl();
+ TreeColumn[] cols = tree.getColumns();
+ for ( int i = 0; i < cols.length; i++ ) {
+ cols[i].addListener(SWT.Resize, l);
+ }
+ }
+ }
+
+ private boolean wrapLines = false;
+ private int measureHeightIndex = -1;
+ private int maxHeight = 0;
+ private int[] knownColumnWidths;
+
+ /**
+ * Creates a new StyledMultiLineLabelSupport.
+ *
+ * @param style
+ * the style bits
+ * @see StyledLabelSupport#CENTER_ITEMS_VERTICALLY
+ * @see StyledLabelSupport#CENTER_TEXT_VERTICALLY
+ */
+ /* @see SWT#WRAP */
+ public StyledMultiLineLabelSupport( int style ) {
+ super(style);
+ if ( (SWT.WRAP & style) != 0 ) {
+ // TODO Wrapping is deactivated as long as either Bug 130024 or Bug 148039 are still existing
+ // wrapLines = true;
+ }
+ }
+
+ protected TextLayout createTextLayout( Event event, String label, Image image, Font defaultFont, Color defaultBackground, Object element ) {
+
+ TextLayout layout = super.createTextLayout(event, label, image, defaultFont, defaultBackground, element);
+
+ if ( centerTextVertically && image != null ) {
+ int imageOffset = Math.max(0, label.indexOf(IMAGE_PLACEHOLDER));
+ GlyphMetrics imageMetrics = layout.getStyle(imageOffset).metrics;
+
+ if ( imageMetrics != null ) {
+ int lineCount = layout.getLineCount();
+ if ( lineCount > 1 ) {
+ // do a different (unfortunately inferior) centering for multiline text
+ // than in the single line case
+ centerMultilineVertically(layout, defaultFont, imageMetrics, imageOffset);
+ }
+ }
+ }
+
+ if ( wrapLines ) {
+ layout.setWidth(Math.max(getItemWidth(event), 16));
+ }
+
+ return layout;
+ }
+
+ protected void measure( Event event, Object element, ViewerLabel viewerLabel ) {
+ super.measure(event, element, viewerLabel);
+
+ if ( measureHeightIndex == event.index ) {
+ maxHeight = Math.max(event.getBounds().height, maxHeight);
+ }
+ }
+
+ private void centerMultilineVertically( TextLayout layout, Font defaultFont, GlyphMetrics imageMetrics, int imageOffset ) {
+
+ Font systemFont = layout.getDevice().getSystemFont();
+
+ int maxFontHeight = 0;
+ int lineIndex = layout.getLineIndex(imageOffset);
+ int[] lineOffsets = layout.getLineOffsets();
+ int lineStart = lineOffsets[lineIndex];
+ int lineEnd = lineOffsets[lineIndex + 1] - 1;
+ int oldEnd = -1;
+ int[] ranges = layout.getRanges();
+ TextStyle[] styles = layout.getStyles();
+ List lineStyles = new ArrayList();
+
+ for ( int i = 0, length = ranges.length; i < length; i += 2 ) {
+ int start = ranges[i];
+ int end = ranges[i + 1];
+
+ if ( start > oldEnd + 1 ) {
+ TextStyle style = new TextStyle(null, null, null);
+ layout.setStyle(style, Math.max(oldEnd + 1, lineStart), Math.min(start - 1, lineEnd));
+ lineStyles.add(style);
+ Font font = getFirstNotNullFont(style.font, defaultFont, systemFont);
+ maxFontHeight = Math.max(maxFontHeight, getFontHeight(font));
+ }
+
+ if ( start > lineEnd || end < lineStart ) {
+ continue;
+ }
+ if ( start == imageOffset && end == imageOffset ) {
+ oldEnd = end;
+ continue;
+ }
+
+ TextStyle style = styles[i >> 1];
+ if ( end > lineEnd ) {
+ TextStyle clonedStyle = cloneStyle(style);
+ layout.setStyle(clonedStyle, Math.max(start, lineStart), Math.min(end, lineEnd));
+ lineStyles.add(clonedStyle);
+ Font font = getFirstNotNullFont(style.font, defaultFont, systemFont);
+ maxFontHeight = Math.max(maxFontHeight, getFontHeight(font));
+ }
+ else {
+ lineStyles.add(style);
+ }
+
+ oldEnd = end;
+ }
+ if ( layout.getText().length() > oldEnd + 1 ) {
+ TextStyle style = new TextStyle(null, null, null);
+ layout.setStyle(style, Math.max(oldEnd + 1, lineStart), Math.min(layout.getText().length() - 1, lineEnd));
+ lineStyles.add(style);
+ Font font = getFirstNotNullFont(style.font, defaultFont, systemFont);
+ maxFontHeight = Math.max(maxFontHeight, getFontHeight(font));
+ }
+
+ if ( imageMetrics.ascent > maxFontHeight ) {
+ int height = imageMetrics.ascent;
+ int space = (height - maxFontHeight);
+ int rise = Math.round(space / 2f);
+ for ( Iterator iterator = lineStyles.iterator(); iterator.hasNext(); ) {
+ TextStyle style = (TextStyle)iterator.next();
+ style.rise = rise;
+ }
+ }
+ }
+
+ private TextStyle cloneStyle( TextStyle style ) {
+ TextStyle clone = new TextStyle(style.font, style.foreground, style.background);
+ clone.rise = style.rise;
+ clone.strikeout = style.strikeout;
+ if ( style.metrics != null ) {
+ clone.metrics = new GlyphMetrics(style.metrics.ascent, style.metrics.descent, style.metrics.width);
+ }
+ return clone;
+ }
+
+ private void columnsResized( Event event ) {
+ if ( !wrapLines ) {
+ return;
+ }
+ initKnownWidths(event);
+ if ( event.widget instanceof TableColumn ) {
+ TableColumn tc = (TableColumn)event.widget;
+ int newWidth = tc.getWidth();
+ if ( newWidth == knownColumnWidths[event.index] ) {
+ return;
+ }
+ knownColumnWidths[event.index] = newWidth;
+ int index = tc.getParent().indexOf(tc);
+ measureHeightIndex = index;
+ maxHeight = 0;
+ tc.getParent().redraw();
+ tc.getParent().update(); // trigger measure events for all visible items -> calculates maxHeight
+ if ( maxHeight >= tc.getParent().getItemHeight() ) {
+ return;
+ }
+ // TODO This is deactivated as long as either Bug 130024 or Bug 148039 are still existing
+ // tc.getParent().setItemHeight(maxHeight);
+ measureHeightIndex = -1;
+ maxHeight = 0;
+ tc.getParent().redraw();
+ tc.getParent().update();
+ }
+ else if ( event.widget instanceof TreeColumn ) {
+ TreeColumn tc = (TreeColumn)event.widget;
+ int newWidth = tc.getWidth();
+ if ( newWidth == knownColumnWidths[event.index] ) {
+ return;
+ }
+ knownColumnWidths[event.index] = newWidth;
+ int index = tc.getParent().indexOf(tc);
+ measureHeightIndex = index;
+ maxHeight = 0;
+ tc.getParent().redraw();
+ tc.getParent().update(); // trigger measure events for all visible items -> calculates maxHeight
+ if ( maxHeight >= tc.getParent().getItemHeight() ) {
+ return;
+ }
+ // TODO This is deactivated as long as either Bug 130024 or Bug 148039 are still existing
+ // tc.getParent().setItemHeight(maxHeight);
+ measureHeightIndex = -1;
+ maxHeight = 0;
+ tc.getParent().redraw();
+ tc.getParent().update();
+ }
+ }
+
+ private Font getFirstNotNullFont( Font f1, Font f2, Font f3 ) {
+ if ( f1 != null ) {
+ return f1;
+ }
+ if ( f2 != null ) {
+ return f2;
+ }
+ return f3;
+ }
+
+ private int getItemWidth( Event event ) {
+ if ( !wrapLines ) {
+ return -1;
+ }
+ if ( event.item instanceof TableItem ) {
+ return ((TableItem)event.item).getBounds(event.index).width;
+ }
+ if ( event.item instanceof TreeItem ) {
+ return ((TreeItem)event.item).getBounds(event.index).width;
+ }
+ return -1;
+ }
+
+ private void initKnownWidths( Event event ) {
+ if ( knownColumnWidths == null ) {
+ if ( event.widget instanceof TableColumn ) {
+ TableColumn tc = (TableColumn)event.widget;
+ knownColumnWidths = new int[tc.getParent().getColumnCount()];
+ }
+ else if ( event.widget instanceof TreeColumn ) {
+ TreeColumn tc = (TreeColumn)event.widget;
+ knownColumnWidths = new int[tc.getParent().getColumnCount()];
+ }
+ }
+ }
+}