KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jface > text > source > projection > ProjectionSupport


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.jface.text.source.projection;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.List JavaDoc;
15
16 import org.eclipse.swt.SWT;
17 import org.eclipse.swt.custom.StyledText;
18 import org.eclipse.swt.custom.StyledTextContent;
19 import org.eclipse.swt.graphics.Color;
20 import org.eclipse.swt.graphics.FontMetrics;
21 import org.eclipse.swt.graphics.GC;
22 import org.eclipse.swt.graphics.Point;
23 import org.eclipse.swt.graphics.RGB;
24 import org.eclipse.swt.widgets.Display;
25
26 import org.eclipse.jface.text.IInformationControlCreator;
27 import org.eclipse.jface.text.source.Annotation;
28 import org.eclipse.jface.text.source.AnnotationPainter;
29 import org.eclipse.jface.text.source.IAnnotationAccess;
30 import org.eclipse.jface.text.source.IAnnotationHover;
31 import org.eclipse.jface.text.source.IAnnotationModel;
32 import org.eclipse.jface.text.source.ISharedTextColors;
33 import org.eclipse.jface.text.source.ISourceViewer;
34
35 /**
36  * Supports the configuration of projection capabilities a {@link org.eclipse.jface.text.source.projection.ProjectionViewer}.
37  * <p>
38  * This class is not intended to be subclassed. Clients are supposed to configure and use it as is.</p>
39  *
40  * @since 3.0
41  */

42 public class ProjectionSupport {
43
44     /**
45      * Key of the projection annotation model inside the visual annotation
46      * model. Also internally used as key for the projection drawing strategy.
47      */

48     public final static Object JavaDoc PROJECTION= new Object JavaDoc();
49
50     private static class ProjectionAnnotationsPainter extends AnnotationPainter {
51
52         /**
53          * Creates a new painter indicating the location of collapsed regions.
54          *
55          * @param sourceViewer the source viewer for the painter
56          * @param access the annotation access
57          */

58         public ProjectionAnnotationsPainter(ISourceViewer sourceViewer, IAnnotationAccess access) {
59             super(sourceViewer, access);
60         }
61
62         /*
63          * @see org.eclipse.jface.text.source.AnnotationPainter#findAnnotationModel(org.eclipse.jface.text.source.ISourceViewer)
64          */

65         protected IAnnotationModel findAnnotationModel(ISourceViewer sourceViewer) {
66             if (sourceViewer instanceof ProjectionViewer) {
67                 ProjectionViewer projectionViewer= (ProjectionViewer) sourceViewer;
68                 return projectionViewer.getProjectionAnnotationModel();
69             }
70             return null;
71         }
72
73         /*
74          * @see org.eclipse.jface.text.source.AnnotationPainter#skip(org.eclipse.jface.text.source.Annotation)
75          */

76         protected boolean skip(Annotation annotation) {
77             if (annotation instanceof ProjectionAnnotation)
78                 return !((ProjectionAnnotation) annotation).isCollapsed();
79
80             return super.skip(annotation);
81         }
82     }
83
84     private static class ProjectionDrawingStrategy implements AnnotationPainter.IDrawingStrategy {
85         /*
86          * @see org.eclipse.jface.text.source.AnnotationPainter.IDrawingStrategy#draw(org.eclipse.swt.graphics.GC, org.eclipse.swt.custom.StyledText, int, int, org.eclipse.swt.graphics.Color)
87          */

88         public void draw(Annotation annotation, GC gc, StyledText textWidget, int offset, int length, Color color) {
89             if (annotation instanceof ProjectionAnnotation) {
90                 ProjectionAnnotation projectionAnnotation= (ProjectionAnnotation) annotation;
91                 if (projectionAnnotation.isCollapsed()) {
92
93                     if (gc != null) {
94
95                         StyledTextContent content= textWidget.getContent();
96                         int line= content.getLineAtOffset(offset);
97                         int lineStart= content.getOffsetAtLine(line);
98                         String JavaDoc text= content.getLine(line);
99                         int lineLength= text == null ? 0 : text.length();
100                         int lineEnd= lineStart + lineLength;
101                         Point p= textWidget.getLocationAtOffset(lineEnd);
102
103                         Color c= gc.getForeground();
104                         gc.setForeground(color);
105
106                         FontMetrics metrics= gc.getFontMetrics();
107
108                         // baseline: where the dots are drawn
109
int baseline= textWidget.getBaseline(offset);
110                         // descent: number of pixels that the box extends over baseline
111
int descent= Math.min(2, textWidget.getLineHeight(offset) - baseline);
112                         // ascent: so much does the box stand up from baseline
113
int ascent= metrics.getAscent();
114                         // leading: free space from line top to box upper line
115
int leading= baseline - ascent;
116                         // height: height of the box
117
int height= ascent + descent;
118
119                         int width= metrics.getAverageCharWidth();
120                         gc.drawRectangle(p.x, p.y + leading, width, height);
121                         int third= width/3;
122                         int dotsVertical= p.y + baseline - 1;
123                         gc.drawPoint(p.x + third, dotsVertical);
124                         gc.drawPoint(p.x + width - third, dotsVertical);
125
126                         gc.setForeground(c);
127
128                     } else {
129                         textWidget.redrawRange(offset, length, true);
130                     }
131                 }
132             }
133         }
134     }
135
136     private class ProjectionListener implements IProjectionListener {
137
138         /*
139          * @see org.eclipse.jface.text.source.projection.IProjectionListener#projectionEnabled()
140          */

141         public void projectionEnabled() {
142             doEnableProjection();
143         }
144
145         /*
146          * @see org.eclipse.jface.text.source.projection.IProjectionListener#projectionDisabled()
147          */

148         public void projectionDisabled() {
149             doDisableProjection();
150         }
151     }
152
153     private ProjectionViewer fViewer;
154     private IAnnotationAccess fAnnotationAccess;
155     private ISharedTextColors fSharedTextColors;
156     private List JavaDoc fSummarizableTypes;
157     private IInformationControlCreator fInformationControlCreator;
158     private IInformationControlCreator fInformationPresenterControlCreator;
159     private ProjectionListener fProjectionListener;
160     private ProjectionAnnotationsPainter fPainter;
161     private ProjectionRulerColumn fColumn;
162     /**
163      * @since 3.1
164      */

165     private AnnotationPainter.IDrawingStrategy fDrawingStrategy;
166
167     /**
168      * Creates new projection support for the given projection viewer. Initially,
169      * no annotation types are summarized. A default hover control creator and a
170      * default drawing strategy are used.
171      *
172      * @param viewer the projection viewer
173      * @param annotationAccess the annotation access
174      * @param sharedTextColors the shared text colors to use
175      */

176     public ProjectionSupport(ProjectionViewer viewer, IAnnotationAccess annotationAccess, ISharedTextColors sharedTextColors) {
177         fViewer= viewer;
178         fAnnotationAccess= annotationAccess;
179         fSharedTextColors= sharedTextColors;
180     }
181
182     /**
183      * Marks the given annotation type to be considered when creating summaries for
184      * collapsed regions of the projection viewer.
185      * <p>
186      * A summary is an annotation that gets created out of all annotations with a
187      * type that has been registered through this method and that are inside the
188      * folded region.
189      * </p>
190      *
191      * @param annotationType the annotation type to consider
192      */

193     public void addSummarizableAnnotationType(String JavaDoc annotationType) {
194         if (fSummarizableTypes == null) {
195             fSummarizableTypes= new ArrayList JavaDoc();
196             fSummarizableTypes.add(annotationType);
197         } else if (!fSummarizableTypes.contains(annotationType))
198             fSummarizableTypes.add(annotationType);
199     }
200
201     /**
202      * Marks the given annotation type to be ignored when creating summaries for
203      * collapsed regions of the projection viewer. This method has only an effect
204      * when <code>addSummarizableAnnotationType</code> has been called before for
205      * the give annotation type.
206      * <p>
207      * A summary is an annotation that gets created out of all annotations with a
208      * type that has been registered through this method and that are inside the
209      * folded region.
210      * </p>
211      *
212      * @param annotationType the annotation type to remove
213      */

214     public void removeSummarizableAnnotationType(String JavaDoc annotationType) {
215         if (fSummarizableTypes != null)
216             fSummarizableTypes.remove(annotationType);
217         if (fSummarizableTypes.size() == 0)
218             fSummarizableTypes= null;
219     }
220
221     /**
222      * Sets the hover control creator that is used for the annotation hovers
223      * that are shown in the projection viewer's projection ruler column.
224      *
225      * @param creator the hover control creator
226      */

227     public void setHoverControlCreator(IInformationControlCreator creator) {
228         fInformationControlCreator= creator;
229     }
230     
231     /**
232      * Sets the information presenter control creator that is used for the annotation
233      * hovers that are shown in the projection viewer's projection ruler column.
234      *
235      * @param creator the information presenter control creator
236      * @since 3.3
237      */

238     public void setInformationPresenterControlCreator(IInformationControlCreator creator) {
239         fInformationPresenterControlCreator= creator;
240     }
241
242     /**
243      * Sets the drawing strategy that the projection support's annotation
244      * painter uses to draw the indication of collapsed regions onto the
245      * projection viewer's text widget. When <code>null</code> is passed in,
246      * the drawing strategy is reset to the default. In order to avoid any
247      * representation use {@link org.eclipse.jface.text.source.AnnotationPainter.NullStrategy}.
248      *
249      * @param strategy the drawing strategy or <code>null</code> to reset the
250      * strategy to the default
251      * @since 3.1
252      */

253     public void setAnnotationPainterDrawingStrategy(AnnotationPainter.IDrawingStrategy strategy) {
254         fDrawingStrategy= strategy;
255     }
256
257     /**
258      * Returns the drawing strategy to be used by the support's annotation painter.
259      *
260      * @return the drawing strategy to be used by the support's annotation painter
261      * @since 3.1
262      */

263     private AnnotationPainter.IDrawingStrategy getDrawingStrategy() {
264         if (fDrawingStrategy == null)
265             fDrawingStrategy= new ProjectionDrawingStrategy();
266         return fDrawingStrategy;
267     }
268
269     /**
270      * Installs this projection support on its viewer.
271      */

272     public void install() {
273         fViewer.setProjectionSummary(createProjectionSummary());
274
275         fProjectionListener= new ProjectionListener();
276         fViewer.addProjectionListener(fProjectionListener);
277     }
278
279     /**
280      * Disposes this projection support.
281      */

282     public void dispose() {
283         if (fProjectionListener != null) {
284             fViewer.removeProjectionListener(fProjectionListener);
285             fProjectionListener= null;
286         }
287     }
288
289     /**
290      * Enables projection mode. If not yet done, installs the projection ruler
291      * column in the viewer's vertical ruler and installs a painter that
292      * indicate the locations of collapsed regions.
293      *
294      */

295     protected void doEnableProjection() {
296
297         if (fPainter == null) {
298             fPainter= new ProjectionAnnotationsPainter(fViewer, fAnnotationAccess);
299             fPainter.addDrawingStrategy(PROJECTION, getDrawingStrategy());
300             fPainter.addAnnotationType(ProjectionAnnotation.TYPE, PROJECTION);
301             fPainter.setAnnotationTypeColor(ProjectionAnnotation.TYPE, fSharedTextColors.getColor(getColor()));
302             fViewer.addPainter(fPainter);
303         }
304
305         if (fColumn == null) {
306             fColumn= new ProjectionRulerColumn(9, fAnnotationAccess);
307             fColumn.addAnnotationType(ProjectionAnnotation.TYPE);
308             fColumn.setHover(createProjectionAnnotationHover());
309             fViewer.addVerticalRulerColumn(fColumn);
310         }
311
312         fColumn.setModel(fViewer.getVisualAnnotationModel());
313     }
314
315     /**
316      * Removes the projection ruler column and the painter from the projection
317      * viewer.
318      */

319     protected void doDisableProjection() {
320         if (fPainter != null) {
321             fViewer.removePainter(fPainter);
322             fPainter.dispose();
323             fPainter= null;
324         }
325
326         if (fColumn != null) {
327             fViewer.removeVerticalRulerColumn(fColumn);
328             fColumn= null;
329         }
330     }
331
332     private ProjectionSummary createProjectionSummary() {
333         ProjectionSummary summary= new ProjectionSummary(fViewer, fAnnotationAccess);
334         if (fSummarizableTypes != null) {
335             int size= fSummarizableTypes.size();
336             for (int i= 0; i < size; i++)
337                 summary.addAnnotationType((String JavaDoc) fSummarizableTypes.get(i));
338         }
339         return summary;
340     }
341
342     private IAnnotationHover createProjectionAnnotationHover() {
343         ProjectionAnnotationHover hover= new ProjectionAnnotationHover();
344         hover.setHoverControlCreator(fInformationControlCreator);
345         hover.setInformationPresenterControlCreator(fInformationPresenterControlCreator);
346         return hover;
347     }
348
349     /**
350      * Implements the contract of {@link org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)}
351      * by forwarding the adapter requests to the given viewer.
352      *
353      * @param viewer the viewer
354      * @param required the required class of the adapter
355      * @return the adapter or <code>null</code>
356      *
357      */

358     public Object JavaDoc getAdapter(ISourceViewer viewer, Class JavaDoc required) {
359         if (ProjectionAnnotationModel.class.equals(required)) {
360             if (viewer instanceof ProjectionViewer) {
361                 ProjectionViewer projectionViewer= (ProjectionViewer) viewer;
362                 return projectionViewer.getProjectionAnnotationModel();
363             }
364         }
365         return null;
366     }
367
368     private RGB getColor() {
369         // TODO read out preference settings
370
Color c= Display.getDefault().getSystemColor(SWT.COLOR_DARK_GRAY);
371         return c.getRGB();
372     }
373 }
374
Popular Tags