1 /*******************************************************************************
2 * Copyright (c) 2000, 2003 IBM Corporation 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
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package net.sourceforge.phpdt.internal.ui.text;
13 import java.util.ArrayList;
14 import java.util.HashMap;
15 import java.util.Iterator;
16 import java.util.List;
19 import net.sourceforge.phpdt.internal.corext.Assert;
20 import net.sourceforge.phpdt.internal.ui.PHPUIMessages;
21 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
23 import org.eclipse.jface.preference.IPreferenceStore;
24 import org.eclipse.jface.text.BadLocationException;
25 import org.eclipse.jface.text.IDocument;
26 import org.eclipse.jface.text.Position;
27 import org.eclipse.jface.text.source.Annotation;
28 import org.eclipse.jface.text.source.IAnnotationHover;
29 import org.eclipse.jface.text.source.IAnnotationModel;
30 import org.eclipse.jface.text.source.ISourceViewer;
31 import org.eclipse.ui.editors.text.EditorsUI;
32 import org.eclipse.ui.texteditor.AnnotationPreference;
35 * Determines all markers for the given line and collects, concatenates, and
36 * formates their messages.
38 public class JavaAnnotationHover implements IAnnotationHover {
39 private static class JavaAnnotationHoverType {
42 public static final JavaAnnotationHoverType OVERVIEW_RULER_HOVER = new JavaAnnotationHoverType();
44 public static final JavaAnnotationHoverType TEXT_RULER_HOVER = new JavaAnnotationHoverType();
46 public static final JavaAnnotationHoverType VERTICAL_RULER_HOVER = new JavaAnnotationHoverType();
48 // private IPreferenceStore fStore =
49 // PHPeclipsePlugin.getDefault().getPreferenceStore();
50 private IPreferenceStore fStore = EditorsUI.getPreferenceStore();
52 private JavaAnnotationHoverType fType;
54 public JavaAnnotationHover(JavaAnnotationHoverType type) {
55 Assert.isTrue(OVERVIEW_RULER_HOVER.equals(type)
56 || TEXT_RULER_HOVER.equals(type)
57 || VERTICAL_RULER_HOVER.equals(type));
62 * Returns the distance to the ruler line.
64 protected int compareRulerLine(Position position, IDocument document,
67 if (position.getOffset() > -1 && position.getLength() > -1) {
69 int javaAnnotationLine = document.getLineOfOffset(position
71 if (line == javaAnnotationLine)
73 if (javaAnnotationLine <= line
74 && line <= document.getLineOfOffset(position
76 + position.getLength()))
78 } catch (BadLocationException x) {
86 * Selects a set of markers from the two lists. By default, it just returns
87 * the set of exact matches.
89 protected List select(List exactMatch, List including) {
94 * Returns one marker which includes the ruler's line of activity.
96 protected List getJavaAnnotationsForLine(ISourceViewer viewer, int line) {
98 IDocument document = viewer.getDocument();
99 IAnnotationModel model = viewer.getAnnotationModel();
104 List exact = new ArrayList();
105 List including = new ArrayList();
107 Iterator e = model.getAnnotationIterator();
108 HashMap messagesAtPosition = new HashMap();
109 while (e.hasNext()) {
110 Annotation annotation = (Annotation) e.next();
112 if (annotation.getText() == null)
115 Position position = model.getPosition(annotation);
116 if (position == null)
119 AnnotationPreference preference = getAnnotationPreference(annotation);
120 if (preference == null)
123 if (OVERVIEW_RULER_HOVER.equals(fType)) {
124 String key = preference.getOverviewRulerPreferenceKey();
125 if (key == null || !fStore.getBoolean(key))
127 } else if (TEXT_RULER_HOVER.equals(fType)) {
128 String key = preference.getTextPreferenceKey();
130 if (!fStore.getBoolean(key))
133 key = preference.getHighlightPreferenceKey();
134 if (key == null || !fStore.getBoolean(key))
137 } else if (VERTICAL_RULER_HOVER.equals(fType)) {
138 String key = preference.getVerticalRulerPreferenceKey();
139 // backward compatibility
140 if (key != null && !fStore.getBoolean(key))
144 if (isDuplicateJavaAnnotation(messagesAtPosition, position,
145 annotation.getText()))
148 switch (compareRulerLine(position, document, line)) {
150 exact.add(annotation);
153 including.add(annotation);
158 return select(exact, including);
162 // * Returns one marker which includes the ruler's line of activity.
164 // protected List getJavaAnnotationsForLine(ISourceViewer viewer, int line)
167 // IDocument document= viewer.getDocument();
168 // IAnnotationModel model= viewer.getAnnotationModel();
170 // if (model == null)
173 // List exact= new ArrayList();
174 // List including= new ArrayList();
176 // Iterator e= model.getAnnotationIterator();
177 // HashMap messagesAtPosition= new HashMap();
178 // while (e.hasNext()) {
179 // Object o= e.next();
180 // if (o instanceof IJavaAnnotation) {
181 // IJavaAnnotation a= (IJavaAnnotation)o;
182 // if (!a.hasOverlay()) {
183 // Position position= model.getPosition((Annotation)a);
184 // if (position == null)
187 // if (isDuplicateJavaAnnotation(messagesAtPosition, position,
191 // switch (compareRulerLine(position, document, line)) {
203 // return select(exact, including);
206 private boolean isDuplicateJavaAnnotation(Map messagesAtPosition,
207 Position position, String message) {
208 if (messagesAtPosition.containsKey(position)) {
209 Object value = messagesAtPosition.get(position);
210 if (message.equals(value))
213 if (value instanceof List) {
214 List messages = (List) value;
215 if (messages.contains(message))
218 messages.add(message);
220 ArrayList messages = new ArrayList();
222 messages.add(message);
223 messagesAtPosition.put(position, messages);
226 messagesAtPosition.put(position, message);
231 * @see IVerticalRulerHover#getHoverInfo(ISourceViewer, int)
233 public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) {
234 List javaAnnotations = getJavaAnnotationsForLine(sourceViewer,
236 if (javaAnnotations != null) {
238 if (javaAnnotations.size() == 1) {
241 Annotation annotation = (Annotation) javaAnnotations.get(0);
242 String message = annotation.getText();
243 if (message != null && message.trim().length() > 0)
244 return formatSingleMessage(message);
248 List messages = new ArrayList();
250 Iterator e = javaAnnotations.iterator();
251 while (e.hasNext()) {
252 Annotation annotation = (Annotation) e.next();
253 String message = annotation.getText();
254 if (message != null && message.trim().length() > 0)
255 messages.add(message.trim());
258 if (messages.size() == 1)
259 return formatSingleMessage((String) messages.get(0));
261 if (messages.size() > 1)
262 return formatMultipleMessages(messages);
270 * @see IVerticalRulerHover#getHoverInfo(ISourceViewer, int)
272 // public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) {
273 // List javaAnnotations= getJavaAnnotationsForLine(sourceViewer,
275 // if (javaAnnotations != null) {
277 // if (javaAnnotations.size() == 1) {
280 // IJavaAnnotation javaAnnotation= (IJavaAnnotation) javaAnnotations.get(0);
281 // String message= javaAnnotation.getMessage();
282 // if (message != null && message.trim().length() > 0)
283 // return formatSingleMessage(message);
287 // List messages= new ArrayList();
289 // Iterator e= javaAnnotations.iterator();
290 // while (e.hasNext()) {
291 // IJavaAnnotation javaAnnotation= (IJavaAnnotation) e.next();
292 // String message= javaAnnotation.getMessage();
293 // if (message != null && message.trim().length() > 0)
294 // messages.add(message.trim());
297 // if (messages.size() == 1)
298 // return formatSingleMessage((String) messages.get(0));
300 // if (messages.size() > 1)
301 // return formatMultipleMessages(messages);
308 * Formats a message as HTML text.
310 private String formatSingleMessage(String message) {
311 StringBuffer buffer = new StringBuffer();
312 HTMLPrinter.addPageProlog(buffer);
313 HTMLPrinter.addParagraph(buffer, HTMLPrinter
314 .convertToHTMLContent(message));
315 HTMLPrinter.addPageEpilog(buffer);
316 return buffer.toString();
320 * Formats several message as HTML text.
322 private String formatMultipleMessages(List messages) {
323 StringBuffer buffer = new StringBuffer();
324 HTMLPrinter.addPageProlog(buffer);
329 .convertToHTMLContent(PHPUIMessages
330 .getString("JavaAnnotationHover.multipleMarkersAtThisLine"))); //$NON-NLS-1$
332 HTMLPrinter.startBulletList(buffer);
333 Iterator e = messages.iterator();
335 HTMLPrinter.addBullet(buffer, HTMLPrinter
336 .convertToHTMLContent((String) e.next()));
337 HTMLPrinter.endBulletList(buffer);
339 HTMLPrinter.addPageEpilog(buffer);
340 return buffer.toString();
344 * Returns the annotation preference for the given annotation.
348 * @return the annotation preference or <code>null</code> if none
350 private AnnotationPreference getAnnotationPreference(Annotation annotation) {
351 return EditorsUI.getAnnotationPreferenceLookup()
352 .getAnnotationPreference(annotation);