update copyrights
[idea/community.git] / platform / lang-api / src / com / intellij / lang / annotation / Annotation.java
1 /*
2  * Copyright 2000-2009 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.lang.annotation;
17
18 import com.intellij.codeInsight.daemon.HighlightDisplayKey;
19 import com.intellij.codeInsight.intention.IntentionAction;
20 import com.intellij.codeInspection.ProblemHighlightType;
21 import com.intellij.openapi.editor.HighlighterColors;
22 import com.intellij.openapi.editor.colors.CodeInsightColors;
23 import com.intellij.openapi.editor.colors.TextAttributesKey;
24 import com.intellij.openapi.editor.markup.GutterIconRenderer;
25 import com.intellij.openapi.editor.markup.TextAttributes;
26 import com.intellij.openapi.util.TextRange;
27 import org.jetbrains.annotations.Nullable;
28
29 import java.util.ArrayList;
30 import java.util.List;
31
32 /**
33  * Defines an annotation, which is displayed as a gutter bar mark or an extra highlight in the editor.
34  *
35  * @author max
36  * @see Annotator
37  * @see AnnotationHolder
38  * @see com.intellij.openapi.editor.markup.RangeHighlighter
39  */
40 public final class Annotation {
41   private final int myStartOffset;
42   private final int myEndOffset;
43   private final HighlightSeverity mySeverity;
44   private final String myMessage;
45
46   private ProblemHighlightType myHighlightType = ProblemHighlightType.GENERIC_ERROR_OR_WARNING;
47   private TextAttributesKey myEnforcedAttributesKey;
48   private TextAttributes myEnforcedAttributes;
49
50   private List<QuickFixInfo> myQuickFixes = null;
51   private Boolean myNeedsUpdateOnTyping = null;
52   private String myTooltip;
53   private boolean myAfterEndOfLine = false;
54   private boolean myIsFileLevelAnnotation = false;
55   private GutterIconRenderer myGutterIconRenderer;
56
57   public static class QuickFixInfo {
58     public final IntentionAction quickFix;
59     public final TextRange textRange;
60     public final List<IntentionAction> options;
61     @Deprecated
62     public final String displayName;
63     public final HighlightDisplayKey key;
64
65     @Deprecated
66     public QuickFixInfo(final IntentionAction quickFix, final TextRange textRange, final List<IntentionAction> options, String displayName) {
67       this.key = null;
68       this.quickFix = quickFix;
69       this.textRange = textRange;
70       this.displayName = quickFix.getText();
71       this.options = options;
72     }
73
74     public QuickFixInfo(final IntentionAction fix, final TextRange range, final HighlightDisplayKey key) {
75       this.key = key;
76       quickFix = fix;
77       textRange = range;
78       displayName = key != null ? HighlightDisplayKey.getDisplayNameByKey(key) : fix.getText();
79       options = null;
80     }
81   }
82
83   /**
84    * Creates an instance of the annotation.
85    *
86    * @param startOffset the start offset of the text range covered by the annotation.
87    * @param endOffset   the end offset of the text range covered by the annotation.
88    * @param severity    the severity of the problem indicated by the annotation (highlight, warning or error).
89    * @param message     the description of the annotation (shown in the status bar or by "View | Error Description" action)
90    * @param tooltip     the tooltip for the annotation (shown when hovering the mouse in the gutter bar)
91    * @see AnnotationHolder#createErrorAnnotation
92    * @see AnnotationHolder#createWarningAnnotation
93    * @see AnnotationHolder#createInfoAnnotation
94    */
95   public Annotation(final int startOffset, final int endOffset, final HighlightSeverity severity, final String message, String tooltip) {
96     assert startOffset <= endOffset : startOffset + ":" + endOffset;
97     myStartOffset = startOffset;
98     myEndOffset = endOffset;
99     myMessage = message;
100     myTooltip = tooltip;
101     mySeverity = severity;
102   }
103
104   /**
105    * Registers a quick fix for the annotation.
106    *
107    * @param fix the quick fix implementation.
108    */
109   public void registerFix(IntentionAction fix) {
110     registerFix(fix, null);
111   }
112
113   public void registerFix(IntentionAction fix, TextRange range) {
114     registerFix(fix,range, null);
115   }
116
117   /**
118    * Registers a quick fix for the annotation which is only available on a particular range of text
119    * within the annotation.
120    *
121    * @param fix   the quick fix implementation.
122    * @param range the text range (relative to the document) where the quick fix is available.
123    */
124   @Deprecated
125   public void registerFix(IntentionAction fix, TextRange range, List<IntentionAction> options, String displayName) {
126     if (range == null) {
127       range = new TextRange(myStartOffset, myEndOffset);
128     }
129     if (myQuickFixes == null) {
130       myQuickFixes = new ArrayList<QuickFixInfo>();
131     }
132     myQuickFixes.add(new QuickFixInfo(fix, range, options, displayName));
133   }
134
135   /**
136    * Registers a quick fix for the annotation which is only available on a particular range of text
137    * within the annotation.
138    *
139    * @param fix   the quick fix implementation.
140    * @param range the text range (relative to the document) where the quick fix is available.
141    */
142   public void registerFix(final IntentionAction fix, TextRange range, final HighlightDisplayKey key) {
143     if (range == null) {
144       range = new TextRange(myStartOffset, myEndOffset);
145     }
146     if (myQuickFixes == null) {
147       myQuickFixes = new ArrayList<QuickFixInfo>();
148     }
149     myQuickFixes.add(new QuickFixInfo(fix, range, key));
150   }
151
152   /**
153    * Sets a flag indicating what happens with the annotation when the user starts typing.
154    * If the parameter is true, the annotation is removed as soon as the user starts typing
155    * and is possibly restored by a later run of the annotator. If false, the annotation remains
156    * in place while the user is typing.
157    *
158    * @param b whether the annotation needs to be removed on typing.
159    * @see #needsUpdateOnTyping()
160    */
161   public void setNeedsUpdateOnTyping(boolean b) {
162     myNeedsUpdateOnTyping = Boolean.valueOf(b);
163   }
164
165   /**
166    * Gets a flag indicating what happens with the annotation when the user starts typing.
167    *
168    * @return true if the annotation is removed on typing, false otherwise.
169    * @see #setNeedsUpdateOnTyping(boolean)
170    */
171   public boolean needsUpdateOnTyping() {
172     if (myNeedsUpdateOnTyping == null) {
173       return mySeverity != HighlightSeverity.INFORMATION;
174     }
175
176     return myNeedsUpdateOnTyping.booleanValue();
177   }
178
179   /**
180    * Returns the start offset of the text range covered by the annotation.
181    *
182    * @return the annotation start offset.
183    */
184   public int getStartOffset() {
185     return myStartOffset;
186   }
187
188   /**
189    * Returns the end offset of the text range covered by the annotation.
190    *
191    * @return the annotation end offset.
192    */
193   public int getEndOffset() {
194     return myEndOffset;
195   }
196
197   /**
198    * Returns the severity of the problem indicated by the annotation (highlight, warning or error).
199    *
200    * @return the annotation severity.
201    */
202   public HighlightSeverity getSeverity() {
203     return mySeverity;
204   }
205
206   /**
207    * If the annotation matches one of commonly encountered problem types, returns the ID of that
208    * problem type so that an appropriate color can be used for highlighting the annotation.
209    *
210    * @return the common problem type.
211    */
212   public ProblemHighlightType getHighlightType() {
213     return myHighlightType;
214   }
215
216   /**
217    * Returns the text attribute key used for highlighting the annotation. If not specified
218    * explicitly, the key is determined automatically based on the problem highlight type and
219    * the annotation severity.
220    *
221    * @return the text attribute key used for highlighting
222    */
223   public TextAttributesKey getTextAttributes() {
224     if (myEnforcedAttributesKey != null) return myEnforcedAttributesKey;
225
226     if (myHighlightType == ProblemHighlightType.GENERIC_ERROR_OR_WARNING) {
227       if (mySeverity == HighlightSeverity.ERROR) return CodeInsightColors.ERRORS_ATTRIBUTES;
228       if (mySeverity == HighlightSeverity.WARNING) return CodeInsightColors.WARNINGS_ATTRIBUTES;
229       if (mySeverity == HighlightSeverity.INFO) return CodeInsightColors.INFO_ATTRIBUTES;
230     }
231
232     if (myHighlightType == ProblemHighlightType.GENERIC_ERROR) {
233       return CodeInsightColors.ERRORS_ATTRIBUTES;
234     }
235
236     if (myHighlightType == ProblemHighlightType.LIKE_DEPRECATED) {
237       return CodeInsightColors.DEPRECATED_ATTRIBUTES;
238     }
239     if (myHighlightType == ProblemHighlightType.LIKE_UNUSED_SYMBOL) {
240       return CodeInsightColors.NOT_USED_ELEMENT_ATTRIBUTES;
241     }
242     if (myHighlightType == ProblemHighlightType.LIKE_UNKNOWN_SYMBOL || myHighlightType == ProblemHighlightType.ERROR) {
243       return CodeInsightColors.WRONG_REFERENCES_ATTRIBUTES;
244     }
245     return HighlighterColors.TEXT;
246   }
247
248   public TextAttributes getEnforcedTextAttributes() {
249     return myEnforcedAttributes;
250   }
251
252   /**
253    * Sets the text attributes used for highlighting the annotation.
254    *
255    * @param enforcedAttributes the text attributes for highlighting,
256    */
257   public void setEnforcedTextAttributes(final TextAttributes enforcedAttributes) {
258     myEnforcedAttributes = enforcedAttributes;
259   }
260
261   /**
262    * Returns the list of quick fixes registered for the annotation.
263    *
264    * @return the list of quick fixes, or null if none have been registered.
265    */
266
267   @Nullable
268   public List<QuickFixInfo> getQuickFixes() {
269     return myQuickFixes;
270   }
271
272   /**
273    * Returns the description of the annotation (shown in the status bar or by "View | Error Description" action).
274    *
275    * @return the description of the annotation.
276    */
277   public String getMessage() {
278     return myMessage;
279   }
280
281   /**
282    * Returns the tooltip for the annotation (shown when hovering the mouse in the gutter bar).
283    *
284    * @return the tooltip for the annotation.
285    */
286   public String getTooltip() {
287     return myTooltip;
288   }
289
290   /**
291    * Sets the tooltip for the annotation (shown when hovering the mouse in the gutter bar).
292    *
293    * @param tooltip the tooltip text.
294    */
295   public void setTooltip(final String tooltip) {
296     myTooltip = tooltip;
297   }
298
299   /**
300    * If the annotation matches one of commonly encountered problem types, sets the ID of that
301    * problem type so that an appropriate color can be used for highlighting the annotation.
302    *
303    * @param highlightType the ID of the problem type.
304    */
305   public void setHighlightType(final ProblemHighlightType highlightType) {
306     myHighlightType = highlightType;
307   }
308
309   /**
310    * Sets the text attributes key used for highlighting the annotation.
311    *
312    * @param enforcedAttributes the text attributes key for highlighting,
313    */
314   public void setTextAttributes(final TextAttributesKey enforcedAttributes) {
315     myEnforcedAttributesKey = enforcedAttributes;
316   }
317
318   /**
319    * Returns the flag indicating whether the annotation is shown after the end of line containing it.
320    *
321    * @return true if the annotation is shown after the end of line, false otherwise.
322    */
323   public boolean isAfterEndOfLine() {
324     return myAfterEndOfLine;
325   }
326
327   /**
328    * Sets the flag indicating whether the annotation is shown after the end of line containing it.
329    * This can be used for errors like "unclosed string literal", "missing semicolon" and so on.
330    *
331    * @param afterEndOfLine true if the annotation should be shown after the end of line, false otherwise.
332    */
333   public void setAfterEndOfLine(final boolean afterEndOfLine) {
334     myAfterEndOfLine = afterEndOfLine;
335   }
336
337   /**
338    * File level annoations are visualized differently than lesser range annotations by showing a title bar on top of the
339    * editor rather than applying text attributes to the text range.
340    * @return <code>true</code> if this particular annotation have been defined as file level.
341    */
342   public boolean isFileLevelAnnotation() {
343     return myIsFileLevelAnnotation;
344   }
345
346   /**
347    * File level annoations are visualized differently than lesser range annotations by showing a title bar on top of the
348    * editor rather than applying text attributes to the text range.
349    * @param isFileLevelAnnotation <code>true</code> if this particular annotation should be visualized at file level.
350    */
351   public void setFileLevelAnnotation(final boolean isFileLevelAnnotation) {
352     myIsFileLevelAnnotation = isFileLevelAnnotation;
353   }
354
355   /**
356    * Gets the renderer used to draw the gutter icon in the region covered by the annotation.
357    *
358    * @return the gutter icon renderer instance.
359    */
360   @Nullable
361   public GutterIconRenderer getGutterIconRenderer() {
362     return myGutterIconRenderer;
363   }
364
365   /**
366    * Sets the renderer used to draw the gutter icon in the region covered by the annotation.
367    *
368    * @param gutterIconRenderer the gutter icon renderer instance.
369    */
370   public void setGutterIconRenderer(@Nullable final GutterIconRenderer gutterIconRenderer) {
371     myGutterIconRenderer = gutterIconRenderer;
372   }
373
374   public String toString() {
375     return "Annotation(" +
376            "message='" + myMessage + "'" +
377            ", severity='" + mySeverity + "'" +
378            ", toolTip='" + myTooltip + "'" +
379            ")";
380   }
381 }