001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.ui.viewsupport;
011:
012: import java.util.HashMap;
013: import java.util.Iterator;
014: import java.util.Map;
015:
016: import org.eclipse.swt.events.DisposeEvent;
017: import org.eclipse.swt.events.DisposeListener;
018: import org.eclipse.swt.graphics.Color;
019: import org.eclipse.swt.widgets.Control;
020: import org.eclipse.swt.widgets.Display;
021: import org.eclipse.swt.widgets.Item;
022: import org.eclipse.swt.widgets.Table;
023: import org.eclipse.swt.widgets.Tree;
024: import org.eclipse.swt.widgets.TreeItem;
025:
026: import org.eclipse.jface.resource.ColorRegistry;
027: import org.eclipse.jface.resource.JFaceResources;
028: import org.eclipse.jface.util.IPropertyChangeListener;
029: import org.eclipse.jface.util.PropertyChangeEvent;
030: import org.eclipse.jface.viewers.IBaseLabelProvider;
031: import org.eclipse.jface.viewers.StructuredViewer;
032:
033: import org.eclipse.jdt.ui.PreferenceConstants;
034:
035: public class ColoredViewersManager implements IPropertyChangeListener {
036:
037: /**
038: * XXX: will probably be moved to {@link PreferenceConstants}.
039: */
040: public static final String PREF_COLORED_LABELS = "colored_labels_in_views"; //$NON-NLS-1$
041:
042: public static final String QUALIFIER_COLOR_NAME = "org.eclipse.jdt.ui.ColoredLabels.qualifier"; //$NON-NLS-1$
043: public static final String DECORATIONS_COLOR_NAME = "org.eclipse.jdt.ui.ColoredLabels.decorations"; //$NON-NLS-1$
044: public static final String COUNTER_COLOR_NAME = "org.eclipse.jdt.ui.ColoredLabels.counter"; //$NON-NLS-1$
045: public static final String INHERITED_COLOR_NAME = "org.eclipse.jdt.ui.ColoredLabels.inherited"; //$NON-NLS-1$
046:
047: public static final String HIGHLIGHT_BG_COLOR_NAME = "org.eclipse.jdt.ui.ColoredLabels.match_highlight"; //$NON-NLS-1$
048:
049: private static ColoredViewersManager fgInstance = new ColoredViewersManager();
050:
051: private Map fManagedViewers;
052: private ColorRegistry fColorRegisty;
053:
054: public ColoredViewersManager() {
055: fManagedViewers = new HashMap();
056: fColorRegisty = JFaceResources.getColorRegistry();
057: }
058:
059: public void installColoredLabels(StructuredViewer viewer) {
060: if (fManagedViewers.containsKey(viewer)) {
061: return; // already installed
062: }
063: if (fManagedViewers.isEmpty()) {
064: // first viewer installed
065: PreferenceConstants.getPreferenceStore()
066: .addPropertyChangeListener(this );
067: fColorRegisty.addListener(this );
068: }
069: fManagedViewers.put(viewer, new ManagedViewer(viewer));
070: }
071:
072: public void uninstallColoredLabels(StructuredViewer viewer) {
073: ManagedViewer mv = (ManagedViewer) fManagedViewers
074: .remove(viewer);
075: if (mv == null)
076: return; // not installed
077:
078: if (fManagedViewers.isEmpty()) {
079: PreferenceConstants.getPreferenceStore()
080: .removePropertyChangeListener(this );
081: fColorRegisty.removeListener(this );
082: // last viewer uninstalled
083: }
084: }
085:
086: public Color getColorForName(String symbolicName) {
087: return fColorRegisty.get(symbolicName);
088: }
089:
090: public void propertyChange(PropertyChangeEvent event) {
091: String property = event.getProperty();
092: if (property.equals(QUALIFIER_COLOR_NAME)
093: || property.equals(COUNTER_COLOR_NAME)
094: || property.equals(DECORATIONS_COLOR_NAME)
095: || property.equals(HIGHLIGHT_BG_COLOR_NAME)
096: || property.equals(PREF_COLORED_LABELS)) {
097: Display.getDefault().asyncExec(new Runnable() {
098: public void run() {
099: refreshAllViewers();
100: }
101: });
102: }
103: }
104:
105: protected final void refreshAllViewers() {
106: for (Iterator iterator = fManagedViewers.values().iterator(); iterator
107: .hasNext();) {
108: ManagedViewer viewer = (ManagedViewer) iterator.next();
109: viewer.refresh();
110: }
111: }
112:
113: private class ManagedViewer implements DisposeListener {
114:
115: private static final String COLORED_LABEL_KEY = "coloredlabel"; //$NON-NLS-1$
116:
117: private StructuredViewer fViewer;
118: private OwnerDrawSupport fOwnerDrawSupport;
119:
120: private ManagedViewer(StructuredViewer viewer) {
121: fViewer = viewer;
122: fOwnerDrawSupport = null;
123: fViewer.getControl().addDisposeListener(this );
124: if (showColoredLabels()) {
125: installOwnerDraw();
126: }
127: }
128:
129: /* (non-Javadoc)
130: * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent)
131: */
132: public void widgetDisposed(DisposeEvent e) {
133: uninstallColoredLabels(fViewer);
134: }
135:
136: public final void refresh() {
137: Control control = fViewer.getControl();
138: if (!control.isDisposed()) {
139: if (showColoredLabels()) {
140: installOwnerDraw();
141: } else {
142: uninstallOwnerDraw();
143: }
144: }
145: }
146:
147: protected void installOwnerDraw() {
148: if (fOwnerDrawSupport == null) {
149: // not yet installed
150: fOwnerDrawSupport = new OwnerDrawSupport(fViewer
151: .getControl()) { // will install itself as listeners
152: public ColoredString getColoredLabel(Item item) {
153: return getColoredLabelForView(item);
154: }
155:
156: public Color getColor(String colorName,
157: Display display) {
158: return getColorForName(colorName);
159: }
160: };
161: }
162: refreshViewer();
163: }
164:
165: protected void uninstallOwnerDraw() {
166: if (fOwnerDrawSupport == null)
167: return; // not installed
168:
169: fOwnerDrawSupport.dispose(); // removes itself as listener
170: fOwnerDrawSupport = null;
171: refreshViewer();
172: }
173:
174: private void refreshViewer() {
175: Control control = fViewer.getControl();
176: if (!control.isDisposed()) {
177: if (control instanceof Tree) {
178: refresh(((Tree) control).getItems());
179: } else if (control instanceof Table) {
180: refresh(((Table) control).getItems());
181: }
182: }
183: }
184:
185: private void refresh(Item[] items) {
186: for (int i = 0; i < items.length; i++) {
187: Item item = items[i];
188: item.setData(COLORED_LABEL_KEY, null);
189: String text = item.getText();
190: item.setText(""); //$NON-NLS-1$
191: item.setText(text);
192: if (item instanceof TreeItem) {
193: refresh(((TreeItem) item).getItems());
194: }
195: }
196: }
197:
198: private ColoredString getColoredLabelForView(Item item) {
199: ColoredString oldLabel = (ColoredString) item
200: .getData(COLORED_LABEL_KEY);
201: String itemText = item.getText();
202: if (oldLabel != null
203: && oldLabel.getString().equals(itemText)) {
204: // avoid accesses to the label provider if possible
205: return oldLabel;
206: }
207: ColoredString newLabel = null;
208: IBaseLabelProvider labelProvider = fViewer
209: .getLabelProvider();
210: if (labelProvider instanceof IRichLabelProvider) {
211: newLabel = ((IRichLabelProvider) labelProvider)
212: .getRichTextLabel(item.getData());
213: }
214: if (newLabel == null) {
215: newLabel = new ColoredString(itemText); // fallback. Should never happen.
216: } else if (!newLabel.getString().equals(itemText)) {
217: // the decorator manager has already queued an new update
218: newLabel = ColoredJavaElementLabels
219: .decorateColoredString(
220: newLabel,
221: itemText,
222: ColoredJavaElementLabels.DECORATIONS_STYLE);
223: }
224: item.setData(COLORED_LABEL_KEY, newLabel); // cache the result
225: return newLabel;
226: }
227:
228: }
229:
230: public static boolean showColoredLabels() {
231: String preference = PreferenceConstants.getPreference(
232: PREF_COLORED_LABELS, null);
233: return preference != null
234: && Boolean.valueOf(preference).booleanValue();
235: }
236:
237: public static void install(StructuredViewer viewer) {
238: fgInstance.installColoredLabels(viewer);
239: }
240:
241: }
|