001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.texteditor;
011:
012: import java.util.ResourceBundle;
013:
014: import org.eclipse.swt.widgets.Shell;
015:
016: import org.eclipse.jface.dialogs.IDialogSettings;
017: import org.eclipse.jface.dialogs.IInputValidator;
018: import org.eclipse.jface.dialogs.InputDialog;
019: import org.eclipse.jface.window.Window;
020:
021: import org.eclipse.jface.text.BadLocationException;
022: import org.eclipse.jface.text.IDocument;
023:
024: import org.eclipse.ui.IWorkbenchPage;
025: import org.eclipse.ui.internal.texteditor.NLSUtility;
026: import org.eclipse.ui.internal.texteditor.TextEditorPlugin;
027:
028: /**
029: * Action for jumping to a particular line in the editor's text viewer.
030: * The user is requested to enter the line number into an input dialog.
031: * The action is initially associated with a text editor via the constructor,
032: * but that can be subsequently changed using <code>setEditor</code>.
033: * <p>
034: * The following keys, prepended by the given option prefix,
035: * are used for retrieving resources from the given bundle:
036: * <ul>
037: * <li><code>"dialog.invalid_range"</code> - to indicate an invalid line number</li>
038: * <li><code>"dialog.invalid_input"</code> - to indicate an invalid line number format</li>
039: * <li><code>"dialog.title"</code> - the input dialog's title</li>
040: * <li><code>"dialog.message"</code> - the input dialog's message</li>
041: * </ul></p>
042: * <p>
043: * This class may be instantiated; it is not intended to be subclassed.
044: * </p>
045: */
046: public class GotoLineAction extends TextEditorAction {
047:
048: /**
049: * Validates whether the text found in the input field of the
050: * dialog forms a valid line number. A number is valid if it is
051: * one to which can be jumped.
052: */
053: class NumberValidator implements IInputValidator {
054:
055: /*
056: * @see IInputValidator#isValid(String)
057: */
058: public String isValid(String input) {
059:
060: if (input == null || input.length() == 0)
061: return " "; //$NON-NLS-1$
062:
063: try {
064: int i = Integer.parseInt(input);
065: if (i <= 0 || fLastLine < i)
066: return fBundle.getString(fPrefix
067: + "dialog.invalid_range"); //$NON-NLS-1$
068:
069: } catch (NumberFormatException x) {
070: return fBundle.getString(fPrefix
071: + "dialog.invalid_input"); //$NON-NLS-1$
072: }
073:
074: return null;
075: }
076: }
077:
078: /**
079: * Standard input dialog with custom dialog bounds
080: * strategy and settings.
081: *
082: * @since 2.0
083: */
084: static class GotoLineDialog extends InputDialog {
085:
086: /*
087: * @see InputDialog#InputDialog(org.eclipse.swt.widgets.Shell, java.lang.String, java.lang.String, java.lang.String, org.eclipse.jface.dialogs.IInputValidator)
088: */
089: public GotoLineDialog(Shell parent, String title,
090: String message, String initialValue,
091: IInputValidator validator) {
092: super (parent, title, message, initialValue, validator);
093: }
094:
095: /*
096: * @see org.eclipse.jface.dialogs.Dialog#getDialogBoundsSettings()
097: * @since 3.2
098: */
099: protected IDialogSettings getDialogBoundsSettings() {
100: String sectionName = getClass().getName() + "_dialogBounds"; //$NON-NLS-1$
101: IDialogSettings settings = TextEditorPlugin.getDefault()
102: .getDialogSettings();
103: IDialogSettings section = settings.getSection(sectionName);
104: if (section == null)
105: section = settings.addNewSection(sectionName);
106: return section;
107: }
108:
109: /*
110: * @see org.eclipse.jface.dialogs.Dialog#getDialogBoundsStrategy()
111: * @since 3.2
112: */
113: protected int getDialogBoundsStrategy() {
114: return DIALOG_PERSISTLOCATION;
115: }
116: }
117:
118: /** The biggest valid line number of the presented document */
119: private int fLastLine;
120: /** This action's resource bundle */
121: private ResourceBundle fBundle;
122: /** This action's prefix used for accessing the resource bundle */
123: private String fPrefix;
124:
125: /**
126: * Creates a new action for the given text editor. The action configures its
127: * visual representation from the given resource bundle.
128: *
129: * @param bundle the resource bundle
130: * @param prefix a prefix to be prepended to the various resource keys
131: * (described in <code>ResourceAction</code> constructor), or
132: * <code>null</code> if none
133: * @param editor the text editor
134: * @see TextEditorAction#TextEditorAction(ResourceBundle, String, ITextEditor)
135: */
136: public GotoLineAction(ResourceBundle bundle, String prefix,
137: ITextEditor editor) {
138: super (bundle, prefix, editor);
139: fBundle = bundle;
140: fPrefix = prefix;
141: }
142:
143: /**
144: * Jumps to the given line.
145: *
146: * @param line the line to jump to
147: */
148: private void gotoLine(int line) {
149:
150: ITextEditor editor = getTextEditor();
151:
152: IDocumentProvider provider = editor.getDocumentProvider();
153: IDocument document = provider.getDocument(editor
154: .getEditorInput());
155: try {
156:
157: int start = document.getLineOffset(line);
158: editor.selectAndReveal(start, 0);
159:
160: IWorkbenchPage page = editor.getSite().getPage();
161: page.activate(editor);
162:
163: } catch (BadLocationException x) {
164: // ignore
165: }
166: }
167:
168: /*
169: * @see Action#run()
170: */
171: public void run() {
172: try {
173:
174: ITextEditor editor = getTextEditor();
175:
176: if (editor == null)
177: return;
178:
179: IDocumentProvider docProvider = editor
180: .getDocumentProvider();
181: if (docProvider == null)
182: return;
183:
184: IDocument document = docProvider.getDocument(editor
185: .getEditorInput());
186: if (document == null)
187: return;
188:
189: fLastLine = document.getLineOfOffset(document.getLength()) + 1;
190:
191: String title = fBundle.getString(fPrefix + "dialog.title"); //$NON-NLS-1$
192: String message = NLSUtility
193: .format(fBundle.getString(fPrefix
194: + "dialog.message"), new Integer(fLastLine)); //$NON-NLS-1$
195:
196: GotoLineDialog d = new GotoLineDialog(editor.getSite()
197: .getShell(), title, message,
198: "", new NumberValidator()); //$NON-NLS-1$
199: if (d.open() == Window.OK) {
200: try {
201: int line = Integer.parseInt(d.getValue());
202: gotoLine(line - 1);
203: } catch (NumberFormatException x) {
204: }
205: }
206:
207: } catch (BadLocationException x) {
208: }
209: }
210: }
|