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.AnnotationBarHoverManager;
|
|
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.LineChangeHover; // packageimport
|
|
22 import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
|
|
23 import dwtx.jface.text.source.IAnnotationMap; // packageimport
|
|
24 import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
|
|
25 import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
|
|
26 import dwtx.jface.text.source.IAnnotationHover; // packageimport
|
|
27 import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
|
|
28 import dwtx.jface.text.source.IAnnotationAccess; // packageimport
|
|
29 import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
|
|
30 import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
|
|
31 import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
|
|
32 import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
|
|
33 import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
|
|
34 import dwtx.jface.text.source.ILineDifferExtension; // packageimport
|
|
35 import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
|
|
36 import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
|
|
37 import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
|
|
38 import dwtx.jface.text.source.ISourceViewer; // packageimport
|
|
39 import dwtx.jface.text.source.AnnotationModel; // packageimport
|
|
40 import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
|
|
41 import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
|
|
42 import dwtx.jface.text.source.IVerticalRuler; // packageimport
|
|
43 import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
|
|
44 import dwtx.jface.text.source.SourceViewer; // packageimport
|
|
45 import dwtx.jface.text.source.SourceViewerConfiguration; // 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
|
|
80 import java.util.Iterator;
|
|
81
|
|
82 import dwt.DWT;
|
|
83 import dwt.custom.StyledText;
|
|
84 import dwt.events.ControlEvent;
|
|
85 import dwt.events.ControlListener;
|
|
86 import dwt.events.DisposeEvent;
|
|
87 import dwt.events.DisposeListener;
|
|
88 import dwt.events.KeyEvent;
|
|
89 import dwt.events.KeyListener;
|
|
90 import dwt.events.MouseEvent;
|
|
91 import dwt.events.MouseListener;
|
|
92 import dwt.events.MouseMoveListener;
|
|
93 import dwt.events.MouseTrackAdapter;
|
|
94 import dwt.events.ShellEvent;
|
|
95 import dwt.events.ShellListener;
|
|
96 import dwt.graphics.Point;
|
|
97 import dwt.graphics.Rectangle;
|
|
98 import dwt.widgets.Control;
|
|
99 import dwt.widgets.Display;
|
|
100 import dwt.widgets.Event;
|
|
101 import dwt.widgets.Listener;
|
|
102 import dwtx.core.runtime.Assert;
|
|
103 import dwtx.jface.internal.text.InformationControlReplacer;
|
|
104 import dwtx.jface.internal.text.InternalAccessor;
|
|
105 import dwtx.jface.text.AbstractHoverInformationControlManager;
|
|
106 import dwtx.jface.text.AbstractInformationControlManager;
|
|
107 import dwtx.jface.text.BadLocationException;
|
|
108 import dwtx.jface.text.IDocument;
|
|
109 import dwtx.jface.text.IInformationControl;
|
|
110 import dwtx.jface.text.IInformationControlCreator;
|
|
111 import dwtx.jface.text.IRegion;
|
|
112 import dwtx.jface.text.ITextViewerExtension5;
|
|
113 import dwtx.jface.text.JFaceTextUtil;
|
|
114 import dwtx.jface.text.Region;
|
|
115 import dwtx.jface.text.TextUtilities;
|
|
116 import dwtx.jface.text.ITextViewerExtension8.EnrichMode;
|
|
117
|
|
118
|
|
119 /**
|
|
120 * This manager controls the layout, content, and visibility of an information
|
|
121 * control in reaction to mouse hover events issued by the vertical ruler of a
|
|
122 * source viewer.
|
|
123 * @since 2.0
|
|
124 */
|
|
125 public class AnnotationBarHoverManager : AbstractHoverInformationControlManager {
|
|
126
|
|
127 /**
|
|
128 * The information control closer for the hover information. Closes the information control as soon as the mouse pointer leaves the subject area, a mouse button is pressed, the user presses a key, or the subject control is resized or moved.
|
|
129 *
|
|
130 * @since 3.0
|
|
131 * @deprecated As of 3.4, no longer used as closer from super class is used
|
|
132 */
|
|
133 protected class Closer : MouseTrackAdapter , IInformationControlCloser, MouseListener, MouseMoveListener, ControlListener, KeyListener, DisposeListener, ShellListener, Listener {
|
|
134
|
|
135 /** The closer's subject control */
|
|
136 private Control fSubjectControl;
|
|
137 /** The subject area */
|
|
138 private Rectangle fSubjectArea;
|
|
139 /** Indicates whether this closer is active */
|
|
140 private bool fIsActive= false;
|
|
141 /** The information control. */
|
|
142 private IInformationControl fInformationControlToClose;
|
|
143 /**
|
|
144 * <code>true</code> if a wheel handler is installed.
|
|
145 * @since 3.2
|
|
146 */
|
|
147 private bool fHasWheelFilter= false;
|
|
148 /**
|
|
149 * The cached display.
|
|
150 * @since 3.2
|
|
151 */
|
|
152 private Display fDisplay;
|
|
153
|
|
154
|
|
155 /**
|
|
156 * Creates a new information control closer.
|
|
157 */
|
|
158 public Closer() {
|
|
159 }
|
|
160
|
|
161 /*
|
|
162 * @see IInformationControlCloser#setSubjectControl(Control)
|
|
163 */
|
|
164 public void setSubjectControl(Control control) {
|
|
165 fSubjectControl= control;
|
|
166 }
|
|
167
|
|
168 /*
|
|
169 * @see IInformationControlCloser#setHoverControl(IHoverControl)
|
|
170 */
|
|
171 public void setInformationControl(IInformationControl control) {
|
|
172 fInformationControlToClose= control;
|
|
173 }
|
|
174
|
|
175 /*
|
|
176 * @see IInformationControlCloser#start(Rectangle)
|
|
177 */
|
|
178 public void start(Rectangle subjectArea) {
|
|
179
|
|
180 if (fIsActive) return;
|
|
181 fIsActive= true;
|
|
182
|
|
183 fSubjectArea= subjectArea;
|
|
184
|
|
185 fInformationControlToClose.addDisposeListener(this);
|
|
186 if (fSubjectControl !is null && !fSubjectControl.isDisposed()) {
|
|
187 fSubjectControl.addMouseListener(this);
|
|
188 fSubjectControl.addMouseMoveListener(this);
|
|
189 fSubjectControl.addMouseTrackListener(this);
|
|
190 fSubjectControl.getShell().addShellListener(this);
|
|
191 fSubjectControl.addControlListener(this);
|
|
192 fSubjectControl.addKeyListener(this);
|
|
193
|
|
194 fDisplay= fSubjectControl.getDisplay();
|
|
195 if (!fDisplay.isDisposed() && fHideOnMouseWheel) {
|
|
196 fHasWheelFilter= true;
|
|
197 fDisplay.addFilter(DWT.MouseWheel, this);
|
|
198 }
|
|
199 }
|
|
200 }
|
|
201
|
|
202 /*
|
|
203 * @see IInformationControlCloser#stop()
|
|
204 */
|
|
205 public void stop() {
|
|
206
|
|
207 if (!fIsActive)
|
|
208 return;
|
|
209 fIsActive= false;
|
|
210
|
|
211 if (fSubjectControl !is null && !fSubjectControl.isDisposed()) {
|
|
212 fSubjectControl.removeMouseListener(this);
|
|
213 fSubjectControl.removeMouseMoveListener(this);
|
|
214 fSubjectControl.removeMouseTrackListener(this);
|
|
215 fSubjectControl.getShell().removeShellListener(this);
|
|
216 fSubjectControl.removeControlListener(this);
|
|
217 fSubjectControl.removeKeyListener(this);
|
|
218 }
|
|
219
|
|
220 if (fDisplay !is null && !fDisplay.isDisposed() && fHasWheelFilter)
|
|
221 fDisplay.removeFilter(DWT.MouseWheel, this);
|
|
222 fHasWheelFilter= false;
|
|
223
|
|
224 fDisplay= null;
|
|
225
|
|
226 }
|
|
227
|
|
228 /**
|
|
229 * Stops the information control and if <code>delayRestart</code> is set allows restart only after a certain delay.
|
|
230 *
|
|
231 * @param delayRestart <code>true</code> if restart should be delayed
|
|
232 * @deprecated As of 3.4, replaced by {@link #stop()}. Note that <code>delayRestart</code> was never honored.
|
|
233 */
|
|
234 protected void stop(bool delayRestart) {
|
|
235 stop();
|
|
236 }
|
|
237
|
|
238 /*
|
|
239 * @see dwt.events.MouseMoveListener#mouseMove(dwt.events.MouseEvent)
|
|
240 */
|
|
241 public void mouseMove(MouseEvent event) {
|
|
242 if (!fSubjectArea.contains(event.x, event.y))
|
|
243 hideInformationControl();
|
|
244 }
|
|
245
|
|
246 /*
|
|
247 * @see dwt.events.MouseListener#mouseUp(dwt.events.MouseEvent)
|
|
248 */
|
|
249 public void mouseUp(MouseEvent event) {
|
|
250 }
|
|
251
|
|
252 /*
|
|
253 * @see MouseListener#mouseDown(MouseEvent)
|
|
254 */
|
|
255 public void mouseDown(MouseEvent event) {
|
|
256 hideInformationControl();
|
|
257 }
|
|
258
|
|
259 /*
|
|
260 * @see MouseListener#mouseDoubleClick(MouseEvent)
|
|
261 */
|
|
262 public void mouseDoubleClick(MouseEvent event) {
|
|
263 hideInformationControl();
|
|
264 }
|
|
265
|
|
266 /*
|
|
267 * @see dwt.widgets.Listener#handleEvent(dwt.widgets.Event)
|
|
268 * @since 3.2
|
|
269 */
|
|
270 public void handleEvent(Event event) {
|
|
271 if (event.type is DWT.MouseWheel)
|
|
272 hideInformationControl();
|
|
273 }
|
|
274
|
|
275 /*
|
|
276 * @see MouseTrackAdapter#mouseExit(MouseEvent)
|
|
277 */
|
|
278 public void mouseExit(MouseEvent event) {
|
|
279 if (!fAllowMouseExit)
|
|
280 hideInformationControl();
|
|
281 }
|
|
282
|
|
283 /*
|
|
284 * @see ControlListener#controlResized(ControlEvent)
|
|
285 */
|
|
286 public void controlResized(ControlEvent event) {
|
|
287 hideInformationControl();
|
|
288 }
|
|
289
|
|
290 /*
|
|
291 * @see ControlListener#controlMoved(ControlEvent)
|
|
292 */
|
|
293 public void controlMoved(ControlEvent event) {
|
|
294 hideInformationControl();
|
|
295 }
|
|
296
|
|
297 /*
|
|
298 * @see KeyListener#keyReleased(KeyEvent)
|
|
299 */
|
|
300 public void keyReleased(KeyEvent event) {
|
|
301 }
|
|
302
|
|
303 /*
|
|
304 * @see KeyListener#keyPressed(KeyEvent)
|
|
305 */
|
|
306 public void keyPressed(KeyEvent event) {
|
|
307 hideInformationControl();
|
|
308 }
|
|
309
|
|
310 /*
|
|
311 * @see dwt.events.ShellListener#shellActivated(dwt.events.ShellEvent)
|
|
312 * @since 3.1
|
|
313 */
|
|
314 public void shellActivated(ShellEvent e) {
|
|
315 }
|
|
316
|
|
317 /*
|
|
318 * @see dwt.events.ShellListener#shellClosed(dwt.events.ShellEvent)
|
|
319 * @since 3.1
|
|
320 */
|
|
321 public void shellClosed(ShellEvent e) {
|
|
322 }
|
|
323
|
|
324 /*
|
|
325 * @see dwt.events.ShellListener#shellDeactivated(dwt.events.ShellEvent)
|
|
326 * @since 3.1
|
|
327 */
|
|
328 public void shellDeactivated(ShellEvent e) {
|
|
329 hideInformationControl();
|
|
330 }
|
|
331
|
|
332 /*
|
|
333 * @see dwt.events.ShellListener#shellDeiconified(dwt.events.ShellEvent)
|
|
334 * @since 3.1
|
|
335 */
|
|
336 public void shellDeiconified(ShellEvent e) {
|
|
337 }
|
|
338
|
|
339 /*
|
|
340 * @see dwt.events.ShellListener#shellIconified(dwt.events.ShellEvent)
|
|
341 * @since 3.1
|
|
342 */
|
|
343 public void shellIconified(ShellEvent e) {
|
|
344 }
|
|
345
|
|
346 /*
|
|
347 * @see dwt.events.DisposeListener#widgetDisposed(dwt.events.DisposeEvent)
|
|
348 */
|
|
349 public void widgetDisposed(DisposeEvent e) {
|
|
350 hideInformationControl();
|
|
351 }
|
|
352 }
|
|
353
|
|
354 /** The source viewer the manager is connected to */
|
|
355 private ISourceViewer fSourceViewer;
|
|
356 /** The vertical ruler the manager is registered with */
|
|
357 private IVerticalRulerInfo fVerticalRulerInfo;
|
|
358 /** The annotation hover the manager uses to retrieve the information to display. Can be <code>null</code>. */
|
|
359 private IAnnotationHover fAnnotationHover;
|
|
360 /**
|
|
361 * Indicates whether the mouse cursor is allowed to leave the subject area without closing the hover.
|
|
362 * @since 3.0
|
|
363 */
|
|
364 protected bool fAllowMouseExit= false;
|
|
365 /**
|
|
366 * Whether we should hide the over on mouse wheel action.
|
|
367 *
|
|
368 * @since 3.2
|
|
369 */
|
|
370 private bool fHideOnMouseWheel= true;
|
|
371
|
|
372 /**
|
|
373 * The current annotation hover.
|
|
374 * @since 3.2
|
|
375 */
|
|
376 private IAnnotationHover fCurrentHover;
|
|
377
|
|
378 /**
|
|
379 * Creates an annotation hover manager with the given parameters. In addition,
|
|
380 * the hovers anchor is RIGHT and the margin is 5 points to the right.
|
|
381 *
|
|
382 * @param sourceViewer the source viewer this manager connects to
|
|
383 * @param ruler the vertical ruler this manager connects to
|
|
384 * @param annotationHover the annotation hover providing the information to be displayed
|
|
385 * @param creator the information control creator
|
|
386 * @deprecated As of 2.1, replaced by {@link AnnotationBarHoverManager#AnnotationBarHoverManager(IVerticalRulerInfo, ISourceViewer, IAnnotationHover, IInformationControlCreator)}
|
|
387 */
|
|
388 public AnnotationBarHoverManager(ISourceViewer sourceViewer, IVerticalRuler ruler, IAnnotationHover annotationHover, IInformationControlCreator creator) {
|
|
389 this(ruler, sourceViewer, annotationHover, creator);
|
|
390 }
|
|
391
|
|
392 /**
|
|
393 * Creates an annotation hover manager with the given parameters. In addition,
|
|
394 * the hovers anchor is RIGHT and the margin is 5 points to the right.
|
|
395 *
|
|
396 * @param rulerInfo the vertical ruler this manager connects to
|
|
397 * @param sourceViewer the source viewer this manager connects to
|
|
398 * @param annotationHover the annotation hover providing the information to be displayed or <code>null</code> if none
|
|
399 * @param creator the information control creator
|
|
400 * @since 2.1
|
|
401 */
|
|
402 public AnnotationBarHoverManager(IVerticalRulerInfo rulerInfo, ISourceViewer sourceViewer, IAnnotationHover annotationHover, IInformationControlCreator creator) {
|
|
403 super(creator);
|
|
404
|
|
405 Assert.isNotNull(sourceViewer);
|
|
406
|
|
407 fSourceViewer= sourceViewer;
|
|
408 fVerticalRulerInfo= rulerInfo;
|
|
409 fAnnotationHover= annotationHover;
|
|
410
|
|
411 setAnchor(ANCHOR_RIGHT);
|
|
412 setMargins(5, 0);
|
|
413 // use closer from super class
|
|
414 }
|
|
415
|
|
416 /*
|
|
417 * @see dwtx.jface.text.AbstractInformationControlManager#computeInformation()
|
|
418 */
|
|
419 protected void computeInformation() {
|
|
420 fAllowMouseExit= false;
|
|
421 MouseEvent event= getHoverEvent();
|
|
422 IAnnotationHover hover= getHover(event);
|
|
423 if (hover is null) {
|
|
424 setInformation(null, null);
|
|
425 return;
|
|
426 }
|
|
427
|
|
428 int line= getHoverLine(event);
|
|
429
|
|
430 if (hover instanceof IAnnotationHoverExtension) {
|
|
431 IAnnotationHoverExtension extension= (IAnnotationHoverExtension) hover;
|
|
432 ILineRange range= extension.getHoverLineRange(fSourceViewer, line);
|
|
433 setCustomInformationControlCreator(extension.getHoverControlCreator());
|
|
434 range= adaptLineRange(range, line);
|
|
435 if (range !is null)
|
|
436 setInformation(extension.getHoverInfo(fSourceViewer, range, computeNumberOfVisibleLines()), computeArea(range));
|
|
437 else
|
|
438 setInformation(null, null);
|
|
439
|
|
440 } else {
|
|
441 setCustomInformationControlCreator(null);
|
|
442 setInformation(hover.getHoverInfo(fSourceViewer, line), computeArea(line));
|
|
443 }
|
|
444
|
|
445 }
|
|
446
|
|
447 /*
|
|
448 * @see dwtx.jface.text.AbstractInformationControlManager#showInformationControl(dwt.graphics.Rectangle)
|
|
449 * @since 3.2
|
|
450 */
|
|
451 protected void showInformationControl(Rectangle subjectArea) {
|
|
452 super.showInformationControl(subjectArea);
|
|
453 fCurrentHover= getHover(getHoverEvent());
|
|
454 }
|
|
455
|
|
456 /*
|
|
457 * @see dwtx.jface.text.AbstractInformationControlManager#hideInformationControl()
|
|
458 * @since 3.2
|
|
459 */
|
|
460 protected void hideInformationControl() {
|
|
461 fCurrentHover= null;
|
|
462 super.hideInformationControl();
|
|
463 }
|
|
464
|
|
465 /**
|
|
466 * Adapts a given line range so that the result is a line range that does
|
|
467 * not overlap with any collapsed region and fits into the view port of the
|
|
468 * attached viewer.
|
|
469 *
|
|
470 * @param lineRange the original line range
|
|
471 * @param line the anchor line
|
|
472 * @return the adapted line range
|
|
473 * @since 3.0
|
|
474 */
|
|
475 private ILineRange adaptLineRange(ILineRange lineRange, int line) {
|
|
476 if (lineRange !is null) {
|
|
477 lineRange= adaptLineRangeToFolding(lineRange, line);
|
|
478 if (lineRange !is null)
|
|
479 return adaptLineRangeToViewport(lineRange);
|
|
480 }
|
|
481 return null;
|
|
482 }
|
|
483
|
|
484 /**
|
|
485 * Adapts a given line range so that the result is a line range that does
|
|
486 * not overlap with any collapsed region of the attached viewer.
|
|
487 *
|
|
488 * @param lineRange the original line range
|
|
489 * @param line the anchor line
|
|
490 * @return the adapted line range
|
|
491 * @since 3.0
|
|
492 */
|
|
493 private ILineRange adaptLineRangeToFolding(ILineRange lineRange, int line) {
|
|
494
|
|
495 if (fSourceViewer instanceof ITextViewerExtension5) {
|
|
496 ITextViewerExtension5 extension= (ITextViewerExtension5) fSourceViewer;
|
|
497
|
|
498 try {
|
|
499 IRegion region= convertToRegion(lineRange);
|
|
500 IRegion[] coverage= extension.getCoveredModelRanges(region);
|
|
501 if (coverage !is null && coverage.length > 0) {
|
|
502 IRegion container= findRegionContainingLine(coverage, line);
|
|
503 if (container !is null)
|
|
504 return convertToLineRange(container);
|
|
505 }
|
|
506
|
|
507 } catch (BadLocationException x) {
|
|
508 }
|
|
509
|
|
510 return null;
|
|
511 }
|
|
512
|
|
513 return lineRange;
|
|
514 }
|
|
515
|
|
516 /**
|
|
517 * Adapts a given line range so that the result is a line range that fits
|
|
518 * into the view port of the attached viewer.
|
|
519 *
|
|
520 * @param lineRange the original line range
|
|
521 * @return the adapted line range
|
|
522 * @since 3.0
|
|
523 */
|
|
524 private ILineRange adaptLineRangeToViewport(ILineRange lineRange) {
|
|
525
|
|
526 try {
|
|
527 StyledText text= fSourceViewer.getTextWidget();
|
|
528
|
|
529 int topLine= text.getTopIndex();
|
|
530 int rangeTopLine= getWidgetLineNumber(lineRange.getStartLine());
|
|
531 int topDelta= Math.max(topLine - rangeTopLine, 0);
|
|
532
|
|
533 Rectangle size= text.getClientArea();
|
|
534 Rectangle trim= text.computeTrim(0, 0, 0, 0);
|
|
535 int height= size.height - trim.height;
|
|
536
|
|
537 int lines= JFaceTextUtil.getLineIndex(text, height) - text.getTopIndex();
|
|
538
|
|
539 int bottomLine= topLine + lines;
|
|
540
|
|
541 int rangeBottomLine= getWidgetLineNumber(lineRange.getStartLine() + lineRange.getNumberOfLines() - 1);
|
|
542 int bottomDelta= Math.max(rangeBottomLine - bottomLine, 0);
|
|
543
|
|
544 return new LineRange(lineRange.getStartLine() + topDelta, lineRange.getNumberOfLines() - bottomDelta - topDelta);
|
|
545
|
|
546 } catch (BadLocationException ex) {
|
|
547 }
|
|
548
|
|
549 return null;
|
|
550 }
|
|
551
|
|
552 /**
|
|
553 * Converts a line range into a character range.
|
|
554 *
|
|
555 * @param lineRange the line range
|
|
556 * @return the corresponding character range
|
|
557 * @throws BadLocationException in case the given line range is invalid
|
|
558 */
|
|
559 private IRegion convertToRegion(ILineRange lineRange) throws BadLocationException {
|
|
560 IDocument document= fSourceViewer.getDocument();
|
|
561 int startOffset= document.getLineOffset(lineRange.getStartLine());
|
|
562 int endLine= lineRange.getStartLine() + Math.max(0, lineRange.getNumberOfLines() - 1);
|
|
563 IRegion lineInfo= document.getLineInformation(endLine);
|
|
564 int endOffset= lineInfo.getOffset() + lineInfo.getLength();
|
|
565 return new Region(startOffset, endOffset - startOffset);
|
|
566 }
|
|
567
|
|
568 /**
|
|
569 * Returns the region out of the given set that contains the given line or
|
|
570 * <code>null</code>.
|
|
571 *
|
|
572 * @param regions the set of regions
|
|
573 * @param line the line
|
|
574 * @return the region of the set that contains the line
|
|
575 * @throws BadLocationException in case line is invalid
|
|
576 */
|
|
577 private IRegion findRegionContainingLine(IRegion[] regions, int line) throws BadLocationException {
|
|
578 IDocument document= fSourceViewer.getDocument();
|
|
579 IRegion lineInfo= document.getLineInformation(line);
|
|
580 for (int i= 0; i < regions.length; i++) {
|
|
581 if (TextUtilities.overlaps(regions[i], lineInfo))
|
|
582 return regions[i];
|
|
583 }
|
|
584 return null;
|
|
585 }
|
|
586
|
|
587 /**
|
|
588 * Converts a given character region into a line range.
|
|
589 *
|
|
590 * @param region the character region
|
|
591 * @return the corresponding line range
|
|
592 * @throws BadLocationException in case the given region in invalid
|
|
593 */
|
|
594 private ILineRange convertToLineRange(IRegion region) throws BadLocationException {
|
|
595 IDocument document= fSourceViewer.getDocument();
|
|
596 int startLine= document.getLineOfOffset(region.getOffset());
|
|
597 int endLine= document.getLineOfOffset(region.getOffset() + region.getLength());
|
|
598 return new LineRange(startLine, endLine - startLine + 1);
|
|
599 }
|
|
600
|
|
601 /**
|
|
602 * Returns the visible area of the vertical ruler covered by the given line
|
|
603 * range.
|
|
604 *
|
|
605 * @param lineRange the line range
|
|
606 * @return the visible area
|
|
607 */
|
|
608 private Rectangle computeArea(ILineRange lineRange) {
|
|
609 try {
|
|
610 StyledText text= fSourceViewer.getTextWidget();
|
|
611 final int startLine= getWidgetLineNumber(lineRange.getStartLine());
|
|
612 int y= JFaceTextUtil.computeLineHeight(text, 0, startLine, startLine) - text.getTopPixel();
|
|
613 int height= JFaceTextUtil.computeLineHeight(text, startLine, startLine + lineRange.getNumberOfLines(), lineRange.getNumberOfLines());
|
|
614 Point size= fVerticalRulerInfo.getControl().getSize();
|
|
615 return new Rectangle(0, y, size.x, height);
|
|
616 } catch (BadLocationException x) {
|
|
617 }
|
|
618 return null;
|
|
619 }
|
|
620
|
|
621 /**
|
|
622 * Returns the number of the currently visible lines.
|
|
623 *
|
|
624 * @return the number of the currently visible lines
|
|
625 * @deprecated to avoid deprecation warning
|
|
626 */
|
|
627 private int computeNumberOfVisibleLines() {
|
|
628 // Hack to reduce amount of copied code.
|
|
629 return LineNumberRulerColumn.getVisibleLinesInViewport(fSourceViewer.getTextWidget());
|
|
630 }
|
|
631
|
|
632 /**
|
|
633 * Determines the hover to be used to display information based on the source of the
|
|
634 * mouse hover event. If <code>fVerticalRulerInfo</code> is not a composite ruler, the
|
|
635 * standard hover is returned.
|
|
636 *
|
|
637 * @param event the source of the mouse hover event
|
|
638 * @return the hover depending on <code>source</code>, or <code>fAnnotationHover</code> if none can be found.
|
|
639 * @since 3.0
|
|
640 */
|
|
641 private IAnnotationHover getHover(MouseEvent event) {
|
|
642 if (event is null || event.getSource() is null)
|
|
643 return fAnnotationHover;
|
|
644
|
|
645 if (fVerticalRulerInfo instanceof CompositeRuler) {
|
|
646 CompositeRuler comp= (CompositeRuler) fVerticalRulerInfo;
|
|
647 for (Iterator it= comp.getDecoratorIterator(); it.hasNext();) {
|
|
648 Object o= it.next();
|
|
649 if (o instanceof IVerticalRulerInfoExtension && o instanceof IVerticalRulerInfo) {
|
|
650 if (((IVerticalRulerInfo) o).getControl() is event.getSource()) {
|
|
651 IAnnotationHover hover= ((IVerticalRulerInfoExtension) o).getHover();
|
|
652 if (hover !is null)
|
|
653 return hover;
|
|
654 }
|
|
655 }
|
|
656 }
|
|
657 }
|
|
658 return fAnnotationHover;
|
|
659 }
|
|
660
|
|
661 /**
|
|
662 * Returns the line of interest deduced from the mouse hover event.
|
|
663 *
|
|
664 * @param event a mouse hover event that triggered hovering
|
|
665 * @return the document model line number on which the hover event occurred or <code>-1</code> if there is no event
|
|
666 * @since 3.0
|
|
667 */
|
|
668 private int getHoverLine(MouseEvent event) {
|
|
669 return event is null ? -1 : fVerticalRulerInfo.toDocumentLineNumber(event.y);
|
|
670 }
|
|
671
|
|
672 /**
|
|
673 * Returns for the widget line number for the given document line number.
|
|
674 *
|
|
675 * @param line the absolute line number
|
|
676 * @return the line number relative to the viewer's visible region
|
|
677 * @throws BadLocationException if <code>line</code> is not valid in the viewer's document
|
|
678 */
|
|
679 private int getWidgetLineNumber(int line) throws BadLocationException {
|
|
680 if (fSourceViewer instanceof ITextViewerExtension5) {
|
|
681 ITextViewerExtension5 extension= (ITextViewerExtension5) fSourceViewer;
|
|
682 return extension.modelLine2WidgetLine(line);
|
|
683 }
|
|
684
|
|
685 IRegion region= fSourceViewer.getVisibleRegion();
|
|
686 int firstLine= fSourceViewer.getDocument().getLineOfOffset(region.getOffset());
|
|
687 return line - firstLine;
|
|
688 }
|
|
689
|
|
690 /**
|
|
691 * Determines graphical area covered by the given line.
|
|
692 *
|
|
693 * @param line the number of the line in the viewer whose graphical extend in the vertical ruler must be computed
|
|
694 * @return the graphical extend of the given line
|
|
695 */
|
|
696 private Rectangle computeArea(int line) {
|
|
697 try {
|
|
698 StyledText text= fSourceViewer.getTextWidget();
|
|
699 int widgetLine= getWidgetLineNumber(line);
|
|
700 int y= JFaceTextUtil.computeLineHeight(text, 0, widgetLine, widgetLine) - text.getTopPixel();
|
|
701 Point size= fVerticalRulerInfo.getControl().getSize();
|
|
702 return new Rectangle(0, y, size.x, text.getLineHeight(text.getOffsetAtLine(widgetLine)));
|
|
703 } catch (IllegalArgumentException ex) {
|
|
704 } catch (BadLocationException ex) {
|
|
705 }
|
|
706 return null;
|
|
707 }
|
|
708
|
|
709 /**
|
|
710 * Returns the annotation hover for this hover manager.
|
|
711 *
|
|
712 * @return the annotation hover for this hover manager or <code>null</code> if none
|
|
713 * @since 2.1
|
|
714 */
|
|
715 protected IAnnotationHover getAnnotationHover() {
|
|
716 return fAnnotationHover;
|
|
717 }
|
|
718
|
|
719 /**
|
|
720 * Returns the source viewer for this hover manager.
|
|
721 *
|
|
722 * @return the source viewer for this hover manager
|
|
723 * @since 2.1
|
|
724 */
|
|
725 protected ISourceViewer getSourceViewer() {
|
|
726 return fSourceViewer;
|
|
727 }
|
|
728
|
|
729 /**
|
|
730 * Returns the vertical ruler info for this hover manager
|
|
731 *
|
|
732 * @return the vertical ruler info for this hover manager
|
|
733 * @since 2.1
|
|
734 */
|
|
735 protected IVerticalRulerInfo getVerticalRulerInfo() {
|
|
736 return fVerticalRulerInfo;
|
|
737 }
|
|
738
|
|
739 /*
|
|
740 * @see dwtx.jface.text.AbstractInformationControlManager#computeSizeConstraints(dwt.widgets.Control, dwt.graphics.Rectangle, dwtx.jface.text.IInformationControl)
|
|
741 * @since 3.0
|
|
742 */
|
|
743 protected Point computeSizeConstraints(Control subjectControl, Rectangle subjectArea, IInformationControl informationControl) {
|
|
744
|
|
745 Point constraints= super.computeSizeConstraints(subjectControl, subjectArea, informationControl);
|
|
746
|
|
747 // make as big as text area, if possible
|
|
748 StyledText styledText= fSourceViewer.getTextWidget();
|
|
749 if (styledText !is null) {
|
|
750 Rectangle r= styledText.getClientArea();
|
|
751 if (r !is null) {
|
|
752 constraints.x= r.width;
|
|
753 constraints.y= r.height;
|
|
754 }
|
|
755 }
|
|
756
|
|
757 return constraints;
|
|
758 }
|
|
759
|
|
760 /*
|
|
761 * @see dwtx.jface.text.AbstractInformationControlManager#computeLocation(dwt.graphics.Rectangle, dwt.graphics.Point, dwtx.jface.text.AbstractInformationControlManager.Anchor)
|
|
762 * @since 3.0
|
|
763 */
|
|
764 protected Point computeLocation(Rectangle subjectArea, Point controlSize, Anchor anchor) {
|
|
765 MouseEvent event= getHoverEvent();
|
|
766 IAnnotationHover hover= getHover(event);
|
|
767
|
|
768 bool allowMouseExit= false;
|
|
769 if (hover instanceof IAnnotationHoverExtension) {
|
|
770 IAnnotationHoverExtension extension= (IAnnotationHoverExtension) hover;
|
|
771 allowMouseExit= extension.canHandleMouseCursor();
|
|
772 }
|
|
773 bool hideOnMouseWheel= true;
|
|
774 if (hover instanceof IAnnotationHoverExtension2) {
|
|
775 IAnnotationHoverExtension2 extension= (IAnnotationHoverExtension2) hover;
|
|
776 hideOnMouseWheel= !extension.canHandleMouseWheel();
|
|
777 }
|
|
778 fHideOnMouseWheel= hideOnMouseWheel;
|
|
779
|
|
780 if (allowMouseExit) {
|
|
781 fAllowMouseExit= true;
|
|
782
|
|
783 Control subjectControl= getSubjectControl();
|
|
784 // return a location that just overlaps the annotation on the bar
|
|
785 if (anchor is AbstractInformationControlManager.ANCHOR_RIGHT)
|
|
786 return subjectControl.toDisplay(subjectArea.x - 4, subjectArea.y - 2);
|
|
787 else if (anchor is AbstractInformationControlManager.ANCHOR_LEFT)
|
|
788 return subjectControl.toDisplay(subjectArea.x + subjectArea.width - controlSize.x + 4, subjectArea.y - 2);
|
|
789 }
|
|
790
|
|
791 fAllowMouseExit= false;
|
|
792 return super.computeLocation(subjectArea, controlSize, anchor);
|
|
793 }
|
|
794
|
|
795 /**
|
|
796 * Returns the currently shown annotation hover or <code>null</code> if none
|
|
797 * hover is shown.
|
|
798 *
|
|
799 * @return the currently shown annotation hover or <code>null</code>
|
|
800 * @since 3.2
|
|
801 */
|
|
802 public IAnnotationHover getCurrentAnnotationHover() {
|
|
803 return fCurrentHover;
|
|
804 }
|
|
805
|
|
806 /**
|
|
807 * Returns an adapter that gives access to internal methods.
|
|
808 * <p>
|
|
809 * <strong>Note:</strong> This method is not intended to be referenced or overridden by clients.
|
|
810 * </p>
|
|
811 *
|
|
812 * @return the replaceable information control accessor
|
|
813 * @since 3.4
|
|
814 * @noreference This method is not intended to be referenced by clients.
|
|
815 * @nooverride This method is not intended to be re-implemented or extended by clients.
|
|
816 */
|
|
817 public InternalAccessor getInternalAccessor() {
|
|
818 return new InternalAccessor() {
|
|
819 public IInformationControl getCurrentInformationControl() {
|
|
820 return AnnotationBarHoverManager.super.getInternalAccessor().getCurrentInformationControl();
|
|
821 }
|
|
822
|
|
823 public void setInformationControlReplacer(InformationControlReplacer replacer) {
|
|
824 AnnotationBarHoverManager.super.getInternalAccessor().setInformationControlReplacer(replacer);
|
|
825 }
|
|
826
|
|
827 public InformationControlReplacer getInformationControlReplacer() {
|
|
828 return AnnotationBarHoverManager.super.getInternalAccessor().getInformationControlReplacer();
|
|
829 }
|
|
830
|
|
831 public bool canReplace(IInformationControl control) {
|
|
832 return AnnotationBarHoverManager.super.getInternalAccessor().canReplace(control);
|
|
833 }
|
|
834
|
|
835 public bool isReplaceInProgress() {
|
|
836 return AnnotationBarHoverManager.super.getInternalAccessor().isReplaceInProgress();
|
|
837 }
|
|
838
|
|
839 public void replaceInformationControl(bool takeFocus) {
|
|
840 AnnotationBarHoverManager.super.getInternalAccessor().replaceInformationControl(takeFocus);
|
|
841 }
|
|
842
|
|
843 public void cropToClosestMonitor(Rectangle bounds) {
|
|
844 AnnotationBarHoverManager.super.getInternalAccessor().cropToClosestMonitor(bounds);
|
|
845 }
|
|
846
|
|
847 public void setHoverEnrichMode(EnrichMode mode) {
|
|
848 AnnotationBarHoverManager.super.getInternalAccessor().setHoverEnrichMode(mode);
|
|
849 }
|
|
850
|
|
851 public bool getAllowMouseExit() {
|
|
852 return fAllowMouseExit;
|
|
853 }
|
|
854 };
|
|
855 }
|
|
856 }
|
|
857
|