KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > texteditor > AnnotationExpansionControl


1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 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.ui.internal.texteditor;
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.IVerticalRulerListener;
65 import org.eclipse.jface.text.source.IAnnotationModel;
66 import org.eclipse.jface.text.source.ISourceViewer;
67 import org.eclipse.jface.text.source.IVerticalRulerInfo;
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  *
75  * <p>Each annotation can have its custom context menu and hover.</p>
76  *
77  * @since 3.0
78  */

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

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

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

168     private final static class MyDisposeListener implements DisposeListener {
169         /*
170          * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent)
171          */

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

186     private final class MyMenuDetectListener implements Listener {
187         /*
188          * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
189          */

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

221     private final class MyMouseListener extends MouseAdapter {
222         /*
223          * @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
224          */

225         public void mouseDoubleClick(MouseEvent e) {
226             Item item= (Item) ((Widget) e.getSource()).getData();
227             if (e.button == 1 && item.fAnnotation == fInput.fAnnotations[0] && fInput.fDoubleClickListener != null) {
228                 fInput.fDoubleClickListener.doubleClick(null);
229                 // special code for JDT to renew the annotation set.
230
if (fInput.redoAction != null)
231                     fInput.redoAction.run(AnnotationExpansionControl.this);
232             }
233 // dispose();
234
// TODO special action to invoke double-click action on the vertical ruler
235
// how about
236
// Canvas can= (Canvas) e.getSource();
237
// Annotation a= (Annotation) can.getData();
238
// if (a != null) {
239
// a.getDoubleClickAction().run();
240
// }
241
}
242
243         /*
244          * @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent)
245          */

246         public void mouseUp(MouseEvent e) {
247             Item item= (Item) ((Widget) e.getSource()).getData();
248             // TODO for now, to make double click work: disable single click on the first item
249
// disable later when the annotationlistener selectively handles input
250
if (item != null && e.button == 1) // && item.fAnnotation != fInput.fAnnotations[0])
251
item.defaultSelected();
252         }
253
254         /*
255          * @see org.eclipse.swt.events.MouseAdapter#mouseDown(org.eclipse.swt.events.MouseEvent)
256          */

257         public void mouseDown(MouseEvent e) {
258             super.mouseDown(e);
259         }
260     }
261
262     /**
263      * Listener on mouse track events on the items.
264      */

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

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

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

305         public void mouseHover(MouseEvent e) {
306             if (fHoverManager == null) {
307                 fHoverManager= new HoverManager();
308                 fHoverManager.takesFocusWhenVisible(false);
309                 fHoverManager.install(fComposite);
310                 fHoverManager.showInformation();
311             }
312         }
313     }
314
315     /**
316      * Listener on paint events on the items. Paints the annotation image on the given <code>GC</code>.
317      */

318     private final class MyPaintListener implements PaintListener {
319         /*
320          * @see org.eclipse.swt.events.PaintListener#paintControl(org.eclipse.swt.events.PaintEvent)
321          */

322         public void paintControl(PaintEvent e) {
323             Canvas can= (Canvas) e.getSource();
324             Annotation a= ((Item) can.getData()).fAnnotation;
325             if (a != null) {
326                 Rectangle rect= new Rectangle(fLayouter.getBorderWidth(), fLayouter.getBorderWidth(), fLayouter.getAnnotationSize(), fLayouter.getAnnotationSize());
327                 if (fAnnotationAccessExtension != null)
328                     fAnnotationAccessExtension.paint(a, e.gc, can, rect);
329             }
330         }
331     }
332
333     /**
334      * Our own private hover manager used to shop per-item pop-ups.
335      */

336     private final class HoverManager extends AbstractInformationControlManager {
337
338         /**
339          *
340          */

341         public HoverManager() {
342             super(new IInformationControlCreator() {
343                 public IInformationControl createInformationControl(Shell parent) {
344                     return new DefaultInformationControl(parent);
345                 }
346             });
347
348             setMargins(5, 10);
349             setAnchor(ANCHOR_BOTTOM);
350             setFallbackAnchors(new Anchor[] {ANCHOR_BOTTOM, ANCHOR_LEFT, ANCHOR_RIGHT} );
351         }
352
353         /*
354          * @see org.eclipse.jface.text.AbstractInformationControlManager#computeInformation()
355          */

356         protected void computeInformation() {
357             if (fSelection != null) {
358                 Rectangle subjectArea= fSelection.canvas.getBounds();
359                 Annotation annotation= fSelection.fAnnotation;
360                 String JavaDoc msg;
361                 if (annotation != null)
362                     msg= annotation.getText();
363                 else
364                     msg= null;
365
366                 setInformation(msg, subjectArea);
367             }
368         }
369
370
371     }
372
373     /** Model data. */
374     protected AnnotationHoverInput fInput;
375     /** The control's shell */
376     private Shell fShell;
377     /** The composite combining all the items. */
378     protected Composite fComposite;
379     /** The hand cursor. */
380     private Cursor fHandCursor;
381     /** The currently selected item, or <code>null</code> if none is selected. */
382     private Item fSelection;
383     /** The hover manager for the per-item hovers. */
384     private HoverManager fHoverManager;
385     /** The annotation access extension. */
386     private IAnnotationAccessExtension fAnnotationAccessExtension;
387
388
389     /* listener legion */
390     private final MyPaintListener fPaintListener;
391     private final MyMouseTrackListener fMouseTrackListener;
392     private final MyMouseListener fMouseListener;
393     private final MyMenuDetectListener fMenuDetectListener;
394     private final DisposeListener fDisposeListener;
395     private final IViewportListener fViewportListener;
396
397     private LinearLayouter fLayouter;
398
399     /**
400      * Creates a new control.
401      *
402      * @param parent
403      * @param shellStyle
404      * @param access
405      */

406     public AnnotationExpansionControl(Shell parent, int shellStyle, IAnnotationAccess access) {
407         fPaintListener= new MyPaintListener();
408         fMouseTrackListener= new MyMouseTrackListener();
409         fMouseListener= new MyMouseListener();
410         fMenuDetectListener= new MyMenuDetectListener();
411         fDisposeListener= new MyDisposeListener();
412         fViewportListener= new IViewportListener() {
413
414             public void viewportChanged(int verticalOffset) {
415                 dispose();
416             }
417
418         };
419         fLayouter= new LinearLayouter();
420
421         if (access instanceof IAnnotationAccessExtension)
422             fAnnotationAccessExtension= (IAnnotationAccessExtension) access;
423
424         fShell= new Shell(parent, shellStyle | SWT.NO_FOCUS | SWT.ON_TOP);
425         Display display= fShell.getDisplay();
426         fShell.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
427         fComposite= new Composite(fShell, SWT.NO_FOCUS | SWT.NO_REDRAW_RESIZE | SWT.NO_TRIM);
428 // fComposite= new Composite(fShell, SWT.NO_FOCUS | SWT.NO_REDRAW_RESIZE | SWT.NO_TRIM | SWT.V_SCROLL);
429

430         GridLayout layout= new GridLayout(1, true);
431         layout.marginHeight= 0;
432         layout.marginWidth= 0;
433         fShell.setLayout(layout);
434
435         GridData data= new GridData(GridData.FILL_BOTH);
436         data.heightHint= fLayouter.getAnnotationSize() + 2 * fLayouter.getBorderWidth() + 4;
437         fComposite.setLayoutData(data);
438         fComposite.addMouseTrackListener(new MouseTrackAdapter() {
439
440             public void mouseExit(MouseEvent e) {
441                 if (fComposite == null)
442                         return;
443                 Control[] children= fComposite.getChildren();
444                 Rectangle bounds= null;
445                 for (int i= 0; i < children.length; i++) {
446                     if (bounds == null)
447                         bounds= children[i].getBounds();
448                     else
449                         bounds.add(children[i].getBounds());
450                     if (bounds.contains(e.x, e.y))
451                         return;
452                 }
453
454                 // if none of the children contains the event, we leave the popup
455
dispose();
456             }
457
458         });
459
460 // fComposite.getVerticalBar().addListener(SWT.Selection, new Listener() {
461
//
462
// public void handleEvent(Event event) {
463
// Rectangle bounds= fShell.getBounds();
464
// int x= bounds.x - fLayouter.getAnnotationSize() - fLayouter.getBorderWidth();
465
// int y= bounds.y;
466
// fShell.setBounds(x, y, bounds.width, bounds.height);
467
// }
468
//
469
// });
470

471         fHandCursor= new Cursor(display, SWT.CURSOR_HAND);
472         fShell.setCursor(fHandCursor);
473         fComposite.setCursor(fHandCursor);
474
475         setInfoSystemColor();
476     }
477
478     private void setInfoSystemColor() {
479         Display display= fShell.getDisplay();
480         setForegroundColor(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
481         setBackgroundColor(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
482     }
483
484     /*
485      * @see org.eclipse.jface.text.IInformationControl#setInformation(java.lang.String)
486      */

487     public void setInformation(String JavaDoc information) {
488         setInput(null);
489     }
490
491
492     /*
493      * @see org.eclipse.jface.text.IInformationControlExtension2#setInput(java.lang.Object)
494      */

495     public void setInput(Object JavaDoc input) {
496         if (fInput != null && fInput.fViewer != null)
497             fInput.fViewer.removeViewportListener(fViewportListener);
498
499         if (input instanceof AnnotationHoverInput)
500             fInput= (AnnotationHoverInput) input;
501         else
502             fInput= null;
503
504         inputChanged(fInput, null);
505     }
506
507     protected void inputChanged(Object JavaDoc newInput, Object JavaDoc newSelection) {
508         refresh();
509     }
510
511     protected void refresh() {
512         adjustItemNumber();
513
514         if (fInput == null)
515             return;
516
517         if (fInput.fAnnotations == null)
518             return;
519
520         if (fInput.fViewer != null)
521             fInput.fViewer.addViewportListener(fViewportListener);
522
523         fShell.setRegion(fLayouter.getShellRegion(fInput.fAnnotations.length));
524
525         Layout layout= fLayouter.getLayout(fInput.fAnnotations.length);
526         fComposite.setLayout(layout);
527
528         Control[] children= fComposite.getChildren();
529         for (int i= 0; i < fInput.fAnnotations.length; i++) {
530             Canvas canvas= (Canvas) children[i];
531             Item item= new Item();
532             item.canvas= canvas;
533             item.fAnnotation= fInput.fAnnotations[i];
534             canvas.setData(item);
535             canvas.redraw();
536         }
537
538     }
539
540     protected void adjustItemNumber() {
541         if (fComposite == null)
542             return;
543
544         Control[] children= fComposite.getChildren();
545         int oldSize= children.length;
546         int newSize= fInput == null ? 0 : fInput.fAnnotations.length;
547
548         Display display= fShell.getDisplay();
549
550         // add missing items
551
for (int i= oldSize; i < newSize; i++) {
552             Canvas canvas= new Canvas(fComposite, SWT.NONE);
553             Object JavaDoc gridData= fLayouter.getLayoutData();
554             canvas.setLayoutData(gridData);
555             canvas.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
556
557             canvas.addPaintListener(fPaintListener);
558
559             canvas.addMouseTrackListener(fMouseTrackListener);
560
561             canvas.addMouseListener(fMouseListener);
562
563             canvas.addListener(SWT.MenuDetect, fMenuDetectListener);
564
565             canvas.addDisposeListener(fDisposeListener);
566         }
567
568         // dispose of exceeding resources
569
for (int i= oldSize; i > newSize; i--) {
570             Item item= (Item) children[i - 1].getData();
571             item.deselect();
572             children[i - 1].dispose();
573         }
574
575     }
576
577     /*
578      * @see IInformationControl#setVisible(boolean)
579      */

580     public void setVisible(boolean visible) {
581         fShell.setVisible(visible);
582     }
583
584     /*
585      * @see IInformationControl#dispose()
586      */

587     public void dispose() {
588         if (fShell != null) {
589             if (!fShell.isDisposed())
590                 fShell.dispose();
591             fShell= null;
592             fComposite= null;
593             if (fHandCursor != null)
594                 fHandCursor.dispose();
595             fHandCursor= null;
596             if (fHoverManager != null)
597                 fHoverManager.dispose();
598             fHoverManager= null;
599             fSelection= null;
600         }
601     }
602
603     /*
604      * @see org.eclipse.jface.text.IInformationControlExtension#hasContents()
605      */

606     public boolean hasContents() {
607         return fInput.fAnnotations != null && fInput.fAnnotations.length > 0;
608     }
609
610     /*
611      * @see org.eclipse.jface.text.IInformationControl#setSizeConstraints(int, int)
612      */

613     public void setSizeConstraints(int maxWidth, int maxHeight) {
614         //fMaxWidth= maxWidth;
615
//fMaxHeight= maxHeight;
616
}
617
618     /*
619      * @see org.eclipse.jface.text.IInformationControl#computeSizeHint()
620      */

621     public Point computeSizeHint() {
622         return fShell.computeSize(SWT.DEFAULT, SWT.DEFAULT);
623     }
624
625     /*
626      * @see IInformationControl#setLocation(Point)
627      */

628     public void setLocation(Point location) {
629         fShell.setLocation(location);
630     }
631
632     /*
633      * @see IInformationControl#setSize(int, int)
634      */

635     public void setSize(int width, int height) {
636         fShell.setSize(width, height);
637     }
638
639     /*
640      * @see IInformationControl#addDisposeListener(DisposeListener)
641      */

642     public void addDisposeListener(DisposeListener listener) {
643         fShell.addDisposeListener(listener);
644     }
645
646     /*
647      * @see IInformationControl#removeDisposeListener(DisposeListener)
648      */

649     public void removeDisposeListener(DisposeListener listener) {
650         fShell.removeDisposeListener(listener);
651     }
652
653     /*
654      * @see IInformationControl#setForegroundColor(Color)
655      */

656     public void setForegroundColor(Color foreground) {
657         fComposite.setForeground(foreground);
658     }
659
660     /*
661      * @see IInformationControl#setBackgroundColor(Color)
662      */

663     public void setBackgroundColor(Color background) {
664         fComposite.setBackground(background);
665     }
666
667     /*
668      * @see IInformationControl#isFocusControl()
669      */

670     public boolean isFocusControl() {
671         if (fComposite.isFocusControl())
672             return true;
673
674         Control[] children= fComposite.getChildren();
675         for (int i= 0; i < children.length; i++) {
676             if (children[i].isFocusControl())
677                 return true;
678         }
679         return false;
680     }
681
682     /*
683      * @see IInformationControl#setFocus()
684      */

685     public void setFocus() {
686         fShell.forceFocus();
687     }
688
689     /*
690      * @see IInformationControl#addFocusListener(FocusListener)
691      */

692     public void addFocusListener(FocusListener listener) {
693         fShell.addFocusListener(listener);
694     }
695
696     /*
697      * @see IInformationControl#removeFocusListener(FocusListener)
698      */

699     public void removeFocusListener(FocusListener listener) {
700         fShell.removeFocusListener(listener);
701     }
702
703     private StyleRange[] setViewerBackground(Annotation annotation) {
704         StyledText text= fInput.fViewer.getTextWidget();
705         if (text == null || text.isDisposed())
706             return null;
707
708         Display disp= text.getDisplay();
709
710         Position pos= fInput.model.getPosition(annotation);
711         if (pos == null)
712             return null;
713
714         IRegion region= ((TextViewer)fInput.fViewer).modelRange2WidgetRange(new Region(pos.offset, pos.length));
715
716         StyleRange[] ranges= text.getStyleRanges(region.getOffset(), region.getLength());
717
718         List JavaDoc undoRanges= new ArrayList JavaDoc(ranges.length);
719         for (int i= 0; i < ranges.length; i++) {
720             undoRanges.add(ranges[i].clone());
721         }
722
723         int offset= region.getOffset();
724         StyleRange current= undoRanges.size() > 0 ? (StyleRange) undoRanges.get(0) : null;
725         int curStart= current != null ? current.start : region.getOffset() + region.getLength();
726         int curEnd= current != null ? current.start + current.length : -1;
727         int index= 0;
728
729         // fill no-style regions
730
while (curEnd < region.getOffset() + region.getLength()) {
731             // add empty range
732
if (curStart > offset) {
733                 StyleRange undoRange= new StyleRange(offset, curStart - offset, null, null);
734                 undoRanges.add(index, undoRange);
735                 index++;
736             }
737
738             // step
739
index++;
740             if (index < undoRanges.size()) {
741                 offset= curEnd;
742                 current= (StyleRange) undoRanges.get(index);
743                 curStart= current.start;
744                 curEnd= current.start + current.length;
745             } else if (index == undoRanges.size()) {
746                 // last one
747
offset= curEnd;
748                 current= null;
749                 curStart= region.getOffset() + region.getLength();
750                 curEnd= -1;
751             } else
752                 curEnd= region.getOffset() + region.getLength();
753         }
754
755         // create modified styles (with background)
756
List JavaDoc shadedRanges= new ArrayList JavaDoc(undoRanges.size());
757         for (Iterator JavaDoc it= undoRanges.iterator(); it.hasNext(); ) {
758             StyleRange range= (StyleRange) ((StyleRange) it.next()).clone();
759             shadedRanges.add(range);
760             range.background= getHighlightColor(disp);
761         }
762
763         // set the ranges one by one
764
for (Iterator JavaDoc iter= shadedRanges.iterator(); iter.hasNext(); ) {
765             text.setStyleRange((StyleRange) iter.next());
766
767         }
768
769         return (StyleRange[]) undoRanges.toArray(undoRanges.toArray(new StyleRange[0]));
770     }
771
772     private void resetViewerBackground(StyleRange[] oldRanges) {
773
774         if (oldRanges == null)
775             return;
776
777         if (fInput == null)
778             return;
779
780         StyledText text= fInput.fViewer.getTextWidget();
781         if (text == null || text.isDisposed())
782             return;
783
784         // set the ranges one by one
785
for (int i= 0; i < oldRanges.length; i++) {
786             text.setStyleRange(oldRanges[i]);
787         }
788     }
789
790     private Color getHighlightColor(Display disp) {
791         return disp.getSystemColor(SWT.COLOR_GRAY);
792     }
793
794     private Color getSelectionColor(Display disp) {
795         return disp.getSystemColor(SWT.COLOR_GRAY);
796     }
797
798 }
799
Popular Tags