KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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
14 import java.util.Iterator JavaDoc;
15
16 import org.eclipse.swt.SWT;
17 import org.eclipse.swt.events.MouseEvent;
18 import org.eclipse.swt.events.MouseMoveListener;
19 import org.eclipse.swt.events.MouseTrackAdapter;
20 import org.eclipse.swt.graphics.Color;
21 import org.eclipse.swt.widgets.Composite;
22 import org.eclipse.swt.widgets.Control;
23 import org.eclipse.swt.widgets.Display;
24
25 import org.eclipse.jface.text.BadLocationException;
26 import org.eclipse.jface.text.IDocument;
27 import org.eclipse.jface.text.Position;
28 import org.eclipse.jface.text.source.AnnotationRulerColumn;
29 import org.eclipse.jface.text.source.CompositeRuler;
30 import org.eclipse.jface.text.source.IAnnotationAccess;
31 import org.eclipse.jface.text.source.IAnnotationModel;
32 import org.eclipse.jface.text.source.IAnnotationModelExtension;
33
34
35 /**
36  * A ruler column for controlling the behavior of a
37  * {@link org.eclipse.jface.text.source.projection.ProjectionViewer}.
38  *
39  * @since 3.0
40  */

41 class ProjectionRulerColumn extends AnnotationRulerColumn {
42
43     private ProjectionAnnotation fCurrentAnnotation;
44
45     /**
46      * Creates a new projection ruler column.
47      *
48      * @param model the column's annotation model
49      * @param width the width in pixels
50      * @param annotationAccess the annotation access
51      */

52     public ProjectionRulerColumn(IAnnotationModel model, int width, IAnnotationAccess annotationAccess) {
53         super(model, width, annotationAccess);
54     }
55
56     /**
57      * Creates a new projection ruler column.
58      *
59      * @param width the width in pixels
60      * @param annotationAccess the annotation access
61      */

62     public ProjectionRulerColumn(int width, IAnnotationAccess annotationAccess) {
63         super(width, annotationAccess);
64     }
65
66     /*
67      * @see org.eclipse.jface.text.source.AnnotationRulerColumn#mouseClicked(int)
68      */

69     protected void mouseClicked(int line) {
70         clearCurrentAnnotation();
71         ProjectionAnnotation annotation= findAnnotation(line, true);
72         if (annotation != null) {
73             ProjectionAnnotationModel model= (ProjectionAnnotationModel) getModel();
74             model.toggleExpansionState(annotation);
75         }
76     }
77
78     /**
79      * Returns the projection annotation of the column's annotation
80      * model that contains the given line.
81      *
82      * @param line the line
83      * @param exact <code>true</code> if the annotation range must match exactly
84      * @return the projection annotation containing the given line
85      */

86     private ProjectionAnnotation findAnnotation(int line, boolean exact) {
87
88         ProjectionAnnotation previousAnnotation= null;
89
90         IAnnotationModel model= getModel();
91         if (model != null) {
92             IDocument document= getCachedTextViewer().getDocument();
93
94             int previousDistance= Integer.MAX_VALUE;
95
96             Iterator JavaDoc e= model.getAnnotationIterator();
97             while (e.hasNext()) {
98                 Object JavaDoc next= e.next();
99                 if (next instanceof ProjectionAnnotation) {
100                     ProjectionAnnotation annotation= (ProjectionAnnotation) next;
101                     Position p= model.getPosition(annotation);
102                     if (p == null)
103                         continue;
104
105                     int distance= getDistance(annotation, p, document, line);
106                     if (distance == -1)
107                         continue;
108
109                     if (!exact) {
110                         if (distance < previousDistance) {
111                             previousAnnotation= annotation;
112                             previousDistance= distance;
113                         }
114                     } else if (distance == 0) {
115                         previousAnnotation= annotation;
116                     }
117                 }
118             }
119         }
120
121         return previousAnnotation;
122     }
123
124     /**
125      * Returns the distance of the given line to the start line of the given position in the given document. The distance is
126      * <code>-1</code> when the line is not included in the given position.
127      *
128      * @param annotation the annotation
129      * @param position the position
130      * @param document the document
131      * @param line the line
132      * @return <code>-1</code> if line is not contained, a position number otherwise
133      */

134     private int getDistance(ProjectionAnnotation annotation, Position position, IDocument document, int line) {
135         if (position.getOffset() > -1 && position.getLength() > -1) {
136             try {
137                 int startLine= document.getLineOfOffset(position.getOffset());
138                 int endLine= document.getLineOfOffset(position.getOffset() + position.getLength());
139                 if (startLine <= line && line < endLine) {
140                     if (annotation.isCollapsed()) {
141                         int captionOffset;
142                         if (position instanceof IProjectionPosition)
143                             captionOffset= ((IProjectionPosition) position).computeCaptionOffset(document);
144                         else
145                             captionOffset= 0;
146
147                         int captionLine= document.getLineOfOffset(position.getOffset() + captionOffset);
148                         if (startLine <= captionLine && captionLine < endLine)
149                             return Math.abs(line - captionLine);
150                     }
151                     return line - startLine;
152                 }
153             } catch (BadLocationException x) {
154             }
155         }
156         return -1;
157     }
158
159     private boolean clearCurrentAnnotation() {
160         if (fCurrentAnnotation != null) {
161             fCurrentAnnotation.setRangeIndication(false);
162             fCurrentAnnotation= null;
163             return true;
164         }
165         return false;
166     }
167
168     /*
169      * @see org.eclipse.jface.text.source.IVerticalRulerColumn#createControl(org.eclipse.jface.text.source.CompositeRuler, org.eclipse.swt.widgets.Composite)
170      */

171     public Control createControl(CompositeRuler parentRuler, Composite parentControl) {
172         Control control= super.createControl(parentRuler, parentControl);
173
174         // set background
175
Display display= parentControl.getDisplay();
176         Color background= display.getSystemColor(SWT.COLOR_LIST_BACKGROUND);
177         control.setBackground(background);
178
179         // install hover listener
180
control.addMouseTrackListener(new MouseTrackAdapter() {
181             public void mouseExit(MouseEvent e) {
182                 if (clearCurrentAnnotation())
183                     redraw();
184             }
185         });
186
187         // install mouse move listener
188
control.addMouseMoveListener(new MouseMoveListener() {
189             public void mouseMove(MouseEvent e) {
190                 boolean redraw= false;
191                 ProjectionAnnotation annotation= findAnnotation(toDocumentLineNumber(e.y), false);
192                 if (annotation != fCurrentAnnotation) {
193                     if (fCurrentAnnotation != null) {
194                         fCurrentAnnotation.setRangeIndication(false);
195                         redraw= true;
196                     }
197                     fCurrentAnnotation= annotation;
198                     if (fCurrentAnnotation != null && !fCurrentAnnotation.isCollapsed()) {
199                         fCurrentAnnotation.setRangeIndication(true);
200                         redraw= true;
201                     }
202                 }
203                 if (redraw)
204                     redraw();
205             }
206         });
207         return control;
208     }
209
210     /*
211      * @see org.eclipse.jface.text.source.AnnotationRulerColumn#setModel(org.eclipse.jface.text.source.IAnnotationModel)
212      */

213     public void setModel(IAnnotationModel model) {
214         if (model instanceof IAnnotationModelExtension) {
215             IAnnotationModelExtension extension= (IAnnotationModelExtension) model;
216             model= extension.getAnnotationModel(ProjectionSupport.PROJECTION);
217         }
218         super.setModel(model);
219     }
220
221     /*
222      * @see org.eclipse.jface.text.source.AnnotationRulerColumn#isPropagatingMouseListener()
223      */

224     protected boolean isPropagatingMouseListener() {
225         return false;
226     }
227
228     /*
229      * @see org.eclipse.jface.text.source.AnnotationRulerColumn#hasAnnotation(int)
230      */

231     protected boolean hasAnnotation(int lineNumber) {
232         return findAnnotation(lineNumber, true) != null;
233     }
234 }
235
Popular Tags