OSDN Git Service

transaction begin
[moreemacs/moreemacs.git] / jp.sourceforge.moreemacs / src / jp / sourceforge / moreemacs / handlers / YankRectangleExecution.java
1 package jp.sourceforge.moreemacs.handlers;\r
2 \r
3 import java.util.List;\r
4 \r
5 import jp.sourceforge.moreemacs.utils.CodePointIterator;\r
6 import jp.sourceforge.moreemacs.utils.ColumnUtils;\r
7 import jp.sourceforge.moreemacs.utils.DocumentCharSequence;\r
8 import jp.sourceforge.moreemacs.utils.DocumentTransaction;\r
9 \r
10 import org.eclipse.jface.text.BadLocationException;\r
11 import org.eclipse.jface.text.IDocument;\r
12 import org.eclipse.jface.text.IRegion;\r
13 import org.eclipse.jface.text.TextUtilities;\r
14 \r
15 public final class YankRectangleExecution extends TextEditorExecution {\r
16     @Override\r
17     public void execute() throws BadLocationException {\r
18         if(!textEditor.isEditable()) {\r
19             return;\r
20         }\r
21         \r
22         List<String> rectangle = RectangleStorage.getRectangle();\r
23         if(rectangle == null) {\r
24             return;\r
25         }\r
26         \r
27         int current = cursor.offset();\r
28         int row = doc.getLineOfOffset(current);\r
29         int column = ColumnUtils.getColumn(doc, current, getTabStop());\r
30         \r
31         ensureLines(doc, row + rectangle.size());\r
32         \r
33         DocumentTransaction transaction = new DocumentTransaction(doc); \r
34         transaction.begin();\r
35         try {\r
36             yankRectangle(doc, row, column, rectangle);\r
37         } finally {\r
38             transaction.end();\r
39         }\r
40     }\r
41     \r
42     private void ensureLines(IDocument doc, int lines) throws BadLocationException {\r
43         int n = lines - doc.getNumberOfLines();\r
44         if(n <= 0) {\r
45             return;\r
46         }\r
47 \r
48         StringBuilder builder = new StringBuilder();\r
49         String delim = TextUtilities.getDefaultLineDelimiter(doc);\r
50         for(int i = 0; i < n; i++) {\r
51             builder.append(delim);\r
52         }\r
53         doc.replace(doc.getLength(), 0, builder.toString());\r
54         \r
55     }\r
56 \r
57     private void yankRectangle(IDocument doc,\r
58             int row, int column, List<String> rectangle)\r
59             throws BadLocationException {\r
60         for(int i = 0; i < rectangle.size(); i++) {\r
61             yankString(doc, row+i, column, rectangle.get(i));\r
62         }\r
63     }\r
64 \r
65     private void yankString(IDocument doc, int row, int column, String str)\r
66     throws BadLocationException\r
67     {\r
68         IRegion line = doc.getLineInformation(row);\r
69         int col = 0;\r
70 \r
71         CharSequence seq = new DocumentCharSequence(doc, line.getOffset(), line.getLength());\r
72         \r
73         for(CodePointIterator itr = new CodePointIterator(seq); itr.hasNext(); ) {\r
74             int offset = line.getOffset() + itr.index();\r
75             int codePoint = itr.next();\r
76             if(col >= column) {\r
77                 doc.replace(offset, 0, str);\r
78                 cursor.move(offset+str.length());\r
79                 return;\r
80             }\r
81             col = ColumnUtils.getNextColumn(col, codePoint, getTabStop());\r
82         }\r
83         \r
84 \r
85         StringBuilder builder = new StringBuilder();\r
86         for(int i = 0; i < column-col; i++) {\r
87             builder.append(" ");\r
88         }\r
89         builder.append(str);\r
90         doc.replace(line.getOffset()+line.getLength(), 0, builder.toString());\r
91         cursor.move(line.getOffset()+line.getLength()+builder.length());\r
92     }\r
93 \r
94 }\r
95 \r
96 \r