/* * Copyright (c) 2012, the Dart project authors. * * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.eclipse.org/legal/epl-v10.html * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.google.dart.tools.ui.internal.viewsupport; import com.google.dart.tools.ui.PreferenceConstants; import com.google.dart.tools.ui.internal.preferences.AppearancePreferencePage; import org.eclipse.jface.preference.JFacePreferences; 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.ui.IWorkbenchPreferenceConstants; import org.eclipse.ui.PlatformUI; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; @SuppressWarnings("deprecation") public class ColoredViewersManager implements IPropertyChangeListener { private class ManagedViewer implements DisposeListener { private static final String COLORED_LABEL_KEY = "coloredlabel"; //$NON-NLS-1$ private final StructuredViewer fViewer; private OwnerDrawSupport fOwnerDrawSupport; private ManagedViewer(StructuredViewer viewer) { fViewer = viewer; fOwnerDrawSupport = null; fViewer.getControl().addDisposeListener(this); if (showColoredLabels()) { installOwnerDraw(); } } public final void refresh() { Control control = fViewer.getControl(); if (!control.isDisposed()) { if (showColoredLabels()) { installOwnerDraw(); } else { uninstallOwnerDraw(); } } } @Override public void widgetDisposed(DisposeEvent e) { uninstallColoredLabels(fViewer); } protected void installOwnerDraw() { if (fOwnerDrawSupport == null) { // not yet installed fOwnerDrawSupport = new OwnerDrawSupport(fViewer.getControl()) { // will install itself as listeners @Override public Color getColor(String foregroundColorName, Display display) { return getColorForName(foregroundColorName); } @Override public ColoredString getColoredLabel(Item item) { return getColoredLabelForView(item); } }; } refreshViewer(); } protected void uninstallOwnerDraw() { if (fOwnerDrawSupport == null) { return; // not installed } fOwnerDrawSupport.dispose(); // removes itself as listener fOwnerDrawSupport = null; refreshViewer(); } 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 = ColoredDartElementLabels.decorateColoredString( newLabel, itemText, ColoredDartElementLabels.DECORATIONS_STYLE); } item.setData(COLORED_LABEL_KEY, newLabel); // cache the result return newLabel; } 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 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()); } } } } public static final String QUALIFIER_COLOR_NAME = "com.google.dart.tools.ui.ColoredLabels.qualifier"; //$NON-NLS-1$ public static final String DECORATIONS_COLOR_NAME = "com.google.dart.tools.ui.ColoredLabels.decorations"; //$NON-NLS-1$ public static final String COUNTER_COLOR_NAME = "com.google.dart.tools.ui.ColoredLabels.counter"; //$NON-NLS-1$ public static final String INHERITED_COLOR_NAME = "com.google.dart.tools.ui.ColoredLabels.inherited"; //$NON-NLS-1$ public static final String HIGHLIGHT_BG_COLOR_NAME = "com.google.dart.tools.ui.ColoredLabels.match_highlight"; //$NON-NLS-1$ public static final String HIGHLIGHT_WRITE_BG_COLOR_NAME = "com.google.dart.tools.ui.ColoredLabels.writeaccess_highlight"; //$NON-NLS-1$ private static ColoredViewersManager fgInstance = new ColoredViewersManager(); public static void install(ColoringLabelProvider labelProvider) { fgInstance.installColoredLabels(labelProvider); } public static void install(StructuredViewer viewer) { fgInstance.installColoredLabels(viewer); } public static boolean showColoredLabels() { String preference = PreferenceConstants.getPreference( AppearancePreferencePage.PREF_COLORED_LABELS); return preference != null && Boolean.valueOf(preference).booleanValue(); } public static void uninstall(ColoringLabelProvider labelProvider) { fgInstance.uninstallColoredLabels(labelProvider); } private final Map<StructuredViewer, ManagedViewer> fManagedViewers; private Set<ColoringLabelProvider> fManagedLabelProviders; private final ColorRegistry fColorRegisty; public ColoredViewersManager() { fManagedViewers = new HashMap<StructuredViewer, ManagedViewer>(); fManagedLabelProviders = new HashSet<ColoringLabelProvider>(); fColorRegisty = JFaceResources.getColorRegistry(); } public Color getColorForName(String symbolicName) { return fColorRegisty.get(symbolicName); } public void installColoredLabels(ColoringLabelProvider labelProvider) { if (fManagedLabelProviders.contains(labelProvider)) { return; } if (fManagedLabelProviders.isEmpty()) { // first lp installed PlatformUI.getPreferenceStore().addPropertyChangeListener(this); JFaceResources.getColorRegistry().addListener(this); } fManagedLabelProviders.add(labelProvider); } 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)); } @Override 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) || property.equals(JFacePreferences.QUALIFIER_COLOR) || property.equals(JFacePreferences.COUNTER_COLOR) || property.equals(JFacePreferences.DECORATIONS_COLOR) || property.equals(HIGHLIGHT_BG_COLOR_NAME) || property.equals(HIGHLIGHT_WRITE_BG_COLOR_NAME) || property.equals(INHERITED_COLOR_NAME) || property.equals(IWorkbenchPreferenceConstants.USE_COLORED_LABELS)) { Display.getDefault().asyncExec(new Runnable() { @Override public void run() { refreshAllViewers(); } }); } } public void uninstallColoredLabels(ColoringLabelProvider labelProvider) { if (!fManagedLabelProviders.remove(labelProvider)) { return; // not installed } if (fManagedLabelProviders.isEmpty()) { PlatformUI.getPreferenceStore().removePropertyChangeListener(this); JFaceResources.getColorRegistry().removeListener(this); // last viewer uninstalled } } public void uninstallColoredLabels(StructuredViewer viewer) { ManagedViewer mv = fManagedViewers.remove(viewer); if (mv == null) { return; // not installed } if (fManagedViewers.isEmpty()) { PreferenceConstants.getPreferenceStore().removePropertyChangeListener(this); fColorRegisty.removeListener(this); // last viewer uninstalled } } protected final void refreshAllViewers() { for (Iterator<ManagedViewer> iterator = fManagedViewers.values().iterator(); iterator.hasNext();) { ManagedViewer viewer = iterator.next(); viewer.refresh(); } for (Iterator<ColoringLabelProvider> iterator = fManagedLabelProviders.iterator(); iterator.hasNext();) { ColoringLabelProvider lp = iterator.next(); lp.update(); } } }