fixed bug #1263858
[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.2 2005-03-06 21:09:52 axelcl 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 icons to elements in the outline. The information is
39  * retrieved from the annotation model corresponding to the input of the associated text editor.
40  */
41 public class ProblemsLabelDecorator extends LabelProvider implements ILabelDecorator {
42
43   // Constants ---------------------------------------------------------------
44
45   private static final String ANNOTATION_TYPE_ERROR = "org.eclipse.ui.workbench.texteditor.error"; //$NON-NLS-1$
46
47   private static final String ANNOTATION_TYPE_WARNING = "org.eclipse.ui.workbench.texteditor.warning"; //$NON-NLS-1$
48
49   // Instance Variables ------------------------------------------------------
50
51   /** The associated text editor if the decorator is used in the outline. */
52   private ITextEditor editor;
53
54   /** Registry of icons and overlay icons. */
55   private ImageDescriptorRegistry registry = new ImageDescriptorRegistry();
56
57   // Constructors ------------------------------------------------------------
58
59   /**
60    * Constructor.
61    * 
62    * @param editor
63    *          the associated text editor
64    */
65   public ProblemsLabelDecorator(ITextEditor editor) {
66     this.editor = editor;
67   }
68
69   // ILabelDecorator Implementation ------------------------------------------
70
71   /*
72    * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
73    */
74   public void dispose() {
75     super.dispose();
76     registry.dispose();
77   }
78
79   /*
80    * @see ILabelDecorator#decorateImage(Image, Object)
81    */
82   public Image decorateImage(Image image, Object element) {
83     Annotation annotations[] = getAssociatedAnnotations((ISourceReference) element);
84     ImageDescriptor overlay = null;
85     for (int i = 0; i < annotations.length; i++) {
86       if (isError(annotations[i])) {
87         overlay = WebUI.getDefault().getImageRegistry().getDescriptor(WebUI.ICON_OVERLAY_ERROR);
88       } else if (isWarning(annotations[i])) {
89         overlay = WebUI.getDefault().getImageRegistry().getDescriptor(WebUI.ICON_OVERLAY_WARNING);
90       }
91     }
92     if (overlay != null) {
93       ImageDescriptor base = new ImageImageDescriptor(image);
94       return registry.get(new OverlayImageDescriptor(base, new ImageDescriptor[][] { null, null, { overlay }, null }, null));
95     } else {
96     }
97     return image;
98   }
99
100   /*
101    * @see ILabelDecorator#decorateText(String, Object)
102    */
103   public String decorateText(String text, Object element) {
104     return text;
105   }
106
107   // Private Methods ---------------------------------------------------------
108
109   /**
110    * Returns all annotations associated with the given model element.
111    * 
112    * @param element
113    *          the model element for which annotations should be collected
114    * @return an array containing all annotations for the given element, or an empty array if no annotations are found
115    */
116   private Annotation[] getAssociatedAnnotations(ISourceReference element) {
117     List retVal = new ArrayList();
118     if (editor != null) {
119       IEditorInput input = editor.getEditorInput();
120       IAnnotationModel model = editor.getDocumentProvider().getAnnotationModel(input);
121       if (model != null) { // bug #1120670
122         for (Iterator i = model.getAnnotationIterator(); i.hasNext();) {
123           Annotation annotation = (Annotation) i.next();
124           Position pos = model.getPosition(annotation);
125           if (pos != null && isInside(pos.getOffset(), element)) {
126             retVal.add(annotation);
127           }
128         }
129       }
130     }
131     return (Annotation[]) retVal.toArray(new Annotation[retVal.size()]);
132   }
133
134   /**
135    * Determines whether the given annotation is an error.
136    * 
137    * @param annotation
138    *          the annotation to check
139    * @return <tt>true</tt> if the annotation is to be displayed as an error, <tt>false</tt> otherwise
140    */
141   private boolean isError(Annotation annotation) {
142     return ANNOTATION_TYPE_ERROR.equals(annotation.getType());
143   }
144
145   /**
146    * Determines whether the given annotation is a warning.
147    * 
148    * @param annotation
149    *          the annotation to check
150    * @return <tt>true</tt> if the annotation is to be displayed as a warning, <tt>false</tt> otherwise
151    */
152   private boolean isWarning(Annotation annotation) {
153     return ANNOTATION_TYPE_WARNING.equals(annotation.getType());
154   }
155
156   /**
157    * Tests if the given position is inside the source region of a model element.
158    * 
159    * @param pos
160    *          the position to be tested
161    * @param element
162    *          the source element
163    * @return boolean <tt>true</tt> if position is located inside the element, otherwise <tt>false</tt>
164    */
165   private boolean isInside(int pos, ISourceReference element) {
166     IRegion region = element.getSourceRegion();
167     if (region != null) {
168       int offset = region.getOffset();
169       return ((offset <= pos) && (offset + region.getLength() > pos));
170     }
171     return false;
172   }
173
174 }