1 /******************************************************************************* 2 * Copyright (c) 2000, 2015 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 * Fair Isaac Corporation <Hemant.Singh@Gmail.com> - Bug 326695 14 *******************************************************************************/ 15 package org.eclipse.ui.model; 16 17 import org.eclipse.core.runtime.Adapters; 18 import org.eclipse.jface.resource.ColorDescriptor; 19 import org.eclipse.jface.resource.FontDescriptor; 20 import org.eclipse.jface.resource.ImageDescriptor; 21 import org.eclipse.jface.resource.JFaceResources; 22 import org.eclipse.jface.resource.LocalResourceManager; 23 import org.eclipse.jface.resource.ResourceManager; 24 import org.eclipse.jface.viewers.DecoratingLabelProvider; 25 import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider; 26 import org.eclipse.jface.viewers.IColorProvider; 27 import org.eclipse.jface.viewers.IFontProvider; 28 import org.eclipse.jface.viewers.ILabelProvider; 29 import org.eclipse.jface.viewers.LabelProvider; 30 import org.eclipse.jface.viewers.LabelProviderChangedEvent; 31 import org.eclipse.jface.viewers.StyledCellLabelProvider; 32 import org.eclipse.jface.viewers.StyledString; 33 import org.eclipse.jface.viewers.StyledString.Styler; 34 import org.eclipse.swt.graphics.Color; 35 import org.eclipse.swt.graphics.Font; 36 import org.eclipse.swt.graphics.FontData; 37 import org.eclipse.swt.graphics.Image; 38 import org.eclipse.swt.graphics.RGB; 39 import org.eclipse.ui.IEditorRegistry; 40 import org.eclipse.ui.IPropertyListener; 41 import org.eclipse.ui.PlatformUI; 42 43 /** 44 * Provides basic labels for adaptable objects that have the 45 * <code>IWorkbenchAdapter</code> adapter associated with them. All dispensed 46 * images are cached until the label provider is explicitly disposed. This class 47 * provides a facility for subclasses to define annotations on the labels and 48 * icons of adaptable objects. 49 */ 50 public class WorkbenchLabelProvider extends LabelProvider 51 implements IColorProvider, IFontProvider, IStyledLabelProvider { 52 53 /** 54 * Returns a workbench label provider that is hooked up to the decorator 55 * mechanism. 56 * 57 * @return a new <code>DecoratingLabelProvider</code> which wraps a new 58 * <code>WorkbenchLabelProvider</code> 59 */ getDecoratingWorkbenchLabelProvider()60 public static ILabelProvider getDecoratingWorkbenchLabelProvider() { 61 return new DecoratingLabelProvider(new WorkbenchLabelProvider(), 62 PlatformUI.getWorkbench().getDecoratorManager().getLabelDecorator()); 63 } 64 65 /** 66 * Listener that tracks changes to the editor registry and does a full update 67 * when it changes, since many workbench adapters derive their icon from the 68 * file associations in the registry. 69 */ 70 private IPropertyListener editorRegistryListener = (source, propId) -> { 71 if (propId == IEditorRegistry.PROP_CONTENTS) { 72 fireLabelProviderChanged(new LabelProviderChangedEvent(WorkbenchLabelProvider.this)); 73 } 74 }; 75 private ResourceManager resourceManager; 76 77 /** 78 * Creates a new workbench label provider. 79 */ WorkbenchLabelProvider()80 public WorkbenchLabelProvider() { 81 PlatformUI.getWorkbench().getEditorRegistry().addPropertyListener(editorRegistryListener); 82 } 83 84 /** 85 * Returns an image descriptor that is based on the given descriptor, but 86 * decorated with additional information relating to the state of the provided 87 * object. 88 * 89 * Subclasses may reimplement this method to decorate an object's image. 90 * 91 * @param input The base image to decorate. 92 * @param element The element used to look up decorations. 93 * @return the resuling ImageDescriptor. 94 * @see org.eclipse.jface.resource.CompositeImageDescriptor 95 */ decorateImage(ImageDescriptor input, Object element)96 protected ImageDescriptor decorateImage(ImageDescriptor input, Object element) { 97 return input; 98 } 99 100 /** 101 * Returns a label that is based on the given label, but decorated with 102 * additional information relating to the state of the provided object. 103 * 104 * Subclasses may implement this method to decorate an object's label. 105 * 106 * @param input The base text to decorate. 107 * @param element The element used to look up decorations. 108 * @return the resulting text 109 */ decorateText(String input, Object element)110 protected String decorateText(String input, Object element) { 111 return input; 112 } 113 114 @Override dispose()115 public void dispose() { 116 PlatformUI.getWorkbench().getEditorRegistry().removePropertyListener(editorRegistryListener); 117 if (resourceManager != null) 118 resourceManager.dispose(); 119 resourceManager = null; 120 super.dispose(); 121 } 122 123 /** 124 * Returns the implementation of IWorkbenchAdapter for the given object. 125 * 126 * @param o the object to look up. 127 * @return IWorkbenchAdapter or<code>null</code> if the adapter is not defined 128 * or the object is not adaptable. 129 */ getAdapter(Object o)130 protected final IWorkbenchAdapter getAdapter(Object o) { 131 return Adapters.adapt(o, IWorkbenchAdapter.class); 132 } 133 134 /** 135 * Returns the implementation of IWorkbenchAdapter2 for the given object. 136 * 137 * @param o the object to look up. 138 * @return IWorkbenchAdapter2 or<code>null</code> if the adapter is not defined 139 * or the object is not adaptable. 140 */ getAdapter2(Object o)141 protected final IWorkbenchAdapter2 getAdapter2(Object o) { 142 return Adapters.adapt(o, IWorkbenchAdapter2.class); 143 } 144 145 /** 146 * Returns the implementation of IWorkbenchAdapter3 for the given object. 147 * 148 * @param o the object to look up. 149 * @return IWorkbenchAdapter3 or<code>null</code> if the adapter is not defined 150 * or the object is not adaptable. 151 * @since 3.7 152 */ getAdapter3(Object o)153 protected final IWorkbenchAdapter3 getAdapter3(Object o) { 154 return Adapters.adapt(o, IWorkbenchAdapter3.class); 155 } 156 157 /** 158 * Lazy load the resource manager 159 * 160 * @return The resource manager, create one if necessary 161 */ getResourceManager()162 private ResourceManager getResourceManager() { 163 if (resourceManager == null) { 164 resourceManager = new LocalResourceManager(JFaceResources.getResources()); 165 } 166 167 return resourceManager; 168 } 169 170 @Override getImage(Object element)171 public final Image getImage(Object element) { 172 // obtain the base image by querying the element 173 IWorkbenchAdapter adapter = getAdapter(element); 174 if (adapter == null) { 175 return null; 176 } 177 ImageDescriptor descriptor = adapter.getImageDescriptor(element); 178 if (descriptor == null) { 179 return null; 180 } 181 182 // add any annotations to the image descriptor 183 descriptor = decorateImage(descriptor, element); 184 185 return (Image) getResourceManager().get(descriptor); 186 } 187 188 /** 189 * The default implementation of this returns the styled text label for the 190 * given element. 191 * 192 * @param element the element to evaluate the styled string for 193 * 194 * @return the styled string. 195 * 196 * @since 3.7 197 */ 198 @Override getStyledText(Object element)199 public StyledString getStyledText(Object element) { 200 IWorkbenchAdapter3 adapter = getAdapter3(element); 201 if (adapter == null) { 202 // If adapter class doesn't implement IWorkbenchAdapter3 than use 203 // StyledString with text of element. Since the output of getText is 204 // already decorated, so we don't need to call decorateText again 205 // here. 206 return new StyledString(getText(element)); 207 } 208 StyledString styledString = adapter.getStyledText(element); 209 // Now, re-use any existing decorateText implementation, to decorate 210 // this styledString. 211 String decorated = decorateText(styledString.getString(), element); 212 Styler styler = getDecorationStyle(element); 213 return StyledCellLabelProvider.styleDecoratedString(decorated, styler, styledString); 214 } 215 216 /** 217 * Sets the {@link Styler} to be used for string decorations. By default the 218 * {@link StyledString#DECORATIONS_STYLER decoration style}. Clients can 219 * override. 220 * 221 * @param element the element that has been decorated 222 * 223 * @return return the decoration style 224 * 225 * @since 3.7 226 */ getDecorationStyle(Object element)227 protected Styler getDecorationStyle(Object element) { 228 return StyledString.DECORATIONS_STYLER; 229 } 230 231 @Override getText(Object element)232 public final String getText(Object element) { 233 // query the element for its label 234 IWorkbenchAdapter adapter = getAdapter(element); 235 if (adapter == null) { 236 return ""; //$NON-NLS-1$ 237 } 238 String label = adapter.getLabel(element); 239 240 // return the decorated label 241 return decorateText(label, element); 242 } 243 244 @Override getForeground(Object element)245 public Color getForeground(Object element) { 246 return getColor(element, true); 247 } 248 249 @Override getBackground(Object element)250 public Color getBackground(Object element) { 251 return getColor(element, false); 252 } 253 254 @Override getFont(Object element)255 public Font getFont(Object element) { 256 IWorkbenchAdapter2 adapter = getAdapter2(element); 257 if (adapter == null) { 258 return null; 259 } 260 261 FontData descriptor = adapter.getFont(element); 262 if (descriptor == null) { 263 return null; 264 } 265 266 return (Font) getResourceManager().get(FontDescriptor.createFrom(descriptor)); 267 } 268 getColor(Object element, boolean forground)269 private Color getColor(Object element, boolean forground) { 270 IWorkbenchAdapter2 adapter = getAdapter2(element); 271 if (adapter == null) { 272 return null; 273 } 274 RGB descriptor = forground ? adapter.getForeground(element) : adapter.getBackground(element); 275 if (descriptor == null) { 276 return null; 277 } 278 279 return (Color) getResourceManager().get(ColorDescriptor.createFrom(descriptor)); 280 } 281 } 282