/*******************************************************************************
* Copyright (c) 2000, 2007 IBM Corporation 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.wst.jsdt.internal.ui.viewsupport;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.jface.resource.ColorRegistry;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Item;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.wst.jsdt.internal.ui.preferences.AppearancePreferencePage;
import org.eclipse.wst.jsdt.ui.PreferenceConstants;
public class ColoredViewersManager implements IPropertyChangeListener {
public static final String QUALIFIER_COLOR_NAME= "org.eclipse.wst.jsdt.ui.ColoredLabels.qualifier"; //$NON-NLS-1$
public static final String DECORATIONS_COLOR_NAME= "org.eclipse.wst.jsdt.ui.ColoredLabels.decorations"; //$NON-NLS-1$
public static final String COUNTER_COLOR_NAME= "org.eclipse.wst.jsdt.ui.ColoredLabels.counter"; //$NON-NLS-1$
public static final String INHERITED_COLOR_NAME= "org.eclipse.wst.jsdt.ui.ColoredLabels.inherited"; //$NON-NLS-1$
private static ColoredViewersManager fgInstance= new ColoredViewersManager();
private Map fManagedViewers;
private ColorRegistry fColorRegisty;
public ColoredViewersManager() {
fManagedViewers= new HashMap();
fColorRegisty= JFaceResources.getColorRegistry();
}
public void installColoredLabels(StructuredViewer viewer) {
if (fManagedViewers.containsKey(viewer)) {
return; // already installed
}
if (fManagedViewers.isEmpty()) {
// first viewer installed
PreferenceConstants.getPreferenceStore().addPropertyChangeListener(this);
fColorRegisty.addListener(this);
}
fManagedViewers.put(viewer, new ManagedViewer(viewer));
}
public void uninstallColoredLabels(StructuredViewer viewer) {
ManagedViewer mv= (ManagedViewer) fManagedViewers.remove(viewer);
if (mv == null)
return; // not installed
if (fManagedViewers.isEmpty()) {
PreferenceConstants.getPreferenceStore().removePropertyChangeListener(this);
fColorRegisty.removeListener(this);
// last viewer uninstalled
}
}
public Color getColorForName(String symbolicName) {
return fColorRegisty.get(symbolicName);
}
public void propertyChange(PropertyChangeEvent event) {
String property= event.getProperty();
if (property.equals(QUALIFIER_COLOR_NAME) || property.equals(COUNTER_COLOR_NAME) || property.equals(DECORATIONS_COLOR_NAME)
|| property.equals(AppearancePreferencePage.PREF_COLORED_LABELS)) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
refreshAllViewers();
}
});
}
}
protected final void refreshAllViewers() {
for (Iterator iterator= fManagedViewers.values().iterator(); iterator.hasNext();) {
ManagedViewer viewer= (ManagedViewer) iterator.next();
viewer.refresh();
}
}
private class ManagedViewer implements DisposeListener {
private static final String COLORED_LABEL_KEY= "coloredlabel"; //$NON-NLS-1$
private StructuredViewer fViewer;
private OwnerDrawSupport fOwnerDrawSupport;
private ManagedViewer(StructuredViewer viewer) {
fViewer= viewer;
fOwnerDrawSupport= null;
fViewer.getControl().addDisposeListener(this);
if (showColoredLabels()) {
installOwnerDraw();
}
}
/* (non-Javadoc)
* @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent)
*/
public void widgetDisposed(DisposeEvent e) {
uninstallColoredLabels(fViewer);
}
public final void refresh() {
Control control= fViewer.getControl();
if (!control.isDisposed()) {
if (showColoredLabels()) {
installOwnerDraw();
} else {
uninstallOwnerDraw();
}
}
}
protected void installOwnerDraw() {
if (fOwnerDrawSupport == null) {
// not yet installed
fOwnerDrawSupport= new OwnerDrawSupport(fViewer.getControl()) { // will install itself as listeners
public ColoredString getColoredLabel(Item item) {
return getColoredLabelForView(item);
}
public Color getColor(String foregroundColorName, Display display) {
return getColorForName(foregroundColorName);
}
};
}
refreshViewer();
}
protected void uninstallOwnerDraw() {
if (fOwnerDrawSupport == null)
return; // not installed
fOwnerDrawSupport.dispose(); // removes itself as listener
fOwnerDrawSupport= null;
refreshViewer();
}
private void refreshViewer() {
Control control= fViewer.getControl();
if (!control.isDisposed()) {
if (control instanceof Tree) {
refresh(((Tree) control).getItems());
} else if (control instanceof Table) {
refresh(((Table) control).getItems());
}
}
}
private void refresh(Item[] items) {
for (int i= 0; i < items.length; i++) {
Item item= items[i];
item.setData(COLORED_LABEL_KEY, null);
String text= item.getText();
item.setText(""); //$NON-NLS-1$
item.setText(text);
if (item instanceof TreeItem) {
refresh(((TreeItem) item).getItems());
}
}
}
private ColoredString getColoredLabelForView(Item item) {
ColoredString oldLabel= (ColoredString) item.getData(COLORED_LABEL_KEY);
String itemText= item.getText();
if (oldLabel != null && oldLabel.getString().equals(itemText)) {
// avoid accesses to the label provider if possible
return oldLabel;
}
ColoredString newLabel= null;
IBaseLabelProvider labelProvider= fViewer.getLabelProvider();
if (labelProvider instanceof IRichLabelProvider) {
newLabel= ((IRichLabelProvider) labelProvider).getRichTextLabel(item.getData());
}
if (newLabel == null) {
newLabel= new ColoredString(itemText); // fallback. Should never happen.
} else if (!newLabel.getString().equals(itemText)) {
// the decorator manager has already queued an new update
newLabel= ColoredJavaElementLabels.decorateColoredString(newLabel, itemText, ColoredJavaElementLabels.DECORATIONS_STYLE);
}
item.setData(COLORED_LABEL_KEY, newLabel); // cache the result
return newLabel;
}
}
public static boolean showColoredLabels() {
String preference= PreferenceConstants.getPreference(AppearancePreferencePage.PREF_COLORED_LABELS, null);
return preference != null && Boolean.valueOf(preference).booleanValue();
}
public static void install(StructuredViewer viewer) {
fgInstance.installColoredLabels(viewer);
}
}