1
2
3
4
5
6
7
8
9
10 package org.syntax.jedit;
11
12 import java.awt.Component;
13 import java.awt.event.ActionEvent;
14 import java.awt.event.ActionListener;
15 import java.awt.event.KeyAdapter;
16 import java.awt.event.KeyEvent;
17 import java.util.Enumeration;
18 import java.util.EventObject;
19 import java.util.Hashtable;
20
21 import javax.swing.AbstractAction;
22 import javax.swing.Action;
23 import javax.swing.JPopupMenu;
24 import javax.swing.text.BadLocationException;
25
26 import com.eviware.soapui.support.UISupport;
27
28 /***
29 * An input handler converts the user's key strokes into concrete actions.
30 * It also takes care of macro recording and action repetition.<p>
31 *
32 * This class provides all the necessary support code for an input
33 * handler, but doesn't actually do any key binding logic. It is up
34 * to the implementations of this class to do so.
35 *
36 * @author Slava Pestov
37 * @version $Id$
38 * @see org.syntax.jedit.DefaultInputHandler
39 *
40 * 08/12/2002 Clipboard actions (Oliver Henning)
41 */
42 public abstract class InputHandler extends KeyAdapter
43 {
44 /***
45 * If this client property is set to Boolean.TRUE on the text area,
46 * the home/end keys will support 'smart' BRIEF-like behaviour
47 * (one press = start/end of line, two presses = start/end of
48 * viewscreen, three presses = start/end of document). By default,
49 * this property is not set.
50 */
51 public static final String SMART_HOME_END_PROPERTY = "InputHandler.homeEnd";
52
53 public static final ActionListener BACKSPACE = new backspace();
54 public static final ActionListener BACKSPACE_WORD = new backspace_word();
55 public static final ActionListener DELETE = new delete();
56 public static final ActionListener DELETE_WORD = new delete_word();
57 public static final ActionListener END = new end(false);
58 public static final ActionListener DOCUMENT_END = new document_end(false);
59 public static final ActionListener SELECT_ALL = new select_all();
60 public static final ActionListener SELECT_END = new end(true);
61 public static final ActionListener SELECT_DOC_END = new document_end(true);
62 public static final ActionListener INSERT_BREAK = new insert_break();
63 public static final ActionListener INSERT_TAB = new insert_tab();
64 public static final ActionListener HOME = new home(false);
65 public static final ActionListener DOCUMENT_HOME = new document_home(false);
66 public static final ActionListener SELECT_HOME = new home(true);
67 public static final ActionListener SELECT_DOC_HOME = new document_home(true);
68 public static final ActionListener NEXT_CHAR = new next_char(false);
69 public static final ActionListener NEXT_LINE = new next_line(false);
70 public static final ActionListener NEXT_PAGE = new next_page(false);
71 public static final ActionListener NEXT_WORD = new next_word(false);
72 public static final ActionListener SELECT_NEXT_CHAR = new next_char(true);
73 public static final ActionListener SELECT_NEXT_LINE = new next_line(true);
74 public static final ActionListener SELECT_NEXT_PAGE = new next_page(true);
75 public static final ActionListener SELECT_NEXT_WORD = new next_word(true);
76 public static final ActionListener OVERWRITE = new overwrite();
77 public static final ActionListener PREV_CHAR = new prev_char(false);
78 public static final ActionListener PREV_LINE = new prev_line(false);
79 public static final ActionListener PREV_PAGE = new prev_page(false);
80 public static final ActionListener PREV_WORD = new prev_word(false);
81 public static final ActionListener SELECT_PREV_CHAR = new prev_char(true);
82 public static final ActionListener SELECT_PREV_LINE = new prev_line(true);
83 public static final ActionListener SELECT_PREV_PAGE = new prev_page(true);
84 public static final ActionListener SELECT_PREV_WORD = new prev_word(true);
85 public static final ActionListener REPEAT = new repeat();
86 public static final ActionListener TOGGLE_RECT = new toggle_rect();
87
88 public static final Action CLIP_COPY = new clip_copy();
89 public static final Action CLIP_PASTE = new clip_paste();
90 public static final Action CLIP_CUT = new clip_cut();
91
92
93 public static final ActionListener INSERT_CHAR = new insert_char();
94
95 private static Hashtable<String,ActionListener> actions;
96
97 static
98 {
99 actions = new Hashtable<String,ActionListener>();
100 actions.put("backspace",BACKSPACE);
101 actions.put("backspace-word",BACKSPACE_WORD);
102 actions.put("delete",DELETE);
103 actions.put("delete-word",DELETE_WORD);
104 actions.put("end",END);
105 actions.put("select-all",SELECT_ALL);
106 actions.put("select-end",SELECT_END);
107 actions.put("document-end",DOCUMENT_END);
108 actions.put("select-doc-end",SELECT_DOC_END);
109 actions.put("insert-break",INSERT_BREAK);
110 actions.put("insert-tab",INSERT_TAB);
111 actions.put("home",HOME);
112 actions.put("select-home",SELECT_HOME);
113 actions.put("document-home",DOCUMENT_HOME);
114 actions.put("select-doc-home",SELECT_DOC_HOME);
115 actions.put("next-char",NEXT_CHAR);
116 actions.put("next-line",NEXT_LINE);
117 actions.put("next-page",NEXT_PAGE);
118 actions.put("next-word",NEXT_WORD);
119 actions.put("select-next-char",SELECT_NEXT_CHAR);
120 actions.put("select-next-line",SELECT_NEXT_LINE);
121 actions.put("select-next-page",SELECT_NEXT_PAGE);
122 actions.put("select-next-word",SELECT_NEXT_WORD);
123 actions.put("overwrite",OVERWRITE);
124 actions.put("prev-char",PREV_CHAR);
125 actions.put("prev-line",PREV_LINE);
126 actions.put("prev-page",PREV_PAGE);
127 actions.put("prev-word",PREV_WORD);
128 actions.put("select-prev-char",SELECT_PREV_CHAR);
129 actions.put("select-prev-line",SELECT_PREV_LINE);
130 actions.put("select-prev-page",SELECT_PREV_PAGE);
131 actions.put("select-prev-word",SELECT_PREV_WORD);
132 actions.put("repeat",REPEAT);
133 actions.put("toggle-rect",TOGGLE_RECT);
134 actions.put("insert-char",INSERT_CHAR);
135 actions.put("clipboard-copy",CLIP_COPY);
136 actions.put("clipboard-paste",CLIP_PASTE);
137 actions.put("clipboard-cut",CLIP_CUT);
138 }
139
140 /***
141 * Returns a named text area action.
142 * @param name The action name
143 */
144 public static ActionListener getAction(String name)
145 {
146 return (ActionListener)actions.get(name);
147 }
148
149 /***
150 * Returns the name of the specified text area action.
151 * @param listener The action
152 */
153 public static String getActionName(ActionListener listener)
154 {
155 Enumeration _enum = getActions();
156 while(_enum.hasMoreElements())
157 {
158 String name = (String)_enum.nextElement();
159 ActionListener _listener = getAction(name);
160 if(_listener == listener)
161 return name;
162 }
163 return null;
164 }
165
166 /***
167 * Returns an enumeration of all available actions.
168 */
169 public static Enumeration getActions()
170 {
171 return actions.keys();
172 }
173
174 /***
175 * Adds the default key bindings to this input handler.
176 * This should not be called in the constructor of this
177 * input handler, because applications might load the
178 * key bindings from a file, etc.
179 */
180 public abstract void addDefaultKeyBindings();
181
182 /***
183 * Adds a key binding to this input handler.
184 * @param keyBinding The key binding (the format of this is
185 * input-handler specific)
186 * @param action The action
187 */
188 public abstract void addKeyBinding(String keyBinding, ActionListener action);
189
190 /***
191 * Removes a key binding from this input handler.
192 * @param keyBinding The key binding
193 */
194 public abstract void removeKeyBinding(String keyBinding);
195
196 /***
197 * Removes all key bindings from this input handler.
198 */
199 public abstract void removeAllKeyBindings();
200
201 /***
202 * Grabs the next key typed event and invokes the specified
203 * action with the key as a the action command.
204 * @param action The action
205 */
206 public void grabNextKeyStroke(ActionListener listener)
207 {
208 grabAction = listener;
209 }
210
211 /***
212 * Returns if repeating is enabled. When repeating is enabled,
213 * actions will be executed multiple times. This is usually
214 * invoked with a special key stroke in the input handler.
215 */
216 public boolean isRepeatEnabled()
217 {
218 return repeat;
219 }
220
221 /***
222 * Enables repeating. When repeating is enabled, actions will be
223 * executed multiple times. Once repeating is enabled, the input
224 * handler should read a number from the keyboard.
225 */
226 public void setRepeatEnabled(boolean repeat)
227 {
228 this.repeat = repeat;
229 }
230
231 /***
232 * Returns the number of times the next action will be repeated.
233 */
234 public int getRepeatCount()
235 {
236 return (repeat ? Math.max(1,repeatCount) : 1);
237 }
238
239 /***
240 * Sets the number of times the next action will be repeated.
241 * @param repeatCount The repeat count
242 */
243 public void setRepeatCount(int repeatCount)
244 {
245 this.repeatCount = repeatCount;
246 }
247
248 /***
249 * Returns the macro recorder. If this is non-null, all executed
250 * actions should be forwarded to the recorder.
251 */
252 public InputHandler.MacroRecorder getMacroRecorder()
253 {
254 return recorder;
255 }
256
257 /***
258 * Sets the macro recorder. If this is non-null, all executed
259 * actions should be forwarded to the recorder.
260 * @param recorder The macro recorder
261 */
262 public void setMacroRecorder(InputHandler.MacroRecorder recorder)
263 {
264 this.recorder = recorder;
265 }
266
267 /***
268 * Returns a copy of this input handler that shares the same
269 * key bindings. Setting key bindings in the copy will also
270 * set them in the original.
271 */
272 public abstract InputHandler copy();
273
274 /***
275 * Executes the specified action, repeating and recording it as
276 * necessary.
277 * @param listener The action listener
278 * @param source The event source
279 * @param actionCommand The action command
280 */
281 public void executeAction(ActionListener listener, Object source,
282 String actionCommand)
283 {
284
285 ActionEvent evt = new ActionEvent(source,
286 ActionEvent.ACTION_PERFORMED,
287 actionCommand);
288
289
290
291 if(listener instanceof Wrapper)
292 {
293 listener.actionPerformed(evt);
294 return;
295 }
296
297
298 boolean _repeat = repeat;
299 int _repeatCount = getRepeatCount();
300
301
302 if(listener instanceof InputHandler.NonRepeatable)
303 listener.actionPerformed(evt);
304 else
305 {
306 for(int i = 0; i < Math.max(1,repeatCount); i++)
307 listener.actionPerformed(evt);
308 }
309
310
311
312 if(grabAction == null)
313 {
314 if(recorder != null)
315 {
316 if(!(listener instanceof InputHandler.NonRecordable))
317 {
318 if(_repeatCount != 1)
319 recorder.actionPerformed(REPEAT,String.valueOf(_repeatCount));
320
321 recorder.actionPerformed(listener,actionCommand);
322 }
323 }
324
325
326
327 if(_repeat)
328 {
329 repeat = false;
330 repeatCount = 0;
331 }
332 }
333 }
334
335 /***
336 * Returns the text area that fired the specified event.
337 * @param evt The event
338 */
339 public static JEditTextArea getTextArea(EventObject evt)
340 {
341 if(evt != null)
342 {
343 Object o = evt.getSource();
344 if(o instanceof Component)
345 {
346
347 Component c = (Component)o;
348 for(;;)
349 {
350 if(c instanceof JEditTextArea)
351 return (JEditTextArea)c;
352 else if(c == null)
353 break;
354 if(c instanceof JPopupMenu)
355 c = ((JPopupMenu)c)
356 .getInvoker();
357 else
358 c = c.getParent();
359 }
360 }
361 }
362
363
364 System.err.println("BUG: getTextArea() returning null");
365 System.err.println("Report this to Slava Pestov <sp@gjt.org>");
366 return null;
367 }
368
369
370
371 /***
372 * If a key is being grabbed, this method should be called with
373 * the appropriate key event. It executes the grab action with
374 * the typed character as the parameter.
375 */
376 protected void handleGrabAction(KeyEvent evt)
377 {
378
379
380 ActionListener _grabAction = grabAction;
381 grabAction = null;
382 executeAction(_grabAction,evt.getSource(),
383 String.valueOf(evt.getKeyChar()));
384 }
385
386
387 protected ActionListener grabAction;
388 protected boolean repeat;
389 protected int repeatCount;
390 protected InputHandler.MacroRecorder recorder;
391
392 /***
393 * If an action implements this interface, it should not be repeated.
394 * Instead, it will handle the repetition itself.
395 */
396 public interface NonRepeatable {}
397
398 /***
399 * If an action implements this interface, it should not be recorded
400 * by the macro recorder. Instead, it will do its own recording.
401 */
402 public interface NonRecordable {}
403
404 /***
405 * For use by EditAction.Wrapper only.
406 * @since jEdit 2.2final
407 */
408 public interface Wrapper {}
409
410 /***
411 * Macro recorder.
412 */
413 public interface MacroRecorder
414 {
415 void actionPerformed(ActionListener listener,
416 String actionCommand);
417 }
418
419 public static class backspace implements ActionListener
420 {
421 public void actionPerformed(ActionEvent evt)
422 {
423 JEditTextArea textArea = getTextArea(evt);
424
425 if(!textArea.isEditable())
426 {
427 textArea.getToolkit().beep();
428 return;
429 }
430
431 if(textArea.getSelectionStart()
432 != textArea.getSelectionEnd())
433 {
434 textArea.setSelectedText("");
435 }
436 else
437 {
438 int caret = textArea.getCaretPosition();
439 if(caret == 0)
440 {
441 textArea.getToolkit().beep();
442 return;
443 }
444 try
445 {
446 textArea.getDocument().remove(caret - 1,1);
447 }
448 catch(BadLocationException bl)
449 {
450 bl.printStackTrace();
451 }
452 }
453 }
454 }
455
456 public static class backspace_word implements ActionListener
457 {
458 public void actionPerformed(ActionEvent evt)
459 {
460 JEditTextArea textArea = getTextArea(evt);
461 int start = textArea.getSelectionStart();
462 if(start != textArea.getSelectionEnd())
463 {
464 textArea.setSelectedText("");
465 }
466
467 int line = textArea.getCaretLine();
468 int lineStart = textArea.getLineStartOffset(line);
469 int caret = start - lineStart;
470
471 String lineText = textArea.getLineText(textArea
472 .getCaretLine());
473
474 if(caret == 0)
475 {
476 if(lineStart == 0)
477 {
478 textArea.getToolkit().beep();
479 return;
480 }
481 caret--;
482 }
483 else
484 {
485 String noWordSep = (String)textArea.getDocument().getProperty("noWordSep");
486 caret = TextUtilities.findWordStart(lineText,caret,noWordSep);
487 }
488
489 try
490 {
491 textArea.getDocument().remove(
492 caret + lineStart,
493 start - (caret + lineStart));
494 }
495 catch(BadLocationException bl)
496 {
497 bl.printStackTrace();
498 }
499 }
500 }
501
502 public static class delete implements ActionListener
503 {
504 public void actionPerformed(ActionEvent evt)
505 {
506 JEditTextArea textArea = getTextArea(evt);
507
508 if(!textArea.isEditable())
509 {
510 textArea.getToolkit().beep();
511 return;
512 }
513
514 if(textArea.getSelectionStart()
515 != textArea.getSelectionEnd())
516 {
517 textArea.setSelectedText("");
518 }
519 else
520 {
521 int caret = textArea.getCaretPosition();
522 if(caret == textArea.getDocumentLength())
523 {
524 textArea.getToolkit().beep();
525 return;
526 }
527 try
528 {
529 textArea.getDocument().remove(caret,1);
530 }
531 catch(BadLocationException bl)
532 {
533 bl.printStackTrace();
534 }
535 }
536 }
537 }
538
539 public static class delete_word implements ActionListener
540 {
541 public void actionPerformed(ActionEvent evt)
542 {
543 JEditTextArea textArea = getTextArea(evt);
544 int start = textArea.getSelectionStart();
545 if(start != textArea.getSelectionEnd())
546 {
547 textArea.setSelectedText("");
548 }
549
550 int line = textArea.getCaretLine();
551 int lineStart = textArea.getLineStartOffset(line);
552 int caret = start - lineStart;
553
554 String lineText = textArea.getLineText(textArea
555 .getCaretLine());
556
557 if(caret == lineText.length())
558 {
559 if(lineStart + caret == textArea.getDocumentLength())
560 {
561 textArea.getToolkit().beep();
562 return;
563 }
564 caret++;
565 }
566 else
567 {
568 String noWordSep = (String)textArea.getDocument().getProperty("noWordSep");
569 caret = TextUtilities.findWordEnd(lineText,caret,noWordSep);
570 }
571
572 try
573 {
574 textArea.getDocument().remove(start,
575 (caret + lineStart) - start);
576 }
577 catch(BadLocationException bl)
578 {
579 bl.printStackTrace();
580 }
581 }
582 }
583
584 public static class end implements ActionListener
585 {
586 private boolean select;
587
588 public end(boolean select)
589 {
590 this.select = select;
591 }
592
593 public void actionPerformed(ActionEvent evt)
594 {
595 JEditTextArea textArea = getTextArea(evt);
596
597 int caret = textArea.getCaretPosition();
598
599 int lastOfLine = textArea.getLineEndOffset(
600 textArea.getCaretLine()) - 1;
601 int lastVisibleLine = textArea.getFirstLine()
602 + textArea.getVisibleLines();
603 if(lastVisibleLine >= textArea.getLineCount())
604 {
605 lastVisibleLine = Math.min(textArea.getLineCount() - 1,
606 lastVisibleLine);
607 }
608 else
609 lastVisibleLine -= 1;
610
611 int lastVisible = textArea.getLineEndOffset(lastVisibleLine) - 1;
612 int lastDocument = textArea.getDocumentLength();
613
614 if(caret == lastDocument)
615 {
616 textArea.getToolkit().beep();
617 return;
618 }
619 else if(!Boolean.TRUE.equals(textArea.getClientProperty(
620 SMART_HOME_END_PROPERTY)))
621 caret = lastOfLine;
622 else if(caret == lastVisible)
623 caret = lastDocument;
624 else if(caret == lastOfLine)
625 caret = lastVisible;
626 else
627 caret = lastOfLine;
628
629 if(select)
630 textArea.select(textArea.getMarkPosition(),caret);
631 else
632 textArea.setCaretPosition(caret);
633 }
634 }
635
636 public static class select_all implements ActionListener {
637 public void actionPerformed(ActionEvent evt)
638 {
639 JEditTextArea textArea = getTextArea(evt);
640 textArea.selectAll();
641 }
642 }
643
644 public static class document_end implements ActionListener
645 {
646 private boolean select;
647
648 public document_end(boolean select)
649 {
650 this.select = select;
651 }
652
653 public void actionPerformed(ActionEvent evt)
654 {
655 JEditTextArea textArea = getTextArea(evt);
656 if(select)
657 textArea.select(textArea.getMarkPosition(),
658 textArea.getDocumentLength());
659 else
660 textArea.setCaretPosition(textArea
661 .getDocumentLength());
662 }
663 }
664
665 public static class home implements ActionListener
666 {
667 private boolean select;
668
669 public home(boolean select)
670 {
671 this.select = select;
672 }
673
674 public void actionPerformed(ActionEvent evt)
675 {
676 JEditTextArea textArea = getTextArea(evt);
677
678 int caret = textArea.getCaretPosition();
679
680 int firstLine = textArea.getFirstLine();
681
682 int firstOfLine = textArea.getLineStartOffset(
683 textArea.getCaretLine());
684 int firstVisibleLine = (firstLine == 0 ? 0 :
685 firstLine + 1 );
686 int firstVisible = textArea.getLineStartOffset(
687 firstVisibleLine);
688
689 if(caret == 0)
690 {
691 textArea.getToolkit().beep();
692 return;
693 }
694 else if(!Boolean.TRUE.equals(textArea.getClientProperty(
695 SMART_HOME_END_PROPERTY)))
696 caret = firstOfLine;
697 else if(caret == firstVisible)
698 caret = 0;
699 else if(caret == firstOfLine)
700 caret = firstVisible;
701 else
702 caret = firstOfLine;
703
704 if(select)
705 textArea.select(textArea.getMarkPosition(),caret);
706 else
707 textArea.setCaretPosition(caret);
708 }
709 }
710
711 public static class document_home implements ActionListener
712 {
713 private boolean select;
714
715 public document_home(boolean select)
716 {
717 this.select = select;
718 }
719
720 public void actionPerformed(ActionEvent evt)
721 {
722 JEditTextArea textArea = getTextArea(evt);
723 if(select)
724 textArea.select(textArea.getMarkPosition(),0);
725 else
726 textArea.setCaretPosition(0);
727 }
728 }
729
730 public static class insert_break implements ActionListener
731 {
732 public void actionPerformed(ActionEvent evt)
733 {
734 JEditTextArea textArea = getTextArea(evt);
735
736 if(!textArea.isEditable())
737 {
738 textArea.getToolkit().beep();
739 return;
740 }
741
742 textArea.setSelectedText("\n");
743 }
744 }
745
746 public static class insert_tab implements ActionListener
747 {
748 public void actionPerformed(ActionEvent evt)
749 {
750 JEditTextArea textArea = getTextArea(evt);
751
752 if(!textArea.isEditable())
753 {
754 textArea.getToolkit().beep();
755 return;
756 }
757
758 textArea.overwriteSetSelectedText("\t");
759 }
760 }
761
762 public static class next_char implements ActionListener
763 {
764 private boolean select;
765
766 public next_char(boolean select)
767 {
768 this.select = select;
769 }
770
771 public void actionPerformed(ActionEvent evt)
772 {
773 JEditTextArea textArea = getTextArea(evt);
774 int caret = textArea.getCaretPosition();
775 if(caret == textArea.getDocumentLength())
776 {
777 textArea.getToolkit().beep();
778 return;
779 }
780
781 if(select)
782 textArea.select(textArea.getMarkPosition(),
783 caret + 1);
784 else
785 textArea.setCaretPosition(caret + 1);
786 }
787 }
788
789 public static class next_line implements ActionListener
790 {
791 private boolean select;
792
793 public next_line(boolean select)
794 {
795 this.select = select;
796 }
797
798 public void actionPerformed(ActionEvent evt)
799 {
800 JEditTextArea textArea = getTextArea(evt);
801 int caret = textArea.getCaretPosition();
802 int line = textArea.getCaretLine();
803
804 if(line == textArea.getLineCount() - 1)
805 {
806 textArea.getToolkit().beep();
807 return;
808 }
809
810 int magic = textArea.getMagicCaretPosition();
811 if(magic == -1)
812 {
813 magic = textArea.offsetToX(line,
814 caret - textArea.getLineStartOffset(line));
815 }
816
817 caret = textArea.getLineStartOffset(line + 1)
818 + textArea.xToOffset(line + 1,magic);
819 if(select)
820 textArea.select(textArea.getMarkPosition(),caret);
821 else
822 textArea.setCaretPosition(caret);
823 textArea.setMagicCaretPosition(magic);
824 }
825 }
826
827 public static class next_page implements ActionListener
828 {
829 private boolean select;
830
831 public next_page(boolean select)
832 {
833 this.select = select;
834 }
835
836 public void actionPerformed(ActionEvent evt)
837 {
838 JEditTextArea textArea = getTextArea(evt);
839 int lineCount = textArea.getLineCount();
840 int firstLine = textArea.getFirstLine();
841 int visibleLines = textArea.getVisibleLines();
842 int line = textArea.getCaretLine();
843
844 firstLine += visibleLines;
845
846 if(firstLine + visibleLines >= lineCount - 1)
847 firstLine = lineCount - visibleLines;
848
849 textArea.setFirstLine(firstLine);
850
851 int caret = textArea.getLineStartOffset(
852 Math.min(textArea.getLineCount() - 1,
853 line + visibleLines));
854 if(select)
855 textArea.select(textArea.getMarkPosition(),caret);
856 else
857 textArea.setCaretPosition(caret);
858 }
859 }
860
861 public static class next_word implements ActionListener
862 {
863 private boolean select;
864
865 public next_word(boolean select)
866 {
867 this.select = select;
868 }
869
870 public void actionPerformed(ActionEvent evt)
871 {
872 JEditTextArea textArea = getTextArea(evt);
873 int caret = textArea.getCaretPosition();
874 int line = textArea.getCaretLine();
875 int lineStart = textArea.getLineStartOffset(line);
876 caret -= lineStart;
877
878 String lineText = textArea.getLineText(textArea
879 .getCaretLine());
880
881 if(caret == lineText.length())
882 {
883 if(lineStart + caret == textArea.getDocumentLength())
884 {
885 textArea.getToolkit().beep();
886 return;
887 }
888 caret++;
889 }
890 else
891 {
892 String noWordSep = (String)textArea.getDocument().getProperty("noWordSep");
893 caret = TextUtilities.findWordEnd(lineText,caret,noWordSep);
894 }
895
896 if(select)
897 textArea.select(textArea.getMarkPosition(),
898 lineStart + caret);
899 else
900 textArea.setCaretPosition(lineStart + caret);
901 }
902 }
903
904 public static class overwrite implements ActionListener
905 {
906 public void actionPerformed(ActionEvent evt)
907 {
908 JEditTextArea textArea = getTextArea(evt);
909 textArea.setOverwriteEnabled(
910 !textArea.isOverwriteEnabled());
911 }
912 }
913
914 public static class prev_char implements ActionListener
915 {
916 private boolean select;
917
918 public prev_char(boolean select)
919 {
920 this.select = select;
921 }
922
923 public void actionPerformed(ActionEvent evt)
924 {
925 JEditTextArea textArea = getTextArea(evt);
926 int caret = textArea.getCaretPosition();
927 if(caret == 0)
928 {
929 textArea.getToolkit().beep();
930 return;
931 }
932
933 if(select)
934 textArea.select(textArea.getMarkPosition(),
935 caret - 1);
936 else
937 textArea.setCaretPosition(caret - 1);
938 }
939 }
940
941 public static class prev_line implements ActionListener
942 {
943 private boolean select;
944
945 public prev_line(boolean select)
946 {
947 this.select = select;
948 }
949
950 public void actionPerformed(ActionEvent evt)
951 {
952 JEditTextArea textArea = getTextArea(evt);
953 int caret = textArea.getCaretPosition();
954 int line = textArea.getCaretLine();
955
956 if(line == 0)
957 {
958 textArea.getToolkit().beep();
959 return;
960 }
961
962 int magic = textArea.getMagicCaretPosition();
963 if(magic == -1)
964 {
965 magic = textArea.offsetToX(line,
966 caret - textArea.getLineStartOffset(line));
967 }
968
969 caret = textArea.getLineStartOffset(line - 1)
970 + textArea.xToOffset(line - 1,magic);
971 if(select)
972 textArea.select(textArea.getMarkPosition(),caret);
973 else
974 textArea.setCaretPosition(caret);
975 textArea.setMagicCaretPosition(magic);
976 }
977 }
978
979 public static class prev_page implements ActionListener
980 {
981 private boolean select;
982
983 public prev_page(boolean select)
984 {
985 this.select = select;
986 }
987
988 public void actionPerformed(ActionEvent evt)
989 {
990 JEditTextArea textArea = getTextArea(evt);
991 int firstLine = textArea.getFirstLine();
992 int visibleLines = textArea.getVisibleLines();
993 int line = textArea.getCaretLine();
994
995 if(firstLine < visibleLines)
996 firstLine = visibleLines;
997
998 textArea.setFirstLine(firstLine - visibleLines);
999
1000 int caret = textArea.getLineStartOffset(
1001 Math.max(0,line - visibleLines));
1002 if(select)
1003 textArea.select(textArea.getMarkPosition(),caret);
1004 else
1005 textArea.setCaretPosition(caret);
1006 }
1007 }
1008
1009 public static class prev_word implements ActionListener
1010 {
1011 private boolean select;
1012
1013 public prev_word(boolean select)
1014 {
1015 this.select = select;
1016 }
1017
1018 public void actionPerformed(ActionEvent evt)
1019 {
1020 JEditTextArea textArea = getTextArea(evt);
1021 int caret = textArea.getCaretPosition();
1022 int line = textArea.getCaretLine();
1023 int lineStart = textArea.getLineStartOffset(line);
1024 caret -= lineStart;
1025
1026 String lineText = textArea.getLineText(textArea
1027 .getCaretLine());
1028
1029 if(caret == 0)
1030 {
1031 if(lineStart == 0)
1032 {
1033 textArea.getToolkit().beep();
1034 return;
1035 }
1036 caret--;
1037 }
1038 else
1039 {
1040 String noWordSep = (String)textArea.getDocument().getProperty("noWordSep");
1041 caret = TextUtilities.findWordStart(lineText,caret,noWordSep);
1042 }
1043
1044 if(select)
1045 textArea.select(textArea.getMarkPosition(),
1046 lineStart + caret);
1047 else
1048 textArea.setCaretPosition(lineStart + caret);
1049 }
1050 }
1051
1052 public static class repeat implements ActionListener,
1053 InputHandler.NonRecordable
1054 {
1055 public void actionPerformed(ActionEvent evt)
1056 {
1057 JEditTextArea textArea = getTextArea(evt);
1058 textArea.getInputHandler().setRepeatEnabled(true);
1059 String actionCommand = evt.getActionCommand();
1060 if(actionCommand != null)
1061 {
1062 textArea.getInputHandler().setRepeatCount(
1063 Integer.parseInt(actionCommand));
1064 }
1065 }
1066 }
1067
1068 public static class toggle_rect implements ActionListener
1069 {
1070 public void actionPerformed(ActionEvent evt)
1071 {
1072 JEditTextArea textArea = getTextArea(evt);
1073 textArea.setSelectionRectangular(
1074 !textArea.isSelectionRectangular());
1075 }
1076 }
1077
1078 public static class insert_char implements ActionListener,
1079 InputHandler.NonRepeatable
1080 {
1081 public void actionPerformed(ActionEvent evt)
1082 {
1083 JEditTextArea textArea = getTextArea(evt);
1084 String str = evt.getActionCommand();
1085 int repeatCount = textArea.getInputHandler().getRepeatCount();
1086
1087 if(textArea.isEditable())
1088 {
1089 StringBuffer buf = new StringBuffer();
1090 for(int i = 0; i < repeatCount; i++)
1091 buf.append(str);
1092 textArea.overwriteSetSelectedText(buf.toString());
1093 }
1094 else
1095 {
1096 textArea.getToolkit().beep();
1097 }
1098 }
1099 }
1100
1101 public static class clip_copy extends AbstractAction {
1102
1103 public clip_copy()
1104 {
1105 super( "Copy" );
1106 putValue( Action.ACCELERATOR_KEY, UISupport.getKeyStroke( "menu C" ));
1107 }
1108
1109 public void actionPerformed(ActionEvent evt)
1110 {
1111 JEditTextArea textArea = getTextArea(evt);
1112 textArea.copy();
1113 }
1114 }
1115
1116 public static class clip_paste extends AbstractAction {
1117
1118 public clip_paste()
1119 {
1120 super( "Paste" );
1121 putValue( Action.ACCELERATOR_KEY, UISupport.getKeyStroke( "menu V" ));
1122 }
1123
1124 public void actionPerformed(ActionEvent evt)
1125 {
1126 JEditTextArea textArea = getTextArea(evt);
1127 textArea.paste();
1128 }
1129 }
1130
1131 public static class clip_cut extends AbstractAction {
1132
1133 public clip_cut()
1134 {
1135 super( "Cut" );
1136 putValue( Action.ACCELERATOR_KEY, UISupport.getKeyStroke( "menu X" ));
1137 }
1138
1139 public void actionPerformed(ActionEvent evt)
1140 {
1141 JEditTextArea textArea = getTextArea(evt);
1142 textArea.cut();
1143 }
1144 }
1145 }