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