PageRenderTime 96ms CodeModel.GetById 89ms app.highlight 3ms RepoModel.GetById 1ms app.codeStats 0ms

/jEdit/tags/jedit-4-0-pre3/macros/Text/Vertical_Paste.bsh

#
Unknown | 285 lines | 236 code | 49 blank | 0 comment | 0 complexity | 0af0412917b530ff102080278fa1c6f6 MD5 | raw file
  1/*
  2 * Vertical_Paste.bsh - a BeanShell macro script for the
  3 * jEdit text editor - Pastes the content of the clipboard
  4 * vertically and fills empty areas if necessary.
  5 * Copyright (c) 2001 Andre Kaplan, portions by Slava Pestov
  6 *
  7 * This program is free software; you can redistribute it and/or
  8 * modify it under the terms of the GNU General Public License
  9 * as published by the Free Software Foundation; either version 2
 10 * of the License, or any later version.
 11 *
 12 * This program is distributed in the hope that it will be useful,
 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 15 * GNU General Public License for more details.
 16 *
 17 * You should have received a copy of the GNU General Public License
 18 * along with this program; if not, write to the Free Software
 19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 20 *
 21 * Checked for jEeit 4.0 API
 22 *
 23 */
 24
 25import java.util.StringTokenizer;
 26import javax.swing.text.BadLocationException;
 27import javax.swing.text.Segment;
 28
 29import org.gjt.sp.jedit.*;
 30import org.gjt.sp.jedit.textarea.*;
 31import org.gjt.sp.util.Log;
 32
 33
 34// Fill empty areas to the left.
 35boolean leftFill  = true;
 36// Fill empty areas to the right.
 37boolean rightFill = true;
 38
 39
 40/**
 41 * Adapted from org.gjt.sp.jedit.gui.StatusBar.VICaretStatus.getVirtualPosition
 42 */
 43int physicalToVirtualLineOffset(int line, int physicalLineOffset) {
 44    Segment seg = new Segment();
 45    textArea.getLineText(line, seg);
 46
 47    int physicalPosition = 0;
 48    int virtualPosition  = 0;
 49    int tabSize = buffer.getTabSize();
 50
 51    for (; (physicalPosition < seg.count) && (physicalPosition < physicalLineOffset); ++physicalPosition) {
 52        char ch = seg.array[seg.offset + physicalPosition];
 53
 54        if (ch == '\t') {
 55            virtualPosition += tabSize
 56                - (virtualPosition % tabSize);
 57        } else {
 58            ++virtualPosition;
 59        }
 60    }
 61
 62    return virtualPosition;
 63}
 64
 65
 66ConversionIndicator() {
 67    type = 0;
 68    return this;
 69}
 70
 71
 72/**
 73 * Returns the virtual to physical line offset conversion.
 74 * The conversion indicator is set to:
 75 * <ul>
 76 *   <li>0 if the virtual line offset could be converted to a physical
 77 *       offset</li>
 78 *   <li>-1 if the virtual line offset is beyond the line end offset</li>
 79 *   <li>1 if the virtual could not be exactly converted to a physical
 80 *       offset due to the expansion of a tab</li>
 81 * </ul>
 82 */
 83int virtualToPhysicalLineOffset(int line, int virtualLineOffset, Object indicator) {
 84    Segment seg = new Segment();
 85    textArea.getLineText(line, seg);
 86
 87    int physicalPosition = 0;
 88    int virtualPosition  = 0;
 89    int tabSize = buffer.getTabSize();
 90
 91    for (; (physicalPosition < seg.count) && (virtualPosition < virtualLineOffset); ++physicalPosition) {
 92        char ch = seg.array[seg.offset + physicalPosition];
 93
 94        if (ch == '\t') {
 95            virtualPosition += tabSize
 96                - (virtualPosition % tabSize);
 97        } else {
 98            ++virtualPosition;
 99        }
100    }
101
102    if (virtualPosition < virtualLineOffset) {
103        indicator.type = -1;
104    } else if (virtualPosition == virtualLineOffset) {
105        indicator.type = 0;
106    } else {
107        indicator.type = 1;
108    }
109
110    return physicalPosition;
111}
112
113
114int getExpandedLength(String text, int virtualLineOffset) {
115    int len = text.length();
116    int virtualPosition  = virtualLineOffset;
117    int tabSize = buffer.getTabSize();
118
119    for (int i = 0; i < len; i++) {
120        char ch = text.charAt(i);
121
122        if (ch == '\t') {
123            virtualPosition += tabSize
124                - (virtualPosition % tabSize);
125        } else {
126            ++virtualPosition;
127        }
128    }
129
130    return (virtualPosition - virtualLineOffset);
131}
132
133
134void verticalPaste() {
135	/*
136	 * Guard for readonly files becuase Buffer.insert()
137	 * ignores the flag
138	 *
139	 */
140	if(buffer.isReadOnly())
141	{
142		Macros.error(view, "This file is read only.");
143		return;
144	}
145    String verticalText = Registers.getRegister('$').toString();
146
147    final int firstLine = textArea.getCaretLine();
148    final int firstPhysicalLineOffset = (
149          textArea.getCaretPosition()
150        - textArea.getLineStartOffset(firstLine)
151    );
152    final int firstVirtualLineOffset = physicalToVirtualLineOffset(
153        firstLine, firstPhysicalLineOffset
154    );
155
156    int minVirtualLineOffset = firstVirtualLineOffset;
157    int maxVirtualLineOffset = firstVirtualLineOffset;
158    StringTokenizer st = new StringTokenizer(verticalText, "\n");
159    int height = st.countTokens();
160
161    for (int line = firstLine; st.hasMoreTokens(); line++) {
162        String s = st.nextToken();
163        int virtualLineEndOffset = (
164              (line >= textArea.getLineCount())
165            ? 0
166            : physicalToVirtualLineOffset(line, textArea.getLineLength(line))
167        );
168        int virtualLineOffset = (
169              (leftFill)
170            ? firstVirtualLineOffset
171            : Math.min(firstVirtualLineOffset, virtualLineEndOffset)
172        );
173        int expandedLen = getExpandedLength(s, virtualLineOffset);
174
175        if (virtualLineOffset < minVirtualLineOffset) {
176            minVirtualLineOffset = virtualLineOffset;
177        }
178
179        if ((virtualLineOffset + expandedLen) > maxVirtualLineOffset) {
180            maxVirtualLineOffset = (virtualLineOffset + expandedLen);
181        }
182    }
183
184    try {
185        buffer.beginCompoundEdit();
186        st = new StringTokenizer(verticalText, "\n");
187
188        for (int line = firstLine; st.hasMoreTokens(); line++) {
189            String s = st.nextToken();
190
191            int virtualLineEndOffset = (
192                  (line >= textArea.getLineCount())
193                ? 0
194                : physicalToVirtualLineOffset(line, textArea.getLineLength(line))
195            );
196
197            int virtualLineOffset = (
198                  (leftFill)
199                ? firstVirtualLineOffset
200                : Math.min(firstVirtualLineOffset, virtualLineEndOffset)
201            );
202            int expandedLen = getExpandedLength(s, virtualLineOffset);
203
204            String leftSpacer  = "";
205            String rightSpacer = "";
206
207            int lineStartOffset;
208            int physicalLineOffset;
209
210            if (line >= textArea.getLineCount()) {
211                buffer.insert(
212                      textArea.getLineEndOffset(textArea.getLineCount() - 1) - 1
213                    , "\n"
214                );
215
216                lineStartOffset = textArea.getLineStartOffset(
217                    textArea.getLineCount() - 1
218                );
219                physicalLineOffset = 0;
220            } else {
221                lineStartOffset = textArea.getLineStartOffset(line);
222                Object indicator = ConversionIndicator();
223                physicalLineOffset = virtualToPhysicalLineOffset(
224                    line, virtualLineOffset, indicator
225                );
226
227                if (indicator.type == 1) {
228                    // A tab is in the way: prepend spaces
229                    int spacesToPrepend =
230                          virtualLineOffset
231                        - physicalToVirtualLineOffset(
232                            line, physicalLineOffset - 1
233                          );
234                    buffer.insert(
235                          lineStartOffset + physicalLineOffset - 1
236                        , MiscUtilities.createWhiteSpace(spacesToPrepend, 0)
237                    );
238
239                    physicalLineOffset--;
240                    physicalLineOffset += spacesToPrepend;
241                }
242            }
243
244            if (leftFill) {
245                if (virtualLineOffset > virtualLineEndOffset) {
246                    leftSpacer = MiscUtilities.createWhiteSpace(
247                        virtualLineOffset - virtualLineEndOffset, 0
248                    );
249                }
250            }
251
252            if (rightFill) {
253                if (maxVirtualLineOffset > (virtualLineOffset + expandedLen)) {
254                    rightSpacer = MiscUtilities.createWhiteSpace(
255                        maxVirtualLineOffset - (virtualLineOffset + expandedLen), 0
256                    );
257                }
258            }
259
260            buffer.insert(
261                  lineStartOffset + physicalLineOffset
262                , leftSpacer + s + rightSpacer
263            );
264        }
265    } catch (BadLocationException ble) {
266    } finally {
267        buffer.endCompoundEdit();
268    }
269}
270
271
272verticalPaste();
273
274/*
275	Macro index data (in DocBook format)
276
277<listitem>
278    <para><filename>Vertical_Paste.bsh</filename></para>
279    <abstract><para>
280		Pastes the content of the clipboard vertically and fills empty
281		areas if necessary.
282    </para></abstract>
283</listitem>
284
285*/