KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > ui > synchronize > AbstractSynchronizeLabelProvider


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.team.ui.synchronize;
12
13 import org.eclipse.compare.CompareConfiguration;
14 import org.eclipse.compare.structuremergeviewer.ICompareInput;
15 import org.eclipse.core.resources.IMarker;
16 import org.eclipse.core.resources.mapping.ModelProvider;
17 import org.eclipse.core.resources.mapping.ResourceMapping;
18 import org.eclipse.core.runtime.CoreException;
19 import org.eclipse.jface.resource.ImageDescriptor;
20 import org.eclipse.jface.resource.JFaceResources;
21 import org.eclipse.jface.viewers.*;
22 import org.eclipse.osgi.util.NLS;
23 import org.eclipse.swt.graphics.*;
24 import org.eclipse.team.core.diff.IDiff;
25 import org.eclipse.team.core.diff.IThreeWayDiff;
26 import org.eclipse.team.core.mapping.ISynchronizationContext;
27 import org.eclipse.team.core.synchronize.SyncInfo;
28 import org.eclipse.team.internal.ui.*;
29 import org.eclipse.team.internal.ui.mapping.ResourceDiffCompareInput;
30 import org.eclipse.team.internal.ui.synchronize.ImageManager;
31 import org.eclipse.team.ui.ISharedImages;
32 import org.eclipse.team.ui.TeamUI;
33 import org.eclipse.team.ui.mapping.*;
34
35 /**
36  * A label provider wrapper that adds synchronization image and/or text decorations
37  * to the image and label obtained from the delegate provider.
38  *
39  * @since 3.2
40  */

41 public abstract class AbstractSynchronizeLabelProvider implements ILabelProvider {
42     
43     private ImageManager localImageManager;
44     
45     /* (non-Javadoc)
46      * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
47      */

48     public Image getImage(Object JavaDoc element) {
49         Image base = getDelegateImage(element);
50         if (isDecorationEnabled() && base != null) {
51             Image decorateImage = decorateImage(base, element);
52             base = decorateImage;
53         }
54         if (isIncludeOverlays() && base != null) {
55             base = addOverlays(base, element);
56         }
57         return base;
58     }
59
60     /**
61      * Decorate the image with the appropriate diff decorations.
62      * By default, this method uses the diff associated with
63      * the given element to determine how to decorate the image.
64      * It then uses the {@link CompareConfiguration#getImage(Image, int)}
65      * method to apply the decoration to the base image.
66      * @param base the base image to be decorated.
67      * @param element the element
68      * @return the image decorated appropriately using the diff associated with
69      * the element
70      * @see #getDiff(Object)
71      * @see CompareConfiguration#getImage(Image, int)
72      */

73     protected Image decorateImage(Image base, Object JavaDoc element) {
74         Image decoratedImage;
75         if (element instanceof ICompareInput) {
76             ICompareInput ci = (ICompareInput) element;
77             decoratedImage = getCompareImage(base, ci.getKind());
78         } else {
79             IDiff node = getDiff(element);
80             decoratedImage = getCompareImage(base, node);
81         }
82         // The reason we still overlay the compare image is to
83
// ensure that the image width for all images shown in the viewer
84
// are consistent.
85
return decoratedImage;
86     }
87
88     /**
89      * Return the image for the item from the delegate label provider.
90      * @param element the element
91      * @return the image for the item from the delegate label provider
92      */

93     protected Image getDelegateImage(Object JavaDoc element) {
94         ILabelProvider modelLabelProvider = getDelegateLabelProvider();
95         Image base = modelLabelProvider.getImage(internalGetElement(element));
96         if (base == null && element instanceof ModelProvider) {
97             ModelProvider mp = (ModelProvider) element;
98             base = getImageManager().getImage(getImageDescriptor(mp));
99         }
100         return base;
101     }
102
103     private ImageDescriptor getImageDescriptor(ModelProvider provider) {
104         ITeamContentProviderManager manager = TeamUI.getTeamContentProviderManager();
105         ITeamContentProviderDescriptor desc = manager.getDescriptor(provider.getId());
106         return desc.getImageDescriptor();
107     }
108     
109     private Object JavaDoc internalGetElement(Object JavaDoc element) {
110         if (element instanceof TreePath) {
111             TreePath tp = (TreePath) element;
112             element = tp.getLastSegment();
113         }
114         return element;
115     }
116
117     private Image getCompareImage(Image base, IDiff node) {
118         int compareKind = getCompareKind(node);
119         return getCompareImage(base, compareKind);
120     }
121
122     private Image getCompareImage(Image base, int compareKind) {
123         return getImageManager().getImage(base, compareKind);
124     }
125
126     private int getCompareKind(IDiff node) {
127         return ResourceDiffCompareInput.getCompareKind(node);
128     }
129     
130     /* (non-Javadoc)
131      * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
132      */

133     public String JavaDoc getText(Object JavaDoc element) {
134         String JavaDoc base = getDelegateText(element);
135         if (isSyncInfoInTextEnabled()) {
136             return decorateText(base, element);
137         }
138         return base;
139     }
140
141     /**
142      * Obtain the text for the object from the delegate label provider.
143      * @param element the element
144      * @return the text label for the element
145      */

146     protected String JavaDoc getDelegateText(Object JavaDoc element) {
147         ILabelProvider modelLabelProvider = getDelegateLabelProvider();
148         element = internalGetElement(element);
149         String JavaDoc base = modelLabelProvider.getText(element);
150         if (base == null || base.length() == 0) {
151             if (element instanceof ModelProvider) {
152                 ModelProvider provider = (ModelProvider) element;
153                 base = Utils.getLabel(provider);
154             }
155         }
156         return base;
157     }
158     
159     /**
160      * Decorate the text with the appropriate diff decorations.
161      * By default, this method uses the diff associated with
162      * the given element to determine how to decorate the text.
163      * @param base the base text to be decorated.
164      * @param element the element
165      * @return the text decorated appropriately using the diff associated with
166      * the element
167      * @see #getDiff(Object)
168      */

169     protected String JavaDoc decorateText(String JavaDoc base, Object JavaDoc element) {
170         IDiff node = getDiff(element);
171         if (node != null && node.getKind() != IDiff.NO_CHANGE) {
172             String JavaDoc syncKindString = node.toDiffString();
173             return NLS.bind(TeamUIMessages.AbstractSynchronizationLabelProvider_0, new String JavaDoc[] { base, syncKindString });
174         }
175         return base;
176     }
177     
178     /* (non-Javadoc)
179      * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener)
180      */

181     public void addListener(ILabelProviderListener listener) {
182         getDelegateLabelProvider().addListener(listener);
183     }
184
185     /* (non-Javadoc)
186      * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
187      */

188     public void dispose() {
189         if (localImageManager != null)
190             localImageManager.dispose();
191     }
192
193     /* (non-Javadoc)
194      * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object, java.lang.String)
195      */

196     public boolean isLabelProperty(Object JavaDoc element, String JavaDoc property) {
197         return getDelegateLabelProvider().isLabelProperty(internalGetElement(element), property);
198     }
199
200     /* (non-Javadoc)
201      * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)
202      */

203     public void removeListener(ILabelProviderListener listener) {
204         getDelegateLabelProvider().removeListener(listener);
205     }
206     
207     /**
208      * Returns whether the synchronization state should be included in the
209      * text of the label. By default, the Team preference is used to determine
210      * what to return. Subclasses may override.
211      * @return whether the synchronization state should be included in the
212      * text of the label
213      */

214     protected boolean isSyncInfoInTextEnabled() {
215         return isDecorationEnabled() && TeamUIPlugin.getPlugin().getPreferenceStore().getBoolean(IPreferenceIds.SYNCVIEW_VIEW_SYNCINFO_IN_LABEL);
216     }
217     
218     /**
219      * Return the label provider that will return the text and image
220      * appropriate for the given model element. Subclasses are responsible for
221      * disposing of the label provider.
222      * @return the label provider that will return the text and image
223      * appropriate for the given model element
224      */

225     protected abstract ILabelProvider getDelegateLabelProvider();
226     
227     /**
228      * Return whether the label provider should decorate with the synchronization state.
229      * @return whether the label provider should decorate with the synchronization state
230      */

231     protected abstract boolean isDecorationEnabled();
232     
233     /**
234      * Return the sync kind of the given element. This is used
235      * to determine how to decorate the image and label of the
236      * element. The sync kind is described in the {@link SyncInfo}
237      * class. A <code>null</code> is returned by default.
238      * @param element the element being tested
239      * @return the sync kind of the given element
240      */

241     protected IDiff getDiff(Object JavaDoc element) {
242         return null;
243     }
244     
245     private Image addOverlays(Image base, Object JavaDoc element) {
246         if (!isIncludeOverlays())
247             return base;
248         
249         ImageDescriptor[] overlayImages = new ImageDescriptor[4];
250         boolean hasOverlay = false;
251         
252         // Decorate with the busy indicator
253
if (isBusy(element)) {
254             overlayImages[IDecoration.TOP_LEFT] = TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_HOURGLASS_OVR);
255             hasOverlay = true;
256         }
257         // Decorate with propagated conflicts and problem markers
258
if (!isConflicting(element)) {
259             // if the folder is already conflicting then don't bother propagating
260
if (hasDecendantConflicts(element)) {
261                 overlayImages[IDecoration.BOTTOM_RIGHT] = TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_CONFLICT_OVR);
262                 hasOverlay = true;
263             }
264         }
265         int severity = getMarkerSeverity(element);
266         if (severity == IMarker.SEVERITY_ERROR) {
267             overlayImages[IDecoration.BOTTOM_LEFT] = TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_ERROR_OVR);
268             hasOverlay = true;
269         } else if (severity == IMarker.SEVERITY_WARNING) {
270             overlayImages[IDecoration.BOTTOM_LEFT] = TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_WARNING_OVR);
271             hasOverlay = true;
272         }
273         if (hasOverlay) {
274             ImageDescriptor overlay = new DecorationOverlayIcon(base, overlayImages, new Point(base.getBounds().width, base.getBounds().height));
275             return getImageManager().getImage(overlay);
276         }
277         return base;
278     }
279     
280     /**
281      * Indicate whether the overlays provided by this class should be applied.
282      * By default, <code>false</code> is returned. Subclasses may override
283      * and control individual overlays by overriding the appropriate
284      * query methods. Overlays provided by this class include problem marker
285      * severity ({@link #getMarkerSeverity(Object)}), propagated conflicts
286      * ({@link #hasDecendantConflicts(Object)} and busy state ({@link #isBusy(Object)}).
287      * @return whether the overlays provided by this class should be applied
288      */

289     protected boolean isIncludeOverlays() {
290         return false;
291     }
292
293     /**
294      * Return the marker severity (one of IMarker.SEVERITY_ERROR or
295      * IMarker.SEVERITY_WARNING) to be overlayed on the given element or -1 if
296      * there are no markers. By Default, the element is adapted to resource
297      * mapping in order to look for markers.
298      * <p>
299      * Although this class handles providing the overlays, it does not react
300      * to marker changes. Subclasses must issue label updates when the markers on
301      * a logical model element change.
302      *
303      * @param element
304      * the element
305      * @return the marker severity
306      */

307     protected int getMarkerSeverity(Object JavaDoc element) {
308         ResourceMapping mapping = Utils.getResourceMapping(internalGetElement(element));
309         int result = -1;
310         if (mapping != null) {
311             try {
312                 IMarker[] markers = mapping.findMarkers(IMarker.PROBLEM, true, null);
313                 for (int i = 0; i < markers.length; i++) {
314                     IMarker marker = markers[i];
315                     Integer JavaDoc severity = (Integer JavaDoc) marker.getAttribute(IMarker.SEVERITY);
316                     if (severity != null) {
317                         if (severity.intValue() == IMarker.SEVERITY_ERROR) {
318                             return IMarker.SEVERITY_ERROR;
319                         } else if (severity.intValue() == IMarker.SEVERITY_WARNING) {
320                             result = IMarker.SEVERITY_WARNING;
321                         }
322                     }
323                 }
324             } catch (CoreException e) {
325                 // Ignore
326
}
327         }
328         return result;
329     }
330
331     /**
332      * Return whether the given element has descendant conflicts.
333      * By default, <code>false</code> is returned. Subclasses
334      * may override.
335      * @param element the element
336      * @return whether the given element has descendant conflicts
337      */

338     protected boolean hasDecendantConflicts(Object JavaDoc element) {
339         return false;
340     }
341
342     private boolean isConflicting(Object JavaDoc element) {
343         IDiff node = getDiff(element);
344         if (node != null) {
345             if (node instanceof IThreeWayDiff) {
346                 IThreeWayDiff twd = (IThreeWayDiff) node;
347                 return twd.getDirection() == IThreeWayDiff.CONFLICTING;
348             }
349         }
350         return false;
351     }
352
353     /**
354      * Return whether the given element is busy (i.e. is involved
355      * in an operation. By default, <code>false</code> is returned.
356      * Subclasses may override.
357      * @param element the element
358      * @return whether the given element is busy
359      */

360     protected boolean isBusy(Object JavaDoc element) {
361         return false;
362     }
363
364     /**
365      * Method that provides a custom font for elements that are
366      * busy. Although this label provider does not implement
367      * {@link IFontProvider}, subclasses that wish to get
368      * busy indication using a font can do so.
369      * @param element the element
370      * @return the font to indicate that the element is busy
371      */

372     public Font getFont(Object JavaDoc element) {
373         if(isBusy(internalGetElement(element))) {
374             return JFaceResources.getFontRegistry().getItalic(JFaceResources.DEFAULT_FONT);
375         }
376         return null;
377     }
378     
379     private ImageManager getImageManager() {
380         ISynchronizationContext context = getContext();
381         if (context != null) {
382             return ImageManager.getImageManager(context);
383         }
384         if (localImageManager == null) {
385             localImageManager = new ImageManager();
386         }
387         return localImageManager;
388     }
389
390     private ISynchronizationContext getContext() {
391         if (this instanceof SynchronizationLabelProvider) {
392             SynchronizationLabelProvider slp = (SynchronizationLabelProvider) this;
393             return slp.getContext();
394         }
395         return null;
396     }
397     
398 }
399
Popular Tags