KickJava   Java API By Example, From Geeks To Geeks.

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


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.HashMap JavaDoc;
14 import java.util.Map JavaDoc;
15 import java.util.ResourceBundle JavaDoc;
16
17 import org.osgi.framework.Bundle;
18
19 import org.eclipse.swt.widgets.Shell;
20
21 import org.eclipse.core.commands.ExecutionException;
22 import org.eclipse.core.commands.operations.IOperationHistory;
23 import org.eclipse.core.commands.operations.IUndoableOperation;
24
25 import org.eclipse.core.runtime.IAdaptable;
26 import org.eclipse.core.runtime.ILog;
27 import org.eclipse.core.runtime.IStatus;
28 import org.eclipse.core.runtime.Platform;
29 import org.eclipse.core.runtime.Status;
30
31 import org.eclipse.core.resources.IResource;
32
33 import org.eclipse.jface.dialogs.IInputValidator;
34 import org.eclipse.jface.dialogs.InputDialog;
35 import org.eclipse.jface.window.Window;
36
37 import org.eclipse.jface.text.BadLocationException;
38 import org.eclipse.jface.text.IDocument;
39 import org.eclipse.jface.text.ITextSelection;
40
41 import org.eclipse.ui.IEditorInput;
42 import org.eclipse.ui.PlatformUI;
43 import org.eclipse.ui.ide.undo.CreateMarkersOperation;
44
45
46 /**
47  * Action for creating a marker of a specified type for the editor's
48  * input element based on the editor's selection. If required, the
49  * action asks the user to provide a marker label. The action is initially
50  * associated with a text editor via the constructor, but that can be
51  * subsequently changed using <code>setEditor</code>.
52  * <p>
53  * The following keys, prepended by the given option prefix,
54  * are used for retrieving resources from the given bundle:
55  * <ul>
56  * <li><code>"dialog.title"</code> - the input dialog's title</li>
57  * <li><code>"dialog.message"</code> - the input dialog's message</li>
58  * <li><code>"error.dialog.title"</code> - the error dialog's title</li>
59  * <li><code>"error.dialog.message"</code> - the error dialog's message</li>
60  * </ul>
61  * This class may be instantiated but is not intended to be subclassed.
62  * </p>
63  */

64 public class AddMarkerAction extends TextEditorAction {
65
66
67     /** The maximum length of an proposed label. */
68     private static final int MAX_LABEL_LENGTH= 80;
69     /** The type for newly created markers. */
70     private String JavaDoc fMarkerType;
71     /** Should the user be asked for a label? */
72     private boolean fAskForLabel;
73     /** The action's resource bundle. */
74     private ResourceBundle JavaDoc fBundle;
75     /** The prefix used for resource bundle lookup. */
76     private String JavaDoc fPrefix;
77
78
79     /**
80      * Creates a new action for the given text editor. The action configures its
81      * visual representation from the given resource bundle.
82      *
83      * @param bundle the resource bundle
84      * @param prefix a prefix to be prepended to the various resource keys
85      * (described in <code>ResourceAction</code> constructor), or
86      * <code>null</code> if none
87      * @param textEditor the text editor
88      * @param markerType the type of marker to add
89      * @param askForLabel <code>true</code> if the user should be asked for
90      * a label for the new marker
91      * @see TextEditorAction#TextEditorAction(ResourceBundle, String, ITextEditor)
92      */

93     public AddMarkerAction(ResourceBundle JavaDoc bundle, String JavaDoc prefix, ITextEditor textEditor, String JavaDoc markerType, boolean askForLabel) {
94         super(bundle, prefix, textEditor);
95         fBundle= bundle;
96         fPrefix= prefix;
97         fMarkerType= markerType;
98         fAskForLabel= askForLabel;
99     }
100
101     /**
102      * Returns this action's resource bundle.
103      *
104      * @return this action's resource bundle
105      */

106     protected ResourceBundle JavaDoc getResourceBundle() {
107         return fBundle;
108     }
109
110     /**
111      * Returns this action's resource key prefix.
112      *
113      * @return this action's resource key prefix
114      */

115     protected String JavaDoc getResourceKeyPrefix() {
116         return fPrefix;
117     }
118
119     /*
120      * @see IAction#run()
121      */

122     public void run() {
123         IResource resource= getResource();
124         if (resource == null)
125             return;
126         Map JavaDoc attributes= getInitialAttributes();
127         if (fAskForLabel) {
128             if (!askForLabel(attributes))
129                 return;
130         }
131         
132         String JavaDoc name= getToolTipText();
133         name= name == null ? TextEditorMessages.AddMarkerAction_addMarker : name;
134         
135         final Shell shell= getTextEditor().getSite().getShell();
136         IAdaptable context= new IAdaptable() {
137             public Object JavaDoc getAdapter(Class JavaDoc adapter) {
138                 if (adapter == Shell.class)
139                     return shell;
140                 return null;
141             }
142         };
143
144         IUndoableOperation operation= new CreateMarkersOperation(fMarkerType, attributes, resource, name);
145         IOperationHistory operationHistory= PlatformUI.getWorkbench().getOperationSupport().getOperationHistory();
146         try {
147             operationHistory.execute(operation, null, context);
148         } catch (ExecutionException x) {
149             Bundle JavaDoc bundle= Platform.getBundle(PlatformUI.PLUGIN_ID);
150             ILog log= Platform.getLog(bundle);
151             String JavaDoc msg= getString(fBundle, fPrefix + "error.dialog.message", fPrefix + "error.dialog.message"); //$NON-NLS-2$ //$NON-NLS-1$
152
log.log(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, IStatus.OK, msg, x));
153         }
154     }
155
156     /*
157      * @see TextEditorAction#update()
158      */

159     public void update() {
160         setEnabled(getResource() != null);
161     }
162
163     /**
164      * Asks the user for a marker label. Returns <code>true</code> if a label
165      * is entered, <code>false</code> if the user cancels the input dialog.
166      * The value for the attribute <code>message</code> is modified in the given
167      * attribute map.
168      *
169      * @param attributes the attributes map
170      * @return <code>true</code> if a label has been entered
171      */

172     protected boolean askForLabel(Map JavaDoc attributes) {
173
174         Object JavaDoc o= attributes.get("message"); //$NON-NLS-1$
175
String JavaDoc proposal= (o instanceof String JavaDoc) ? (String JavaDoc) o : ""; //$NON-NLS-1$
176
if (proposal == null)
177             proposal= ""; //$NON-NLS-1$
178

179         String JavaDoc title= getString(fBundle, fPrefix + "dialog.title", fPrefix + "dialog.title"); //$NON-NLS-2$ //$NON-NLS-1$
180
String JavaDoc message= getString(fBundle, fPrefix + "dialog.message", fPrefix + "dialog.message"); //$NON-NLS-2$ //$NON-NLS-1$
181
IInputValidator inputValidator= new IInputValidator() {
182             public String JavaDoc isValid(String JavaDoc newText) {
183                 return (newText == null || newText.trim().length() == 0) ? " " : null; //$NON-NLS-1$
184
}
185         };
186         InputDialog dialog= new InputDialog(getTextEditor().getSite().getShell(), title, message, proposal, inputValidator);
187
188         String JavaDoc label= null;
189         if (dialog.open() != Window.CANCEL)
190             label= dialog.getValue();
191
192         if (label == null)
193             return false;
194
195         label= label.trim();
196         if (label.length() == 0)
197             return false;
198
199         attributes.put("message", label); //$NON-NLS-1$
200
return true;
201     }
202
203     /**
204      * Returns the attributes the new marker will be initialized with.
205      * <p>
206      * Subclasses may extend or replace this method.</p>
207      *
208      * @return the attributes the new marker will be initialized with
209      */

210     protected Map JavaDoc getInitialAttributes() {
211
212         Map JavaDoc attributes= new HashMap JavaDoc(11);
213
214         ITextSelection selection= (ITextSelection) getTextEditor().getSelectionProvider().getSelection();
215         if (!selection.isEmpty()) {
216
217             int start= selection.getOffset();
218             int length= selection.getLength();
219
220             if (length < 0) {
221                 length= -length;
222                 start -= length;
223             }
224
225             MarkerUtilities.setCharStart(attributes, start);
226             MarkerUtilities.setCharEnd(attributes, start + length);
227
228             // marker line numbers are 1-based
229
int line= selection.getStartLine();
230             MarkerUtilities.setLineNumber(attributes, line == -1 ? -1 : line + 1);
231
232             IDocument document= getTextEditor().getDocumentProvider().getDocument(getTextEditor().getEditorInput());
233             MarkerUtilities.setMessage(attributes, getLabelProposal(document, start, length));
234
235         }
236
237         return attributes;
238     }
239
240     /**
241      * Returns the initial label for the marker.
242      *
243      * @param document the document from which to extract a label proposal
244      * @param offset the document offset of the range from which to extract the label proposal
245      * @param length the length of the range from which to extract the label proposal
246      * @return the label proposal
247      */

248     protected String JavaDoc getLabelProposal(IDocument document, int offset, int length) {
249
250
251         try {
252
253
254             if (length > 0) {
255
256                 // find first white char but skip leading white chars
257
int i= 0;
258                 boolean skip= true;
259                 while (i < length) {
260                     boolean isWhitespace= Character.isWhitespace(document.getChar(offset + i));
261                     if (!skip && isWhitespace)
262                         break;
263                     if (skip && !isWhitespace)
264                         skip= false;
265                     i++;
266                 }
267
268                 String JavaDoc label= document.get(offset, i);
269                 return label.trim();
270             }
271
272
273             char ch;
274
275             // Get the first white char before the selection.
276
int left= offset;
277
278             int line= document.getLineOfOffset(offset);
279             int limit= document.getLineOffset(line);
280
281             while (left > limit) {
282                 ch= document.getChar(left);
283                 if (Character.isWhitespace(ch))
284                     break;
285                 --left;
286             }
287
288             limit += document.getLineLength(line);
289
290             // Now get the first letter.
291
while (left <= limit) {
292                 ch= document.getChar(left);
293                 if (!Character.isWhitespace(ch))
294                     break;
295                 ++left;
296             }
297
298             if (left > limit)
299                 return null;
300
301             limit= Math.min(limit, left + MAX_LABEL_LENGTH);
302
303             // Get the next white char.
304
int right= (offset + length > limit ? limit : offset + length);
305             while (right < limit) {
306                 ch= document.getChar(right);
307                 if (Character.isWhitespace(ch))
308                     break;
309                 ++right;
310             }
311
312             // Trim the string and return it.
313
if (left != right) {
314                 String JavaDoc label= document.get(left, right - left);
315                 return label.trim();
316             }
317
318         } catch (BadLocationException x) {
319             // don't proposal label then
320
}
321
322         return null;
323     }
324
325     /**
326      * Returns the resource on which to create the marker,
327      * or <code>null</code> if there is no applicable resource. This
328      * queries the editor's input using <code>getAdapter(IResource.class)</code>.
329      * Subclasses may override this method.
330      *
331      * @return the resource to which to attach the newly created marker
332      */

333     protected IResource getResource() {
334         ITextEditor editor= getTextEditor();
335         if (editor != null) {
336             IEditorInput input= editor.getEditorInput();
337             return (IResource) ((IAdaptable) input).getAdapter(IResource.class);
338         }
339         return null;
340     }
341 }
342
Popular Tags