Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 219393 | Differences between
and this patch

Collapse All | Expand All

(-)Eclipse UI/org/eclipse/ui/dialogs/FilteredItemsSelectionDialog.java (-97 / +69 lines)
Lines 17-33 Link Here
17
import java.io.IOException;
17
import java.io.IOException;
18
import java.io.StringReader;
18
import java.io.StringReader;
19
import java.io.StringWriter;
19
import java.io.StringWriter;
20
import java.util.ArrayList;
20
import java.util.*;
21
import java.util.Arrays;
22
import java.util.Collections;
23
import java.util.Comparator;
24
import java.util.HashMap;
25
import java.util.HashSet;
26
import java.util.Iterator;
27
import java.util.LinkedList;
28
import java.util.List;
21
import java.util.List;
29
import java.util.Set;
30
22
23
import org.eclipse.core.commands.AbstractHandler;
24
import org.eclipse.core.commands.ExecutionEvent;
25
import org.eclipse.core.commands.IHandler;
31
import org.eclipse.core.runtime.Assert;
26
import org.eclipse.core.runtime.Assert;
32
import org.eclipse.core.runtime.CoreException;
27
import org.eclipse.core.runtime.CoreException;
33
import org.eclipse.core.runtime.IProgressMonitor;
28
import org.eclipse.core.runtime.IProgressMonitor;
Lines 37-62 Link Here
37
import org.eclipse.core.runtime.Status;
32
import org.eclipse.core.runtime.Status;
38
import org.eclipse.core.runtime.SubProgressMonitor;
33
import org.eclipse.core.runtime.SubProgressMonitor;
39
import org.eclipse.core.runtime.jobs.Job;
34
import org.eclipse.core.runtime.jobs.Job;
40
35
import org.eclipse.jface.action.Action;
41
import org.eclipse.core.commands.AbstractHandler;
36
import org.eclipse.jface.action.ActionContributionItem;
42
import org.eclipse.core.commands.ExecutionEvent;
37
import org.eclipse.jface.action.IAction;
43
import org.eclipse.core.commands.IHandler;
38
import org.eclipse.jface.action.IMenuListener;
44
39
import org.eclipse.jface.action.IMenuManager;
40
import org.eclipse.jface.action.LegacyActionTools;
41
import org.eclipse.jface.action.MenuManager;
42
import org.eclipse.jface.dialogs.IDialogSettings;
43
import org.eclipse.jface.viewers.*;
44
import org.eclipse.jface.viewers.DecoratingStyledCellLabelProvider.IStyledLabelProvider;
45
import org.eclipse.osgi.util.NLS;
45
import org.eclipse.swt.SWT;
46
import org.eclipse.swt.SWT;
46
import org.eclipse.swt.accessibility.AccessibleAdapter;
47
import org.eclipse.swt.accessibility.AccessibleAdapter;
47
import org.eclipse.swt.accessibility.AccessibleEvent;
48
import org.eclipse.swt.accessibility.AccessibleEvent;
48
import org.eclipse.swt.custom.CLabel;
49
import org.eclipse.swt.custom.CLabel;
49
import org.eclipse.swt.custom.ViewForm;
50
import org.eclipse.swt.custom.ViewForm;
50
import org.eclipse.swt.events.KeyAdapter;
51
import org.eclipse.swt.events.*;
51
import org.eclipse.swt.events.KeyEvent;
52
import org.eclipse.swt.events.ModifyEvent;
53
import org.eclipse.swt.events.ModifyListener;
54
import org.eclipse.swt.events.MouseAdapter;
55
import org.eclipse.swt.events.MouseEvent;
56
import org.eclipse.swt.events.SelectionAdapter;
57
import org.eclipse.swt.events.SelectionEvent;
58
import org.eclipse.swt.events.TraverseEvent;
59
import org.eclipse.swt.events.TraverseListener;
60
import org.eclipse.swt.graphics.Color;
52
import org.eclipse.swt.graphics.Color;
61
import org.eclipse.swt.graphics.Font;
53
import org.eclipse.swt.graphics.Font;
62
import org.eclipse.swt.graphics.GC;
54
import org.eclipse.swt.graphics.GC;
Lines 65-110 Link Here
65
import org.eclipse.swt.graphics.Rectangle;
57
import org.eclipse.swt.graphics.Rectangle;
66
import org.eclipse.swt.layout.GridData;
58
import org.eclipse.swt.layout.GridData;
67
import org.eclipse.swt.layout.GridLayout;
59
import org.eclipse.swt.layout.GridLayout;
68
import org.eclipse.swt.widgets.Composite;
60
import org.eclipse.swt.widgets.*;
69
import org.eclipse.swt.widgets.Control;
70
import org.eclipse.swt.widgets.Display;
71
import org.eclipse.swt.widgets.Event;
72
import org.eclipse.swt.widgets.Label;
73
import org.eclipse.swt.widgets.Menu;
74
import org.eclipse.swt.widgets.Shell;
75
import org.eclipse.swt.widgets.Text;
76
import org.eclipse.swt.widgets.ToolBar;
77
import org.eclipse.swt.widgets.ToolItem;
78
79
import org.eclipse.jface.action.Action;
80
import org.eclipse.jface.action.ActionContributionItem;
81
import org.eclipse.jface.action.IAction;
82
import org.eclipse.jface.action.IMenuListener;
83
import org.eclipse.jface.action.IMenuManager;
84
import org.eclipse.jface.action.LegacyActionTools;
85
import org.eclipse.jface.action.MenuManager;
86
import org.eclipse.jface.dialogs.IDialogSettings;
87
import org.eclipse.jface.viewers.ContentViewer;
88
import org.eclipse.jface.viewers.DoubleClickEvent;
89
import org.eclipse.jface.viewers.IColorProvider;
90
import org.eclipse.jface.viewers.IContentProvider;
91
import org.eclipse.jface.viewers.IDoubleClickListener;
92
import org.eclipse.jface.viewers.IFontProvider;
93
import org.eclipse.jface.viewers.ILabelDecorator;
94
import org.eclipse.jface.viewers.ILabelProvider;
95
import org.eclipse.jface.viewers.ILabelProviderListener;
96
import org.eclipse.jface.viewers.ILazyContentProvider;
97
import org.eclipse.jface.viewers.ISelection;
98
import org.eclipse.jface.viewers.ISelectionChangedListener;
99
import org.eclipse.jface.viewers.IStructuredContentProvider;
100
import org.eclipse.jface.viewers.LabelProvider;
101
import org.eclipse.jface.viewers.LabelProviderChangedEvent;
102
import org.eclipse.jface.viewers.SelectionChangedEvent;
103
import org.eclipse.jface.viewers.StructuredSelection;
104
import org.eclipse.jface.viewers.TableViewer;
105
import org.eclipse.jface.viewers.Viewer;
106
import org.eclipse.jface.viewers.ViewerFilter;
107
108
import org.eclipse.ui.ActiveShellExpression;
61
import org.eclipse.ui.ActiveShellExpression;
109
import org.eclipse.ui.IMemento;
62
import org.eclipse.ui.IMemento;
110
import org.eclipse.ui.PlatformUI;
63
import org.eclipse.ui.PlatformUI;
Lines 119-126 Link Here
119
import org.eclipse.ui.progress.UIJob;
72
import org.eclipse.ui.progress.UIJob;
120
import org.eclipse.ui.statushandlers.StatusManager;
73
import org.eclipse.ui.statushandlers.StatusManager;
121
74
122
import org.eclipse.osgi.util.NLS;
123
124
/**
75
/**
125
 * Shows a list of items to the user with a text entry field for a string
76
 * Shows a list of items to the user with a text entry field for a string
126
 * pattern used to filter the list of items.
77
 * pattern used to filter the list of items.
Lines 1520-1527 Link Here
1520
		}
1471
		}
1521
	}
1472
	}
1522
1473
1523
	private class ItemsListLabelProvider extends LabelProvider implements
1474
	private class ItemsListLabelProvider extends StyledCellLabelProvider implements ILabelProviderListener {
1524
			IColorProvider, IFontProvider, ILabelProviderListener {
1525
		private ILabelProvider provider;
1475
		private ILabelProvider provider;
1526
1476
1527
		private ILabelDecorator selectionDecorator;
1477
		private ILabelDecorator selectionDecorator;
Lines 1606-1617 Link Here
1606
			return provider;
1556
			return provider;
1607
		}
1557
		}
1608
1558
1609
		/*
1559
		private Image getImage(Object element) {
1610
		 * (non-Javadoc)
1611
		 * 
1612
		 * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
1613
		 */
1614
		public Image getImage(Object element) {
1615
			if (element instanceof ItemsListSeparator) {
1560
			if (element instanceof ItemsListSeparator) {
1616
				return WorkbenchImages
1561
				return WorkbenchImages
1617
						.getImage(IWorkbenchGraphicConstants.IMG_OBJ_SEPARATOR);
1562
						.getImage(IWorkbenchGraphicConstants.IMG_OBJ_SEPARATOR);
Lines 1620-1631 Link Here
1620
			return provider.getImage(element);
1565
			return provider.getImage(element);
1621
		}
1566
		}
1622
1567
1623
		/*
1568
		private StyledString getStyledString(Object element, IStyledLabelProvider provider) {
1624
		 * (non-Javadoc)
1569
			StyledString string= provider.getStyledText(element);
1625
		 * 
1570
			
1626
		 * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
1571
			if (selectionDecorator != null && isSelected(element)) {
1627
		 */
1572
				String decorated= selectionDecorator.decorateText(string.getString(), element);
1628
		public String getText(Object element) {
1573
				return new StyledString(decorated); // no need to add colors when element is selected
1574
			}
1575
			return string;
1576
		}
1577
		
1578
		public void update(ViewerCell cell) {
1579
			Object element= cell.getElement();
1580
			
1581
			if (!(element instanceof ItemsListSeparator) && provider instanceof IStyledLabelProvider) {
1582
				IStyledLabelProvider styledLabelProvider= (IStyledLabelProvider) provider;
1583
				StyledString styledString= getStyledString(element, styledLabelProvider);
1584
				
1585
				cell.setText(styledString.getString());
1586
				cell.setStyleRanges(styledString.getStyleRanges());
1587
				cell.setImage(styledLabelProvider.getImage(element));
1588
			} else {
1589
				cell.setText(getText(element));
1590
				cell.setImage(getImage(element));
1591
			}
1592
			cell.setFont(getFont(element));
1593
			cell.setForeground(getForeground(element));
1594
			cell.setBackground(getBackground(element));
1595
			
1596
			super.update(cell);
1597
		}
1598
		
1599
		private boolean isSelected(Object element) {
1600
			int[] selectionIndices = list.getTable().getSelectionIndices();
1601
			List elements = Arrays
1602
					.asList(contentProvider.getElements(null));
1603
			for (int i = 0; i < selectionIndices.length; i++) {
1604
				if (elements.size() > selectionIndices[i]
1605
						&& element
1606
								.equals(elements.get(selectionIndices[i]))) {
1607
					return true;
1608
				}
1609
			}
1610
			return false;
1611
		}
1612
		
1613
		private String getText(Object element) {
1629
			if (element instanceof ItemsListSeparator) {
1614
			if (element instanceof ItemsListSeparator) {
1630
				return getSeparatorLabel(((ItemsListSeparator) element)
1615
				return getSeparatorLabel(((ItemsListSeparator) element)
1631
						.getName());
1616
						.getName());
Lines 1633-1655 Link Here
1633
1618
1634
			String str = provider.getText(element);
1619
			String str = provider.getText(element);
1635
1620
1636
			if (selectionDecorator != null && element != null) {
1621
			if (selectionDecorator != null && element != null && isSelected(element)) {
1637
1622
				str = selectionDecorator.decorateText(str, element);
1638
				// ((StructuredSelection)list.getSelection()).toList().contains(element))
1639
				// cannot be used - virtual tables produce cycles in
1640
				// update item - get selection invocation scenarios
1641
1642
				int[] selectionIndices = list.getTable().getSelectionIndices();
1643
				List elements = Arrays
1644
						.asList(contentProvider.getElements(null));
1645
				for (int i = 0; i < selectionIndices.length; i++) {
1646
					if (elements.size() > selectionIndices[i]
1647
							&& element
1648
									.equals(elements.get(selectionIndices[i]))) {
1649
						str = selectionDecorator.decorateText(str, element);
1650
						break;
1651
					}
1652
				}
1653
			}
1623
			}
1654
			return str;
1624
			return str;
1655
		}
1625
		}
Lines 1794-1799 Link Here
1794
				((ILabelProviderListener) l[i]).labelProviderChanged(event);
1764
				((ILabelProviderListener) l[i]).labelProviderChanged(event);
1795
			}
1765
			}
1796
		}
1766
		}
1767
1768
1797
	}
1769
	}
1798
1770
1799
	/**
1771
	/**
(-)src/org/eclipse/jface/viewers/ViewerRow.java (+15 lines)
Lines 322-325 Link Here
322
	public Rectangle getTextBounds(int index) {
322
	public Rectangle getTextBounds(int index) {
323
		return null;
323
		return null;
324
	}
324
	}
325
	
326
327
	/**
328
	 * Returns the location and bounds of the area where the image is drawn.
329
	 * 
330
	 * @param index
331
	 *            the column index
332
	 * @return the bounds of the of the image area. May return <code>null</code>
333
	 *         if the underlying widget implementation doesn't provide this
334
	 *         information
335
	 * @since 3.4
336
	 */
337
	public Rectangle getImageBounds(int index) {
338
		return null;
339
	}
325
}
340
}
(-)src/org/eclipse/jface/viewers/SimpleStyledCellLabelProvider.java (+3 lines)
Lines 50-55 Link Here
50
 * <p><strong>NOTE:</strong> This API is experimental and may be deleted or
50
 * <p><strong>NOTE:</strong> This API is experimental and may be deleted or
51
 * changed before 3.4 is released.</p>
51
 * changed before 3.4 is released.</p>
52
 * 
52
 * 
53
 * 
54
 * @deprecated Will be removed before 3.4 M6. Use {@link StyledCellLabelProvider} instead.
55
 * 
53
 * @since 3.4
56
 * @since 3.4
54
 */
57
 */
55
public abstract class SimpleStyledCellLabelProvider extends
58
public abstract class SimpleStyledCellLabelProvider extends
(-)src/org/eclipse/jface/viewers/TableViewerRow.java (+7 lines)
Lines 221-226 Link Here
221
	public Rectangle getTextBounds(int index) {
221
	public Rectangle getTextBounds(int index) {
222
		return item.getTextBounds(index);
222
		return item.getTextBounds(index);
223
	}
223
	}
224
	
225
	/* (non-Javadoc)
226
	 * @see org.eclipse.jface.viewers.ViewerRow#getImageBounds(int)
227
	 */
228
	public Rectangle getImageBounds(int index) {
229
		return item.getImageBounds(index);
230
	}
224
231
225
	private boolean hasColumns() {
232
	private boolean hasColumns() {
226
		return this.item.getParent().getColumnCount() != 0;
233
		return this.item.getParent().getColumnCount() != 0;
(-)src/org/eclipse/jface/viewers/ViewerCell.java (+74 lines)
Lines 13-18 Link Here
13
13
14
package org.eclipse.jface.viewers;
14
package org.eclipse.jface.viewers;
15
15
16
import org.eclipse.swt.custom.StyleRange;
16
import org.eclipse.swt.graphics.Color;
17
import org.eclipse.swt.graphics.Color;
17
import org.eclipse.swt.graphics.Font;
18
import org.eclipse.swt.graphics.Font;
18
import org.eclipse.swt.graphics.Image;
19
import org.eclipse.swt.graphics.Image;
Lines 54-59 Link Here
54
	 */
55
	 */
55
	public static int RIGHT = 1 << 3;
56
	public static int RIGHT = 1 << 3;
56
57
58
	
59
	private static final String KEY_TEXT_LAYOUT = "styled_label_key_"; //$NON-NLS-1$
60
	
57
	/**
61
	/**
58
	 * Create a new instance of the receiver on the row.
62
	 * Create a new instance of the receiver on the row.
59
	 *
63
	 *
Lines 168-173 Link Here
168
		row.setImage(columnIndex, image);
172
		row.setImage(columnIndex, image);
169
173
170
	}
174
	}
175
	
176
	/**
177
	 * Set the style ranges to be applied on the text label
178
	 * Note: Requires {@link StyledCellLabelProvider} with owner draw enabled.
179
	 * 
180
	 * @param styleRanges the styled ranges
181
	 * 
182
	 * @since 3.4
183
	 */
184
	public void setStyleRanges(StyleRange[] styleRanges) {
185
		getItem().setData(KEY_TEXT_LAYOUT + columnIndex, styleRanges);
186
	}
187
	
188
	
189
	/**
190
	 * Returns the style ranges to be applied on the text label or <code>null</code> if no
191
	 * style ranges have been set.
192
	 * 
193
	 * @return styleRanges the styled ranges
194
	 * 
195
	 * @since 3.4
196
	 */
197
	public StyleRange[] getStyleRanges() {
198
		return (StyleRange[]) getItem().getData(KEY_TEXT_LAYOUT + columnIndex);
199
	}
171
200
172
	/**
201
	/**
173
	 * Set the columnIndex.
202
	 * Set the columnIndex.
Lines 302-308 Link Here
302
	public Rectangle getTextBounds() {
331
	public Rectangle getTextBounds() {
303
		return row.getTextBounds(columnIndex);
332
		return row.getTextBounds(columnIndex);
304
	}
333
	}
334
	
335
	/**
336
	 * Returns the location and bounds of the area where the image is drawn 
337
	 * 
338
	 * @return The bounds of the of the image area. May return <code>null</code>
339
	 *         if the underlying widget implementation doesn't provide this
340
	 *         information
341
	 * @since 3.4
342
	 */
343
	public Rectangle getImageBounds() {
344
		return row.getImageBounds(columnIndex);
345
	}
305
346
347
	/**
348
	 * Gets the foreground color of the cell.
349
	 * 
350
	 * @return the foreground of the cell or <code>null</code> for the default foreground
351
	 * 
352
	 * @since 3.4
353
	 */
354
	public Color getForeground() {
355
		return row.getForeground(columnIndex);
356
	}
357
	
358
	/**
359
	 * Gets the background color of the cell.
360
	 * 
361
	 * @return the background of the cell or <code>null</code> for the default background
362
	 * 
363
	 * @since 3.4
364
	 */
365
	public Color getBackground() {
366
		return row.getBackground(columnIndex);
367
	}
368
	
369
	/**
370
	 * Gets the font of the cell.
371
	 * 
372
	 * @return the font of the cell or <code>null</code> for the default font
373
	 * 
374
	 * @since 3.4
375
	 */
376
	public Font getFont() {
377
		return row.getFont(columnIndex);
378
	}
379
	
306
	/*
380
	/*
307
	 * (non-Javadoc)
381
	 * (non-Javadoc)
308
	 *
382
	 *
(-)src/org/eclipse/jface/viewers/TreeViewerRow.java (+7 lines)
Lines 375-380 Link Here
375
		return item.getTextBounds(index);
375
		return item.getTextBounds(index);
376
	}
376
	}
377
	
377
	
378
	/* (non-Javadoc)
379
	 * @see org.eclipse.jface.viewers.ViewerRow#getImageBounds(int)
380
	 */
381
	public Rectangle getImageBounds(int index) {
382
		return item.getImageBounds(index);
383
	}	
384
	
378
	private boolean hasColumns() {
385
	private boolean hasColumns() {
379
		return this.item.getParent().getColumnCount() != 0;
386
		return this.item.getParent().getColumnCount() != 0;
380
	}
387
	}
(-)src/org/eclipse/jface/preference/JFacePreferences.java (+24 lines)
Lines 31-36 Link Here
31
     * Identifier for the Active Hyperlink Colour
31
     * Identifier for the Active Hyperlink Colour
32
     */
32
     */
33
    public static final String ACTIVE_HYPERLINK_COLOR = "ACTIVE_HYPERLINK_COLOR"; //$NON-NLS-1$
33
    public static final String ACTIVE_HYPERLINK_COLOR = "ACTIVE_HYPERLINK_COLOR"; //$NON-NLS-1$
34
    
35
    /**
36
     * Identifier for the color used to show extra informations in labels, as a qualified name.
37
     * For example in 'Foo.txt - myproject/bar', the qualifier is '- myproject/bar'.
38
     * 
39
     * @since 3.4
40
     */
41
	public static final String QUALIFIER_COLOR= "QUALIFIER_COLOR"; //$NON-NLS-1$
42
	
43
    /**
44
     * Identifier for the color used to show label decorations
45
     * For example in 'Foo.txt [1.16]', the decoration is '[1.16]'.
46
     * 
47
     * @since 3.4
48
     */
49
	public static final String DECORATIONS_COLOR= "DECORATIONS_COLOR"; //$NON-NLS-1$
50
	
51
    /**
52
     * Identifier for the color used to counter informations
53
     * For example in 'Foo.txt (2 matches)', the counter information is '(2 matches)'.
54
     * 
55
     * @since 3.4
56
     */
57
	public static final String COUNTER_COLOR= "COUNTER_COLOR"; //$NON-NLS-1$
34
58
35
    private static IPreferenceStore preferenceStore;
59
    private static IPreferenceStore preferenceStore;
36
60
(-)src/org/eclipse/jface/viewers/DecoratingStyledCellLabelProvider.java (+462 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.jface.viewers;
12
13
import org.eclipse.core.runtime.Assert;
14
import org.eclipse.jface.resource.JFaceResources;
15
import org.eclipse.jface.resource.LocalResourceManager;
16
import org.eclipse.jface.resource.ResourceManager;
17
import org.eclipse.jface.viewers.StyledString.Style;
18
import org.eclipse.swt.graphics.Color;
19
import org.eclipse.swt.graphics.Font;
20
import org.eclipse.swt.graphics.Image;
21
22
23
/**
24
 * A {@link DecoratingStyledCellLabelProvider} is a {@link StyledCellLabelProvider}
25
 * that uses a nested {@link DecoratingStyledCellLabelProvider.IStyledLabelProvider}
26
 * to compute styled text label and image.
27
 * Optionally, it can also take a {@link ILabelDecorator} to decorate the label.
28
 * 
29
 * <p>Use this label provider to add styled ranges to existing label providers: 
30
 * Existing label providers can be enhanced by implementing
31
 * {@link DecoratingStyledCellLabelProvider.IStyledLabelProvider}, and are then able of being
32
 *  used in viewer with styled labels.</p>
33
 * 
34
 * <p>The {@link DecoratingStyledCellLabelProvider.IStyledLabelProvider} can
35
 * optionally implement {@link IColorProvider} and {@link IFontProvider} to provide
36
 * foreground and background color and a default font.
37
 * </p>
38
 * 
39
 * <p>The {@link ILabelDecorator} can
40
 * optionally implement {@link IColorDecorator} and {@link IFontDecorator} to provide
41
 * foreground and background color and font decoration.
42
 * </p>
43
 * 
44
 * @since 3.4
45
 */
46
public class DecoratingStyledCellLabelProvider extends StyledCellLabelProvider {
47
	
48
	/**
49
	 * Interface marking a label provider that provides styled text labels and images.
50
	 * <p>The {@link DecoratingStyledCellLabelProvider.IStyledLabelProvider} can
51
	 * optionally implement {@link IColorProvider} and {@link IFontProvider} to provide
52
	 * foreground and background color and a default font.
53
	 * </p>
54
	 */
55
	public static interface IStyledLabelProvider extends IBaseLabelProvider {
56
		
57
		/**
58
		 * Returns the styled text label for the given element
59
		 * 
60
		 * @param element the element to evaluate the styled string for
61
		 * 
62
		 * @return the styled string.
63
		 */
64
		public StyledString getStyledText(Object element);
65
		
66
	    /**
67
	     * Returns the image for the label of the given element.  The image
68
	     * is owned by the label provider and must not be disposed directly.
69
	     * Instead, dispose the label provider when no longer needed.
70
	     *
71
	     * @param element the element for which to provide the label image
72
	     * @return the image used to label the element, or <code>null</code>
73
	     *   if there is no image for the given object
74
	     */
75
	    public Image getImage(Object element);
76
	}
77
	
78
	
79
	private IStyledLabelProvider styledLabelProvider;
80
	
81
	private ILabelDecorator decorator;
82
	private IDecorationContext decorationContext;
83
	private ILabelProviderListener labelProviderListener;
84
	
85
	/**
86
	 * Creates a {@link DecoratingStyledCellLabelProvider} that delegates the requests for
87
	 * styled labels and for images to a {@link IStyledLabelProvider}.
88
	 * 
89
	 * @param labelProvider the styled label provider
90
	 * @param decorator a label decorator or <code>null</code> to not decorate the label
91
	 * @param decorationContext a decoration context or <code>null</code> if the no decorator
92
	 * is configured or the default decorator should be used
93
	 */
94
	public DecoratingStyledCellLabelProvider(IStyledLabelProvider labelProvider, ILabelDecorator decorator, IDecorationContext decorationContext) {
95
		if (labelProvider == null)
96
			throw new IllegalArgumentException("Label provider must not be null"); //$NON-NLS-1$
97
		
98
		this.styledLabelProvider= labelProvider;
99
		this.decorator= decorator;
100
		this.decorationContext= decorationContext;
101
		if (decorator != null && decorationContext == null) {
102
			decorationContext= createDefaultDecorationContext();
103
		}
104
		labelProviderListener= new ILabelProviderListener() {
105
			public void labelProviderChanged(LabelProviderChangedEvent event) {
106
				fireLabelProviderChanged(event);
107
			}
108
		};
109
		labelProvider.addListener(labelProviderListener);
110
		if (decorator != null)
111
			decorator.addListener(labelProviderListener);
112
	}
113
	
114
	/**
115
	 * Creates a {@link DecoratingStyledCellLabelProvider} that delegates the requests for
116
	 * styled labels and for images to a {@link IStyledLabelProvider}.
117
	 * 
118
	 * @param labelProvider the styled label provider
119
	 */
120
	public DecoratingStyledCellLabelProvider(IStyledLabelProvider labelProvider) {
121
		this(labelProvider, null, null);
122
	}
123
	
124
	private IDecorationContext createDefaultDecorationContext() {
125
		DecorationContext newContext = new DecorationContext();
126
		newContext.putProperty(DecorationContext.RESOURCE_MANAGER_KEY, new LocalResourceManager(JFaceResources.getResources()));
127
		return newContext;
128
	}
129
	
130
	/**
131
	 * Returns the decoration context associated with this label provider. It
132
	 * will be passed to the decorator if the decorator is an instance of
133
	 * {@link LabelDecorator}.
134
	 * 
135
	 * @return the decoration context associated with this label provider
136
	 */
137
	public IDecorationContext getDecorationContext() {
138
		return decorationContext;
139
	}
140
	
141
	/**
142
	 * Set the decoration context that will be based to the decorator for this
143
	 * label provider if that decorator implements {@link LabelDecorator}.
144
	 * 
145
	 * If this decorationContext has a {@link ResourceManager} stored for the
146
	 * {@link DecorationContext#RESOURCE_MANAGER_KEY} property it will be
147
	 * disposed when the label provider is disposed.
148
	 * 
149
	 * @param decorationContext
150
	 *            the decoration context.
151
	 */
152
	public void setDecorationContext(IDecorationContext decorationContext) {
153
		Assert.isNotNull(decorationContext);
154
		this.decorationContext = decorationContext;
155
	}
156
	
157
	private boolean waitForPendingDecoration(ViewerCell cell) {
158
		if (decorator == null)
159
			return false;
160
		
161
		Object element= cell.getElement();
162
		String oldText= cell.getText();
163
		
164
		boolean isDecorationPending= false;
165
		if (decorator instanceof LabelDecorator) {
166
			isDecorationPending= !((LabelDecorator) decorator).prepareDecoration(element, oldText, getDecorationContext());
167
		} else if (decorator instanceof IDelayedLabelDecorator) {
168
			isDecorationPending= !((IDelayedLabelDecorator) decorator).prepareDecoration(element, oldText);
169
		}
170
		if (isDecorationPending && oldText.length() == 0) {
171
			// item is empty: is shown for the first time: don't wait
172
			return false;
173
		}
174
		return isDecorationPending;
175
	}
176
	
177
	
178
	/* (non-Javadoc)
179
	 * @see org.eclipse.jface.viewers.StyledCellLabelProvider#update(org.eclipse.jface.viewers.ViewerCell)
180
	 */
181
	public void update(ViewerCell cell) {
182
		if (waitForPendingDecoration(cell)) {
183
			return; // wait until the decoration is ready
184
		}
185
		
186
		Object element= cell.getElement();
187
		
188
		StyledString styledString= getStyledText(element);
189
		cell.setText(styledString.getString());	
190
191
		if (isOwnerDrawEnabled()) {
192
			cell.setStyleRanges(styledString.getStyleRanges());
193
		} else {
194
			cell.setStyleRanges(null);
195
		}
196
		
197
		cell.setImage(getImage(element));
198
		cell.setFont(getFont(element));
199
		cell.setForeground(getForeground(element));
200
		cell.setBackground(getBackground(element));
201
		
202
		super.update(cell);
203
	}
204
	
205
    /**
206
     * Provides a foreground color for the given element.
207
     * 
208
     * @param element the element
209
     * @return	the foreground color for the element, or <code>null</code> 
210
     *   to use the default foreground color
211
     */
212
	public Color getForeground(Object element) {
213
		if (decorator instanceof IColorDecorator) {
214
			Color foreground= ((IColorDecorator) decorator).decorateForeground(element);
215
			if (foreground != null)
216
				return foreground;
217
		}
218
		if (styledLabelProvider instanceof IColorProvider) {
219
			return ((IColorProvider) styledLabelProvider).getForeground(element);
220
		}
221
		return null;
222
	}
223
	
224
    /**
225
     * Provides a background color for the given element.
226
     * 
227
     * @param element the element
228
     * @return	the background color for the element, or <code>null</code> 
229
     *   to use the default background color
230
     */
231
	public Color getBackground(Object element) {
232
		if (decorator instanceof IColorDecorator) {
233
			Color color= ((IColorDecorator) decorator).decorateBackground(element);
234
			if (color != null)
235
				return color;
236
		}
237
		if (styledLabelProvider instanceof IColorProvider) {
238
			return ((IColorProvider) styledLabelProvider).getBackground(element);
239
		}
240
		return null;
241
	}
242
	
243
    /**
244
     * Provides a font for the given element.
245
     * 
246
     * @param element the element
247
     * @return the font for the element, or <code>null</code> 
248
     *   to use the default font
249
     */
250
	public Font getFont(Object element) {
251
		if (decorator instanceof IFontDecorator) {
252
			Font font= ((IFontDecorator) decorator).decorateFont(element);
253
			if (font != null)
254
				return font;
255
		}
256
		if (styledLabelProvider instanceof IFontProvider) {
257
			return ((IFontProvider) styledLabelProvider).getFont(element);
258
		}
259
		return null;
260
	}
261
	
262
	
263
    /**
264
     * Returns the image for the label of the given element.  The image
265
     * is owned by the label provider and must not be disposed directly.
266
     * Instead, dispose the label provider when no longer needed.
267
     *
268
     * @param element the element for which to provide the label image
269
     * @return the image used to label the element, or <code>null</code>
270
     *   if there is no image for the given object
271
     */
272
	public Image getImage(Object element) {
273
		Image image= styledLabelProvider.getImage(element);
274
		if (decorator == null) {
275
			return image;
276
		}
277
		
278
		Image decorated= null;
279
		if (decorator instanceof LabelDecorator) {
280
			decorated= ((LabelDecorator) decorator).decorateImage(image, element, getDecorationContext());
281
		} else {
282
			decorated= decorator.decorateImage(image, element);
283
		}
284
		if (decorated != null)
285
			return decorated;
286
		
287
		return image;
288
	}
289
290
    /**
291
     * Returns the styled text for the label of the given element.
292
     *
293
     * @param element the element for which to provide the styled label text
294
     * @return the styled text string used to label the element
295
     */
296
	public StyledString getStyledText(Object element) {
297
		StyledString string= styledLabelProvider.getStyledText(element);
298
		if (decorator == null) {
299
			return string;
300
		}
301
		
302
		String label= string.getString();
303
		String decorated;
304
		if (decorator instanceof LabelDecorator) {
305
			decorated= ((LabelDecorator) decorator).decorateText(label, element, getDecorationContext());
306
		} else {
307
			decorated= decorator.decorateText(label, element);
308
		}
309
		if (decorated == null)
310
			return string;
311
		
312
		int originalStart= decorated.indexOf(label);
313
		if (originalStart == -1) {
314
			return new StyledString(decorated); // the decorator did something wild
315
		}
316
		
317
		if (decorated.length() == label.length())
318
			return string;
319
320
		Style style= getDecorationStyle(element);
321
		if (originalStart > 0) {
322
			StyledString newString= new StyledString(decorated.substring(0, originalStart), style);
323
			newString.append(string);
324
			string= newString;
325
		}
326
		if (decorated.length() > originalStart + label.length()) { // decorator appended something
327
			return string.append(decorated.substring(originalStart + label.length()), style);
328
		}
329
		return string;
330
	}
331
		
332
	/**
333
	 * Sets the {@link StyledString.Style} to be used for string decorations. By default 
334
	 * the {@link StyledString#DECORATIONS_STYLE decoration style}. Clients can override.
335
	 * 
336
	 * Note that it is the client's responsibility to react on color changes of the decoration color by
337
	 * refreshing the view
338
	 * 
339
	 * @param element the element that has been decorated
340
	 * 
341
	 * @return return the decoration style
342
	 */
343
	protected Style getDecorationStyle(Object element) {
344
		return StyledString.DECORATIONS_STYLE;
345
	}
346
347
	/**
348
	 * Returns the styled string provider.
349
	 * 
350
	 * @return  the wrapped label provider
351
	 */
352
	public IStyledLabelProvider getStyledStringProvider() {
353
		return styledLabelProvider;
354
	}
355
	
356
	/**
357
	 * Sets the styled label provider. Removes all known listeners from the old
358
	 * provider, and adds all known listeners to the new provider. The old
359
	 * provider is not disposed. Fires a label provider changed event
360
	 * indicating that all labels should be updated. Has no effect if the given
361
	 * decorator is identical to the current one.
362
	 * 
363
	 * @param newLabelProvider the new styled label provider
364
	 */
365
	public void setStyledLabelProvider(IStyledLabelProvider newLabelProvider) {
366
		if (newLabelProvider == null)
367
			throw new IllegalArgumentException();
368
		
369
		IStyledLabelProvider oldProvider= this.styledLabelProvider;
370
		if (newLabelProvider != oldProvider) {
371
			oldProvider.removeListener(labelProviderListener);
372
			this.styledLabelProvider= newLabelProvider;
373
			newLabelProvider.addListener(labelProviderListener);
374
			
375
		}
376
		fireLabelProviderChanged(new LabelProviderChangedEvent(this));
377
	}
378
	
379
	/**
380
	 * Returns the decorator or <code>null</code> if no decorator is installed
381
	 * 
382
	 * @return the decorator or <code>null</code> if no decorator is installed
383
	 */ 
384
	public ILabelDecorator getLabelDecorator() {
385
		return decorator;
386
	}
387
	
388
	/**
389
	 * Sets the label decorator. Removes all known listeners from the old
390
	 * decorator, and adds all known listeners to the new decorator. The old
391
	 * decorator is not disposed. Fires a label provider changed event
392
	 * indicating that all labels should be updated. Has no effect if the given
393
	 * decorator is identical to the current one.
394
	 * 
395
	 * @param newDecorator
396
	 *            the label decorator, or <code>null</code> if no decorations
397
	 *            are to be applied
398
	 */
399
	public void setLabelDecorator(ILabelDecorator newDecorator) {
400
		ILabelDecorator oldDecorator= this.decorator;
401
		if (oldDecorator != newDecorator) {
402
			if (oldDecorator != null)
403
				oldDecorator.removeListener(labelProviderListener);
404
			this.decorator= newDecorator;
405
			if (newDecorator != null) {
406
				newDecorator.addListener(labelProviderListener);
407
			}
408
		}
409
		fireLabelProviderChanged(new LabelProviderChangedEvent(this));
410
	}
411
	
412
	/* (non-Javadoc)
413
	 * @see org.eclipse.jface.viewers.BaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener)
414
	 */
415
	public void addListener(ILabelProviderListener listener) {
416
		super.addListener(listener);
417
		styledLabelProvider.addListener(listener);
418
		if (decorator != null) {
419
			decorator.addListener(listener);
420
		}
421
	}
422
	
423
	/* (non-Javadoc)
424
	 * @see org.eclipse.jface.viewers.BaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)
425
	 */
426
	public void removeListener(ILabelProviderListener listener) {
427
		super.removeListener(listener);
428
		styledLabelProvider.removeListener(listener);
429
		if (decorator != null) {
430
			decorator.removeListener(listener);
431
		}
432
	}
433
		
434
	/* (non-Javadoc)
435
	 * @see org.eclipse.jface.viewers.BaseLabelProvider#isLabelProperty(java.lang.Object, java.lang.String)
436
	 */
437
	public boolean isLabelProperty(Object element, String property) {
438
		if (styledLabelProvider.isLabelProperty(element, property)) {
439
			return true;
440
		}
441
		return decorator != null && decorator.isLabelProperty(element, property);
442
	}
443
		
444
	/* (non-Javadoc)
445
	 * @see org.eclipse.jface.viewers.StyledCellLabelProvider#dispose()
446
	 */
447
	public void dispose() {
448
		super.dispose();
449
		if (decorationContext != null) {
450
			Object manager = decorationContext.getProperty(DecorationContext.RESOURCE_MANAGER_KEY);
451
			if (manager instanceof ResourceManager)
452
				((ResourceManager) manager).dispose();
453
		}
454
		styledLabelProvider.removeListener(labelProviderListener);
455
		styledLabelProvider.dispose();
456
		if (decorator != null) {
457
			decorator.removeListener(labelProviderListener);
458
			decorator.dispose();
459
		}
460
	}
461
462
}
(-)src/org/eclipse/jface/viewers/StyledString.java (+423 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.jface.viewers;
12
13
import java.util.ArrayList;
14
import java.util.List;
15
16
import org.eclipse.jface.preference.JFacePreferences;
17
import org.eclipse.jface.resource.ColorRegistry;
18
import org.eclipse.jface.resource.JFaceResources;
19
import org.eclipse.swt.custom.StyleRange;
20
import org.eclipse.swt.graphics.TextStyle;
21
22
/**
23
 * Represents a string with styled ranges. All ranges mark substrings of the string and do not overlap.
24
 * Styles are represented by {@link Style}.
25
 * 
26
 * The styled string can be modified:
27
 * <ul>
28
 * <li>new strings with styles can be appended</li>
29
 * <li>styles can by applied to to the existing string</li>
30
 * </ul>
31
 * 
32
 * <p>
33
 * This class may be instantiated; it is not intended to be subclassed.
34
 * </p>
35
 *  @since 3.4
36
 */
37
public class StyledString {
38
	
39
	/**
40
	 * Represents a style that can be associated to one ore more ranges in the {@link StyledString}
41
	 *  
42
	 */
43
	public static abstract class Style {
44
		
45
		/**
46
		 * Applies the styles represented by this object to the given textStyle.
47
		 * 
48
		 * @param textStyle the {@link TextStyle} to modify
49
		 */
50
		public abstract void applyStyles(TextStyle textStyle);
51
	}
52
	
53
54
	/**
55
	 * A built-in style using the {@link JFacePreferences#QUALIFIER_COLOR} 
56
	 * managed in the JFace color registry (See {@link JFaceResources#getColorRegistry()}).
57
	 */
58
	public static final Style QUALIFIER_STYLE= createColorRegistryStyle(JFacePreferences.QUALIFIER_COLOR, null);
59
	
60
	/**
61
	 * A built-in style using the {@link JFacePreferences#COUNTER_COLOR} 
62
	 * managed in the JFace color registry (See {@link JFaceResources#getColorRegistry()}).
63
	 */	
64
	public static final Style COUNTER_STYLE= createColorRegistryStyle(JFacePreferences.COUNTER_COLOR, null);
65
	
66
	/**
67
	 * A built-in style using the {@link JFacePreferences#DECORATIONS_COLOR} 
68
	 * managed in the JFace color registry (See {@link JFaceResources#getColorRegistry()}).
69
	 */
70
	public static final Style DECORATIONS_STYLE= createColorRegistryStyle(JFacePreferences.DECORATIONS_COLOR, null); 
71
72
	/**
73
	 * Creates a style that takes the given foreground and background colors from the JFace color registry.
74
	 * 
75
	 * @param foregroundColorName the color name for the foreground color
76
	 * @param backgroundColorName the color name for the background color
77
	 * 
78
	 * @return the created style
79
	 */
80
	public static Style createColorRegistryStyle(String foregroundColorName, String backgroundColorName) {
81
		return new DefaultStyle(foregroundColorName, backgroundColorName); 
82
	}
83
	
84
	private static final StyleRange[] EMPTY= new StyleRange[0];
85
	private StringBuffer fBuffer;
86
	private StyleRunList fStyleRuns;
87
	
88
	/**
89
	 * Creates an empty {@link StyledString}.
90
	 */
91
	public StyledString() {
92
		fBuffer= new StringBuffer();
93
		fStyleRuns= null;
94
	}
95
	
96
	/**
97
	 * Creates an {@link StyledString} initialized with a string without a style associated.
98
	 * 
99
	 * @param string the string 
100
	 */
101
	public StyledString(String string) {
102
		this(string, null);
103
	}
104
	
105
	/**
106
	 * Creates an {@link StyledString} initialized with a string and a style.  
107
	 * 
108
	 * @param string the string 
109
	 * @param style the style of the text or <code>null</code> to not associated a style.
110
	 */
111
	public StyledString(String string, Style style) {
112
		this();
113
		append(string, style);
114
	}
115
	
116
	/**
117
	 * Returns the string of this {@link StyledString}.
118
	 * 
119
	 * @return the current string of this {@link StyledString}.
120
	 */
121
	public String getString() {
122
		return fBuffer.toString();
123
	}
124
	
125
	/**
126
	 * Returns the length of the string of this {@link StyledString}.
127
	 * 
128
	 * @return the length of the current string
129
	 */
130
	public int length() {
131
		return fBuffer.length();
132
	}
133
	
134
	/**
135
	 * Appends a string to the {@link StyledString}. The appended string will have no style associated.
136
	 * 
137
	 * @param string the string to append.
138
	 * @return returns a reference to this object.
139
	 */
140
	public StyledString append(String string) {
141
		return append(string, null);
142
	}
143
	
144
	/**
145
	 * Appends a character to the {@link StyledString}. The appended character will have no style associated.
146
	 * 
147
	 * @param ch the character to append.
148
	 * @return returns a reference to this object.
149
	 */
150
	public StyledString append(char ch) {
151
		return append(String.valueOf(ch), null);
152
	}
153
	
154
	/**
155
	 * Appends a string with styles to the {@link StyledString}.
156
	 * 
157
	 * @param string the string to append.
158
	 * @return returns a reference to this object.
159
	 */
160
	public StyledString append(StyledString string) {
161
		if (string.length() == 0) {
162
			return this;
163
		}
164
		
165
		int offset= fBuffer.length();
166
		fBuffer.append(string.getString());
167
		
168
		List otherRuns= string.fStyleRuns;
169
		if (otherRuns != null && !otherRuns.isEmpty()) {
170
			for (int i= 0; i < otherRuns.size(); i++) {
171
				StyleRun curr= (StyleRun) otherRuns.get(i);
172
				if (i == 0 && curr.offset != 0) {
173
					appendStyleRun(null, offset); // appended string will start with the default color
174
				}
175
				appendStyleRun(curr.style, offset + curr.offset);
176
			}
177
		} else {
178
			appendStyleRun(null, offset); // appended string will start with the default color
179
		}
180
		return this;
181
	}
182
	
183
	/**
184
	 * Appends a character with a style to the {@link StyledString}. The appended character will
185
	 * have the given style associated.
186
	 * 
187
	 * @param ch the character to append.
188
	 * @param style the style to of the character to append or <code>null</code> if no style should be
189
	 * associated to the string.
190
	 * @return returns a reference to this object.
191
	 */
192
	public StyledString append(char ch, Style style) {
193
		return append(String.valueOf(ch), style);
194
	}
195
	
196
	/**
197
	 * Appends a string with a style to the {@link StyledString}. The appended string will
198
	 * have the given style associated.
199
	 * 
200
	 * @param string the string to append.
201
	 * @param style the style to of the string to append or <code>null</code> if no style should be
202
	 * associated to the string.
203
	 * @return returns a reference to this object.
204
	 */
205
	public StyledString append(String string, Style style) {
206
		if (string.length() == 0)
207
			return this;
208
		
209
		int offset= fBuffer.length(); // the length before appending
210
		fBuffer.append(string);
211
		appendStyleRun(style, offset);
212
		return this;
213
	}
214
	
215
	/**
216
	 * Sets a style to the given source range. The range must be subrange of actual string of this {@link StyledString}.
217
	 * Styles previously set for that range will be overwritten.
218
	 * 
219
	 * @param offset the start offset of the range
220
	 * @param length the length of the range
221
	 * @param style the style to set
222
	 * 
223
	 * @throws StringIndexOutOfBoundsException if <code>start</code> is
224
     *             less than zero, or if offset plus length is greater than the length of this object.
225
	 */
226
	public void setStyle(int offset, int length, Style style) {
227
		if (offset < 0 || offset + length > fBuffer.length()) {
228
			throw new StringIndexOutOfBoundsException("Invalid offset (" + offset + ") or length (" + length + ")");   //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
229
		}
230
		if (length == 0) {
231
			return;
232
		}
233
		if (!hasRuns() || getLastRun().offset <= offset) {
234
			appendStyleRun(style, offset);
235
			if (offset + length != fBuffer.length()) {
236
				appendStyleRun(null, offset + length);
237
			}
238
			return;
239
		}
240
		
241
		int endRun= findRun(offset + length);
242
		if (endRun >= 0) {
243
			// run with the same end index, nothing to change
244
		} else {
245
			endRun= -(endRun + 1);
246
			if (offset + length < fBuffer.length()) {
247
				Style prevStyle= endRun > 0 ? fStyleRuns.getRun(endRun - 1).style : null;
248
				fStyleRuns.add(endRun, new StyleRun(offset + length, prevStyle));
249
			}
250
		}
251
		
252
		int startRun= findRun(offset);
253
		if (startRun >= 0) {
254
			// run with the same start index
255
			StyleRun styleRun= fStyleRuns.getRun(startRun);
256
			styleRun.style= style;
257
		} else {
258
			startRun= -(startRun + 1);
259
			
260
			Style prevStyle= startRun > 0 ? fStyleRuns.getRun(startRun - 1).style : null;
261
			if (isDifferentStyle(prevStyle, style) || (startRun == 0 && style != null)) {
262
				fStyleRuns.add(startRun, new StyleRun(offset, style));
263
				endRun++; // endrun is moved one back
264
			} else {
265
				startRun--; // we use the previous
266
			}
267
		}
268
		if (startRun + 1 < endRun) {
269
			fStyleRuns.removeRange(startRun + 1, endRun);
270
		}
271
	}
272
	
273
	/**
274
	 * Returns {@link StyleRange} for all applied styles to this string
275
	 * 
276
	 * @return an array of all {@link StyleRange} applied to this string.
277
	 */
278
	public StyleRange[] getStyleRanges() {
279
		if (hasRuns()) {
280
			ArrayList res= new ArrayList();
281
			
282
			List styleRuns= getStyleRuns();
283
			int offset= 0;
284
			Style style= null;
285
			for (int i= 0; i < styleRuns.size(); i++) {
286
				StyleRun curr= (StyleRun) styleRuns.get(i);
287
				if (isDifferentStyle(curr.style, style)) {
288
					if (curr.offset > offset && style != null) {
289
						res.add(createStyleRange(offset, curr.offset, style));
290
					}
291
					offset= curr.offset;
292
					style= curr.style;
293
				}
294
			}
295
			if (fBuffer.length() > offset && style != null) {
296
				res.add(createStyleRange(offset, fBuffer.length(), style));
297
			}
298
			return (StyleRange[]) res.toArray(new StyleRange[res.size()]);
299
		}
300
		return EMPTY;
301
	}
302
	
303
	private int findRun(int offset) {
304
		// method assumes that fStyleRuns is not null
305
		int low= 0;
306
		int high= fStyleRuns.size() - 1;
307
		while (low <= high) {
308
		    int mid = (low + high) / 2;
309
		    StyleRun styleRun= fStyleRuns.getRun(mid);
310
		    if (styleRun.offset < offset) {
311
		    	low = mid + 1;
312
		    } else if (styleRun.offset > offset) {
313
		    	high = mid - 1;
314
		    } else {
315
		    	return mid; // key found
316
		    }
317
		}
318
		return -(low + 1);  // key not found.
319
	}
320
	
321
	private StyleRange createStyleRange(int start, int end, Style style) {
322
		StyleRange styleRange= new StyleRange();
323
		styleRange.start= start;
324
		styleRange.length= end - start;
325
		style.applyStyles(styleRange);
326
		return styleRange;
327
	}
328
	
329
	
330
	/* (non-Javadoc)
331
	 * @see java.lang.Object#toString()
332
	 */
333
	public String toString() {
334
		return fBuffer.toString();
335
	}
336
	
337
	private boolean hasRuns() {
338
		return fStyleRuns != null && !fStyleRuns.isEmpty();
339
	}
340
		
341
	private void appendStyleRun(Style style, int offset) {
342
		StyleRun lastRun= getLastRun();
343
		if (lastRun != null && lastRun.offset == offset) {
344
			lastRun.style= style;
345
			return;
346
		}
347
		
348
		if (lastRun == null && style != null || lastRun != null && isDifferentStyle(style, lastRun.style)) {
349
			getStyleRuns().add(new StyleRun(offset, style));
350
		}
351
	}
352
	
353
	private boolean isDifferentStyle(Style style1, Style style2) {
354
		if (style1 == null) {
355
			return style2 != null;
356
		}
357
		return !style1.equals(style2);
358
	}
359
	
360
	private StyleRun getLastRun() {
361
		if (fStyleRuns == null || fStyleRuns.isEmpty()) {
362
			return null;
363
		}
364
		return fStyleRuns.getRun(fStyleRuns.size() - 1);
365
	}
366
	
367
	private List getStyleRuns() {
368
		if (fStyleRuns == null)
369
			fStyleRuns= new StyleRunList();
370
		return fStyleRuns;
371
	}
372
	
373
	private static class StyleRun {
374
		public int offset;
375
		public Style style;
376
		
377
		public StyleRun(int offset, Style style) {
378
			this.offset= offset;
379
			this.style= style;
380
		}
381
		
382
		public String toString() {
383
			return "Offset " + offset + ", style: " + style.toString();  //$NON-NLS-1$//$NON-NLS-2$
384
		}
385
	}
386
	
387
	private static class StyleRunList extends ArrayList {
388
		private static final long serialVersionUID= 123L;
389
390
		public StyleRunList() {
391
			super(3);
392
		}
393
394
		public StyleRun getRun(int index) {
395
			return (StyleRun) get(index);
396
		}
397
				
398
		public void removeRange(int fromIndex, int toIndex) {
399
			super.removeRange(fromIndex, toIndex);
400
		}	
401
	}
402
	
403
	private static class DefaultStyle extends Style {
404
		private final String fForegroundColorName;
405
		private final String fBackgroundColorName;
406
407
		public DefaultStyle(String foregroundColorName, String backgroundColorName) {
408
			fForegroundColorName= foregroundColorName;	
409
			fBackgroundColorName= backgroundColorName;
410
		}
411
		
412
		public void applyStyles(TextStyle textStyle) {
413
			ColorRegistry colorRegistry= JFaceResources.getColorRegistry();
414
			if (fForegroundColorName != null) {
415
				textStyle.foreground= colorRegistry.get(fForegroundColorName);
416
			}
417
			if (fBackgroundColorName != null) {
418
				textStyle.background= colorRegistry.get(fBackgroundColorName);
419
			}
420
		}
421
	}
422
	
423
}
(-)src/org/eclipse/jface/viewers/StyledCellLabelProvider.java (+377 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007, 2008 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *     Michael Krkoska - initial API and implementation (bug 188333)
11
 *******************************************************************************/
12
package org.eclipse.jface.viewers;
13
14
import org.eclipse.core.runtime.Assert;
15
import org.eclipse.jface.window.Window;
16
import org.eclipse.swt.SWT;
17
import org.eclipse.swt.custom.StyleRange;
18
import org.eclipse.swt.graphics.Color;
19
import org.eclipse.swt.graphics.GC;
20
import org.eclipse.swt.graphics.Image;
21
import org.eclipse.swt.graphics.Rectangle;
22
import org.eclipse.swt.graphics.TextLayout;
23
import org.eclipse.swt.widgets.Display;
24
import org.eclipse.swt.widgets.Event;
25
26
/**
27
 * A {@link StyledCellLabelProvider} supports styled labels by using owner
28
 * draw.
29
 * Besides the styles in labels, the label provider preserves native viewer behavior:
30
 * <ul>
31
 * <li>similar image and label positioning</li>
32
 * <li>native drawing of focus and selection</li>
33
 * </ul>
34
 * <p>
35
 * For providing the label's styles, create a subclass and overwrite
36
 * {@link StyledCellLabelProvider#update(ViewerCell)} to
37
 * return set all information needed to render a element. Use
38
 * {@link ViewerCell#setStyleRanges(StyleRange[])} to set style ranges
39
 * on the label.
40
 * </p>
41
 * <p>
42
 * The current version of the {@link StyledCellLabelProvider} will ignore all font settings on
43
 * {@link StyleRange}. Different fonts would make labels wider, and the native
44
 * selection drawing could not be reused.
45
 * </p>
46
 * 
47
 * <p><strong>NOTE:</strong> This API is experimental and may be deleted or
48
 * changed before 3.4 is released.</p>
49
 * 
50
 * @since 3.4
51
 */
52
public abstract class StyledCellLabelProvider extends OwnerDrawLabelProvider {
53
54
	/**
55
	 * Style constant for indicating that the styled colors are to be applied
56
	 * even it the viewer's item is selected. Default is not to apply colors.
57
	 */
58
	public static final int COLORS_ON_SELECTION = 1 << 0;
59
60
	/**
61
	 * Style constant for indicating to draw the focus if requested by the owner
62
	 * draw event. Default is to draw the focus.
63
	 */
64
	public static final int NO_FOCUS = 1 << 1;
65
	
66
	/**
67
	 * Private constant to indicate if owner draw is enabled for the
68
	 * label provider's column.
69
	 */
70
	private static final int OWNER_DRAW_ENABLED = 1 << 4;
71
72
	private int style;
73
74
	// reused text layout
75
	private TextLayout cachedTextLayout; 
76
	
77
	private ColumnViewer viewer;
78
	private ViewerColumn column;
79
80
	/**
81
	 * Creates a new StyledCellLabelProvider. By default, owner draw is enabled, focus is drawn and no 
82
	 * colors are painted on selected elements.
83
	 */
84
	public StyledCellLabelProvider() {
85
		this(0);
86
	}
87
88
	/**
89
	 * Creates a new StyledCellLabelProvider. By default, owner draw is enabled.
90
	 * 
91
	 * @param style
92
	 *            the style bits
93
	 * @see StyledCellLabelProvider#COLORS_ON_SELECTION
94
	 * @see StyledCellLabelProvider#NO_FOCUS
95
	 */
96
	public StyledCellLabelProvider(int style) {
97
		this.style = style & (COLORS_ON_SELECTION | NO_FOCUS)
98
							| OWNER_DRAW_ENABLED;
99
	}
100
	
101
	/**
102
	 * Returns <code>true</code> is the owner draw rendering is enabled for this label provider.
103
	 * By default owner draw rendering is enabled. If owner draw rendering is disabled, rending is 
104
	 * done by the viewer and no styled ranges (see {@link ViewerCell#getStyleRanges()})
105
	 * are drawn.
106
	 * 
107
	 * @return <code>true</code> is the rendering of styles is enabled. 
108
	 */
109
	public boolean isOwnerDrawEnabled() {
110
		return (this.style & OWNER_DRAW_ENABLED) != 0;
111
	}
112
	
113
	/**
114
	 * Specifies whether owner draw rendering is enabled for this label
115
	 * provider. By default owner draw rendering is enabled. If owner draw
116
	 * rendering is disabled, rendering is done by the viewer and no styled
117
	 * ranges (see {@link ViewerCell#getStyleRanges()}) are drawn.
118
	 * It is the caller's responsibility to also call
119
	 * {@link StructuredViewer#refresh()} or similar methods to update the
120
	 * underlying widget.
121
	 * 
122
	 * @param enabled
123
	 *            specifies if owner draw rendering is enabled
124
	 */
125
	public void setOwnerDrawEnabled(boolean enabled) {
126
		boolean isEnabled= isOwnerDrawEnabled();
127
		if (isEnabled != enabled) {
128
			if (enabled) {
129
				this.style |= OWNER_DRAW_ENABLED;
130
			} else {
131
				this.style &= ~OWNER_DRAW_ENABLED;
132
			}
133
			if (this.viewer != null) {
134
				setOwnerDrawEnabled(this.viewer, this.column, enabled);
135
			}
136
		}
137
	}
138
	
139
	/**
140
	 * Returns the viewer on which this label provider is installed on or <code>null</code> if the
141
	 * label provider is not installed.
142
	 * 
143
	 * @return the viewer on which this label provider is installed on or <code>null</code> if the
144
	 * label provider is not installed.
145
	 */
146
	protected final ColumnViewer getViewer() {
147
		return this.viewer;
148
	}
149
	
150
	/**
151
	 * Returns the column on which this label provider is installed on or <code>null</code> if the
152
	 * label provider is not installed.
153
	 * 
154
	 * @return the column on which this label provider is installed on or <code>null</code> if the
155
	 * label provider is not installed.
156
	 */
157
	protected final ViewerColumn getColumn() {
158
		return this.column;
159
	}
160
		
161
	/* (non-Javadoc)
162
	 * @see org.eclipse.jface.viewers.OwnerDrawLabelProvider#initialize(org.eclipse.jface.viewers.ColumnViewer, org.eclipse.jface.viewers.ViewerColumn)
163
	 */
164
	public void initialize(ColumnViewer viewer, ViewerColumn column) {
165
		Assert.isTrue(this.viewer == null && this.column == null, "Label provider instance already in use"); //$NON-NLS-1$
166
		
167
		this.viewer= viewer;
168
		this.column= column;
169
		super.initialize(viewer, column, isOwnerDrawEnabled());
170
	}
171
	
172
	/*
173
	 * (non-Javadoc)
174
	 * 
175
	 * @see org.eclipse.jface.viewers.BaseLabelProvider#dispose()
176
	 */
177
	public void dispose() {
178
		if (this.cachedTextLayout != null) {
179
			cachedTextLayout.dispose();
180
			cachedTextLayout = null;
181
		}
182
	
183
		this.viewer= null;
184
		this.column= null;
185
		
186
		super.dispose();
187
	}
188
189
	/*
190
	 * (non-Javadoc)
191
	 * 
192
	 * @see org.eclipse.jface.viewers.OwnerDrawLabelProvider#update(org.eclipse.jface.viewers.ViewerCell)
193
	 */
194
	public void update(ViewerCell cell) {
195
		// clients must override and configure the cell and call super
196
		super.update(cell); // calls 'repaint' to trigger the paint listener
197
	}
198
199
	private TextLayout getSharedTextLayout(Display display) {
200
		if (cachedTextLayout == null) {
201
			cachedTextLayout = new TextLayout(display);
202
			cachedTextLayout.setOrientation(Window.getDefaultOrientation());
203
		} else {
204
			cachedTextLayout.setText(""); // make sure no previous ranges are cleared //$NON-NLS-1$
205
		}
206
		return cachedTextLayout;
207
	}
208
209
	private boolean useColors(Event event) {
210
		return (event.detail & SWT.SELECTED) == 0
211
				|| (this.style & COLORS_ON_SELECTION) != 0;
212
	}
213
214
	private boolean drawFocus(Event event) {
215
		return (event.detail & SWT.FOCUSED) != 0
216
				&& (this.style & NO_FOCUS) == 0;
217
	}
218
219
	/**
220
	 * Returns a {@link TextLayout} instance for the given cell
221
	 * configured with the style ranges. The text layout instance is managed by
222
	 * the label provider. Caller of the method must not dispose the text
223
	 * layout.
224
	 * 
225
	 * @param diplay
226
	 *            the current display
227
	 * @param applyColors
228
	 *            if set, create colors in the result
229
	 * @param cell
230
	 *            the viewer cell
231
	 * @return a TextLayout instance
232
	 */
233
	private TextLayout getTextLayoutForInfo(Display display, ViewerCell cell, boolean applyColors) {
234
		TextLayout layout = getSharedTextLayout(display);
235
		
236
		layout.setText(cell.getText());
237
		layout.setFont(cell.getFont()); // set also if null to clear previous usages
238
		
239
		StyleRange[] styleRanges = cell.getStyleRanges();
240
		if (styleRanges != null) { // user didn't fill styled ranges
241
			for (int i = 0; i < styleRanges.length; i++) {
242
				StyleRange curr = prepareStyleRange(styleRanges[i], applyColors);
243
				layout.setStyle(curr, curr.start, curr.start + curr.length - 1);
244
			}
245
		}
246
247
		return layout;
248
	}
249
	
250
	/**
251
	 * Prepares the given style range before it is applied to the label. This method makes sure that
252
	 * no colors are drawn when the element is selected.
253
	 * The current version of the {@link StyledCellLabelProvider} will also ignore all font settings on the
254
	 * style range. Clients can override. 
255
	 *  
256
	 * @param styleRange
257
	 *               the style range to prepare. the style range element must not be modified
258
	 * @param applyColors
259
	 *               specifies if colors should be applied.
260
	 * @return
261
	 *               returns the style range to use on the label
262
	 */
263
	protected StyleRange prepareStyleRange(StyleRange styleRange, boolean applyColors) {
264
		// if no colors apply or font is set, create a clone and clear the
265
		// colors and font
266
		if (styleRange.font != null || !applyColors
267
				&& (styleRange.foreground != null || styleRange.background != null)) {
268
			styleRange = (StyleRange) styleRange.clone();
269
			styleRange.font = null; // ignore font settings until bug 168807 is resolved
270
			if (!applyColors) {
271
				styleRange.foreground = null;
272
				styleRange.background = null;
273
			}
274
		}
275
		return styleRange;
276
	}
277
278
	private ViewerCell getViewerCell(Event event, Object element) {
279
		ViewerRow row= viewer.getViewerRowFromItem(event.item);
280
		return new ViewerCell(row, event.index, element);
281
	}
282
	
283
	/**
284
	 * Handle the erase event. The default implementation does nothing to ensure
285
	 * keep native selection highlighting working.
286
	 * 
287
	 * @param event
288
	 *            the erase event
289
	 * @param element
290
	 *            the model object
291
	 * @see SWT#EraseItem
292
	 */
293
	protected void erase(Event event, Object element) {
294
		// use native erase
295
		if (isOwnerDrawEnabled()) {
296
			// info has been set by 'update': announce that we paint ourselves
297
			event.detail &= ~SWT.FOREGROUND;
298
		}
299
	}
300
301
	/*
302
	 * (non-Javadoc)
303
	 * 
304
	 * @see org.eclipse.jface.viewers.OwnerDrawLabelProvider#measure(org.eclipse.swt.widgets.Event,
305
	 *      java.lang.Object)
306
	 */
307
	protected void measure(Event event, Object element) {
308
		// use native measuring
309
	}
310
	
311
	/*
312
	 * (non-Javadoc)
313
	 * 
314
	 * @see org.eclipse.jface.viewers.OwnerDrawLabelProvider#paint(org.eclipse.swt.widgets.Event,
315
	 *      java.lang.Object)
316
	 */
317
	protected void paint(Event event, Object element) {
318
		if (!isOwnerDrawEnabled())
319
			return;
320
		
321
		ViewerCell cell= getViewerCell(event, element);
322
323
		boolean applyColors = useColors(event);
324
		GC gc = event.gc;
325
		// remember colors to restore the GC later
326
		Color oldForeground = gc.getForeground();
327
		Color oldBackground = gc.getBackground();
328
		
329
		if (applyColors) {
330
			Color foreground= cell.getForeground();
331
			if (foreground != null) {
332
				gc.setForeground(foreground);
333
			}
334
			
335
			Color background= cell.getBackground();
336
			if (background != null) {
337
				gc.setBackground(background);
338
			}
339
		}
340
341
		Image image = cell.getImage();
342
		if (image != null) {
343
			Rectangle imageBounds = cell.getImageBounds();
344
			Rectangle bounds = image.getBounds();
345
346
			// center the image in the given space
347
			int x = imageBounds.x
348
					+ Math.max(0, (imageBounds.width - bounds.width) / 2);
349
			int y = imageBounds.y
350
					+ Math.max(0, (imageBounds.height - bounds.height) / 2);
351
			gc.drawImage(image, x, y);
352
		}
353
354
		TextLayout textLayout = getTextLayoutForInfo(event.display, cell, applyColors);
355
356
		Rectangle textBounds = cell.getTextBounds();
357
		Rectangle layoutBounds = textLayout.getBounds();
358
359
		int x = textBounds.x;
360
		int y = textBounds.y
361
				+ Math.max(0, (textBounds.height - layoutBounds.height) / 2);
362
363
		textLayout.draw(gc, x, y);
364
365
		if (drawFocus(event)) {
366
			Rectangle focusBounds = cell.getViewerRow().getBounds();
367
			gc.drawFocus(focusBounds.x, focusBounds.y, focusBounds.width,
368
					focusBounds.height);
369
		}
370
		
371
		if (applyColors) {
372
			gc.setForeground(oldForeground);
373
			gc.setBackground(oldBackground);
374
		}
375
	}
376
377
}
(-)Eclipse JFace Snippets/org/eclipse/jface/snippets/viewers/Snippet049SimpleStyledCellLabelProvider.java (-103 / +44 lines)
Lines 12-35 Link Here
12
package org.eclipse.jface.snippets.viewers;
12
package org.eclipse.jface.snippets.viewers;
13
13
14
import java.io.File;
14
import java.io.File;
15
import java.text.DateFormat;
15
import java.text.MessageFormat;
16
import java.text.MessageFormat;
16
import java.util.Date;
17
import java.util.Date;
17
18
18
import org.eclipse.jface.viewers.CellLabelProvider;
19
import org.eclipse.jface.preference.JFacePreferences;
19
import org.eclipse.jface.viewers.ColumnLabelProvider;
20
import org.eclipse.jface.resource.JFaceResources;
20
import org.eclipse.jface.viewers.ColumnViewer;
21
import org.eclipse.jface.viewers.*;
21
import org.eclipse.jface.viewers.ILabelProvider;
22
import org.eclipse.jface.viewers.DecoratingStyledCellLabelProvider.IStyledLabelProvider;
22
import org.eclipse.jface.viewers.ITreeContentProvider;
23
import org.eclipse.jface.viewers.SimpleStyledCellLabelProvider;
24
import org.eclipse.jface.viewers.TreeViewer;
25
import org.eclipse.jface.viewers.TreeViewerColumn;
26
import org.eclipse.jface.viewers.Viewer;
27
import org.eclipse.swt.SWT;
23
import org.eclipse.swt.SWT;
28
import org.eclipse.swt.custom.StyleRange;
29
import org.eclipse.swt.events.SelectionAdapter;
24
import org.eclipse.swt.events.SelectionAdapter;
30
import org.eclipse.swt.events.SelectionEvent;
25
import org.eclipse.swt.events.SelectionEvent;
31
import org.eclipse.swt.graphics.Color;
32
import org.eclipse.swt.graphics.Image;
26
import org.eclipse.swt.graphics.Image;
27
import org.eclipse.swt.graphics.RGB;
33
import org.eclipse.swt.layout.GridData;
28
import org.eclipse.swt.layout.GridData;
34
import org.eclipse.swt.layout.GridLayout;
29
import org.eclipse.swt.layout.GridLayout;
35
import org.eclipse.swt.widgets.Button;
30
import org.eclipse.swt.widgets.Button;
Lines 40-46 Link Here
40
35
41
36
42
/**
37
/**
43
 * Using a {@link SimpleStyledCellLabelProvider} on tree viewer. Compare the result with a native tree viewer.
38
 * Using a {@link StyledCellLabelProvider} on tree viewer. Compare the result with a native tree viewer.
44
 */
39
 */
45
public class Snippet049SimpleStyledCellLabelProvider {
40
public class Snippet049SimpleStyledCellLabelProvider {
46
	
41
	
Lines 50-55 Link Here
50
45
51
46
52
	public static void main(String[] args) {
47
	public static void main(String[] args) {
48
		
49
		JFaceResources.getColorRegistry().put(JFacePreferences.COUNTER_COLOR, new RGB(0,127,174));
50
		
51
		
53
52
54
		Shell shell= new Shell(DISPLAY, SWT.CLOSE | SWT.RESIZE);
53
		Shell shell= new Shell(DISPLAY, SWT.CLOSE | SWT.RESIZE);
55
		shell.setSize(SHELL_WIDTH, 300);
54
		shell.setSize(SHELL_WIDTH, 300);
Lines 79-85 Link Here
79
		ExampleLabelProvider labelProvider= new ExampleLabelProvider();
78
		ExampleLabelProvider labelProvider= new ExampleLabelProvider();
80
		ModifiedDateLabelProvider dateLabelProvider= new ModifiedDateLabelProvider();
79
		ModifiedDateLabelProvider dateLabelProvider= new ModifiedDateLabelProvider();
81
80
82
		final ColumnViewer ownerDrawViewer= createViewer("Owner draw viewer:", composite, new DecoratingLabelProvider(labelProvider), new DecoratingDateLabelProvider(dateLabelProvider)); //$NON-NLS-1$
81
		final ColumnViewer ownerDrawViewer= createViewer("Owner draw viewer:", composite, new DecoratingStyledCellLabelProvider(labelProvider), new DecoratingStyledCellLabelProvider(dateLabelProvider)); //$NON-NLS-1$
83
82
84
		final ColumnViewer normalViewer= createViewer("Normal viewer:", composite, labelProvider, dateLabelProvider); //$NON-NLS-1$
83
		final ColumnViewer normalViewer= createViewer("Normal viewer:", composite, labelProvider, dateLabelProvider); //$NON-NLS-1$
85
84
Lines 105-111 Link Here
105
104
106
			public void widgetSelected(SelectionEvent e) {
105
			public void widgetSelected(SelectionEvent e) {
107
				boolean newState= button2.getSelection();
106
				boolean newState= button2.getSelection();
108
				((DecoratingLabelProvider) ownerDrawViewer.getLabelProvider(0)).setOwnerDrawEnabled(newState);
107
				((DecoratingStyledCellLabelProvider) ownerDrawViewer.getLabelProvider(0)).setOwnerDrawEnabled(newState);
109
				ownerDrawViewer.refresh();
108
				ownerDrawViewer.refresh();
110
			}
109
			}
111
		});
110
		});
Lines 117-123 Link Here
117
116
118
			public void widgetSelected(SelectionEvent e) {
117
			public void widgetSelected(SelectionEvent e) {
119
				boolean newState= button3.getSelection();
118
				boolean newState= button3.getSelection();
120
				((DecoratingDateLabelProvider) ownerDrawViewer.getLabelProvider(1)).setOwnerDrawEnabled(newState);
119
				((DecoratingStyledCellLabelProvider) ownerDrawViewer.getLabelProvider(1)).setOwnerDrawEnabled(newState);
121
				ownerDrawViewer.refresh();
120
				ownerDrawViewer.refresh();
122
			}
121
			}
123
		});
122
		});
Lines 145-156 Link Here
145
		treeViewer.setContentProvider(new FileSystemContentProvider());
144
		treeViewer.setContentProvider(new FileSystemContentProvider());
146
		
145
		
147
		TreeViewerColumn tvc1 = new TreeViewerColumn(treeViewer, SWT.NONE);
146
		TreeViewerColumn tvc1 = new TreeViewerColumn(treeViewer, SWT.NONE);
148
		tvc1.getColumn().setText("Name");
147
		tvc1.getColumn().setText("Name"); //$NON-NLS-1$
149
		tvc1.getColumn().setWidth(200);
148
		tvc1.getColumn().setWidth(200);
150
		tvc1.setLabelProvider(labelProvider1);
149
		tvc1.setLabelProvider(labelProvider1);
151
150
152
		TreeViewerColumn tvc2 = new TreeViewerColumn(treeViewer, SWT.NONE);
151
		TreeViewerColumn tvc2 = new TreeViewerColumn(treeViewer, SWT.NONE);
153
		tvc2.getColumn().setText("Date Modified");
152
		tvc2.getColumn().setText("Date Modified"); //$NON-NLS-1$
154
		tvc2.getColumn().setWidth(200);
153
		tvc2.getColumn().setWidth(200);
155
		tvc2.setLabelProvider(labelProvider2);
154
		tvc2.setLabelProvider(labelProvider2);
156
		
155
		
Lines 161-254 Link Here
161
160
162
		return treeViewer;
161
		return treeViewer;
163
	}
162
	}
164
	
165
	/**
166
	 * Implements a {@link SimpleStyledCellLabelProvider} that wraps a normal label
167
	 * provider and adds some decorations in color
168
	 */
169
	private static class DecoratingLabelProvider extends SimpleStyledCellLabelProvider {
170
171
		private static final StyleRange[] NO_RANGES= new StyleRange[0];
172
		private final ILabelProvider fWrappedLabelProvider;
173
		
174
		public DecoratingLabelProvider(ILabelProvider labelProvider) {
175
			fWrappedLabelProvider= labelProvider;
176
		}
177
178
		protected LabelPresentationInfo getLabelPresentationInfo(Object element) {
179
			String text= fWrappedLabelProvider.getText(element);
180
			Image image= fWrappedLabelProvider.getImage(element);
181
182
			
183
			StyleRange[] ranges= NO_RANGES;
184
			if (element instanceof File) {
185
				File file= (File) element;
186
				if (file.isFile()) {
187
					String decoration= MessageFormat.format(" ({0} bytes)", new Object[] { new Long(file.length()) }); //$NON-NLS-1$
188
										
189
					int decorationStart= text.length();
190
					int decorationLength= decoration.length();
191
192
					text+= decoration;
193
					
194
					Color decorationColor= Display.getDefault().getSystemColor(SWT.COLOR_DARK_BLUE);
195
					
196
					StyleRange styleRange= new StyleRange(decorationStart, decorationLength, decorationColor, null);
197
					ranges= new StyleRange[] { styleRange };
198
				}
199
			}
200
			return new LabelPresentationInfo(text, ranges, image, null, null, null);
201
		}
202
		
203
		public void dispose() {
204
			super.dispose();
205
			fWrappedLabelProvider.dispose();
206
		}
207
	}
208
	
209
	private static class DecoratingDateLabelProvider extends SimpleStyledCellLabelProvider {
210
		
211
		private static final String[] DAYS = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
212
		private static final StyleRange[] NO_RANGES= new StyleRange[0];
213
		private final ILabelProvider fWrappedLabelProvider;
214
		
215
		public DecoratingDateLabelProvider(ILabelProvider labelProvider) {
216
			fWrappedLabelProvider= labelProvider;
217
		}
218
		
219
		protected LabelPresentationInfo getLabelPresentationInfo(Object element) {
220
			String text= fWrappedLabelProvider.getText(element);
221
			Image image= fWrappedLabelProvider.getImage(element);
222
			
223
			StyleRange[] ranges= NO_RANGES;
224
			if (element instanceof File) {
225
				File file= (File) element;
226
				String decoration= " " + DAYS[new Date(file.lastModified()).getDay()]; 
227
				
228
				int decorationStart= text.length();
229
				int decorationLength= decoration.length();
230
				
231
				text+= decoration;
232
				
233
				Color decorationColor= Display.getDefault().getSystemColor(SWT.COLOR_GRAY);
234
				
235
				StyleRange styleRange= new StyleRange(decorationStart, decorationLength, decorationColor, null);
236
				ranges= new StyleRange[] { styleRange };
237
			}
238
			return new LabelPresentationInfo(text, ranges, image, null, null, null);
239
		}
240
		
241
		public void dispose() {
242
			super.dispose();
243
			fWrappedLabelProvider.dispose();
244
		}
245
	}
246
	
247
163
248
	/**
164
	/**
249
	 * A simple label provider
165
	 * A simple label provider
250
	 */
166
	 */
251
	private static class ExampleLabelProvider extends ColumnLabelProvider {
167
	private static class ExampleLabelProvider extends ColumnLabelProvider implements IStyledLabelProvider {
252
		
168
		
253
		private static int IMAGE_SIZE= 16;
169
		private static int IMAGE_SIZE= 16;
254
		private static final Image IMAGE1= new Image(DISPLAY, DISPLAY.getSystemImage(SWT.ICON_WARNING).getImageData().scaledTo(IMAGE_SIZE, IMAGE_SIZE));
170
		private static final Image IMAGE1= new Image(DISPLAY, DISPLAY.getSystemImage(SWT.ICON_WARNING).getImageData().scaledTo(IMAGE_SIZE, IMAGE_SIZE));
Lines 277-292 Link Here
277
			return "null"; //$NON-NLS-1$
193
			return "null"; //$NON-NLS-1$
278
		}
194
		}
279
195
196
		public StyledString getStyledText(Object element) {
197
			String text= getText(element);
198
			StyledString styledString= new StyledString(text);
199
			if (element instanceof File) {
200
				File file= (File) element;
201
				if (file.isFile()) {
202
					String decoration= MessageFormat.format(" ({0} bytes)", new Object[] { new Long(file.length()) }); //$NON-NLS-1$
203
					styledString.append(decoration, StyledString.COUNTER_STYLE);
204
				}
205
			}	
206
			return styledString;
207
		}
280
	}
208
	}
281
	
209
	
282
	private static class ModifiedDateLabelProvider extends ColumnLabelProvider {
210
	private static class ModifiedDateLabelProvider extends ColumnLabelProvider implements IStyledLabelProvider {
283
		public String getText(Object element) {
211
		public String getText(Object element) {
284
			if (element instanceof File) {
212
			if (element instanceof File) {
285
				File file= (File) element;
213
				File file= (File) element;
286
				return new Date(file.lastModified()).toLocaleString();
214
				return DateFormat.getDateInstance().format(new Date(file.lastModified()));
287
			}
215
			}
288
			return "-"; //$NON-NLS-1$
216
			return "-"; //$NON-NLS-1$
289
		}
217
		}
218
		
219
		public StyledString getStyledText(Object element) {
220
			String text= getText(element);
221
			
222
			StyledString styledString= new StyledString(text);
223
			if (element instanceof File) {
224
				File file= (File) element;
225
				String decoration = DateFormat.getTimeInstance(3).format(new Date(file.lastModified()));
226
				styledString.append(' ');
227
				styledString.append(decoration, StyledString.COUNTER_STYLE);
228
			}
229
			return styledString;
230
		}
290
	}
231
	}
291
	
232
	
292
	private static class FileSystemContentProvider implements ITreeContentProvider {
233
	private static class FileSystemContentProvider implements ITreeContentProvider {
(-)Eclipse JFace Snippets/org/eclipse/jface/snippets/viewers/Snippet050SimpleStyledCellLabelProvider.java (-33 / +32 lines)
Lines 14-31 Link Here
14
import java.io.File;
14
import java.io.File;
15
import java.text.MessageFormat;
15
import java.text.MessageFormat;
16
16
17
import org.eclipse.jface.viewers.ColumnViewer;
17
import org.eclipse.jface.preference.JFacePreferences;
18
import org.eclipse.jface.viewers.IBaseLabelProvider;
18
import org.eclipse.jface.resource.JFaceResources;
19
import org.eclipse.jface.viewers.ILabelProvider;
19
import org.eclipse.jface.viewers.*;
20
import org.eclipse.jface.viewers.ITreeContentProvider;
21
import org.eclipse.jface.viewers.LabelProvider;
22
import org.eclipse.jface.viewers.SimpleStyledCellLabelProvider;
23
import org.eclipse.jface.viewers.TableViewer;
24
import org.eclipse.jface.viewers.Viewer;
25
import org.eclipse.swt.SWT;
20
import org.eclipse.swt.SWT;
26
import org.eclipse.swt.custom.StyleRange;
27
import org.eclipse.swt.graphics.Color;
28
import org.eclipse.swt.graphics.Image;
21
import org.eclipse.swt.graphics.Image;
22
import org.eclipse.swt.graphics.RGB;
29
import org.eclipse.swt.layout.GridData;
23
import org.eclipse.swt.layout.GridData;
30
import org.eclipse.swt.layout.GridLayout;
24
import org.eclipse.swt.layout.GridLayout;
31
import org.eclipse.swt.widgets.Button;
25
import org.eclipse.swt.widgets.Button;
Lines 37-43 Link Here
37
import org.eclipse.swt.widgets.Shell;
31
import org.eclipse.swt.widgets.Shell;
38
32
39
/**
33
/**
40
 * Using a {@link SimpleStyledCellLabelProvider} on table viewer. Compare the result with a native table viewer.
34
 * Using a {@link StyledCellLabelProvider} on table viewer. Compare the result with a native table viewer.
41
 */
35
 */
42
36
43
public class Snippet050SimpleStyledCellLabelProvider {
37
public class Snippet050SimpleStyledCellLabelProvider {
Lines 49-54 Link Here
49
43
50
	public static void main(String[] args) {
44
	public static void main(String[] args) {
51
45
46
		JFaceResources.getColorRegistry().put(JFacePreferences.COUNTER_COLOR, new RGB(0,127,174));
47
		
52
		Shell shell= new Shell(DISPLAY, SWT.CLOSE | SWT.RESIZE);
48
		Shell shell= new Shell(DISPLAY, SWT.CLOSE | SWT.RESIZE);
53
		shell.setSize(SHELL_WIDTH, 300);
49
		shell.setSize(SHELL_WIDTH, 300);
54
		shell.setLayout(new GridLayout(1, false));
50
		shell.setLayout(new GridLayout(1, false));
Lines 118-124 Link Here
118
			}
114
			}
119
		}
115
		}
120
		if (root == null) {
116
		if (root == null) {
121
			throw new RuntimeException("couldn't get a non-empty root file");
117
			throw new RuntimeException("couldn't get a non-empty root file"); //$NON-NLS-1$
122
		}
118
		}
123
		tableViewer.setInput(root);
119
		tableViewer.setInput(root);
124
120
Lines 126-168 Link Here
126
	}
122
	}
127
	
123
	
128
	/**
124
	/**
129
	 * Implements a {@link SimpleStyledCellLabelProvider} that wraps a normal label
125
	 * Implements a {@link StyledCellLabelProvider} that wraps a normal label
130
	 * provider and adds some decorations in color
126
	 * provider and adds some decorations in color
131
	 */
127
	 */
132
	private static class DecoratingLabelProvider extends SimpleStyledCellLabelProvider {
128
	private static class DecoratingLabelProvider extends StyledCellLabelProvider {
133
129
134
		private static final StyleRange[] NO_RANGES= new StyleRange[0];
135
		private final ILabelProvider fWrappedLabelProvider;
130
		private final ILabelProvider fWrappedLabelProvider;
136
		
131
		
137
		public DecoratingLabelProvider(ILabelProvider labelProvider) {
132
		public DecoratingLabelProvider(ILabelProvider labelProvider) {
138
			fWrappedLabelProvider= labelProvider;
133
			fWrappedLabelProvider= labelProvider;
139
		}
134
		}
140
135
		
141
		protected LabelPresentationInfo getLabelPresentationInfo(Object element) {
136
		public void update(ViewerCell cell) {
137
			Object element= cell.getElement();
138
			
142
			String text= fWrappedLabelProvider.getText(element);
139
			String text= fWrappedLabelProvider.getText(element);
143
			Image image= fWrappedLabelProvider.getImage(element);
140
			Image image= fWrappedLabelProvider.getImage(element);
144
145
			
141
			
146
			StyleRange[] ranges= NO_RANGES;
142
			StyledString styledString= new StyledString(text);
147
			if (element instanceof File) {
143
			if (element instanceof File) {
148
				File file= (File) element;
144
				File file= (File) element;
149
				if (file.isFile()) {
145
				String decoration = MessageFormat.format(" ({0} bytes)", new Object[] { new Long(file.length()) }); //$NON-NLS-1$
150
					String decoration= MessageFormat.format(" ({0} bytes)", new Object[] { new Long(file.length()) }); //$NON-NLS-1$
146
				styledString.append(decoration, StyledString.COUNTER_STYLE);
151
										
152
					int decorationStart= text.length();
153
					int decorationLength= decoration.length();
154
155
					text+= decoration;
156
					
157
					Color decorationColor= Display.getDefault().getSystemColor(SWT.COLOR_DARK_BLUE);
158
					
159
					StyleRange styleRange= new StyleRange(decorationStart, decorationLength, decorationColor, null);
160
					ranges= new StyleRange[] { styleRange };
161
				}
162
			}
147
			}
163
			return new LabelPresentationInfo(text, ranges, image, null, null, null);
148
			
149
			cell.setText(styledString.getString());
150
			cell.setStyleRanges(styledString.getStyleRanges());
151
			cell.setImage(image);
152
			super.update(cell);
153
		}
154
155
		public void addListener(ILabelProviderListener listener) {
156
			super.addListener(listener);
157
			fWrappedLabelProvider.addListener(listener);
164
		}
158
		}
165
		
159
		
160
		public void removeListener(ILabelProviderListener listener) {
161
			super.removeListener(listener);
162
			fWrappedLabelProvider.removeListener(listener);
163
		}
164
				
166
		public void dispose() {
165
		public void dispose() {
167
			super.dispose();
166
			super.dispose();
168
			fWrappedLabelProvider.dispose();
167
			fWrappedLabelProvider.dispose();

Return to bug 219393