intial source from http://www.sf.net/projects/wdte
[phpeclipse.git] / net.sourceforge.phpeclipse.ui / src / net / sourceforge / phpeclipse / ui / views / outline / ProblemsLabelDecorator.java
1 /*
2  * Copyright (c) 2004 Christopher Lenz and others
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     Christopher Lenz - initial implementation
10  * 
11  * $Id: ProblemsLabelDecorator.java,v 1.1 2004-09-02 18:26:28 jsurfer Exp $
12  */
13
14 package net.sourceforge.phpeclipse.ui.views.outline;
15
16 import java.util.ArrayList;
17 import java.util.Iterator;
18 import java.util.List;
19
20 import net.sourceforge.phpeclipse.core.model.ISourceReference;
21 import net.sourceforge.phpeclipse.ui.WebUI;
22 import net.sourceforge.phpeclipse.ui.views.util.ImageDescriptorRegistry;
23 import net.sourceforge.phpeclipse.ui.views.util.ImageImageDescriptor;
24 import net.sourceforge.phpeclipse.ui.views.util.OverlayImageDescriptor;
25
26 import org.eclipse.jface.resource.ImageDescriptor;
27 import org.eclipse.jface.text.IRegion;
28 import org.eclipse.jface.text.Position;
29 import org.eclipse.jface.text.source.Annotation;
30 import org.eclipse.jface.text.source.IAnnotationModel;
31 import org.eclipse.jface.viewers.ILabelDecorator;
32 import org.eclipse.jface.viewers.LabelProvider;
33 import org.eclipse.swt.graphics.Image;
34 import org.eclipse.ui.IEditorInput;
35 import org.eclipse.ui.texteditor.ITextEditor;
36
37 /**
38  * Label decorator for the outline page that adds error and warning overlay
39  * icons to elements in the outline. The information is retrieved from the 
40  * annotation model corresponding to the input of the associated text editor.
41  */
42 public class ProblemsLabelDecorator extends LabelProvider
43         implements ILabelDecorator {
44
45         // Constants ---------------------------------------------------------------
46
47         private static final String ANNOTATION_TYPE_ERROR =
48                 "org.eclipse.ui.workbench.texteditor.error"; //$NON-NLS-1$
49
50         private static final String ANNOTATION_TYPE_WARNING =
51                 "org.eclipse.ui.workbench.texteditor.warning"; //$NON-NLS-1$
52
53         // Instance Variables ------------------------------------------------------
54
55         /** The associated text editor if the decorator is used in the outline. */
56         private ITextEditor editor;
57
58         /** Registry of icons and overlay icons. */
59         private ImageDescriptorRegistry registry = new ImageDescriptorRegistry();
60
61         // Constructors ------------------------------------------------------------
62
63         /**
64          * Constructor.
65          * 
66          * @param editor the associated text editor
67          */
68         public ProblemsLabelDecorator(ITextEditor editor) {
69                 this.editor = editor;
70         }
71
72         // ILabelDecorator Implementation ------------------------------------------
73
74         /* 
75          * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
76          */
77         public void dispose() {
78                 super.dispose();
79                 registry.dispose();
80         }
81
82         /* 
83          * @see ILabelDecorator#decorateImage(Image, Object)
84          */
85         public Image decorateImage(Image image, Object element) {
86                 Annotation annotations[] =
87                         getAssociatedAnnotations((ISourceReference) element);
88                 ImageDescriptor overlay = null;
89                 for (int i = 0; i < annotations.length; i++) {
90                         if (isError(annotations[i])) {
91                                 overlay = WebUI.getDefault().getImageRegistry().getDescriptor(
92                                                 WebUI.ICON_OVERLAY_ERROR);
93                         } else if (isWarning(annotations[i])) {
94                                 overlay = WebUI.getDefault().getImageRegistry().getDescriptor(
95                                                 WebUI.ICON_OVERLAY_WARNING);
96                         }
97                 }
98                 if (overlay != null) {
99                         ImageDescriptor base = new ImageImageDescriptor(image);
100                         return registry.get(new OverlayImageDescriptor(base,
101                                         new ImageDescriptor[][] { null, null, { overlay }, null },
102                                         null));
103                 } else {
104                 }
105                 return image;
106         }
107
108         /* 
109          * @see ILabelDecorator#decorateText(String, Object)
110          */
111         public String decorateText(String text, Object element) {
112                 return text;
113         }
114
115         // Private Methods ---------------------------------------------------------
116
117         /**
118          * Returns all annotations associated with the given model element.
119          * 
120          * @param element the model element for which annotations should be
121          *        collected
122          * @return an array containing all annotations for the given element, or an
123          *         empty array if no annotations are found
124          */
125         private Annotation[] getAssociatedAnnotations(ISourceReference element) {
126                 List retVal = new ArrayList();
127                 if (editor != null) {
128                         IEditorInput input = editor.getEditorInput();
129                         IAnnotationModel model =
130                                 editor.getDocumentProvider().getAnnotationModel(input);
131                         for (Iterator i = model.getAnnotationIterator(); i.hasNext(); ) {
132                                 Annotation annotation = (Annotation) i.next();
133                                 Position pos = model.getPosition(annotation);
134                                 if (pos!=null && isInside(pos.getOffset(), element)) {
135                                         retVal.add(annotation);
136                                 }
137                         }
138                 }
139                 return (Annotation[]) retVal.toArray(new Annotation[retVal.size()]);
140         }
141
142         /**
143          * Determines whether the given annotation is an error.
144          * 
145          * @param annotation the annotation to check
146          * @return <tt>true</tt> if the annotation is to be displayed as an error,
147          *         <tt>false</tt> otherwise
148          */
149         private boolean isError(Annotation annotation) {
150                 return ANNOTATION_TYPE_ERROR.equals(annotation.getType());
151         }
152
153         /**
154          * Determines whether the given annotation is a warning.
155          * 
156          * @param annotation the annotation to check
157          * @return <tt>true</tt> if the annotation is to be displayed as a warning,
158          *         <tt>false</tt> otherwise
159          */
160         private boolean isWarning(Annotation annotation) {
161                 return ANNOTATION_TYPE_WARNING.equals(annotation.getType());
162         }
163
164         /**
165          * Tests if the given position is inside the source region of a model
166          * element.
167          * 
168          * @param pos the position to be tested
169          * @param element the source element
170          * @return boolean <tt>true</tt> if position is located inside the
171          *         element, otherwise <tt>false</tt>
172          */
173         private boolean isInside(int pos, ISourceReference element) {
174                 IRegion region = element.getSourceRegion();
175                 if (region != null) {
176                         int offset = region.getOffset();
177                         return ((offset <= pos) && (offset + region.getLength() > pos));                        
178                 }
179                 return false;
180         }
181
182 }