comparison dwtx/jface/text/source/DefaultAnnotationHover.d @ 129:eb30df5ca28b

Added JFace Text sources
author Frank Benoit <benoit@tionex.de>
date Sat, 23 Aug 2008 19:10:48 +0200
parents
children c4fb132a086c
comparison
equal deleted inserted replaced
128:8df1d4193877 129:eb30df5ca28b
1 /*******************************************************************************
2 * Copyright (c) 2006, 2007 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 * Port to the D programming language:
11 * Frank Benoit <benoit@tionex.de>
12 *******************************************************************************/
13 module dwtx.jface.text.source.DefaultAnnotationHover;
14
15 import dwt.dwthelper.utils;
16
17 import java.util.ArrayList;
18 import java.util.HashMap;
19 import java.util.Iterator;
20 import java.util.List;
21 import java.util.Map;
22
23 import dwtx.jface.text.BadLocationException;
24 import dwtx.jface.text.IDocument;
25 import dwtx.jface.text.Position;
26 import dwtx.jface.text.source.projection.AnnotationBag;
27
28 /**
29 * Standard implementation of {@link dwtx.jface.text.source.IAnnotationHover}.
30 *
31 * @since 3.2
32 */
33 public class DefaultAnnotationHover : IAnnotationHover {
34
35
36 /**
37 * Tells whether the line number should be shown when no annotation is found
38 * under the cursor.
39 *
40 * @since 3.4
41 */
42 private bool fShowLineNumber;
43
44 /**
45 * Creates a new default annotation hover.
46 *
47 * @since 3.4
48 */
49 public DefaultAnnotationHover() {
50 this(false);
51 }
52
53 /**
54 * Creates a new default annotation hover.
55 *
56 * @param showLineNumber <code>true</code> if the line number should be shown when no annotation is found
57 * @since 3.4
58 */
59 public DefaultAnnotationHover(bool showLineNumber) {
60 fShowLineNumber= showLineNumber;
61 }
62
63 /*
64 * @see dwtx.jface.text.source.IAnnotationHover#getHoverInfo(dwtx.jface.text.source.ISourceViewer, int)
65 */
66 public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) {
67 List javaAnnotations= getAnnotationsForLine(sourceViewer, lineNumber);
68 if (javaAnnotations !is null) {
69
70 if (javaAnnotations.size() is 1) {
71
72 // optimization
73 Annotation annotation= (Annotation) javaAnnotations.get(0);
74 String message= annotation.getText();
75 if (message !is null && message.trim().length() > 0)
76 return formatSingleMessage(message);
77
78 } else {
79
80 List messages= new ArrayList();
81
82 Iterator e= javaAnnotations.iterator();
83 while (e.hasNext()) {
84 Annotation annotation= (Annotation) e.next();
85 String message= annotation.getText();
86 if (message !is null && message.trim().length() > 0)
87 messages.add(message.trim());
88 }
89
90 if (messages.size() is 1)
91 return formatSingleMessage((String)messages.get(0));
92
93 if (messages.size() > 1)
94 return formatMultipleMessages(messages);
95 }
96 }
97
98 if (fShowLineNumber && lineNumber > -1)
99 return JFaceTextMessages.getFormattedString("DefaultAnnotationHover.lineNumber", new String[] { Integer.toString(lineNumber + 1) }); //$NON-NLS-1$
100
101 return null;
102 }
103
104 /**
105 * Tells whether the annotation should be included in
106 * the computation.
107 *
108 * @param annotation the annotation to test
109 * @return <code>true</code> if the annotation is included in the computation
110 */
111 protected bool isIncluded(Annotation annotation) {
112 return true;
113 }
114
115 /**
116 * Hook method to format the given single message.
117 * <p>
118 * Subclasses can change this to create a different
119 * format like HTML.
120 * </p>
121 *
122 * @param message the message to format
123 * @return the formatted message
124 */
125 protected String formatSingleMessage(String message) {
126 return message;
127 }
128
129 /**
130 * Hook method to formats the given messages.
131 * <p>
132 * Subclasses can change this to create a different
133 * format like HTML.
134 * </p>
135 *
136 * @param messages the messages to format
137 * @return the formatted message
138 */
139 protected String formatMultipleMessages(List messages) {
140 StringBuffer buffer= new StringBuffer();
141 buffer.append(JFaceTextMessages.getString("DefaultAnnotationHover.multipleMarkers")); //$NON-NLS-1$
142
143 Iterator e= messages.iterator();
144 while (e.hasNext()) {
145 buffer.append('\n');
146 String listItemText= (String) e.next();
147 buffer.append(JFaceTextMessages.getFormattedString("DefaultAnnotationHover.listItem", new String[] { listItemText })); //$NON-NLS-1$
148 }
149 return buffer.toString();
150 }
151
152 private bool isRulerLine(Position position, IDocument document, int line) {
153 if (position.getOffset() > -1 && position.getLength() > -1) {
154 try {
155 return line is document.getLineOfOffset(position.getOffset());
156 } catch (BadLocationException x) {
157 }
158 }
159 return false;
160 }
161
162 private IAnnotationModel getAnnotationModel(ISourceViewer viewer) {
163 if (viewer instanceof ISourceViewerExtension2) {
164 ISourceViewerExtension2 extension= (ISourceViewerExtension2) viewer;
165 return extension.getVisualAnnotationModel();
166 }
167 return viewer.getAnnotationModel();
168 }
169
170 private bool isDuplicateAnnotation(Map messagesAtPosition, Position position, String message) {
171 if (messagesAtPosition.containsKey(position)) {
172 Object value= messagesAtPosition.get(position);
173 if (message.equals(value))
174 return true;
175
176 if (value instanceof List) {
177 List messages= (List)value;
178 if (messages.contains(message))
179 return true;
180
181 messages.add(message);
182 } else {
183 ArrayList messages= new ArrayList();
184 messages.add(value);
185 messages.add(message);
186 messagesAtPosition.put(position, messages);
187 }
188 } else
189 messagesAtPosition.put(position, message);
190 return false;
191 }
192
193 private bool includeAnnotation(Annotation annotation, Position position, HashMap messagesAtPosition) {
194 if (!isIncluded(annotation))
195 return false;
196
197 String text= annotation.getText();
198 return (text !is null && !isDuplicateAnnotation(messagesAtPosition, position, text));
199 }
200
201 private List getAnnotationsForLine(ISourceViewer viewer, int line) {
202 IAnnotationModel model= getAnnotationModel(viewer);
203 if (model is null)
204 return null;
205
206 IDocument document= viewer.getDocument();
207 List javaAnnotations= new ArrayList();
208 HashMap messagesAtPosition= new HashMap();
209 Iterator iterator= model.getAnnotationIterator();
210
211 while (iterator.hasNext()) {
212 Annotation annotation= (Annotation) iterator.next();
213
214 Position position= model.getPosition(annotation);
215 if (position is null)
216 continue;
217
218 if (!isRulerLine(position, document, line))
219 continue;
220
221 if (annotation instanceof AnnotationBag) {
222 AnnotationBag bag= (AnnotationBag) annotation;
223 Iterator e= bag.iterator();
224 while (e.hasNext()) {
225 annotation= (Annotation) e.next();
226 position= model.getPosition(annotation);
227 if (position !is null && includeAnnotation(annotation, position, messagesAtPosition))
228 javaAnnotations.add(annotation);
229 }
230 continue;
231 }
232
233 if (includeAnnotation(annotation, position, messagesAtPosition))
234 javaAnnotations.add(annotation);
235 }
236
237 return javaAnnotations;
238 }
239 }