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,263 @@ +/******************************************************************************* + * 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.OwnerDrawLabelProvider; +import org.eclipse.jface.viewers.StyledCellLabelProvider; +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.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 possibilities: + * + * + * @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(); + + OwnerDrawLabelProvider.setUpOwnerDraw(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 StyledLabelSupport { + + public MyStyledFontSupport() { + super(StyledLabelSupport.CENTER_ITEMS_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: 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,370 @@ +/******************************************************************************* + * 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 + * Tom Schindl - initial API + *******************************************************************************/ +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; + +/** + * StyledLabelSupport is the abstract superclass of the support for styled cells for viewers. + *

+ * By extending this class and passing an instance to a StyledCellLabelProvider you can control + * the appearance of your viewer's labels by {@link StyleRange} instances. + *

+ *

+ * To specify the position of the image provided by the label provider, include the + * IMAGE_PLACEHOLDER char in your label. If this char is not included, the label is + * positioned at the beginning. + *

+ *

+ * For multi line labels usage of {@link StyledMultiLineLabelSupport} is recommended. + *

+ * @since 3.4 + * @author Michael Krkoska + * @author Tom Schindl + * @see StyledCellLabelProvider + * @see StyleRange + */ +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; + } + + /** + * Handle the MeasureItem event. + * @param event The MeasureItem event + * @param element The element of the viewer's item of this MeasureItem event + * @param viewerLabel The ViewerLabel of the viewer's item of this MeasureItem event + * @see SWT#MeasureItem + */ + 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(); + } + + /** + * Handle the PaintItem event. + * @param event The PaintItem event + * @param element The element of the viewer's item of this PaintItem event + * @param viewerLabel The ViewerLabel of the viewer's item of this PaintItem event + * @see SWT#PaintItem + */ + 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,153 @@ +/******************************************************************************* + * 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 + * Tom Schindl - initial API + *******************************************************************************/ +package org.eclipse.jface.viewers; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.Widget; + + +/** + * A CellLabelProvider which supports styled labels by using owner draw. + *

+ * For providing the label's styles an instance of StyledLabelSupport is needed. + * The default values for colors and fonts, which are applied on all parts of the + * label where no style is specified, can be provided by overwritting the + * corresponding methods of this class. + *

+ *

+ * To set up styled labels for your viewer's control, you must call + * {@link OwnerDrawLabelProvider#setUpOwnerDraw(ColumnViewer)}. + *

+ * @since 3.4 + * @author Michael Krkoska + * @author Tom Schindl + */ +public class StyledCellLabelProvider extends OwnerDrawLabelProvider implements ILabelProvider, IFontProvider, IColorProvider { + + private static final boolean isCarbon = SWT.getPlatform().equals("carbon"); //$NON-NLS-1$ + + 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(); + } + + /** + * Provides a default background color for the given element, which is used for the + * part of the label where no background color is specified in the StyleRanges + * provided by this provider's StyledLabelSupport. + * + * @param element the element + * @return the background color for the element, or null + * to use the default background color + */ + public Color getBackground( Object element ) { + return null; + } + + /** + * Provides a default font for the given element, which is used for the + * part of the label where no font is specified in the StyleRanges + * provided by this provider's StyledLabelSupport. + * + * @param element the element + * @return the font for the element, or null + * to use the default font + */ + public Font getFont( Object element ) { + return null; + } + + /** + * Provides a default foreground color for the given element, which is used for the + * part of the label where no foreground color is specified in the StyleRanges + * provided by this provider's StyledLabelSupport. + * + * @param element the element + * @return the foreground color for the element, or null + * to use the default foreground color + */ + 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 = isCarbon?getCurrentHeight(event.widget):0; + + 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 ( isCarbon && event.height > height) { + // On Carbon the first cell in a Table is not updated properly, if the size changes. + viewer.getControl().redraw(); + } + } + + private int getCurrentHeight(Widget widget) { + if(widget instanceof Table) + return ((Table)widget).getItemHeight(); + if(widget instanceof Tree) + return ((Tree)widget).getItemHeight(); + return -1; + } + + 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; + } + } + +}