001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 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.lang.reflect.InvocationTargetException;
013: import java.util.Map;
014: import java.util.MissingResourceException;
015: import java.util.ResourceBundle;
016:
017: import org.eclipse.core.runtime.IProgressMonitor;
018: import org.eclipse.core.runtime.NullProgressMonitor;
019:
020: import org.eclipse.swt.custom.BusyIndicator;
021: import org.eclipse.swt.widgets.Shell;
022:
023: import org.eclipse.jface.dialogs.ProgressMonitorDialog;
024: import org.eclipse.jface.operation.IRunnableWithProgress;
025: import org.eclipse.jface.text.BadLocationException;
026: import org.eclipse.jface.text.IDocument;
027: import org.eclipse.jface.text.IRegion;
028: import org.eclipse.jface.text.IRewriteTarget;
029: import org.eclipse.jface.text.TextUtilities;
030:
031: /**
032: * An action to convert line delimiters of a text editor document to a
033: * particular line delimiter.
034: *
035: * @since 2.0
036: * @deprecated since 3.1. Line delimiter conversion has been modified to work on groups of files rather than being editor specific
037: */
038: public class ConvertLineDelimitersAction extends TextEditorAction {
039:
040: /** The target line delimiter. */
041: private final String fLineDelimiter;
042:
043: /**
044: * Creates a line delimiter conversion action.
045: *
046: * @param editor the editor
047: * @param lineDelimiter the target line delimiter to convert the editor's document to
048: */
049: public ConvertLineDelimitersAction(ITextEditor editor,
050: String lineDelimiter) {
051: this (EditorMessages.getBundleForConstructedKeys(),
052: "dummy", editor, lineDelimiter); //$NON-NLS-1$
053: }
054:
055: /**
056: * Creates a line delimiter conversion action.
057: *
058: * @param bundle the resource bundle
059: * @param prefix the prefix for the resource bundle lookup
060: * @param editor the editor
061: * @param lineDelimiter the target line delimiter to convert the editor's document to
062: */
063: public ConvertLineDelimitersAction(ResourceBundle bundle,
064: String prefix, ITextEditor editor, String lineDelimiter) {
065: super (bundle, prefix, editor);
066: fLineDelimiter = lineDelimiter;
067:
068: String platformLineDelimiter = System
069: .getProperty("line.separator"); //$NON-NLS-1$
070: setText(getString(getLabelKey(fLineDelimiter,
071: platformLineDelimiter)));
072:
073: update();
074: }
075:
076: /*
077: * @see org.eclipse.jface.action.Action#run()
078: */
079: public void run() {
080:
081: try {
082:
083: ITextEditor editor = getTextEditor();
084: if (editor == null)
085: return;
086:
087: if (!validateEditorInputState())
088: return;
089:
090: Object adapter = editor.getAdapter(IRewriteTarget.class);
091: if (adapter instanceof IRewriteTarget) {
092:
093: IRewriteTarget target = (IRewriteTarget) adapter;
094: IDocument document = target.getDocument();
095: if (document != null) {
096: Shell shell = getTextEditor().getSite().getShell();
097: ConvertRunnable runnable = new ConvertRunnable(
098: target, fLineDelimiter);
099:
100: if (document.getNumberOfLines() < 40) {
101: BusyIndicator.showWhile(shell.getDisplay(),
102: runnable);
103:
104: } else {
105: ProgressMonitorDialog dialog = new ProgressMonitorDialog(
106: shell);
107: dialog.run(false, true, runnable);
108: }
109: }
110: }
111:
112: } catch (InterruptedException e) {
113: // action canceled
114: } catch (InvocationTargetException e) {
115: // should not happen
116: }
117: }
118:
119: /**
120: * A runnable that converts all line delimiters of a document to <code>lineDelimiter</code>.
121: */
122: private static class ConvertRunnable implements
123: IRunnableWithProgress, Runnable {
124:
125: /** The rewrite target */
126: private final IRewriteTarget fRewriteTarget;
127: /** The line delimiter to which to convert to */
128: private final String fLineDelimiter;
129:
130: /**
131: * Returns a new runnable for converting all line delimiters in
132: * the <code>rewriteTarget</code> to <code>lineDelimter</code>.
133: * @param rewriteTarget
134: * @param lineDelimiter
135: */
136: public ConvertRunnable(IRewriteTarget rewriteTarget,
137: String lineDelimiter) {
138: fRewriteTarget = rewriteTarget;
139: fLineDelimiter = lineDelimiter;
140: }
141:
142: /*
143: * @see IRunnableWithProgress#run(org.eclipse.core.runtime.IProgressMonitor)
144: */
145: public void run(IProgressMonitor monitor)
146: throws InvocationTargetException, InterruptedException {
147:
148: IDocument document = fRewriteTarget.getDocument();
149: final int lineCount = document.getNumberOfLines();
150: monitor.beginTask(
151: EditorMessages.Editor_ConvertLineDelimiter_title,
152: lineCount);
153:
154: final boolean isLargeUpdate = lineCount > 50;
155: if (isLargeUpdate)
156: fRewriteTarget.setRedraw(false);
157: fRewriteTarget.beginCompoundChange();
158:
159: Map partitioners = TextUtilities
160: .removeDocumentPartitioners(document);
161:
162: try {
163: for (int i = 0; i < lineCount; i++) {
164: if (monitor.isCanceled())
165: throw new InterruptedException();
166:
167: final String delimiter = document
168: .getLineDelimiter(i);
169: if (delimiter != null && delimiter.length() > 0
170: && !delimiter.equals(fLineDelimiter)) {
171: IRegion region = document.getLineInformation(i);
172: document.replace(region.getOffset()
173: + region.getLength(), delimiter
174: .length(), fLineDelimiter);
175: }
176:
177: monitor.worked(1);
178: }
179:
180: } catch (BadLocationException e) {
181: throw new InvocationTargetException(e);
182:
183: } finally {
184:
185: if (partitioners != null)
186: TextUtilities.addDocumentPartitioners(document,
187: partitioners);
188:
189: fRewriteTarget.endCompoundChange();
190: if (isLargeUpdate)
191: fRewriteTarget.setRedraw(true);
192:
193: monitor.done();
194: }
195: }
196:
197: /*
198: * @see Runnable#run()
199: */
200: public void run() {
201: try {
202: run(new NullProgressMonitor());
203:
204: } catch (InterruptedException e) {
205: // should not happen
206:
207: } catch (InvocationTargetException e) {
208: // should not happen
209: }
210: }
211: }
212:
213: // /**
214: // * Returns whether the given document uses only the given line delimiter.
215: // * @param document the document to check
216: // * @param lineDelimiter the line delimiter to check for
217: // */
218: // private static boolean usesLineDelimiterExclusively(IDocument document, String lineDelimiter) {
219: //
220: // try {
221: // final int lineCount= document.getNumberOfLines();
222: // for (int i= 0; i < lineCount; i++) {
223: // final String delimiter= document.getLineDelimiter(i);
224: // if (delimiter != null && delimiter.length() > 0 && !delimiter.equals(lineDelimiter))
225: // return false;
226: // }
227: //
228: // } catch (BadLocationException e) {
229: // return false;
230: // }
231: //
232: // return true;
233: // }
234:
235: /**
236: * Computes and returns the key to be used to lookup the action's label in
237: * its resource bundle.
238: *
239: * @param lineDelimiter the line delimiter
240: * @param platformLineDelimiter the platform line delimiter
241: * @return the key used to lookup the action's label
242: */
243: private static String getLabelKey(String lineDelimiter,
244: String platformLineDelimiter) {
245: if (lineDelimiter.equals(platformLineDelimiter)) {
246:
247: if (lineDelimiter.equals("\r\n")) //$NON-NLS-1$
248: return "Editor.ConvertLineDelimiter.toWindows.default.label"; //$NON-NLS-1$
249:
250: if (lineDelimiter.equals("\n")) //$NON-NLS-1$
251: return "Editor.ConvertLineDelimiter.toUNIX.default.label"; //$NON-NLS-1$
252:
253: if (lineDelimiter.equals("\r")) //$NON-NLS-1$
254: return "Editor.ConvertLineDelimiter.toMac.default.label"; //$NON-NLS-1$
255:
256: } else {
257:
258: if (lineDelimiter.equals("\r\n")) //$NON-NLS-1$
259: return "Editor.ConvertLineDelimiter.toWindows.label"; //$NON-NLS-1$
260:
261: if (lineDelimiter.equals("\n")) //$NON-NLS-1$
262: return "Editor.ConvertLineDelimiter.toUNIX.label"; //$NON-NLS-1$
263:
264: if (lineDelimiter.equals("\r")) //$NON-NLS-1$
265: return "Editor.ConvertLineDelimiter.toMac.label"; //$NON-NLS-1$
266: }
267:
268: return null;
269: }
270:
271: /*
272: * @since 3.1
273: */
274: private static String getString(String key) {
275: try {
276: return EditorMessages.getBundleForConstructedKeys()
277: .getString(key);
278: } catch (MissingResourceException e) {
279: return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$
280: }
281: }
282:
283: /*
284: * @see IUpdate#update()
285: */
286: public void update() {
287: super.update();
288: setEnabled(canModifyEditor());
289: }
290:
291: }
|