| /******************************************************************************* |
| * Copyright (c) 2000, 2006 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.ui.internal.decorators; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.Set; |
| import java.util.StringTokenizer; |
| |
| import org.eclipse.core.runtime.IConfigurationElement; |
| import org.eclipse.core.runtime.IExtension; |
| import org.eclipse.core.runtime.IExtensionPoint; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.ListenerList; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.dynamichelpers.ExtensionTracker; |
| import org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler; |
| import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker; |
| import org.eclipse.jface.util.SafeRunnable; |
| import org.eclipse.jface.viewers.DecorationContext; |
| import org.eclipse.jface.viewers.IBaseLabelProvider; |
| import org.eclipse.jface.viewers.IColorDecorator; |
| import org.eclipse.jface.viewers.IDecorationContext; |
| import org.eclipse.jface.viewers.IDelayedLabelDecorator; |
| import org.eclipse.jface.viewers.IFontDecorator; |
| import org.eclipse.jface.viewers.ILabelDecorator; |
| import org.eclipse.jface.viewers.ILabelProviderListener; |
| import org.eclipse.jface.viewers.ILightweightLabelDecorator; |
| import org.eclipse.jface.viewers.LabelDecorator; |
| import org.eclipse.jface.viewers.LabelProviderChangedEvent; |
| import org.eclipse.swt.graphics.Color; |
| import org.eclipse.swt.graphics.Font; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.ui.IDecoratorManager; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.internal.IPreferenceConstants; |
| import org.eclipse.ui.internal.LegacyResourceSupport; |
| import org.eclipse.ui.internal.Workbench; |
| import org.eclipse.ui.internal.WorkbenchMessages; |
| import org.eclipse.ui.internal.WorkbenchPlugin; |
| import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants; |
| import org.eclipse.ui.internal.util.PrefUtil; |
| import org.eclipse.ui.internal.util.Util; |
| import org.eclipse.ui.progress.WorkbenchJob; |
| |
| /** |
| * The DecoratorManager is the class that handles all of the |
| * decorators defined in the image. |
| * |
| * @since 2.0 |
| */ |
| public class DecoratorManager extends LabelDecorator implements IDelayedLabelDecorator, |
| ILabelProviderListener, IDecoratorManager, IFontDecorator, IColorDecorator, IExtensionChangeHandler { |
| |
| private static String EXTENSIONPOINT_UNIQUE_ID = WorkbenchPlugin.PI_WORKBENCH + "." + IWorkbenchRegistryConstants.PL_DECORATORS; //$NON-NLS-1$ |
| |
| /** |
| * The family for the decorate job. |
| */ |
| public static final Object FAMILY_DECORATE = new Object(); |
| |
| private DecorationScheduler scheduler; |
| |
| private LightweightDecoratorManager lightweightManager; |
| |
| //Hold onto the list of listeners to be told if a change has occured |
| private ListenerList listeners = new ListenerList(); |
| |
| //The full definitions read from the registry. |
| //Initalize to an empty collection as this is rarely used now. |
| private FullDecoratorDefinition[] fullDefinitions; |
| |
| private FullTextDecoratorRunnable fullTextRunnable = new FullTextDecoratorRunnable(); |
| |
| private FullImageDecoratorRunnable fullImageRunnable = new FullImageDecoratorRunnable(); |
| |
| private static final FullDecoratorDefinition[] EMPTY_FULL_DEF = new FullDecoratorDefinition[0]; |
| |
| private final String PREFERENCE_SEPARATOR = ","; //$NON-NLS-1$ |
| |
| private final String VALUE_SEPARATOR = ":"; //$NON-NLS-1$ |
| |
| private final String P_TRUE = "true"; //$NON-NLS-1$ |
| |
| private final String P_FALSE = "false"; //$NON-NLS-1$ |
| |
| /** |
| * Create a new instance of the receiver and load the |
| * settings from the installed plug-ins. |
| */ |
| public DecoratorManager() { |
| |
| scheduler = new DecorationScheduler(this); |
| IExtensionTracker tracker = PlatformUI.getWorkbench() |
| .getExtensionTracker(); |
| tracker.registerHandler(this, ExtensionTracker.createExtensionPointFilter(getExtensionPointFilter())); |
| } |
| |
| /** |
| * Initalize the decorator definitions. |
| */ |
| private void initializeDecoratorDefinitions() { |
| DecoratorRegistryReader reader = new DecoratorRegistryReader(); |
| Collection values = reader |
| .readRegistry(Platform.getExtensionRegistry()); |
| |
| ArrayList full = new ArrayList(); |
| ArrayList lightweight = new ArrayList(); |
| Iterator allDefinitions = values.iterator(); |
| IExtensionTracker configurationElementTracker = PlatformUI |
| .getWorkbench().getExtensionTracker(); |
| while (allDefinitions.hasNext()) { |
| DecoratorDefinition nextDefinition = (DecoratorDefinition) allDefinitions |
| .next(); |
| if (nextDefinition.isFull()) { |
| full.add(nextDefinition); |
| } else { |
| lightweight.add(nextDefinition); |
| } |
| |
| configurationElementTracker.registerObject(nextDefinition.getConfigurationElement().getDeclaringExtension(), nextDefinition, IExtensionTracker.REF_WEAK); |
| } |
| |
| fullDefinitions = new FullDecoratorDefinition[full.size()]; |
| full.toArray(fullDefinitions); |
| |
| LightweightDecoratorDefinition[] lightweightDefinitions = new LightweightDecoratorDefinition[lightweight |
| .size()]; |
| lightweight.toArray(lightweightDefinitions); |
| |
| lightweightManager = new LightweightDecoratorManager( |
| lightweightDefinitions); |
| |
| applyDecoratorsPreference(); |
| } |
| |
| /** |
| * For dynamic UI |
| * |
| * @param definition the definition to add |
| * @since 3.0 |
| */ |
| public void addDecorator(DecoratorDefinition definition) { |
| if (definition.isFull()) { |
| if (getFullDecoratorDefinition(definition.getId()) == null) { |
| FullDecoratorDefinition[] oldDefs = getFullDefinitions(); |
| fullDefinitions = new FullDecoratorDefinition[fullDefinitions.length + 1]; |
| System |
| .arraycopy(oldDefs, 0, fullDefinitions, 0, |
| oldDefs.length); |
| fullDefinitions[oldDefs.length] = (FullDecoratorDefinition) definition; |
| clearCaches(); |
| updateForEnablementChange(); |
| } |
| } else { |
| if (getLightweightManager().addDecorator( |
| (LightweightDecoratorDefinition) definition)) { |
| clearCaches(); |
| updateForEnablementChange(); |
| } |
| } |
| ((Workbench) PlatformUI.getWorkbench()) |
| .getExtensionTracker().registerObject( |
| definition.getConfigurationElement().getDeclaringExtension(), definition, IExtensionTracker.REF_WEAK); |
| } |
| |
| /** |
| * See if the supplied decorator cache has a value for the |
| * element. If not calculate it from the enabledDefinitions and |
| * update the cache. |
| * @return Collection of DecoratorDefinition. |
| * @param element The element being tested. |
| * @param enabledDefinitions The definitions currently defined for this decorator. |
| */ |
| static Collection getDecoratorsFor(Object element, |
| DecoratorDefinition[] enabledDefinitions) { |
| |
| ArrayList decorators = new ArrayList(); |
| |
| for (int i = 0; i < enabledDefinitions.length; i++) { |
| if (enabledDefinitions[i].isEnabledFor(element)) { |
| decorators.add(enabledDefinitions[i]); |
| } |
| } |
| |
| return decorators; |
| |
| } |
| |
| |
| /** |
| * Add the listener to the list of listeners. |
| */ |
| public void addListener(ILabelProviderListener listener) { |
| listeners.add(listener); |
| } |
| |
| /** |
| * Remove the listener from the list. |
| */ |
| public void removeListener(ILabelProviderListener listener) { |
| listeners.remove(listener); |
| scheduler.listenerRemoved(listener); |
| } |
| |
| /** |
| * Get the list of elements listening to the receiver. |
| * @return ILabelProviderListener [] |
| */ |
| ILabelProviderListener [] getListeners(){ |
| Object[] array = listeners.getListeners(); |
| ILabelProviderListener [] listenerArray = |
| new ILabelProviderListener [array.length]; |
| System.arraycopy(array,0,listenerArray,0,listenerArray.length); |
| return listenerArray; |
| } |
| |
| /** |
| * Inform all of the listeners that require an update |
| * @param listener The listener we are updating. |
| * @param event |
| * the event with the update details |
| */ |
| void fireListener(final LabelProviderChangedEvent event, final ILabelProviderListener listener) { |
| Platform.run(new SafeRunnable() { |
| public void run() { |
| listener.labelProviderChanged(event); |
| } |
| }); |
| |
| } |
| |
| /** |
| * Inform all of the listeners that require an update |
| * @param event the event with the update details |
| */ |
| void fireListeners(final LabelProviderChangedEvent event) { |
| Object[] array = listeners.getListeners(); |
| for (int i = 0; i < array.length; i++) { |
| final ILabelProviderListener l = (ILabelProviderListener) array[i]; |
| Platform.run(new SafeRunnable() { |
| public void run() { |
| l.labelProviderChanged(event); |
| } |
| }); |
| } |
| } |
| |
| /** |
| * Fire any listeners from the UIThread. Used for cases where this |
| * may be invoked outside of the UI by the public API. |
| * @param event the event with the update details |
| */ |
| void fireListenersInUIThread(final LabelProviderChangedEvent event) { |
| |
| //No updates if there is no UI |
| if (!PlatformUI.isWorkbenchRunning()) { |
| return; |
| } |
| |
| //Only bother with the job if in the UI Thread |
| if (Thread.currentThread() == PlatformUI.getWorkbench().getDisplay() |
| .getThread()) { |
| fireListeners(event); |
| return; |
| } |
| |
| WorkbenchJob updateJob = new WorkbenchJob(WorkbenchMessages.DecorationScheduler_UpdateJobName) { |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| public IStatus runInUIThread(IProgressMonitor monitor) { |
| fireListeners(event); |
| return Status.OK_STATUS; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.core.runtime.jobs.Job#belongsTo(java.lang.Object) |
| */ |
| public boolean belongsTo(Object family) { |
| return FAMILY_DECORATE == family; |
| } |
| }; |
| updateJob.setSystem(true); |
| updateJob.schedule(); |
| |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.viewers.ILabelDecorator2#decorateText(java.lang.String, java.lang.Object, org.eclipse.jface.viewers.IDecorationContext) |
| */ |
| public String decorateText(String text, Object element, IDecorationContext context) { |
| //Get any adaptations to IResource |
| Object adapted = getResourceAdapter(element); |
| String result = scheduler.decorateWithText(text, element, adapted, context); |
| FullDecoratorDefinition[] decorators = getDecoratorsFor(element); |
| for (int i = 0; i < decorators.length; i++) { |
| if (decorators[i].isEnabledFor(element)) { |
| String newResult = safeDecorateText(element, result, |
| decorators[i]); |
| if (newResult != null) { |
| result = newResult; |
| } |
| } |
| } |
| |
| if (adapted != null) { |
| decorators = getDecoratorsFor(adapted); |
| for (int i = 0; i < decorators.length; i++) { |
| if (decorators[i].isAdaptable() |
| && decorators[i].isEnabledFor(adapted)) { |
| String newResult = safeDecorateText(adapted, result, |
| decorators[i]); |
| if (newResult != null) { |
| result = newResult; |
| } |
| } |
| } |
| } |
| |
| return result; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * @see org.eclipse.jface.viewers.ILabelDecorator#decorateText(java.lang.String, java.lang.Object) |
| */ |
| public String decorateText(String text, Object element) { |
| return decorateText(text, element, DecorationContext.DEFAULT_CONTEXT); |
| } |
| |
| /** |
| * Decorate the text in a SafeRunnable. |
| * @param element The element we are decorating |
| * @param start The currently decorated String |
| * @param decorator The decorator to run. |
| * @param context the decoration context |
| * @return String |
| */ |
| private String safeDecorateText(Object element, String start, |
| FullDecoratorDefinition decorator) { |
| fullTextRunnable.setValues(start, element, decorator); |
| Platform.run(fullTextRunnable); |
| String newResult = fullTextRunnable.getResult(); |
| return newResult; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.viewers.ILabelDecorator2#decorateImage(org.eclipse.swt.graphics.Image, java.lang.Object, org.eclipse.jface.viewers.IDecorationContext) |
| */ |
| public Image decorateImage(Image image, Object element, IDecorationContext context) { |
| Object adapted = getResourceAdapter(element); |
| Image result = scheduler.decorateWithOverlays(image, element, adapted, context); |
| FullDecoratorDefinition[] decorators = getDecoratorsFor(element); |
| |
| for (int i = 0; i < decorators.length; i++) { |
| if (decorators[i].isEnabledFor(element)) { |
| Image newResult = safeDecorateImage(element, result, |
| decorators[i]); |
| if (newResult != null) { |
| result = newResult; |
| } |
| } |
| } |
| |
| //Get any adaptations to IResource |
| |
| if (adapted != null) { |
| decorators = getDecoratorsFor(adapted); |
| for (int i = 0; i < decorators.length; i++) { |
| if (decorators[i].isAdaptable() |
| && decorators[i].isEnabledFor(adapted)) { |
| Image newResult = safeDecorateImage(adapted, result, |
| decorators[i]); |
| if (newResult != null) { |
| result = newResult; |
| } |
| } |
| } |
| } |
| |
| return result; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * @see org.eclipse.jface.viewers.ILabelDecorator#decorateImage(org.eclipse.swt.graphics.Image, java.lang.Object) |
| */ |
| public Image decorateImage(Image image, Object element) { |
| return decorateImage(image, element, DecorationContext.DEFAULT_CONTEXT); |
| } |
| |
| /** |
| * Decorate the image in a SafeRunnable. |
| * @param element The element we are decorating |
| * @param start The currently decorated Image |
| * @param decorator The decorator to run. |
| * @param context The decoration context |
| * @return Image |
| */ |
| private Image safeDecorateImage(Object element, Image start, |
| FullDecoratorDefinition decorator) { |
| fullImageRunnable.setValues(start, element, decorator); |
| Platform.run(fullImageRunnable); |
| Image newResult = fullImageRunnable.getResult(); |
| return newResult; |
| } |
| |
| /** |
| * Get the resource adapted object for the supplied |
| * element. Return <code>null</code>. if there isn't one. |
| * @param element |
| * @return Object or <code>null</code>. |
| */ |
| private Object getResourceAdapter(Object element) { |
| Object adapted = LegacyResourceSupport.getAdaptedContributorResource(element); |
| if (adapted != element) { |
| return adapted; //Avoid applying decorator twice |
| } |
| return null; |
| } |
| |
| /** |
| * Return whether or not the decorator registered for element |
| * has a label property called property name. |
| */ |
| public boolean isLabelProperty(Object element, String property) { |
| return isLabelProperty(element, property, true); |
| } |
| |
| /** |
| * Return whether or not the decorator registered for element |
| * has a label property called property name. |
| * Check for an adapted resource if checkAdapted is true. |
| * @param element |
| * @param property |
| * @param checkAdapted |
| * @return boolean <code>true</code> if there is a label property |
| * for element or its adapted value |
| */ |
| public boolean isLabelProperty(Object element, String property, |
| boolean checkAdapted) { |
| boolean fullCheck = isLabelProperty(element, property, |
| getDecoratorsFor(element)); |
| |
| if (fullCheck) { |
| return fullCheck; |
| } |
| |
| boolean lightweightCheck = isLabelProperty(element, property, |
| getLightweightManager().getDecoratorsFor(element)); |
| |
| if (lightweightCheck) { |
| return true; |
| } |
| |
| if (checkAdapted) { |
| //Get any adaptions to IResource |
| Object adapted = getResourceAdapter(element); |
| if (adapted == null || adapted == element) { |
| return false; |
| } |
| |
| fullCheck = isLabelProperty(adapted, property, |
| getDecoratorsFor(adapted)); |
| if (fullCheck) { |
| return fullCheck; |
| } |
| |
| return isLabelProperty(adapted, property, lightweightManager |
| .getDecoratorsFor(adapted)); |
| } |
| return false; |
| } |
| |
| private boolean isLabelProperty(Object element, String property, |
| DecoratorDefinition[] decorators) { |
| for (int i = 0; i < decorators.length; i++) { |
| if (decorators[i].isEnabledFor(element) |
| && decorators[i].isLabelProperty(element, property)) { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| /** |
| * Return the enabled full decorator definitions. |
| * @return FullDecoratorDefinition[] |
| */ |
| private FullDecoratorDefinition[] enabledFullDefinitions() { |
| |
| FullDecoratorDefinition[] full = getFullDefinitions(); |
| //As this are a deprecated data type optimize for |
| //the undefined case. |
| if(full.length == 0) { |
| return full; |
| } |
| ArrayList result = new ArrayList(); |
| for (int i = 0; i < full.length; i++) { |
| if (full[i].isEnabled()) { |
| result.add(full[i]); |
| } |
| } |
| FullDecoratorDefinition[] returnArray = new FullDecoratorDefinition[result |
| .size()]; |
| result.toArray(returnArray); |
| return returnArray; |
| } |
| |
| /* |
| * @see IBaseLabelProvider#dispose() |
| */ |
| public void dispose() { |
| //do nothing |
| } |
| |
| /** |
| * Clear the caches in the manager. This is required |
| * to avoid updates that may occur due to changes in |
| * enablement. |
| */ |
| public void clearCaches() { |
| getLightweightManager().reset(); |
| fullTextRunnable.clearReferences(); |
| fullImageRunnable.clearReferences(); |
| } |
| |
| /** |
| * Enablement had changed. Fire the listeners and write |
| * the preference. |
| */ |
| public void updateForEnablementChange() { |
| //Clear any results that may be around as all labels have changed |
| scheduler.clearResults(); |
| fireListenersInUIThread(new LabelProviderChangedEvent(this)); |
| writeDecoratorsPreference(); |
| } |
| |
| /** |
| * Get the DecoratorDefinitions defined on the receiver. |
| * @return DecoratorDefinition[] |
| */ |
| public DecoratorDefinition[] getAllDecoratorDefinitions() { |
| LightweightDecoratorDefinition[] lightweightDefinitions = getLightweightManager() |
| .getDefinitions(); |
| DecoratorDefinition[] returnValue = new DecoratorDefinition[fullDefinitions.length |
| + lightweightDefinitions.length]; |
| System.arraycopy(fullDefinitions, 0, returnValue, 0, |
| fullDefinitions.length); |
| System.arraycopy(lightweightDefinitions, 0, returnValue, |
| fullDefinitions.length, lightweightDefinitions.length); |
| return returnValue; |
| } |
| |
| /* |
| * @see ILabelProviderListener#labelProviderChanged(LabelProviderChangedEvent) |
| */ |
| public void labelProviderChanged(LabelProviderChangedEvent event) { |
| Object[] elements = event.getElements(); |
| scheduler.clearResults(); |
| //If the elements are not specified send out a general update |
| if (elements == null) { |
| fireListeners(event); |
| } else { |
| //Assume that someone is going to care about the |
| //decoration result and just start it right away |
| for (int i = 0; i < elements.length; i++) { |
| Object adapted = getResourceAdapter(elements[i]); |
| //Force an update in case full decorators are the only ones enabled |
| scheduler.queueForDecoration(elements[i], adapted, true, null, DecorationContext.DEFAULT_CONTEXT); |
| } |
| } |
| } |
| |
| /** |
| * Store the currently enabled decorators in |
| * preference store. |
| */ |
| private void writeDecoratorsPreference() { |
| StringBuffer enabledIds = new StringBuffer(); |
| writeDecoratorsPreference(enabledIds, getFullDefinitions()); |
| writeDecoratorsPreference(enabledIds, getLightweightManager() |
| .getDefinitions()); |
| |
| WorkbenchPlugin.getDefault().getPreferenceStore().setValue( |
| IPreferenceConstants.ENABLED_DECORATORS, enabledIds.toString()); |
| PrefUtil.savePrefs(); |
| } |
| |
| private void writeDecoratorsPreference(StringBuffer enabledIds, |
| DecoratorDefinition[] definitions) { |
| for (int i = 0; i < definitions.length; i++) { |
| enabledIds.append(definitions[i].getId()); |
| enabledIds.append(VALUE_SEPARATOR); |
| if (definitions[i].isEnabled()) { |
| enabledIds.append(P_TRUE); |
| } else { |
| enabledIds.append(P_FALSE); |
| } |
| |
| enabledIds.append(PREFERENCE_SEPARATOR); |
| } |
| } |
| |
| /** |
| * Get the currently enabled decorators in |
| * preference store and set the state of the |
| * current definitions accordingly. |
| */ |
| public void applyDecoratorsPreference() { |
| |
| String preferenceValue = WorkbenchPlugin.getDefault() |
| .getPreferenceStore().getString( |
| IPreferenceConstants.ENABLED_DECORATORS); |
| |
| StringTokenizer tokenizer = new StringTokenizer(preferenceValue, |
| PREFERENCE_SEPARATOR); |
| Set enabledIds = new HashSet(); |
| Set disabledIds = new HashSet(); |
| while (tokenizer.hasMoreTokens()) { |
| String nextValuePair = tokenizer.nextToken(); |
| |
| //Strip out the true or false to get the id |
| String id = nextValuePair.substring(0, nextValuePair |
| .indexOf(VALUE_SEPARATOR)); |
| if (nextValuePair.endsWith(P_TRUE)) { |
| enabledIds.add(id); |
| } else { |
| disabledIds.add(id); |
| } |
| } |
| |
| FullDecoratorDefinition[] full = getFullDefinitions(); |
| for (int i = 0; i < full.length; i++) { |
| String id = full[i].getId(); |
| if (enabledIds.contains(id)) { |
| full[i].setEnabled(true); |
| } else { |
| if (disabledIds.contains(id)) { |
| full[i].setEnabled(false); |
| } |
| } |
| } |
| |
| LightweightDecoratorDefinition[] lightweightDefinitions = getLightweightManager() |
| .getDefinitions(); |
| for (int i = 0; i < lightweightDefinitions.length; i++) { |
| String id = lightweightDefinitions[i].getId(); |
| if (enabledIds.contains(id)) { |
| lightweightDefinitions[i].setEnabled(true); |
| } else { |
| if (disabledIds.contains(id)) { |
| lightweightDefinitions[i].setEnabled(false); |
| } |
| } |
| } |
| |
| } |
| |
| /** |
| * Shutdown the decorator manager by disabling all |
| * of the decorators so that dispose() will be called |
| * on them. |
| */ |
| public void shutdown() { |
| //Disable all of the enabled decorators |
| //so as to force a dispose of thier decorators |
| FullDecoratorDefinition[] full = getFullDefinitions(); |
| for (int i = 0; i < full.length; i++) { |
| if (full[i].isEnabled()) { |
| full[i].setEnabled(false); |
| } |
| } |
| if(lightweightManager != null) { |
| getLightweightManager().shutdown(); |
| } |
| scheduler.shutdown(); |
| dispose(); |
| } |
| |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.IDecoratorManager#getEnabled(java.lang.String) |
| */ |
| public boolean getEnabled(String decoratorId) { |
| DecoratorDefinition definition = getDecoratorDefinition(decoratorId); |
| if (definition == null) { |
| return false; |
| } |
| return definition.isEnabled(); |
| } |
| |
| /** |
| * @see IDecoratorManager#getLabelDecorator() |
| */ |
| public ILabelDecorator getLabelDecorator() { |
| return this; |
| } |
| |
| /** |
| * @see IDecoratorManager#setEnabled(String, boolean) |
| */ |
| public void setEnabled(String decoratorId, boolean enabled) { |
| DecoratorDefinition definition = getDecoratorDefinition(decoratorId); |
| if (definition != null) { |
| definition.setEnabled(enabled); |
| clearCaches(); |
| updateForEnablementChange(); |
| } |
| } |
| |
| /* |
| * @see IDecoratorManager#getBaseLabelProvider(String) |
| */ |
| public IBaseLabelProvider getBaseLabelProvider(String decoratorId) { |
| IBaseLabelProvider fullProvider = getLabelDecorator(decoratorId); |
| if (fullProvider == null) { |
| return getLightweightLabelDecorator(decoratorId); |
| } |
| return fullProvider; |
| } |
| |
| /* |
| * @see IDecoratorManager#getLabelDecorator(String) |
| */ |
| public ILabelDecorator getLabelDecorator(String decoratorId) { |
| FullDecoratorDefinition definition = getFullDecoratorDefinition(decoratorId); |
| |
| //Do not return for a disabled decorator |
| if (definition != null && definition.isEnabled()) { |
| return definition.getDecorator(); |
| } |
| return null; |
| } |
| |
| /* |
| * @see IDecoratorManager#getLightweightLabelDecorator(String) |
| */ |
| public ILightweightLabelDecorator getLightweightLabelDecorator( |
| String decoratorId) { |
| LightweightDecoratorDefinition definition = getLightweightManager() |
| .getDecoratorDefinition(decoratorId); |
| //Do not return for a disabled decorator |
| if (definition != null && definition.isEnabled()) { |
| return definition.getDecorator(); |
| } |
| return null; |
| } |
| |
| /** |
| * Get the DecoratorDefinition with the supplied id |
| * @return DecoratorDefinition or <code>null</code> if it is not found |
| * @param decoratorId String |
| */ |
| private DecoratorDefinition getDecoratorDefinition(String decoratorId) { |
| DecoratorDefinition returnValue = getFullDecoratorDefinition(decoratorId); |
| if (returnValue == null) { |
| return getLightweightManager().getDecoratorDefinition(decoratorId); |
| } |
| return returnValue; |
| } |
| |
| /** |
| * Get the FullDecoratorDefinition with the supplied id |
| * @return FullDecoratorDefinition or <code>null</code> if it is not found |
| * @param decoratorId the id |
| */ |
| private FullDecoratorDefinition getFullDecoratorDefinition( |
| String decoratorId) { |
| int idx = getFullDecoratorDefinitionIdx(decoratorId); |
| if (idx != -1) { |
| return getFullDefinitions()[idx]; |
| } |
| return null; |
| } |
| |
| /** |
| * Return the index of the definition in the array. |
| * |
| * @param decoratorId the id |
| * @return the index of the definition in the array or <code>-1</code> |
| * @since 3.1 |
| */ |
| private int getFullDecoratorDefinitionIdx( |
| String decoratorId) { |
| FullDecoratorDefinition[] full = getFullDefinitions(); |
| for (int i = 0; i < full.length; i++) { |
| if (full[i].getId().equals(decoratorId)) { |
| return i; |
| } |
| } |
| return -1; |
| } |
| |
| |
| /** |
| * Get the full decorator definitions registered for elements of this type. |
| * @param element The element to look up |
| * @return FullDecoratorDefinition[] |
| */ |
| private FullDecoratorDefinition[] getDecoratorsFor(Object element) { |
| |
| if (element == null) { |
| return EMPTY_FULL_DEF; |
| } |
| |
| Collection decorators = getDecoratorsFor(element, |
| enabledFullDefinitions()); |
| FullDecoratorDefinition[] decoratorArray = EMPTY_FULL_DEF; |
| if (decorators.size() > 0){ |
| decoratorArray = new FullDecoratorDefinition[decorators.size()]; |
| decorators.toArray(decoratorArray); |
| } |
| |
| return decoratorArray; |
| } |
| |
| /** |
| * Returns the lightweightManager. This method is |
| * public for use by test cases. No other classes outside of |
| * this package should use this method. |
| * @return LightweightDecoratorManager |
| */ |
| public LightweightDecoratorManager getLightweightManager() { |
| if(lightweightManager == null) { |
| initializeDecoratorDefinitions(); |
| } |
| return lightweightManager; |
| } |
| |
| /** |
| * @see org.eclipse.ui.IDecoratorManager#update(java.lang.String) |
| */ |
| public void update(String decoratorId) { |
| |
| IBaseLabelProvider provider = getBaseLabelProvider(decoratorId); |
| if (provider != null) { |
| scheduler.clearResults(); |
| fireListeners(new LabelProviderChangedEvent(provider)); |
| } |
| |
| } |
| |
| public boolean prepareDecoration(Object element, String originalText, IDecorationContext context) { |
| // Check if there is a decoration ready or if there is no lightweight decorators to be applied |
| if (scheduler.isDecorationReady(element, context) |
| || !getLightweightManager().hasEnabledDefinitions()) { |
| return true; |
| } |
| |
| // Force an update if there is a text already |
| boolean force = true; |
| //If not then do not force as the undecorated value is fine |
| if(originalText == null || originalText.length() == 0) { |
| force = false; |
| } |
| |
| // Queue the decoration. |
| scheduler.queueForDecoration(element, getResourceAdapter(element), |
| force, originalText, context); |
| |
| //If all that is there is deferred ones then defer decoration. |
| //For the sake of efficiency we do not test for enablement at this |
| //point and just abandon deferment if there are any to run right |
| //away |
| return getFullDefinitions().length > 0; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.viewers.IDelayedLabelDecorator#prepareDecoration(java.lang.Object, java.lang.String) |
| */ |
| public boolean prepareDecoration(Object element, String originalText) { |
| return prepareDecoration(element, originalText, DecorationContext.DEFAULT_CONTEXT); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.viewers.IFontDecorator#decorateFont(java.lang.Object) |
| */ |
| public Font decorateFont(Object element) { |
| return scheduler.getFont(element, getResourceAdapter(element)); |
| } |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.viewers.IColorDecorator#decorateBackground(java.lang.Object) |
| */ |
| public Color decorateBackground(Object element) { |
| return scheduler.getBackgroundColor(element, getResourceAdapter(element)); |
| } |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.viewers.IColorDecorator#decorateForeground(java.lang.Object) |
| */ |
| public Color decorateForeground(Object element) { |
| return scheduler.getForegroundColor(element, getResourceAdapter(element)); |
| } |
| /** |
| * Get all of the defined fullDefinitions. Initalize if |
| * required |
| * @return FullDecoratorDefinition[] |
| */ |
| private FullDecoratorDefinition[] getFullDefinitions() { |
| if(fullDefinitions == null) { |
| initializeDecoratorDefinitions(); |
| } |
| return fullDefinitions; |
| } |
| |
| private IExtensionPoint getExtensionPointFilter() { |
| return Platform.getExtensionRegistry().getExtensionPoint(EXTENSIONPOINT_UNIQUE_ID); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.core.runtime.dynamicHelpers.IExtensionChangeHandler#addExtension(org.eclipse.core.runtime.dynamicHelpers.IExtensionTracker, org.eclipse.core.runtime.IExtension) |
| */ |
| public void addExtension(IExtensionTracker tracker, IExtension addedExtension) { |
| IConfigurationElement addedElements[] = addedExtension.getConfigurationElements(); |
| for (int i = 0; i < addedElements.length; i++) { |
| DecoratorRegistryReader reader = new DecoratorRegistryReader(); |
| reader.readElement(addedElements[i]); |
| for (Iterator j = reader.getValues().iterator(); j.hasNext();) { |
| addDecorator((DecoratorDefinition) j.next()); |
| } |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.core.runtime.dynamicHelpers.IExtensionChangeHandler#removeExtension(org.eclipse.core.runtime.IExtension, java.lang.Object[]) |
| */ |
| public void removeExtension(IExtension source, Object[] objects) { |
| |
| boolean shouldClear = false; |
| for (int i = 0; i < objects.length; i++) { |
| if (objects[i] instanceof DecoratorDefinition) { |
| DecoratorDefinition definition = (DecoratorDefinition) objects[i]; |
| if (definition.isFull()) { |
| int idx = getFullDecoratorDefinitionIdx(definition.getId()); |
| if (idx != -1) { |
| FullDecoratorDefinition[] oldDefs = getFullDefinitions(); |
| Util |
| .arrayCopyWithRemoval( |
| oldDefs, |
| fullDefinitions = new FullDecoratorDefinition[fullDefinitions.length - 1], |
| idx); |
| shouldClear = true; |
| } |
| } else { |
| shouldClear |= getLightweightManager().removeDecorator( |
| (LightweightDecoratorDefinition) definition); |
| } |
| } |
| } |
| |
| if(shouldClear){ |
| clearCaches(); |
| updateForEnablementChange(); |
| } |
| |
| } |
| |
| } |