KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > texteditor > SelectMarkerRulerAction


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.ui.texteditor;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Collections JavaDoc;
15 import java.util.Iterator JavaDoc;
16 import java.util.List JavaDoc;
17 import java.util.ResourceBundle JavaDoc;
18
19 import org.osgi.framework.Bundle;
20
21 import org.eclipse.core.resources.IFile;
22 import org.eclipse.core.resources.IMarker;
23 import org.eclipse.core.resources.IResource;
24 import org.eclipse.core.runtime.CoreException;
25 import org.eclipse.core.runtime.ILog;
26 import org.eclipse.core.runtime.IStatus;
27 import org.eclipse.core.runtime.Platform;
28 import org.eclipse.core.runtime.Status;
29
30 import org.eclipse.swt.widgets.Shell;
31
32 import org.eclipse.jface.text.BadLocationException;
33 import org.eclipse.jface.text.IDocument;
34 import org.eclipse.jface.text.Position;
35 import org.eclipse.jface.text.source.Annotation;
36 import org.eclipse.jface.text.source.IAnnotationAccess;
37 import org.eclipse.jface.text.source.IAnnotationAccessExtension;
38 import org.eclipse.jface.text.source.IAnnotationModel;
39 import org.eclipse.jface.text.source.IVerticalRuler;
40 import org.eclipse.jface.text.source.IVerticalRulerInfo;
41
42 import org.eclipse.jface.dialogs.ErrorDialog;
43 import org.eclipse.ui.IEditorInput;
44 import org.eclipse.ui.IWorkbenchPage;
45 import org.eclipse.ui.PlatformUI;
46 import org.eclipse.ui.ide.IGotoMarker;
47 import org.eclipse.ui.views.markers.MarkerViewUtil;
48
49
50 /**
51  * A ruler action which can select the textual range of a marker
52  * that has a visual representation in a vertical ruler.
53  * <p>
54  * This class may be instantiated but is not intended for sub-classing.
55  * </p>
56  * @since 2.0
57  */

58 public class SelectMarkerRulerAction extends ResourceAction implements IUpdate {
59
60     /** The vertical ruler info of the action's editor. */
61     private IVerticalRulerInfo fRuler;
62     /** The associated editor. */
63     private ITextEditor fTextEditor;
64     /** The action's resource bundle. */
65     private ResourceBundle JavaDoc fBundle;
66     /** The prefix for resource bundle lookups. */
67     private String JavaDoc fPrefix;
68
69     /**
70      * Creates a new action for the given ruler and editor. The action configures
71      * its visual representation from the given resource bundle.
72      *
73      * @param bundle the resource bundle
74      * @param prefix a prefix to be prepended to the various resource keys
75      * (described in <code>ResourceAction</code> constructor), or <code>null</code> if none
76      * @param editor the editor
77      * @param ruler the ruler
78      *
79      * @see ResourceAction#ResourceAction(ResourceBundle, String)
80      */

81     public SelectMarkerRulerAction(ResourceBundle JavaDoc bundle, String JavaDoc prefix, ITextEditor editor, IVerticalRulerInfo ruler) {
82         super(bundle, prefix);
83         fRuler= ruler;
84         fTextEditor= editor;
85
86         fBundle= bundle;
87         fPrefix= prefix;
88     }
89
90     /**
91      * Creates a new action for the given ruler and editor. The action configures
92      * its visual representation from the given resource bundle.
93      *
94      * @param bundle the resource bundle
95      * @param prefix a prefix to be prepended to the various resource keys
96      * @param ruler the ruler
97      * @param editor the editor
98      * @deprecated As of 3.0, replaced by {@link #SelectMarkerRulerAction(ResourceBundle, String, ITextEditor, IVerticalRulerInfo)}
99      */

100     public SelectMarkerRulerAction(ResourceBundle JavaDoc bundle, String JavaDoc prefix, IVerticalRuler ruler, ITextEditor editor) {
101         this(bundle, prefix, editor, ruler);
102     }
103
104     /*
105      * @see IUpdate#update()
106      */

107     public void update() {
108         setEnabled(hasMarkers());
109     }
110
111     /*
112      * @see Action#run()
113      */

114     public void run() {
115
116         IMarker marker= chooseMarker(getMarkers());
117         if (marker == null)
118             return;
119
120         IWorkbenchPage page= fTextEditor.getSite().getPage();
121         MarkerViewUtil.showMarker(page, marker, false);
122         
123         gotoMarker(marker);
124     }
125     
126     private void gotoMarker(IMarker marker) {
127         
128         // Use the provided adapter if any
129
IGotoMarker gotoMarkerAdapter= (IGotoMarker)fTextEditor.getAdapter(IGotoMarker.class);
130         if (gotoMarkerAdapter != null) {
131             gotoMarkerAdapter.gotoMarker(marker);
132             return;
133         }
134         
135         int start= MarkerUtilities.getCharStart(marker);
136         int end= MarkerUtilities.getCharEnd(marker);
137         
138         boolean selectLine= start < 0 || end < 0;
139
140         IDocumentProvider documentProvider= fTextEditor.getDocumentProvider();
141         IEditorInput editorInput= fTextEditor.getEditorInput();
142         
143         // look up the current range of the marker when the document has been edited
144
IAnnotationModel model= documentProvider.getAnnotationModel(editorInput);
145         if (model instanceof AbstractMarkerAnnotationModel) {
146
147             AbstractMarkerAnnotationModel markerModel= (AbstractMarkerAnnotationModel) model;
148             Position pos= markerModel.getMarkerPosition(marker);
149             if (pos != null && !pos.isDeleted()) {
150                 // use position instead of marker values
151
start= pos.getOffset();
152                 end= pos.getOffset() + pos.getLength();
153             }
154
155             if (pos != null && pos.isDeleted()) {
156                 // do nothing if position has been deleted
157
return;
158             }
159         }
160
161         IDocument document= documentProvider.getDocument(editorInput);
162
163         if (selectLine) {
164             int line;
165             try {
166                 if (start >= 0)
167                     line= document.getLineOfOffset(start);
168                 else {
169                     line= MarkerUtilities.getLineNumber(marker);
170                     // Marker line numbers are 1-based
171
-- line;
172                 }
173                 end= start + document.getLineLength(line) - 1;
174             } catch (BadLocationException e) {
175                 return;
176             }
177         }
178
179         int length= document.getLength();
180         if (end - 1 < length && start < length)
181             fTextEditor.selectAndReveal(start, end - start);
182     }
183     
184
185     /**
186      * Chooses the marker with the highest layer. If there are multiple
187      * markers at the found layer, the first marker is taken.
188      *
189      * @param markers the list of markers to choose from
190      * @return the chosen marker or <code>null</code> if none of the given markers has a marker annotation in the model
191      */

192     protected IMarker chooseMarker(List JavaDoc markers) {
193
194         AbstractMarkerAnnotationModel model= getAnnotationModel();
195         IAnnotationAccessExtension access= getAnnotationAccessExtension();
196
197         IMarker marker= null;
198         int maxLayer= 0;
199
200         Iterator JavaDoc iter= markers.iterator();
201         while (iter.hasNext()) {
202             IMarker m= (IMarker) iter.next();
203             Annotation a= model.getMarkerAnnotation(m);
204             if (a != null) {
205                 if (access == null) {
206                     marker= m;
207                     break;
208                 }
209                 int l= access.getLayer(a);
210                 if (l == maxLayer) {
211                     if (marker == null)
212                         marker= m;
213                 } else if (l > maxLayer) {
214                     maxLayer= l;
215                     marker= m;
216                 }
217             }
218         }
219
220         return marker;
221     }
222
223     /**
224      * Returns the annotation access extension.
225      *
226      * @return the annotation access extension or <code>null</code> if
227      * this action's editor has no such extension
228      * @since 3.0
229      */

230     protected IAnnotationAccessExtension getAnnotationAccessExtension() {
231         Object JavaDoc adapter= fTextEditor.getAdapter(IAnnotationAccess.class);
232         if (adapter instanceof IAnnotationAccessExtension)
233             return (IAnnotationAccessExtension)adapter;
234
235         return null;
236     }
237
238     /**
239      * Returns the resource for which to create the marker,
240      * or <code>null</code> if there is no applicable resource.
241      *
242      * @return the resource for which to create the marker or <code>null</code>
243      */

244     protected IResource getResource() {
245         IEditorInput input= fTextEditor.getEditorInput();
246
247         IResource resource= (IResource) input.getAdapter(IFile.class);
248
249         if (resource == null)
250             resource= (IResource) input.getAdapter(IResource.class);
251
252         return resource;
253     }
254
255     /**
256      * Returns the <code>AbstractMarkerAnnotationModel</code> of the editor's input.
257      *
258      * @return the marker annotation model or <code>null</code> if there's none
259      */

260     protected AbstractMarkerAnnotationModel getAnnotationModel() {
261         IDocumentProvider provider= fTextEditor.getDocumentProvider();
262         IAnnotationModel model= provider.getAnnotationModel(fTextEditor.getEditorInput());
263         if (model instanceof AbstractMarkerAnnotationModel)
264             return (AbstractMarkerAnnotationModel) model;
265         return null;
266     }
267
268     /**
269      * Returns the <code>IDocument</code> of the editor's input.
270      *
271      * @return the document of the editor's input
272      */

273     protected IDocument getDocument() {
274         IDocumentProvider provider= fTextEditor.getDocumentProvider();
275         return provider.getDocument(fTextEditor.getEditorInput());
276     }
277
278     /**
279      * Checks whether a position includes the ruler's line of activity.
280      *
281      * @param position the position to be checked
282      * @param document the document the position refers to
283      * @return <code>true</code> if the line is included by the given position
284      */

285     protected boolean includesRulerLine(Position position, IDocument document) {
286
287         if (position != null) {
288             try {
289                 int markerLine= document.getLineOfOffset(position.getOffset());
290                 int line= fRuler.getLineOfLastMouseButtonActivity();
291                 if (line == markerLine)
292                     return true;
293                 // commented because of "1GEUOZ9: ITPJUI:ALL - Confusing UI for multi-line Bookmarks and Tasks"
294
// return (markerLine <= line && line <= document.getLineOfOffset(position.getOffset() + position.getLength()));
295
} catch (BadLocationException x) {
296             }
297         }
298
299         return false;
300     }
301
302     /**
303      * Checks whether a position includes the ruler's line of activity.
304      *
305      * @param position the position to be checked
306      * @param document the document the position refers to
307      * @param line the line of the last ruler activity
308      * @return <code>true</code> if the line is included by the given position
309      * @since 3.3
310      */

311     private boolean includesLine(Position position, IDocument document, int line) {
312
313         if (position != null) {
314             try {
315                 int markerLine= document.getLineOfOffset(position.getOffset());
316                 if (line == markerLine)
317                     return true;
318                 // commented because of "1GEUOZ9: ITPJUI:ALL - Confusing UI for multi-line Bookmarks and Tasks"
319
// return (markerLine <= line && line <= document.getLineOfOffset(position.getOffset() + position.getLength()));
320
} catch (BadLocationException x) {
321             }
322         }
323
324         return false;
325     }
326
327     /**
328      * Handles core exceptions. This implementation logs the exceptions
329      * with the workbench plug-in and shows an error dialog.
330      *
331      * @param exception the exception to be handled
332      * @param message the message to be logged with the given exception
333      */

334     protected void handleCoreException(CoreException exception, String JavaDoc message) {
335         Bundle JavaDoc bundle = Platform.getBundle(PlatformUI.PLUGIN_ID);
336         ILog log= Platform.getLog(bundle);
337
338         if (message != null)
339             log.log(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, IStatus.OK, message, exception));
340         else
341             log.log(exception.getStatus());
342
343
344         Shell shell= fTextEditor.getSite().getShell();
345         String JavaDoc title= getString(fBundle, fPrefix + "error.dialog.title", fPrefix + "error.dialog.title"); //$NON-NLS-2$ //$NON-NLS-1$
346
String JavaDoc msg= getString(fBundle, fPrefix + "error.dialog.message", fPrefix + "error.dialog.message"); //$NON-NLS-2$ //$NON-NLS-1$
347

348         ErrorDialog.openError(shell, title, msg, exception.getStatus());
349     }
350
351     /**
352      * Returns all markers which include the ruler's line of activity.
353      *
354      * @return an unmodifiable list with all markers which include the ruler's line of activity
355      * (element type: {@link IMarker})
356      */

357     protected List JavaDoc getMarkers() {
358         final IResource resource= getResource();
359         if (resource == null || !resource.exists())
360             return Collections.EMPTY_LIST;
361
362         final IDocument document= getDocument();
363         if (document == null)
364             return Collections.EMPTY_LIST;
365
366         final AbstractMarkerAnnotationModel model= getAnnotationModel();
367         if (model == null)
368             return Collections.EMPTY_LIST;
369
370         final IMarker[] allMarkers;
371         try {
372             allMarkers= resource.findMarkers(null, true, IResource.DEPTH_ZERO);
373         } catch (CoreException x) {
374             handleCoreException(x, TextEditorMessages.SelectMarkerRulerAction_getMarker);
375             return Collections.EMPTY_LIST;
376         }
377
378         if (allMarkers.length == 0)
379             return Collections.EMPTY_LIST;
380
381         final int activeLine= fRuler.getLineOfLastMouseButtonActivity();
382         List JavaDoc markers= null;
383         for (Iterator JavaDoc it= model.getAnnotationIterator(); it.hasNext();) {
384             Annotation annotation= (Annotation) it.next();
385             if (annotation instanceof MarkerAnnotation) {
386                 Position position= model.getPosition(annotation);
387                 if (includesLine(position, document, activeLine)) {
388                     if (markers == null)
389                         markers= new ArrayList JavaDoc(10);
390
391                     markers.add(((MarkerAnnotation) annotation).getMarker());
392                 }
393             }
394         }
395
396         if (markers == null)
397             return Collections.EMPTY_LIST;
398
399         return Collections.unmodifiableList(markers);
400     }
401
402     /**
403      * Returns all markers which include the ruler's line of activity.
404      *
405      * @return an unmodifiable list with all markers which include the ruler's line of activity
406      * (element type: {@link IMarker})
407      * @since 3.3
408      */

409     protected boolean hasMarkers() {
410         final IResource resource= getResource();
411         if (resource == null || !resource.exists())
412             return false;
413
414         final IDocument document= getDocument();
415         if (document == null)
416             return false;
417
418         final AbstractMarkerAnnotationModel model= getAnnotationModel();
419         if (model == null)
420             return false;
421
422         final IMarker[] allMarkers;
423         try {
424             allMarkers= resource.findMarkers(null, true, IResource.DEPTH_ZERO);
425         } catch (CoreException x) {
426             handleCoreException(x, TextEditorMessages.SelectMarkerRulerAction_getMarker);
427             return false;
428         }
429
430         if (allMarkers.length == 0)
431             return false;
432
433         final int activeLine= fRuler.getLineOfLastMouseButtonActivity();
434         for (Iterator JavaDoc it= model.getAnnotationIterator(); it.hasNext();) {
435             Annotation annotation= (Annotation) it.next();
436             if (annotation instanceof MarkerAnnotation) {
437                 Position position= model.getPosition(annotation);
438                 if (includesLine(position, document, activeLine)) {
439                     return true;
440                 }
441             }
442         }
443
444         return false;
445     }
446 }
447
Popular Tags