1 package org.catacomb.druid.xtext.canvas;
2
3
4 import org.catacomb.druid.xtext.base.*;
5 import org.catacomb.report.E;
6
7 import java.awt.event.KeyEvent;
8 import java.awt.event.KeyListener;
9
10
11 public class KeyWriter implements KeyListener {
12
13 TextBoard textBoard;
14
15 int keyCode;
16
17 TextBlock caretBlock;
18 int caretPos;
19
20
21 public KeyWriter(TextBoard tb) {
22 textBoard = tb;
23 }
24
25
26 public TextBlock getCaretBlock() {
27 return caretBlock;
28 }
29
30
31 public int getCaretPos() {
32 return caretPos;
33 }
34
35
36 public void setCaretBlock(TextBlock tb) {
37 caretBlock = tb;
38 }
39
40
41 public void setCaretPos(int ip) {
42 caretPos = ip;
43 }
44
45
46 public void keyPressed(KeyEvent e) {
47 keyCode = e.getKeyCode();
48 switch (keyCode) {
49 case KeyEvent.VK_LEFT:
50 caretLeft();
51 break;
52 case KeyEvent.VK_RIGHT:
53 caretRight();
54 break;
55 case KeyEvent.VK_UP:
56 caretUp();
57 break;
58 case KeyEvent.VK_DOWN:
59 caretDown();
60 break;
61 case KeyEvent.VK_BACK_SPACE:
62 deletBackwards();
63 break;
64
65 case KeyEvent.VK_ENTER:
66 newline();
67 break;
68
69 default:
70
71 }
72 }
73
74
75
76 public void keyTyped(KeyEvent e) {
77
78 if (e.isActionKey()) {
79 E.info("action key " + KeyEvent.getKeyText(keyCode));
80
81 } else {
82 char c = e.getKeyChar();
83 insertCharacter(c);
84 }
85 }
86
87
88 public void keyReleased(KeyEvent e) {
89
90 }
91
92
93
94 public void caretLeft() {
95 if (caretBlock == null) {
96 return;
97 }
98 if (caretPos > 0) {
99 caretPos -= 1;
100 } else {
101 TextBlock tb = caretBlock.previousTextBlock();
102 if (tb == null) {
103
104 } else {
105 caretBlock = tb;
106 caretPos = caretBlock.textLength() - 1;
107 }
108 }
109
110 textBoard.repaint();
111 }
112
113
114 public void caretRight() {
115 if (caretBlock == null) {
116 return;
117 }
118 if (caretPos < caretBlock.textLength()) {
119 caretPos += 1;
120 } else {
121 TextBlock tb = caretBlock.nextTextBlock();
122 if (tb == null) {
123
124 } else {
125 caretBlock = tb;
126 caretPos = 1;
127 }
128 }
129 textBoard.repaint();
130 }
131
132
133 public void caretUp() {
134 if (caretBlock == null) {
135 return;
136 }
137
138 }
139
140
141 public void caretDown() {
142 if (caretBlock == null) {
143 return;
144 }
145
146 }
147
148
149 public void insertCharacter(char c) {
150 String s = "" + c;
151 if (Character.isLetter(c)) {
152 insertLetter(c);
153 textBoard.repaint();
154
155 } else if (TextBoard.PUNCTUATION.indexOf(s) >= 0) {
156 insertPunctuation(c);
157 textBoard.repaint();
158
159 } else {
160
161 }
162 }
163
164
165
166 private void insertLetter(char c) {
167 if (caretBlock instanceof WordBlock) {
168 insertLetterInWord(caretBlock, c, caretPos);
169
170 } else {
171 if (caretPos == 0) {
172 insertLetterBeforeNonWord(caretBlock, c);
173
174 } else if (caretPos == caretBlock.textLength()) {
175 insertLetterAfterNonWord(caretBlock, c);
176
177 } else {
178 insertLetterInNonWord(caretBlock, c, caretPos);
179 }
180 }
181 }
182
183
184 private void insertLetterInWord(TextBlock tb, char c, int cp) {
185 tb.insertCharacter(c, cp);
186 caretBlock = tb;
187 caretPos = cp + 1;
188 }
189
190
191 private void insertLetterInNonWord(TextBlock tb, char c, int cp) {
192 WordBlock wb = new WordBlock();
193 wb.setText("" + c);
194 tb.insert(wb, cp);
195 caretBlock = wb;
196 caretPos = 1;
197 }
198
199
200 private void insertLetterBeforeNonWord(TextBlock tb, char c) {
201 TextBlock bpr = tb.previousTextBlock();
202 if (bpr instanceof WordBlock) {
203 insertLetterInWord(bpr, c, bpr.textLength());
204
205 } else {
206 addNewWordBlockAfter(bpr, c);
207 }
208 }
209
210
211 private void addNewWordBlockAfter(TextBlock bpr, char c) {
212 WordBlock wb = new WordBlock();
213 wb.setText("" + c);
214 Block bnx = bpr.next();
215 bpr.setNext(wb);
216 wb.setNext(bnx);
217 caretBlock = wb;
218 caretPos = 1;
219 }
220
221
222
223 private void insertLetterAfterNonWord(TextBlock tb, char c) {
224 TextBlock bnx = tb.nextTextBlock();
225 if (bnx instanceof WordBlock) {
226 insertLetterInWord(bnx, c, 0);
227
228 } else {
229 addNewWordBlockAfter(tb, c);
230 }
231 }
232
233
234
235 private void insertPuncInPunc(TextBlock tb, char c, int cp) {
236 tb.insertCharacter(c, cp);
237 caretBlock = tb;
238 caretPos = cp + 1;
239 }
240
241
242
243 private void insertPunctuation(char c) {
244 if (caretBlock instanceof PunctuationBlock) {
245 insertPuncInPunc(caretBlock, c, caretPos);
246
247 } else {
248 if (caretPos == 0) {
249 insertPuncBeforeNonPunc(caretBlock, c);
250
251 } else if (caretPos == caretBlock.textLength()) {
252 insertPuncAfterNonPunc(caretBlock, c);
253 } else {
254 insertPuncInNonPunc(caretBlock, c, caretPos);
255 }
256 }
257 }
258
259
260
261 private void insertPuncInNonPunc(TextBlock tb, char c, int cp) {
262 PunctuationBlock wb = new PunctuationBlock();
263 wb.setText("" + c);
264 tb.insert(wb, cp);
265 caretBlock = wb;
266 caretPos = 1;
267 }
268
269
270 private void insertPuncBeforeNonPunc(TextBlock tb, char c) {
271 TextBlock bpr = tb.previousTextBlock();
272 if (bpr instanceof PunctuationBlock) {
273 insertPuncInPunc(bpr, c, bpr.textLength());
274
275 } else {
276 addNewPuncBlockAfter(bpr, c);
277 }
278 }
279
280
281 private void addNewPuncBlockAfter(TextBlock bpr, char c) {
282 PunctuationBlock wb = new PunctuationBlock();
283 wb.setText("" + c);
284 Block bnx = bpr.next();
285 bpr.setNext(wb);
286 wb.setNext(bnx);
287 caretBlock = wb;
288 caretPos = 1;
289 }
290
291
292
293 private void insertPuncAfterNonPunc(TextBlock tb, char c) {
294 TextBlock bnx = tb.nextTextBlock();
295 if (bnx instanceof PunctuationBlock) {
296 insertPuncInPunc(bnx, c, 0);
297
298 } else {
299 addNewPuncBlockAfter(tb, c);
300 }
301 }
302
303
304
305 public void deletBackwards() {
306 if (caretPos == 0) {
307 TextBlock tb = caretBlock.previousTextBlock();
308 if (tb == null) {
309 return;
310
311 } else {
312 caretBlock = tb;
313 caretPos = caretBlock.textLength();
314 }
315 }
316
317 if (caretBlock.textLength() == 1) {
318 TextBlock tb = caretBlock.previousTextBlock();
319 int newPos = tb.textLength();
320 caretBlock.remove();
321 if (tb == null) {
322 caretBlock = textBoard.firstTextBlock();
323 caretPos = 0;
324 } else {
325 caretBlock = tb;
326 caretPos = newPos;
327 }
328
329 } else {
330 caretBlock.deleteCharBefore(caretPos);
331 caretPos -= 1;
332 }
333
334 textBoard.repaint();
335 }
336
337
338
339 private void newline() {
340 if (caretPos == 0) {
341 TextBlock tbp = caretBlock.previousTextBlock();
342 if (tbp != null) {
343 tbp.newlineAfter();
344 }
345
346 } else if (caretPos == caretBlock.textLength()) {
347 caretBlock.newlineAfter();
348 caretBlock = caretBlock.nextTextBlock();
349 caretPos = 1;
350
351 } else {
352 caretBlock.insertNewline(caretPos);
353 caretBlock = caretBlock.nextTextBlock();
354 caretPos = 1;
355 }
356 }
357
358
359
360 public boolean hasCaret() {
361 return (caretBlock != null);
362 }
363
364
365
366 }