001: /*******************************************************************************
002: * Copyright (c) 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: * Benjamin Muskalla - initial API and implementation - https://bugs.eclipse.org/bugs/show_bug.cgi?id=41573
010: *******************************************************************************/package org.eclipse.ui.texteditor;
011:
012: import java.util.ResourceBundle;
013:
014: import org.eclipse.core.runtime.Assert;
015:
016: import org.eclipse.jface.viewers.ISelection;
017: import org.eclipse.jface.viewers.ISelectionProvider;
018:
019: import org.eclipse.jface.text.BadLocationException;
020: import org.eclipse.jface.text.IDocument;
021: import org.eclipse.jface.text.ITextSelection;
022:
023: /**
024: * Action for joining two or more lines together by deleting the
025: * line delimiters and trimming the whitespace between them.
026: *
027: * @since 3.3
028: */
029: public class JoinLinesAction extends TextEditorAction {
030:
031: private String fJoint = null;
032:
033: /**
034: * Creates a line joining action.
035: *
036: * @param bundle the resource bundle for UI strings
037: * @param prefix the prefix for the property keys into <code>bundle</code>
038: * @param editor the editor
039: * @param joint the string to put between the lines
040: */
041: public JoinLinesAction(ResourceBundle bundle, String prefix,
042: ITextEditor editor, String joint) {
043: super (bundle, prefix, editor);
044: Assert.isLegal(joint != null);
045: fJoint = joint;
046: update();
047: }
048:
049: /*
050: * @see org.eclipse.jface.action.Action#run()
051: */
052: public void run() {
053:
054: ITextEditor editor = getTextEditor();
055: if (editor == null)
056: return;
057:
058: if (!validateEditorInputState())
059: return;
060:
061: IDocument document = getDocument(editor);
062: if (document == null)
063: return;
064:
065: ITextSelection selection = getSelection(editor);
066: if (selection == null)
067: return;
068:
069: int startLine = selection.getStartLine();
070: int endLine = selection.getEndLine();
071: try {
072: int caretOffset = joinLines(document, startLine, endLine);
073: if (caretOffset > -1)
074: editor.selectAndReveal(caretOffset, 0);
075: } catch (BadLocationException e) {
076: // should not happen
077: }
078:
079: }
080:
081: /**
082: * Returns the editor's document.
083: *
084: * @param editor the editor
085: * @return the editor's document
086: */
087: private static IDocument getDocument(ITextEditor editor) {
088:
089: IDocumentProvider documentProvider = editor
090: .getDocumentProvider();
091: if (documentProvider == null)
092: return null;
093:
094: IDocument document = documentProvider.getDocument(editor
095: .getEditorInput());
096: if (document == null)
097: return null;
098:
099: return document;
100: }
101:
102: /**
103: * Returns the editor's selection.
104: *
105: * @param editor the editor
106: * @return the editor's selection
107: */
108: private static ITextSelection getSelection(ITextEditor editor) {
109:
110: ISelectionProvider selectionProvider = editor
111: .getSelectionProvider();
112: if (selectionProvider == null)
113: return null;
114:
115: ISelection selection = selectionProvider.getSelection();
116: if (!(selection instanceof ITextSelection))
117: return null;
118:
119: return (ITextSelection) selection;
120: }
121:
122: /*
123: * @see org.eclipse.ui.texteditor.TextEditorAction#update()
124: */
125: public void update() {
126: super .update();
127: if (!isEnabled())
128: return;
129:
130: if (!canModifyEditor()) {
131: setEnabled(false);
132: return;
133: }
134:
135: ITextEditor editor = getTextEditor();
136: setEnabled(editor.isEditable());
137: }
138:
139: /**
140: * Joins several text lines to one line.
141: *
142: * @param document the document
143: * @param startLine the start line
144: * @param endLine the end line
145: * @return the new caret offset
146: * @throws BadLocationException
147: */
148: private int joinLines(IDocument document, int startLine, int endLine)
149: throws BadLocationException {
150: if (startLine == document.getNumberOfLines() - 1) {
151: // do nothing because we are in the last line
152: return -1;
153: }
154:
155: if (startLine == endLine)
156: endLine++; // append join with the next line
157:
158: StringBuffer buffer = new StringBuffer();
159: for (int line = startLine; line <= endLine; line++) {
160: buffer.append(trim(document, line, line == startLine));
161: if (line != endLine)
162: buffer.append(fJoint);
163: }
164:
165: int startLineOffset = document.getLineOffset(startLine);
166: int endLineOffset = document.getLineOffset(endLine)
167: + document.getLineLength(endLine)
168: - getLineDelimiterLength(document, endLine);
169: String replaceString = buffer.toString();
170: document.replace(startLineOffset, endLineOffset
171: - startLineOffset, replaceString);
172: return startLineOffset + replaceString.length();
173: }
174:
175: private String trim(IDocument document, int line,
176: boolean ignoreLeadingWhitespace)
177: throws BadLocationException {
178: int lineOffset = document.getLineOffset(line);
179: int lineLength = document.getLineLength(line);
180: lineLength = lineLength
181: - getLineDelimiterLength(document, line);
182: if (!ignoreLeadingWhitespace)
183: return document.get(lineOffset, lineLength).trim();
184:
185: while (lineLength > 0
186: && Character.isWhitespace(document.getChar(lineOffset
187: + lineLength - 1)))
188: lineLength--;
189:
190: return document.get(lineOffset, lineLength);
191: }
192:
193: private int getLineDelimiterLength(IDocument document, int line)
194: throws BadLocationException {
195: String lineDelimiter = document.getLineDelimiter(line);
196: return lineDelimiter != null ? lineDelimiter.length() : 0;
197:
198: }
199:
200: }
|