Mercurial > projects > dwt-addons
annotate dwtx/jface/text/source/LineChangeHover.d @ 172:d994a8b2cdf7
again compile fixes
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Wed, 10 Sep 2008 23:14:02 +0200 |
parents | 1a5b8f8129df |
children |
rev | line source |
---|---|
129 | 1 /******************************************************************************* |
2 * Copyright (c) 2000, 2008 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.LineChangeHover; | |
14 | |
131 | 15 import dwtx.jface.text.source.ISharedTextColors; // packageimport |
16 import dwtx.jface.text.source.ILineRange; // packageimport | |
17 import dwtx.jface.text.source.IAnnotationPresentation; // packageimport | |
18 import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport | |
19 import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport | |
20 import dwtx.jface.text.source.TextInvocationContext; // packageimport | |
21 import dwtx.jface.text.source.IChangeRulerColumn; // packageimport | |
22 import dwtx.jface.text.source.IAnnotationMap; // packageimport | |
23 import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport | |
24 import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport | |
25 import dwtx.jface.text.source.IAnnotationHover; // packageimport | |
26 import dwtx.jface.text.source.ContentAssistantFacade; // packageimport | |
27 import dwtx.jface.text.source.IAnnotationAccess; // packageimport | |
28 import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport | |
29 import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport | |
30 import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport | |
31 import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport | |
32 import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport | |
33 import dwtx.jface.text.source.ILineDifferExtension; // packageimport | |
34 import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport | |
35 import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport | |
36 import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport | |
37 import dwtx.jface.text.source.ISourceViewer; // packageimport | |
38 import dwtx.jface.text.source.AnnotationModel; // packageimport | |
39 import dwtx.jface.text.source.ILineDifferExtension2; // packageimport | |
40 import dwtx.jface.text.source.IAnnotationModelListener; // packageimport | |
41 import dwtx.jface.text.source.IVerticalRuler; // packageimport | |
42 import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport | |
43 import dwtx.jface.text.source.SourceViewer; // packageimport | |
44 import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport | |
45 import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport | |
46 import dwtx.jface.text.source.CompositeRuler; // packageimport | |
47 import dwtx.jface.text.source.ImageUtilities; // packageimport | |
48 import dwtx.jface.text.source.VisualAnnotationModel; // packageimport | |
49 import dwtx.jface.text.source.IAnnotationModel; // packageimport | |
50 import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport | |
51 import dwtx.jface.text.source.ILineDiffInfo; // packageimport | |
52 import dwtx.jface.text.source.VerticalRulerEvent; // packageimport | |
53 import dwtx.jface.text.source.ChangeRulerColumn; // packageimport | |
54 import dwtx.jface.text.source.ILineDiffer; // packageimport | |
55 import dwtx.jface.text.source.AnnotationModelEvent; // packageimport | |
56 import dwtx.jface.text.source.AnnotationColumn; // packageimport | |
57 import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport | |
58 import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport | |
59 import dwtx.jface.text.source.AbstractRulerColumn; // packageimport | |
60 import dwtx.jface.text.source.ISourceViewerExtension; // packageimport | |
61 import dwtx.jface.text.source.AnnotationMap; // packageimport | |
62 import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport | |
63 import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport | |
64 import dwtx.jface.text.source.LineRange; // packageimport | |
65 import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport | |
66 import dwtx.jface.text.source.VerticalRuler; // packageimport | |
67 import dwtx.jface.text.source.JFaceTextMessages; // packageimport | |
68 import dwtx.jface.text.source.IOverviewRuler; // packageimport | |
69 import dwtx.jface.text.source.Annotation; // packageimport | |
70 import dwtx.jface.text.source.IVerticalRulerListener; // packageimport | |
71 import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport | |
72 import dwtx.jface.text.source.AnnotationPainter; // packageimport | |
73 import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport | |
74 import dwtx.jface.text.source.OverviewRuler; // packageimport | |
75 import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport | |
76 | |
77 | |
129 | 78 import dwt.dwthelper.utils; |
79 | |
153
f70d9508c95c
Fix java Collection imports
Frank Benoit <benoit@tionex.de>
parents:
141
diff
changeset
|
80 import dwtx.dwtxhelper.Collection; |
f70d9508c95c
Fix java Collection imports
Frank Benoit <benoit@tionex.de>
parents:
141
diff
changeset
|
81 |
f70d9508c95c
Fix java Collection imports
Frank Benoit <benoit@tionex.de>
parents:
141
diff
changeset
|
82 |
129 | 83 |
84 import dwt.graphics.Point; | |
85 import dwt.widgets.Shell; | |
86 import dwtx.jface.action.ToolBarManager; | |
87 import dwtx.jface.text.DefaultInformationControl; | |
88 import dwtx.jface.text.IDocument; | |
89 import dwtx.jface.text.IInformationControl; | |
90 import dwtx.jface.text.IInformationControlCreator; | |
91 import dwtx.jface.text.information.IInformationProviderExtension2; | |
92 | |
93 | |
94 /** | |
95 * A hover for line oriented diffs. It determines the text to show as hover for a certain line in the | |
96 * document. | |
97 * | |
98 * @since 3.0 | |
99 */ | |
100 public class LineChangeHover : IAnnotationHover, IAnnotationHoverExtension, IInformationProviderExtension2 { | |
101 | |
102 /* | |
103 * @see dwtx.jface.text.source.IAnnotationHover#getHoverInfo(dwtx.jface.text.source.ISourceViewer, int) | |
104 */ | |
105 public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) { | |
106 return null; | |
107 } | |
108 | |
109 /** | |
110 * Formats the source w/ syntax coloring etc. This implementation replaces tabs with spaces. | |
111 * May be overridden by subclasses. | |
112 * | |
113 * @param content the hover content | |
114 * @return <code>content</code> reformatted | |
115 */ | |
116 protected String formatSource(String content) { | |
117 if (content !is null) { | |
118 StringBuffer sb= new StringBuffer(content); | |
119 final String tabReplacement= getTabReplacement(); | |
120 for (int pos= 0; pos < sb.length(); pos++) { | |
162 | 121 if (sb.slice()[pos] is '\t'){ |
122 sb.select( pos, pos + 1); | |
123 sb.replace(tabReplacement); | |
124 } | |
129 | 125 } |
126 return sb.toString(); | |
127 } | |
128 return content; | |
129 } | |
130 | |
131 /** | |
132 * Returns a replacement for the tab character. The default implementation | |
133 * returns a tabulator character, but subclasses may override to specify a | |
134 * number of spaces. | |
135 * | |
136 * @return a whitespace String that will be substituted for the tabulator | |
137 * character | |
138 */ | |
139 protected String getTabReplacement() { | |
140 return "\t"; //$NON-NLS-1$ | |
141 } | |
142 | |
143 /** | |
144 * Computes the content of the hover for the document contained in <code>viewer</code> on | |
145 * line <code>line</code>. | |
146 * | |
147 * @param viewer the connected viewer | |
148 * @param first the first line in <code>viewer</code>'s document to consider | |
149 * @param last the last line in <code>viewer</code>'s document to consider | |
150 * @param maxLines the max number of lines | |
151 * @return The hover content corresponding to the parameters | |
152 * @see #getHoverInfo(ISourceViewer, int) | |
153 * @see #getHoverInfo(ISourceViewer, ILineRange, int) | |
154 */ | |
155 private String computeContent(ISourceViewer viewer, int first, int last, int maxLines) { | |
156 ILineDiffer differ= getDiffer(viewer); | |
157 if (differ is null) | |
158 return null; | |
159 | |
160 final List lines= new LinkedList(); | |
161 for (int l= first; l <= last; l++) { | |
162 ILineDiffInfo info= differ.getLineInfo(l); | |
163 if (info !is null) | |
162 | 164 lines.add(cast(Object)info); |
129 | 165 } |
166 | |
167 return decorateText(lines, maxLines); | |
168 } | |
169 | |
170 /** | |
171 * Takes a list of <code>ILineDiffInfo</code>s and computes a hover of at most <code>maxLines</code>. | |
172 * Added lines are prefixed with a <code>'+'</code>, changed lines with <code>'>'</code> and | |
173 * deleted lines with <code>'-'</code>. | |
174 * <p>Deleted and added lines can even each other out, so that a number of deleted lines get | |
175 * displayed where - in the current document - the added lines are. | |
176 * | |
177 * @param diffInfos a <code>List</code> of <code>ILineDiffInfo</code> | |
178 * @param maxLines the maximum number of lines. Note that adding up all annotations might give | |
179 * more than that due to deleted lines. | |
180 * @return a <code>String</code> suitable for hover display | |
181 */ | |
182 protected String decorateText(List diffInfos, int maxLines) { | |
183 /* maxLines controls the size of the hover (not more than what fits into the display are of | |
184 * the viewer). | |
185 * added controls how many lines are added - added lines are | |
186 */ | |
187 String text= ""; //$NON-NLS-1$ | |
188 int added= 0; | |
189 for (Iterator it= diffInfos.iterator(); it.hasNext();) { | |
134 | 190 ILineDiffInfo info= cast(ILineDiffInfo)it.next(); |
129 | 191 String[] original= info.getOriginalText(); |
192 int type= info.getChangeType(); | |
193 int i= 0; | |
194 if (type is ILineDiffInfo.ADDED) | |
195 added++; | |
196 else if (type is ILineDiffInfo.CHANGED) { | |
162 | 197 text ~= "> " ~ (original.length > 0 ? original[i++] : ""); //$NON-NLS-1$ //$NON-NLS-2$ |
129 | 198 maxLines--; |
199 } else if (type is ILineDiffInfo.UNCHANGED) { | |
200 maxLines++; | |
201 } | |
202 if (maxLines is 0) | |
203 return trimTrailing(text); | |
204 for (; i < original.length; i++) { | |
162 | 205 text ~= "- " ~ original[i]; //$NON-NLS-1$ |
129 | 206 added--; |
207 if (--maxLines is 0) | |
208 return trimTrailing(text); | |
209 } | |
210 } | |
211 text= text.trim(); | |
212 if (text.length() is 0 && added-- > 0 && maxLines-- > 0) | |
162 | 213 text ~= "+ "; //$NON-NLS-1$ |
129 | 214 while (added-- > 0 && maxLines-- > 0) |
162 | 215 text ~= "\n+ "; //$NON-NLS-1$ |
129 | 216 return text; |
217 } | |
218 | |
219 /** | |
220 * Trims trailing spaces | |
221 * | |
222 * @param text a <code>String</code> | |
223 * @return a copy of <code>text</code> with trailing spaces removed | |
224 */ | |
225 private String trimTrailing(String text) { | |
226 int pos= text.length() - 1; | |
227 while (pos >= 0 && Character.isWhitespace(text.charAt(pos))) { | |
228 pos--; | |
229 } | |
230 return text.substring(0, pos + 1); | |
231 } | |
232 | |
233 /** | |
234 * Extracts the line differ - if any - from the viewer's document's annotation model. | |
235 * @param viewer the viewer | |
236 * @return a line differ for the document displayed in viewer, or <code>null</code>. | |
237 */ | |
238 private ILineDiffer getDiffer(ISourceViewer viewer) { | |
239 IAnnotationModel model= viewer.getAnnotationModel(); | |
240 | |
241 if (model is null) | |
242 return null; | |
243 | |
138 | 244 if ( cast(IAnnotationModelExtension)model ) { |
172 | 245 IAnnotationModel diffModel= (cast(IAnnotationModelExtension)model).getAnnotationModel(stringcast(IChangeRulerColumn.QUICK_DIFF_MODEL_ID)); |
129 | 246 if (diffModel !is null) |
247 model= diffModel; | |
248 } | |
138 | 249 if ( cast(ILineDiffer)model ) { |
141 | 250 if (cast(ILineDifferExtension2)model && (cast(ILineDifferExtension2)model).isSuspended()) |
129 | 251 return null; |
134 | 252 return cast(ILineDiffer)model; |
129 | 253 } |
254 return null; | |
255 } | |
256 | |
257 /** | |
258 * Computes the block of lines which form a contiguous block of changes covering <code>line</code>. | |
259 * | |
260 * @param viewer the source viewer showing | |
261 * @param line the line which a hover is displayed for | |
262 * @param min the first line in <code>viewer</code>'s document to consider | |
263 * @param max the last line in <code>viewer</code>'s document to consider | |
264 * @return the selection in the document displayed in <code>viewer</code> containing <code>line</code> | |
265 * that is covered by the hover information returned by the receiver. | |
266 */ | |
267 protected Point computeLineRange(ISourceViewer viewer, int line, int min, int max) { | |
268 /* Algorithm: | |
269 * All lines that have changes to themselves (added, changed) are taken that form a | |
270 * contiguous block of lines that includes <code>line</code>. | |
271 * | |
272 * If <code>line</code> is itself unchanged, if there is a deleted line either above or | |
273 * below, or both, the lines +/- 1 from <code>line</code> are included in the search as well, | |
274 * without applying this last rule to them, though. (I.e., if <code>line</code> is unchanged, | |
275 * but has a deleted line above, this one is taken in. If the line above has changes, the block | |
276 * is extended from there. If the line has no changes itself, the search stops). | |
277 * | |
278 * The block never extends the visible line range of the viewer. | |
279 */ | |
280 | |
281 ILineDiffer differ= getDiffer(viewer); | |
282 if (differ is null) | |
283 return new Point(-1, -1); | |
284 | |
285 // backward search | |
286 | |
287 int l= line; | |
288 ILineDiffInfo info= differ.getLineInfo(l); | |
289 // search backwards until a line has no changes to itself | |
290 while (l >= min && info !is null && (info.getChangeType() is ILineDiffInfo.CHANGED || info.getChangeType() is ILineDiffInfo.ADDED)) { | |
291 info= differ.getLineInfo(--l); | |
292 } | |
293 | |
294 int first= Math.min(l + 1, line); | |
295 | |
296 // forward search | |
297 | |
298 l= line; | |
299 info= differ.getLineInfo(l); | |
300 // search forward until a line has no changes to itself | |
301 while (l <= max && info !is null && (info.getChangeType() is ILineDiffInfo.CHANGED || info.getChangeType() is ILineDiffInfo.ADDED)) { | |
302 info= differ.getLineInfo(++l); | |
303 } | |
304 | |
305 int last= Math.max(l - 1, line); | |
306 | |
307 return new Point(first, last); | |
308 } | |
309 | |
310 /* | |
311 * @see dwtx.jface.text.source.IAnnotationHoverExtension#getHoverInfo(dwtx.jface.text.source.ISourceViewer, dwtx.jface.text.source.ILineRange, int) | |
312 */ | |
313 public Object getHoverInfo(ISourceViewer sourceViewer, ILineRange lineRange, int visibleLines) { | |
314 int first= adaptFirstLine(sourceViewer, lineRange.getStartLine()); | |
315 int last= adaptLastLine(sourceViewer, lineRange.getStartLine() + lineRange.getNumberOfLines() - 1); | |
316 String content= computeContent(sourceViewer, first, last, visibleLines); | |
162 | 317 return stringcast(formatSource(content)); |
129 | 318 } |
319 | |
320 /** | |
321 * Adapts the start line to the implementation of <code>ILineDiffInfo</code>. | |
322 * | |
323 * @param viewer the source viewer | |
324 * @param startLine the line to adapt | |
325 * @return <code>startLine - 1</code> if that line exists and is an | |
326 * unchanged line followed by deletions, <code>startLine</code> | |
327 * otherwise | |
328 */ | |
329 private int adaptFirstLine(ISourceViewer viewer, int startLine) { | |
330 ILineDiffer differ= getDiffer(viewer); | |
331 if (differ !is null && startLine > 0) { | |
332 int l= startLine - 1; | |
333 ILineDiffInfo info= differ.getLineInfo(l); | |
334 if (info !is null && info.getChangeType() is ILineDiffInfo.UNCHANGED && info.getRemovedLinesBelow() > 0) | |
335 return l; | |
336 } | |
337 return startLine; | |
338 } | |
339 | |
340 /** | |
341 * Adapts the last line to the implementation of <code>ILineDiffInfo</code>. | |
342 * | |
343 * @param viewer the source viewer | |
344 * @param lastLine the line to adapt | |
345 * @return <code>lastLine - 1</code> if that line exists and is an | |
346 * unchanged line followed by deletions, <code>startLine</code> | |
347 * otherwise | |
348 */ | |
349 private int adaptLastLine(ISourceViewer viewer, int lastLine) { | |
350 ILineDiffer differ= getDiffer(viewer); | |
351 if (differ !is null && lastLine > 0) { | |
352 ILineDiffInfo info= differ.getLineInfo(lastLine); | |
353 if (info !is null && info.getChangeType() is ILineDiffInfo.UNCHANGED) | |
354 return lastLine - 1; | |
355 } | |
356 return lastLine; | |
357 } | |
358 | |
359 /* | |
360 * @see dwtx.jface.text.source.IAnnotationHoverExtension#getHoverLineRange(dwtx.jface.text.source.ISourceViewer, int) | |
361 */ | |
362 public ILineRange getHoverLineRange(ISourceViewer viewer, int lineNumber) { | |
363 IDocument document= viewer.getDocument(); | |
364 if (document !is null) { | |
365 Point range= computeLineRange(viewer, lineNumber, 0, Math.max(0, document.getNumberOfLines() - 1)); | |
366 if (range.x !is -1 && range.y !is -1) | |
367 return new LineRange(range.x, range.y - range.x + 1); | |
368 } | |
369 return null; | |
370 } | |
371 | |
372 /* | |
373 * @see dwtx.jface.text.source.IAnnotationHoverExtension#canHandleMouseCursor() | |
374 */ | |
375 public bool canHandleMouseCursor() { | |
376 return false; | |
377 } | |
378 | |
379 /* | |
380 * @see dwtx.jface.text.source.IAnnotationHoverExtension#getHoverControlCreator() | |
381 */ | |
382 public IInformationControlCreator getHoverControlCreator() { | |
383 return null; | |
384 } | |
385 | |
386 /* | |
387 * @see dwtx.jface.text.information.IInformationProviderExtension2#getInformationPresenterControlCreator() | |
388 * @since 3.2 | |
389 */ | |
390 public IInformationControlCreator getInformationPresenterControlCreator() { | |
135 | 391 return new class() IInformationControlCreator { |
129 | 392 public IInformationControl createInformationControl(Shell parent) { |
134 | 393 return new DefaultInformationControl(parent, cast(ToolBarManager)null, null); |
129 | 394 } |
395 }; | |
396 } | |
397 } |