Skip to main content

This CGIT instance is deprecated, and repositories have been moved to Gitlab or Github. See the repository descriptions for specific locations.

aboutsummaryrefslogtreecommitdiffstats
blob: db1d7bee6008d5860e1cfc43a063b7ae7aede9a1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
/*******************************************************************************
 * Copyright (c) 2000, 2016 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
 *     Alexander Kurtakov <akurtako@redhat.com> - Bug 459761
 *******************************************************************************/
package org.eclipse.jface.viewers;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;

/**
 * A decorating label provider is a label provider which combines
 * a nested label provider and an optional decorator.
 * The decorator decorates the label text, image, font and colors provided by
 * the nested label provider.
 */
public class DecoratingLabelProvider extends LabelProvider implements IViewerLabelProvider, IColorProvider,
		IFontProvider, ITreePathLabelProvider {

    private ILabelProvider provider;

    private ILabelDecorator decorator;

    // Need to keep our own list of listeners
	private ListenerList<ILabelProviderListener> listeners = new ListenerList<>();

	private IDecorationContext decorationContext = DecorationContext.DEFAULT_CONTEXT;

    /**
     * Creates a decorating label provider which uses the given label decorator
     * to decorate labels provided by the given label provider.
     *
     * @param provider the nested label provider
     * @param decorator the label decorator, or <code>null</code> if no decorator is to be used initially
     */
    public DecoratingLabelProvider(ILabelProvider provider,
            ILabelDecorator decorator) {
        Assert.isNotNull(provider);
        this.provider = provider;
        this.decorator = decorator;
    }

    /**
     * The <code>DecoratingLabelProvider</code> implementation of this <code>IBaseLabelProvider</code> method
     * adds the listener to both the nested label provider and the label decorator.
     *
     * @param listener a label provider listener
     */
    @Override
	public void addListener(ILabelProviderListener listener) {
        super.addListener(listener);
        provider.addListener(listener);
        if (decorator != null) {
            decorator.addListener(listener);
        }
        listeners.add(listener);
    }

    /**
     * The <code>DecoratingLabelProvider</code> implementation of this <code>IBaseLabelProvider</code> method
     * disposes both the nested label provider and the label decorator.
     */
    @Override
	public void dispose() {
        provider.dispose();
        if (decorator != null) {
            decorator.dispose();
        }
    }

    /**
     * The <code>DecoratingLabelProvider</code> implementation of this
     * <code>ILabelProvider</code> method returns the image provided
     * by the nested label provider's <code>getImage</code> method,
     * decorated with the decoration provided by the label decorator's
     * <code>decorateImage</code> method.
     */
    @Override
	public Image getImage(Object element) {
        Image image = provider.getImage(element);
        if (decorator != null) {
        	if (decorator instanceof LabelDecorator) {
				LabelDecorator ld2 = (LabelDecorator) decorator;
	            Image decorated = ld2.decorateImage(image, element, getDecorationContext());
	            if (decorated != null) {
	                return decorated;
	            }
			} else {
	            Image decorated = decorator.decorateImage(image, element);
	            if (decorated != null) {
	                return decorated;
	            }
			}
        }
        return image;
    }

	/**
     * Returns the label decorator, or <code>null</code> if none has been set.
     *
     * @return the label decorator, or <code>null</code> if none has been set.
     */
    public ILabelDecorator getLabelDecorator() {
        return decorator;
    }

    /**
     * Returns the nested label provider.
     *
     * @return the nested label provider
     */
    public ILabelProvider getLabelProvider() {
        return provider;
    }

    /**
     * The <code>DecoratingLabelProvider</code> implementation of this
     * <code>ILabelProvider</code> method returns the text label provided
     * by the nested label provider's <code>getText</code> method,
     * decorated with the decoration provided by the label decorator's
     * <code>decorateText</code> method.
     */
    @Override
	public String getText(Object element) {
        String text = provider.getText(element);
        if (decorator != null) {
        	if (decorator instanceof LabelDecorator) {
				LabelDecorator ld2 = (LabelDecorator) decorator;
	            String decorated = ld2.decorateText(text, element, getDecorationContext());
	            if (decorated != null) {
	                return decorated;
	            }
			} else {
	            String decorated = decorator.decorateText(text, element);
	            if (decorated != null) {
	                return decorated;
	            }
			}
        }
        return text;
    }

    /**
     * The <code>DecoratingLabelProvider</code> implementation of this
     * <code>IBaseLabelProvider</code> method returns <code>true</code> if the corresponding method
     * on the nested label provider returns <code>true</code> or if the corresponding method on the
     * decorator returns <code>true</code>.
     */
    @Override
	public boolean isLabelProperty(Object element, String property) {
        if (provider.isLabelProperty(element, property)) {
			return true;
		}
        if (decorator != null && decorator.isLabelProperty(element, property)) {
			return true;
		}
        return false;
    }

    /**
     * The <code>DecoratingLabelProvider</code> implementation of this <code>IBaseLabelProvider</code> method
     * removes the listener from both the nested label provider and the label decorator.
     *
     * @param listener a label provider listener
     */
    @Override
	public void removeListener(ILabelProviderListener listener) {
        super.removeListener(listener);
        provider.removeListener(listener);
        if (decorator != null) {
            decorator.removeListener(listener);
        }
        listeners.remove(listener);
    }

    /**
     * Sets the label decorator.
     * Removes all known listeners from the old decorator, and adds all known listeners to the new decorator.
     * The old decorator is not disposed.
     * Fires a label provider changed event indicating that all labels should be updated.
     * Has no effect if the given decorator is identical to the current one.
     *
     * @param decorator the label decorator, or <code>null</code> if no decorations are to be applied
     */
    public void setLabelDecorator(ILabelDecorator decorator) {
        ILabelDecorator oldDecorator = this.decorator;
        if (oldDecorator != decorator) {
            if (oldDecorator != null) {
				for (ILabelProviderListener l : listeners) {
					oldDecorator.removeListener(l);
                }
            }
            this.decorator = decorator;
            if (decorator != null) {
				for (ILabelProviderListener l : listeners) {
					decorator.addListener(l);
                }
            }
            fireLabelProviderChanged(new LabelProviderChangedEvent(this));
        }
    }

    @Override
	public void updateLabel(ViewerLabel settings, Object element) {

        ILabelDecorator currentDecorator = getLabelDecorator();
        String oldText = settings.getText();
        boolean decorationReady = true;
        if (currentDecorator instanceof IDelayedLabelDecorator) {
            IDelayedLabelDecorator delayedDecorator = (IDelayedLabelDecorator) currentDecorator;
            if (!delayedDecorator.prepareDecoration(element, oldText)) {
                // The decoration is not ready but has been queued for processing
                decorationReady = false;
            }
        }
        // update icon and label

        if (decorationReady || oldText == null
                || settings.getText().length() == 0) {
			settings.setText(getText(element));
		}

        Image oldImage = settings.getImage();
        if (decorationReady || oldImage == null) {
            settings.setImage(getImage(element));
        }

        if(decorationReady) {
			updateForDecorationReady(settings,element);
		}

    }

	/**
	 * Decoration is ready. Update anything else for the settings.
	 * @param settings The object collecting the settings.
	 * @param element The Object being decorated.
	 * @since 3.1
	 */
	protected void updateForDecorationReady(ViewerLabel settings, Object element) {

		if(decorator instanceof IColorDecorator){
			IColorDecorator colorDecorator = (IColorDecorator) decorator;
			settings.setBackground(colorDecorator.decorateBackground(element));
			settings.setForeground(colorDecorator.decorateForeground(element));
		}

		if(decorator instanceof IFontDecorator) {
			settings.setFont(((IFontDecorator) decorator).decorateFont(element));
		}

	}

	@Override
	public Color getBackground(Object element) {
		if(provider instanceof IColorProvider) {
			return ((IColorProvider) provider).getBackground(element);
		}
		return null;
	}

	@Override
	public Font getFont(Object element) {
		if(provider instanceof IFontProvider) {
			return ((IFontProvider) provider).getFont(element);
		}
		return null;
	}

	@Override
	public Color getForeground(Object element) {
		if(provider instanceof IColorProvider) {
			return ((IColorProvider) provider).getForeground(element);
		}
		return null;
	}

    /**
     * Return the decoration context associated with this label provider.
     * It will be passed to the decorator if the decorator is an
     * instance of {@link LabelDecorator}.
     * @return the decoration context associated with this label provider
     *
     * @since 3.2
     */
    public IDecorationContext getDecorationContext() {
		return decorationContext;
	}

    /**
     * Set the decoration context that will be based to the decorator
     * for this label provider if that decorator implements {@link LabelDecorator}.
     * @param decorationContext the decoration context.
     *
     * @since 3.2
     */
	public void setDecorationContext(IDecorationContext decorationContext) {
		Assert.isNotNull(decorationContext);
		this.decorationContext = decorationContext;
	}

	@Override
	public void updateLabel(ViewerLabel settings, TreePath elementPath) {
        ILabelDecorator currentDecorator = getLabelDecorator();
        String oldText = settings.getText();
        Object element = elementPath.getLastSegment();
        boolean decorationReady = true;
        if (currentDecorator instanceof LabelDecorator) {
			LabelDecorator labelDecorator = (LabelDecorator) currentDecorator;
           if (!labelDecorator.prepareDecoration(element, oldText, getDecorationContext())) {
                // The decoration is not ready but has been queued for processing
                decorationReady = false;
            }
		} else if (currentDecorator instanceof IDelayedLabelDecorator) {
            IDelayedLabelDecorator delayedDecorator = (IDelayedLabelDecorator) currentDecorator;
            if (!delayedDecorator.prepareDecoration(element, oldText)) {
                // The decoration is not ready but has been queued for processing
                decorationReady = false;
            }
        }
        settings.setHasPendingDecorations(!decorationReady);
        // update icon and label

        if (provider instanceof ITreePathLabelProvider) {
			ITreePathLabelProvider pprov = (ITreePathLabelProvider) provider;
			if (decorationReady || oldText == null
	                || settings.getText().length() == 0) {
				pprov.updateLabel(settings, elementPath);
				decorateSettings(settings, elementPath);
			}
		} else {
	        if (decorationReady || oldText == null
	                || settings.getText().length() == 0) {
				settings.setText(getText(element));
			}

	        Image oldImage = settings.getImage();
	        if (decorationReady || oldImage == null) {
	            settings.setImage(getImage(element));
	        }

	        if(decorationReady) {
				updateForDecorationReady(settings,element);
			}
		}

	}

	/**
	 * Decorate the settings
	 * @param settings the settings obtained from the label provider
	 * @param elementPath the element path being decorated
	 */
	private void decorateSettings(ViewerLabel settings, TreePath elementPath) {
		Object element = elementPath.getLastSegment();
        if (decorator != null) {
        	if (decorator instanceof LabelDecorator) {
				LabelDecorator labelDecorator = (LabelDecorator) decorator;
				String text = labelDecorator.decorateText(settings.getText(), element, getDecorationContext());
	            if (text != null && text.length() > 0)
	            	settings.setText(text);
	            Image image = labelDecorator.decorateImage(settings.getImage(), element, getDecorationContext());
	            if (image != null)
	            	settings.setImage(image);

			} else {
				String text = decorator.decorateText(settings.getText(), element);
	            if (text != null && text.length() > 0)
	            	settings.setText(text);
	            Image image = decorator.decorateImage(settings.getImage(), element);
	            if (image != null)
	            	settings.setImage(image);
			}
    		if(decorator instanceof IColorDecorator){
    			IColorDecorator colorDecorator = (IColorDecorator) decorator;
    			Color background = colorDecorator.decorateBackground(element);
    			if (background != null)
    				settings.setBackground(background);
    			Color foreground = colorDecorator.decorateForeground(element);
    			if (foreground != null)
    				settings.setForeground(foreground);
    		}

    		if(decorator instanceof IFontDecorator) {
    			Font font = ((IFontDecorator) decorator).decorateFont(element);
    			if (font != null)
    				settings.setFont(font);
    		}
        }
	}
}

Back to the top