KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > text > java > hover > AnnotationExpansionControl


1 /*******************************************************************************
2  * Copyright (c) 2000, 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  *******************************************************************************/

11 package org.eclipse.jdt.internal.ui.text.java.hover;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Iterator JavaDoc;
15 import java.util.List JavaDoc;
16
17 import org.eclipse.swt.SWT;
18 import org.eclipse.swt.custom.StyleRange;
19 import org.eclipse.swt.custom.StyledText;
20 import org.eclipse.swt.events.DisposeEvent;
21 import org.eclipse.swt.events.DisposeListener;
22 import org.eclipse.swt.events.FocusListener;
23 import org.eclipse.swt.events.MenuEvent;
24 import org.eclipse.swt.events.MenuListener;
25 import org.eclipse.swt.events.MouseAdapter;
26 import org.eclipse.swt.events.MouseEvent;
27 import org.eclipse.swt.events.MouseTrackAdapter;
28 import org.eclipse.swt.events.MouseTrackListener;
29 import org.eclipse.swt.events.PaintEvent;
30 import org.eclipse.swt.events.PaintListener;
31 import org.eclipse.swt.graphics.Color;
32 import org.eclipse.swt.graphics.Cursor;
33 import org.eclipse.swt.graphics.Point;
34 import org.eclipse.swt.graphics.Rectangle;
35 import org.eclipse.swt.layout.GridData;
36 import org.eclipse.swt.layout.GridLayout;
37 import org.eclipse.swt.widgets.Canvas;
38 import org.eclipse.swt.widgets.Composite;
39 import org.eclipse.swt.widgets.Control;
40 import org.eclipse.swt.widgets.Display;
41 import org.eclipse.swt.widgets.Event;
42 import org.eclipse.swt.widgets.Layout;
43 import org.eclipse.swt.widgets.Listener;
44 import org.eclipse.swt.widgets.Menu;
45 import org.eclipse.swt.widgets.Shell;
46 import org.eclipse.swt.widgets.Widget;
47
48 import org.eclipse.jface.viewers.IDoubleClickListener;
49
50 import org.eclipse.jface.text.AbstractInformationControlManager;
51 import org.eclipse.jface.text.DefaultInformationControl;
52 import org.eclipse.jface.text.IInformationControl;
53 import org.eclipse.jface.text.IInformationControlCreator;
54 import org.eclipse.jface.text.IInformationControlExtension;
55 import org.eclipse.jface.text.IInformationControlExtension2;
56 import org.eclipse.jface.text.IRegion;
57 import org.eclipse.jface.text.IViewportListener;
58 import org.eclipse.jface.text.Position;
59 import org.eclipse.jface.text.Region;
60 import org.eclipse.jface.text.TextViewer;
61 import org.eclipse.jface.text.source.Annotation;
62 import org.eclipse.jface.text.source.IAnnotationAccess;
63 import org.eclipse.jface.text.source.IAnnotationAccessExtension;
64 import org.eclipse.jface.text.source.IAnnotationModel;
65 import org.eclipse.jface.text.source.ISourceViewer;
66 import org.eclipse.jface.text.source.IVerticalRulerInfo;
67 import org.eclipse.jface.text.source.IVerticalRulerListener;
68 import org.eclipse.jface.text.source.VerticalRulerEvent;
69
70
71 /**
72  * A control that can display a number of annotations. The control can decide how it layouts the
73  * annotations to present them to the user.
74  * <p>
75  * This class got moved here form Platform Text since it was not used there
76  * and caused discouraged access warnings. It will be moved down again once
77  * annotation roll-over support is provided by Platform Text.
78  * </p>
79  * <p>Each annotation can have its custom context menu and hover.</p>
80  *
81  * @since 3.2
82  */

83 public class AnnotationExpansionControl implements IInformationControl, IInformationControlExtension, IInformationControlExtension2 {
84
85
86     public interface ICallback {
87         void run(IInformationControlExtension2 control);
88     }
89
90     /**
91      * Input used by the control to display the annotations.
92      * TODO move to top-level class
93      * TODO encapsulate fields
94      *
95      * @since 3.0
96      */

97     public static class AnnotationHoverInput {
98         public Annotation[] fAnnotations;
99         public ISourceViewer fViewer;
100         public IVerticalRulerInfo fRulerInfo;
101         public IVerticalRulerListener fAnnotationListener;
102         public IDoubleClickListener fDoubleClickListener;
103         public ICallback redoAction;
104         public IAnnotationModel model;
105     }
106
107     private final class Item {
108         Annotation fAnnotation;
109         Canvas canvas;
110         StyleRange[] oldStyles;
111
112         public void selected() {
113             Display disp= fShell.getDisplay();
114             canvas.setCursor(fHandCursor);
115             // TODO: shade - for now: set grey background
116
canvas.setBackground(getSelectionColor(disp));
117
118             // highlight the viewer background at its position
119
oldStyles= setViewerBackground(fAnnotation);
120
121             // set the selection
122
fSelection= this;
123
124             if (fHoverManager != null)
125                 fHoverManager.showInformation();
126
127             if (fInput.fAnnotationListener != null) {
128                 VerticalRulerEvent event= new VerticalRulerEvent(fAnnotation);
129                 fInput.fAnnotationListener.annotationSelected(event);
130             }
131
132         }
133
134         public void defaultSelected() {
135             if (fInput.fAnnotationListener != null) {
136                 VerticalRulerEvent event= new VerticalRulerEvent(fAnnotation);
137                 fInput.fAnnotationListener.annotationDefaultSelected(event);
138             }
139
140             dispose();
141         }
142
143         public void showContextMenu(Menu menu) {
144             if (fInput.fAnnotationListener != null) {
145                 VerticalRulerEvent event= new VerticalRulerEvent(fAnnotation);
146                 fInput.fAnnotationListener.annotationContextMenuAboutToShow(event, menu);
147             }
148         }
149
150         public void deselect() {
151             // hide the popup
152
// fHoverManager.disposeInformationControl();
153

154             // deselect
155
fSelection= null;
156
157             resetViewerBackground(oldStyles);
158             oldStyles= null;
159
160             Display disp= fShell.getDisplay();
161             canvas.setCursor(null);
162             // TODO: remove shading - for now: set standard background
163
canvas.setBackground(disp.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
164
165         }
166
167     }
168
169     /**
170      * Disposes of an item
171      */

172     private final static class MyDisposeListener implements DisposeListener {
173         /*
174          * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent)
175          */

176         public void widgetDisposed(DisposeEvent e) {
177             Item item= (Item) ((Widget) e.getSource()).getData();
178             item.deselect();
179             item.canvas= null;
180             item.fAnnotation= null;
181             item.oldStyles= null;
182
183             ((Widget) e.getSource()).setData(null);
184         }
185     }
186
187     /**
188      * Listener on context menu invocation on the items
189      */

190     private final class MyMenuDetectListener implements Listener {
191         /*
192          * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
193          */

194         public void handleEvent(Event event) {
195             if (event.type == SWT.MenuDetect) {
196                 // TODO: show per-item menu
197
// for now: show ruler context menu
198
if (fInput != null) {
199                     Control ruler= fInput.fRulerInfo.getControl();
200                     if (ruler != null && !ruler.isDisposed()) {
201                         Menu menu= ruler.getMenu();
202                         if (menu != null && !menu.isDisposed()) {
203                             menu.setLocation(event.x, event.y);
204                             menu.addMenuListener(new MenuListener() {
205
206                                 public void menuHidden(MenuEvent e) {
207                                     dispose();
208                                 }
209
210                                 public void menuShown(MenuEvent e) {
211                                 }
212
213                             });
214                             menu.setVisible(true);
215                         }
216                     }
217                 }
218             }
219         }
220     }
221
222     
223     /**
224      * Listener on mouse events on the items.
225      */

226     private final class MyMouseListener extends MouseAdapter {
227         /*
228          * @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
229          */

230         public void mouseDoubleClick(MouseEvent e) {
231             Item item= (Item) ((Widget) e.getSource()).getData();
232             if (e.button == 1 && item.fAnnotation == fInput.fAnnotations[0] && fInput.fDoubleClickListener != null) {
233                 fInput.fDoubleClickListener.doubleClick(null);
234                 // special code for JDT to renew the annotation set.
235
if (fInput.redoAction != null)
236                     fInput.redoAction.run(AnnotationExpansionControl.this);
237             }
238 // dispose();
239
// TODO special action to invoke double-click action on the vertical ruler
240
// how about
241
// Canvas can= (Canvas) e.getSource();
242
// Annotation a= (Annotation) can.getData();
243
// if (a != null) {
244
// a.getDoubleClickAction().run();
245
// }
246
}
247
248         /*
249          * Using mouseDown as mouseUp isn't fired on some Platforms, for
250          * details see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=165533
251          *
252          * @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent)
253          */

254         public void mouseDown(MouseEvent e) {
255             Item item= (Item) ((Widget) e.getSource()).getData();
256             // TODO for now, to make double click work: disable single click on the first item
257
// disable later when the annotationlistener selectively handles input
258
if (item != null && e.button == 1) // && item.fAnnotation != fInput.fAnnotations[0])
259
item.defaultSelected();
260         }
261
262     }
263
264     /**
265      * Listener on mouse track events on the items.
266      */

267     private final class MyMouseTrackListener implements MouseTrackListener {
268         /*
269          * @see org.eclipse.swt.events.MouseTrackListener#mouseEnter(org.eclipse.swt.events.MouseEvent)
270          */

271         public void mouseEnter(MouseEvent e) {
272             Item item= (Item) ((Widget) e.getSource()).getData();
273             if (item != null)
274                 item.selected();
275         }
276
277         /*
278          * @see org.eclipse.swt.events.MouseTrackListener#mouseExit(org.eclipse.swt.events.MouseEvent)
279          */

280         public void mouseExit(MouseEvent e) {
281
282             Item item= (Item) ((Widget) e.getSource()).getData();
283             if (item != null)
284                 item.deselect();
285
286             // if the event lies outside the entire popup, dispose
287
org.eclipse.swt.graphics.Region region= fShell.getRegion();
288             Canvas can= (Canvas) e.getSource();
289             Point p= can.toDisplay(e.x, e.y);
290             if (region == null) {
291                 Rectangle bounds= fShell.getBounds();
292 // p= fShell.toControl(p);
293
if (!bounds.contains(p))
294                     dispose();
295             } else {
296                 p= fShell.toControl(p);
297                 if (!region.contains(p))
298                     dispose();
299             }
300
301
302         }
303
304         /*
305          * @see org.eclipse.swt.events.MouseTrackListener#mouseHover(org.eclipse.swt.events.MouseEvent)
306          */

307         public void mouseHover(MouseEvent e) {
308             if (fHoverManager == null) {
309                 fHoverManager= new HoverManager();
310                 fHoverManager.takesFocusWhenVisible(false);
311                 fHoverManager.install(fComposite);
312                 fHoverManager.showInformation();
313             }
314         }
315     }
316
317     
318     /**
319      *
320      *
321      * @since 3.0
322      */

323     public class LinearLayouter {
324
325         private static final int ANNOTATION_SIZE= 14;
326         private static final int BORDER_WIDTH= 2;
327
328         public Layout getLayout(int itemCount) {
329             // simple layout: a row of items
330
GridLayout layout= new GridLayout(itemCount, true);
331             layout.horizontalSpacing= 1;
332             layout.verticalSpacing= 0;
333             layout.marginHeight= 1;
334             layout.marginWidth= 1;
335             return layout;
336         }
337
338         public Object JavaDoc getLayoutData() {
339             GridData gridData= new GridData(ANNOTATION_SIZE + 2 * BORDER_WIDTH, ANNOTATION_SIZE + 2 * BORDER_WIDTH);
340             gridData.horizontalAlignment= GridData.CENTER;
341             gridData.verticalAlignment= GridData.CENTER;
342             return gridData;
343         }
344
345         public int getAnnotationSize() {
346             return ANNOTATION_SIZE;
347         }
348
349         public int getBorderWidth() {
350             return BORDER_WIDTH;
351         }
352
353         public org.eclipse.swt.graphics.Region getShellRegion(int itemCount) {
354             // no special region - set to null for default shell size
355
return null;
356         }
357
358     }
359     
360     
361     /**
362      * Listener on paint events on the items. Paints the annotation image on the given <code>GC</code>.
363      */

364     private final class MyPaintListener implements PaintListener {
365         /*
366          * @see org.eclipse.swt.events.PaintListener#paintControl(org.eclipse.swt.events.PaintEvent)
367          */

368         public void paintControl(PaintEvent e) {
369             Canvas can= (Canvas) e.getSource();
370             Annotation a= ((Item) can.getData()).fAnnotation;
371             if (a != null) {
372                 Rectangle rect= new Rectangle(fLayouter.getBorderWidth(), fLayouter.getBorderWidth(), fLayouter.getAnnotationSize(), fLayouter.getAnnotationSize());
373                 if (fAnnotationAccessExtension != null)
374                     fAnnotationAccessExtension.paint(a, e.gc, can, rect);
375             }
376         }
377     }
378
379     /**
380      * Our own private hover manager used to shop per-item pop-ups.
381      */

382     private final class HoverManager extends AbstractInformationControlManager {
383
384         /**
385          *
386          */

387         public HoverManager() {
388             super(new IInformationControlCreator() {
389                 public IInformationControl createInformationControl(Shell parent) {
390                     return new DefaultInformationControl(parent);
391                 }
392             });
393
394             setMargins(5, 10);
395             setAnchor(ANCHOR_BOTTOM);
396             setFallbackAnchors(new Anchor[] {ANCHOR_BOTTOM, ANCHOR_LEFT, ANCHOR_RIGHT} );
397         }
398
399         /*
400          * @see org.eclipse.jface.text.AbstractInformationControlManager#computeInformation()
401          */

402         protected void computeInformation() {
403             if (fSelection != null) {
404                 Rectangle subjectArea= fSelection.canvas.getBounds();
405                 Annotation annotation= fSelection.fAnnotation;
406                 String JavaDoc msg;
407                 if (annotation != null)
408                     msg= annotation.getText();
409                 else
410                     msg= null;
411
412                 setInformation(msg, subjectArea);
413             }
414         }
415
416
417     }
418
419     /** Model data. */
420     protected AnnotationHoverInput fInput;
421     /** The control's shell */
422     private Shell fShell;
423     /** The composite combining all the items. */
424     protected Composite fComposite;
425     /** The hand cursor. */
426     private Cursor fHandCursor;
427     /** The currently selected item, or <code>null</code> if none is selected. */
428     private Item fSelection;
429     /** The hover manager for the per-item hovers. */
430     private HoverManager fHoverManager;
431     /** The annotation access extension. */
432     private IAnnotationAccessExtension fAnnotationAccessExtension;
433
434
435     /* listener legion */
436     private final MyPaintListener fPaintListener;
437     private final MyMouseTrackListener fMouseTrackListener;
438     private final MyMouseListener fMouseListener;
439     private final MyMenuDetectListener fMenuDetectListener;
440     private final DisposeListener fDisposeListener;
441     private final IViewportListener fViewportListener;
442
443     private LinearLayouter fLayouter;
444
445     /**
446      * Creates a new control.
447      *
448      * @param parent
449      * @param shellStyle
450      * @param access
451      */

452     public AnnotationExpansionControl(Shell parent, int shellStyle, IAnnotationAccess access) {
453         fPaintListener= new MyPaintListener();
454         fMouseTrackListener= new MyMouseTrackListener();
455         fMouseListener= new MyMouseListener();
456         fMenuDetectListener= new MyMenuDetectListener();
457         fDisposeListener= new MyDisposeListener();
458         fViewportListener= new IViewportListener() {
459
460             public void viewportChanged(int verticalOffset) {
461                 dispose();
462             }
463
464         };
465         fLayouter= new LinearLayouter();
466
467         if (access instanceof IAnnotationAccessExtension)
468             fAnnotationAccessExtension= (IAnnotationAccessExtension) access;
469
470         fShell= new Shell(parent, shellStyle | SWT.NO_FOCUS | SWT.ON_TOP);
471         Display display= fShell.getDisplay();
472         fShell.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
473         fComposite= new Composite(fShell, SWT.NO_FOCUS | SWT.NO_REDRAW_RESIZE | SWT.NO_TRIM);
474 // fComposite= new Composite(fShell, SWT.NO_FOCUS | SWT.NO_REDRAW_RESIZE | SWT.NO_TRIM | SWT.V_SCROLL);
475

476         GridLayout layout= new GridLayout(1, true);
477         layout.marginHeight= 0;
478         layout.marginWidth= 0;
479         fShell.setLayout(layout);
480
481         GridData data= new GridData(GridData.FILL_BOTH);
482         data.heightHint= fLayouter.getAnnotationSize() + 2 * fLayouter.getBorderWidth() + 4;
483         fComposite.setLayoutData(data);
484         fComposite.addMouseTrackListener(new MouseTrackAdapter() {
485
486             public void mouseExit(MouseEvent e) {
487                 if (fComposite == null)
488                         return;
489                 Control[] children= fComposite.getChildren();
490                 Rectangle bounds= null;
491                 for (int i= 0; i < children.length; i++) {
492                     if (bounds == null)
493                         bounds= children[i].getBounds();
494                     else
495                         bounds.add(children[i].getBounds());
496                     if (bounds.contains(e.x, e.y))
497                         return;
498                 }
499
500                 // if none of the children contains the event, we leave the popup
501
dispose();
502             }
503
504         });
505
506 // fComposite.getVerticalBar().addListener(SWT.Selection, new Listener() {
507
//
508
// public void handleEvent(Event event) {
509
// Rectangle bounds= fShell.getBounds();
510
// int x= bounds.x - fLayouter.getAnnotationSize() - fLayouter.getBorderWidth();
511
// int y= bounds.y;
512
// fShell.setBounds(x, y, bounds.width, bounds.height);
513
// }
514
//
515
// });
516

517         fHandCursor= new Cursor(display, SWT.CURSOR_HAND);
518         fShell.setCursor(fHandCursor);
519         fComposite.setCursor(fHandCursor);
520
521         setInfoSystemColor();
522     }
523
524     private void setInfoSystemColor() {
525         Display display= fShell.getDisplay();
526         setForegroundColor(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
527         setBackgroundColor(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
528     }
529
530     /*
531      * @see org.eclipse.jface.text.IInformationControl#setInformation(java.lang.String)
532      */

533     public void setInformation(String JavaDoc information) {
534         setInput(null);
535     }
536
537
538     /*
539      * @see org.eclipse.jface.text.IInformationControlExtension2#setInput(java.lang.Object)
540      */

541     public void setInput(Object JavaDoc input) {
542         if (fInput != null && fInput.fViewer != null)
543             fInput.fViewer.removeViewportListener(fViewportListener);
544
545         if (input instanceof AnnotationHoverInput)
546             fInput= (AnnotationHoverInput) input;
547         else
548             fInput= null;
549
550         inputChanged(fInput, null);
551     }
552
553     protected void inputChanged(Object JavaDoc newInput, Object JavaDoc newSelection) {
554         refresh();
555     }
556
557     protected void refresh() {
558         adjustItemNumber();
559
560         if (fInput == null)
561             return;
562
563         if (fInput.fAnnotations == null)
564             return;
565
566         if (fInput.fViewer != null)
567             fInput.fViewer.addViewportListener(fViewportListener);
568
569         fShell.setRegion(fLayouter.getShellRegion(fInput.fAnnotations.length));
570
571         Layout layout= fLayouter.getLayout(fInput.fAnnotations.length);
572         fComposite.setLayout(layout);
573
574         Control[] children= fComposite.getChildren();
575         for (int i= 0; i < fInput.fAnnotations.length; i++) {
576             Canvas canvas= (Canvas) children[i];
577             Item item= new Item();
578             item.canvas= canvas;
579             item.fAnnotation= fInput.fAnnotations[i];
580             canvas.setData(item);
581             canvas.redraw();
582         }
583
584     }
585
586     protected void adjustItemNumber() {
587         if (fComposite == null)
588             return;
589
590         Control[] children= fComposite.getChildren();
591         int oldSize= children.length;
592         int newSize= fInput == null ? 0 : fInput.fAnnotations.length;
593
594         Display display= fShell.getDisplay();
595
596         // add missing items
597
for (int i= oldSize; i < newSize; i++) {
598             Canvas canvas= new Canvas(fComposite, SWT.NONE);
599             Object JavaDoc gridData= fLayouter.getLayoutData();
600             canvas.setLayoutData(gridData);
601             canvas.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
602
603             canvas.addPaintListener(fPaintListener);
604
605             canvas.addMouseTrackListener(fMouseTrackListener);
606
607             canvas.addMouseListener(fMouseListener);
608
609             canvas.addListener(SWT.MenuDetect, fMenuDetectListener);
610
611             canvas.addDisposeListener(fDisposeListener);
612         }
613
614         // dispose of exceeding resources
615
for (int i= oldSize; i > newSize; i--) {
616             Item item= (Item) children[i - 1].getData();
617             item.deselect();
618             children[i - 1].dispose();
619         }
620
621     }
622
623     /*
624      * @see IInformationControl#setVisible(boolean)
625      */

626     public void setVisible(boolean visible) {
627         fShell.setVisible(visible);
628     }
629
630     /*
631      * @see IInformationControl#dispose()
632      */

633     public void dispose() {
634         if (fShell != null) {
635             if (!fShell.isDisposed())
636                 fShell.dispose();
637             fShell= null;
638             fComposite= null;
639             if (fHandCursor != null)
640                 fHandCursor.dispose();
641             fHandCursor= null;
642             if (fHoverManager != null)
643                 fHoverManager.dispose();
644             fHoverManager= null;
645             fSelection= null;
646         }
647     }
648
649     /*
650      * @see org.eclipse.jface.text.IInformationControlExtension#hasContents()
651      */

652     public boolean hasContents() {
653         return fInput.fAnnotations != null && fInput.fAnnotations.length > 0;
654     }
655
656     /*
657      * @see org.eclipse.jface.text.IInformationControl#setSizeConstraints(int, int)
658      */

659     public void setSizeConstraints(int maxWidth, int maxHeight) {
660         //fMaxWidth= maxWidth;
661
//fMaxHeight= maxHeight;
662
}
663
664     /*
665      * @see org.eclipse.jface.text.IInformationControl#computeSizeHint()
666      */

667     public Point computeSizeHint() {
668         return fShell.computeSize(SWT.DEFAULT, SWT.DEFAULT);
669     }
670
671     /*
672      * @see IInformationControl#setLocation(Point)
673      */

674     public void setLocation(Point location) {
675         fShell.setLocation(location);
676     }
677
678     /*
679      * @see IInformationControl#setSize(int, int)
680      */

681     public void setSize(int width, int height) {
682         fShell.setSize(width, height);
683     }
684
685     /*
686      * @see IInformationControl#addDisposeListener(DisposeListener)
687      */

688     public void addDisposeListener(DisposeListener listener) {
689         fShell.addDisposeListener(listener);
690     }
691
692     /*
693      * @see IInformationControl#removeDisposeListener(DisposeListener)
694      */

695     public void removeDisposeListener(DisposeListener listener) {
696         fShell.removeDisposeListener(listener);
697     }
698
699     /*
700      * @see IInformationControl#setForegroundColor(Color)
701      */

702     public void setForegroundColor(Color foreground) {
703         fComposite.setForeground(foreground);
704     }
705
706     /*
707      * @see IInformationControl#setBackgroundColor(Color)
708      */

709     public void setBackgroundColor(Color background) {
710         fComposite.setBackground(background);
711     }
712
713     /*
714      * @see IInformationControl#isFocusControl()
715      */

716     public boolean isFocusControl() {
717         if (fComposite.isFocusControl())
718             return true;
719
720         Control[] children= fComposite.getChildren();
721         for (int i= 0; i < children.length; i++) {
722             if (children[i].isFocusControl())
723                 return true;
724         }
725         return false;
726     }
727
728     /*
729      * @see IInformationControl#setFocus()
730      */

731     public void setFocus() {
732         fShell.forceFocus();
733     }
734
735     /*
736      * @see IInformationControl#addFocusListener(FocusListener)
737      */

738     public void addFocusListener(FocusListener listener) {
739         fShell.addFocusListener(listener);
740     }
741
742     /*
743      * @see IInformationControl#removeFocusListener(FocusListener)
744      */

745     public void removeFocusListener(FocusListener listener) {
746         fShell.removeFocusListener(listener);
747     }
748
749     private StyleRange[] setViewerBackground(Annotation annotation) {
750         StyledText text= fInput.fViewer.getTextWidget();
751         if (text == null || text.isDisposed())
752             return null;
753
754         Display disp= text.getDisplay();
755
756         Position pos= fInput.model.getPosition(annotation);
757         if (pos == null)
758             return null;
759
760         IRegion region= ((TextViewer)fInput.fViewer).modelRange2WidgetRange(new Region(pos.offset, pos.length));
761         if (region == null)
762             return null;
763
764         StyleRange[] ranges= text.getStyleRanges(region.getOffset(), region.getLength());
765
766         List JavaDoc undoRanges= new ArrayList JavaDoc(ranges.length);
767         for (int i= 0; i < ranges.length; i++) {
768             undoRanges.add(ranges[i].clone());
769         }
770
771         int offset= region.getOffset();
772         StyleRange current= undoRanges.size() > 0 ? (StyleRange) undoRanges.get(0) : null;
773         int curStart= current != null ? current.start : region.getOffset() + region.getLength();
774         int curEnd= current != null ? current.start + current.length : -1;
775         int index= 0;
776
777         // fill no-style regions
778
while (curEnd < region.getOffset() + region.getLength()) {
779             // add empty range
780
if (curStart > offset) {
781                 StyleRange undoRange= new StyleRange(offset, curStart - offset, null, null);
782                 undoRanges.add(index, undoRange);
783                 index++;
784             }
785
786             // step
787
index++;
788             if (index < undoRanges.size()) {
789                 offset= curEnd;
790                 current= (StyleRange) undoRanges.get(index);
791                 curStart= current.start;
792                 curEnd= current.start + current.length;
793             } else if (index == undoRanges.size()) {
794                 // last one
795
offset= curEnd;
796                 current= null;
797                 curStart= region.getOffset() + region.getLength();
798                 curEnd= -1;
799             } else
800                 curEnd= region.getOffset() + region.getLength();
801         }
802
803         // create modified styles (with background)
804
List JavaDoc shadedRanges= new ArrayList JavaDoc(undoRanges.size());
805         for (Iterator JavaDoc it= undoRanges.iterator(); it.hasNext(); ) {
806             StyleRange range= (StyleRange) ((StyleRange) it.next()).clone();
807             shadedRanges.add(range);
808             range.background= getHighlightColor(disp);
809         }
810
811         // set the ranges one by one
812
for (Iterator JavaDoc iter= shadedRanges.iterator(); iter.hasNext(); ) {
813             text.setStyleRange((StyleRange) iter.next());
814
815         }
816
817         return (StyleRange[]) undoRanges.toArray(undoRanges.toArray(new StyleRange[0]));
818     }
819
820     private void resetViewerBackground(StyleRange[] oldRanges) {
821
822         if (oldRanges == null)
823             return;
824
825         if (fInput == null)
826             return;
827
828         StyledText text= fInput.fViewer.getTextWidget();
829         if (text == null || text.isDisposed())
830             return;
831
832         // set the ranges one by one
833
for (int i= 0; i < oldRanges.length; i++) {
834             text.setStyleRange(oldRanges[i]);
835         }
836     }
837
838     private Color getHighlightColor(Display disp) {
839         return disp.getSystemColor(SWT.COLOR_GRAY);
840     }
841
842     private Color getSelectionColor(Display disp) {
843         return disp.getSystemColor(SWT.COLOR_GRAY);
844     }
845
846 }
847
Popular Tags