Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.utils / src / main / java / org / gvsig / utils / console / jedit / InputHandler.java @ 40561

History | View | Annotate | Download (27.2 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.utils.console.jedit;
25
/*
26
 * InputHandler.java - Manages key bindings and executes actions
27
 * Copyright (C) 1999 Slava Pestov
28
 *
29
 * You may use and modify this package for any purpose. Redistribution is
30
 * permitted, in both source and binary form, provided that this notice
31
 * remains intact in all source distributions of this package.
32
 */
33

    
34
import java.awt.Component;
35
import java.awt.event.ActionEvent;
36
import java.awt.event.ActionListener;
37
import java.awt.event.KeyAdapter;
38
import java.awt.event.KeyEvent;
39
import java.util.Enumeration;
40
import java.util.EventObject;
41
import java.util.Hashtable;
42

    
43
import javax.swing.JPopupMenu;
44
import javax.swing.text.BadLocationException;
45

    
46
/**
47
 * An input handler converts the user's key strokes into concrete actions.
48
 * It also takes care of macro recording and action repetition.<p>
49
 *
50
 * This class provides all the necessary support code for an input
51
 * handler, but doesn't actually do any key binding logic. It is up
52
 * to the implementations of this class to do so.
53
 *
54
 * @author Slava Pestov
55
 * @version $Id$
56
 * @see org.gjt.sp.jedit.textarea.DefaultInputHandler
57
 */
58
public abstract class InputHandler extends KeyAdapter
59
{
60
        /**
61
         * If this client property is set to Boolean.TRUE on the text area,
62
         * the home/end keys will support 'smart' BRIEF-like behaviour
63
         * (one press = start/end of line, two presses = start/end of
64
         * viewscreen, three presses = start/end of document). By default,
65
         * this property is not set.
66
         */
67
        public static final String SMART_HOME_END_PROPERTY = "InputHandler.homeEnd";
68

    
69
        public static final ActionListener BACKSPACE = new backspace();
70
        public static final ActionListener BACKSPACE_WORD = new backspace_word();
71
        public static final ActionListener DELETE = new delete();
72
        public static final ActionListener DELETE_WORD = new delete_word();
73
        public static final ActionListener END = new end(false);
74
        public static final ActionListener DOCUMENT_END = new document_end(false);
75
        public static final ActionListener SELECT_END = new end(true);
76
        public static final ActionListener SELECT_DOC_END = new document_end(true);
77
        public static final ActionListener INSERT_BREAK = new insert_break();
78
        public static final ActionListener INSERT_TAB = new insert_tab();
79
        public static final ActionListener HOME = new home(false);
80
        public static final ActionListener DOCUMENT_HOME = new document_home(false);
81
        public static final ActionListener SELECT_HOME = new home(true);
82
        public static final ActionListener SELECT_DOC_HOME = new document_home(true);
83
        public static final ActionListener NEXT_CHAR = new next_char(false);
84
        public static final ActionListener NEXT_LINE = new next_line(false);
85
        public static final ActionListener NEXT_PAGE = new next_page(false);
86
        public static final ActionListener NEXT_WORD = new next_word(false);
87
        public static final ActionListener SELECT_NEXT_CHAR = new next_char(true);
88
        public static final ActionListener SELECT_NEXT_LINE = new next_line(true);
89
        public static final ActionListener SELECT_NEXT_PAGE = new next_page(true);
90
        public static final ActionListener SELECT_NEXT_WORD = new next_word(true);
91
        public static final ActionListener OVERWRITE = new overwrite();
92
        public static final ActionListener PREV_CHAR = new prev_char(false);
93
        public static final ActionListener PREV_LINE = new prev_line(false);
94
        public static final ActionListener PREV_PAGE = new prev_page(false);
95
        public static final ActionListener PREV_WORD = new prev_word(false);
96
        public static final ActionListener SELECT_PREV_CHAR = new prev_char(true);
97
        public static final ActionListener SELECT_PREV_LINE = new prev_line(true);
98
        public static final ActionListener SELECT_PREV_PAGE = new prev_page(true);
99
        public static final ActionListener SELECT_PREV_WORD = new prev_word(true);
100
        public static final ActionListener REPEAT = new repeat();
101
        public static final ActionListener TOGGLE_RECT = new toggle_rect();
102

    
103
        // Default action
104
        public static final ActionListener INSERT_CHAR = new insert_char();
105

    
106
        private static Hashtable actions;
107

    
108
        static
109
        {
110
                actions = new Hashtable();
111
                actions.put("backspace",BACKSPACE);
112
                actions.put("backspace-word",BACKSPACE_WORD);
113
                actions.put("delete",DELETE);
114
                actions.put("delete-word",DELETE_WORD);
115
                actions.put("end",END);
116
                actions.put("select-end",SELECT_END);
117
                actions.put("document-end",DOCUMENT_END);
118
                actions.put("select-doc-end",SELECT_DOC_END);
119
                actions.put("insert-break",INSERT_BREAK);
120
                actions.put("insert-tab",INSERT_TAB);
121
                actions.put("home",HOME);
122
                actions.put("select-home",SELECT_HOME);
123
                actions.put("document-home",DOCUMENT_HOME);
124
                actions.put("select-doc-home",SELECT_DOC_HOME);
125
                actions.put("next-char",NEXT_CHAR);
126
                actions.put("next-line",NEXT_LINE);
127
                actions.put("next-page",NEXT_PAGE);
128
                actions.put("next-word",NEXT_WORD);
129
                actions.put("select-next-char",SELECT_NEXT_CHAR);
130
                actions.put("select-next-line",SELECT_NEXT_LINE);
131
                actions.put("select-next-page",SELECT_NEXT_PAGE);
132
                actions.put("select-next-word",SELECT_NEXT_WORD);
133
                actions.put("overwrite",OVERWRITE);
134
                actions.put("prev-char",PREV_CHAR);
135
                actions.put("prev-line",PREV_LINE);
136
                actions.put("prev-page",PREV_PAGE);
137
                actions.put("prev-word",PREV_WORD);
138
                actions.put("select-prev-char",SELECT_PREV_CHAR);
139
                actions.put("select-prev-line",SELECT_PREV_LINE);
140
                actions.put("select-prev-page",SELECT_PREV_PAGE);
141
                actions.put("select-prev-word",SELECT_PREV_WORD);
142
                actions.put("repeat",REPEAT);
143
                actions.put("toggle-rect",TOGGLE_RECT);
144
                actions.put("insert-char",INSERT_CHAR);
145
        }
146

    
147
        /**
148
         * Returns a named text area action.
149
         * @param name The action name
150
         */
151
        public static ActionListener getAction(String name)
152
        {
153
                return (ActionListener)actions.get(name);
154
        }
155

    
156
        /**
157
         * Returns the name of the specified text area action.
158
         * @param listener The action
159
         */
160
        public static String getActionName(ActionListener listener)
161
        {
162
                Enumeration enumeration = getActions();
163
                while(enumeration.hasMoreElements())
164
                {
165
                        String name = (String)enumeration.nextElement();
166
                        ActionListener _listener = getAction(name);
167
                        if(_listener == listener)
168
                                return name;
169
                }
170
                return null;
171
        }
172

    
173
        /**
174
         * Returns an enumeration of all available actions.
175
         */
176
        public static Enumeration getActions()
177
        {
178
                return actions.keys();
179
        }
180

    
181
        /**
182
         * Adds the default key bindings to this input handler.
183
         * This should not be called in the constructor of this
184
         * input handler, because applications might load the
185
         * key bindings from a file, etc.
186
         */
187
        public abstract void addDefaultKeyBindings();
188

    
189
        /**
190
         * Adds a key binding to this input handler.
191
         * @param keyBinding The key binding (the format of this is
192
         * input-handler specific)
193
         * @param action The action
194
         */
195
        public abstract void addKeyBinding(String keyBinding, ActionListener action);
196

    
197
        /**
198
         * Removes a key binding from this input handler.
199
         * @param keyBinding The key binding
200
         */
201
        public abstract void removeKeyBinding(String keyBinding);
202

    
203
        /**
204
         * Removes all key bindings from this input handler.
205
         */
206
        public abstract void removeAllKeyBindings();
207

    
208
        /**
209
         * Grabs the next key typed event and invokes the specified
210
         * action with the key as a the action command.
211
         * @param action The action
212
         */
213
        public void grabNextKeyStroke(ActionListener listener)
214
        {
215
                grabAction = listener;
216
        }
217

    
218
        /**
219
         * Returns if repeating is enabled. When repeating is enabled,
220
         * actions will be executed multiple times. This is usually
221
         * invoked with a special key stroke in the input handler.
222
         */
223
        public boolean isRepeatEnabled()
224
        {
225
                return repeat;
226
        }
227

    
228
        /**
229
         * Enables repeating. When repeating is enabled, actions will be
230
         * executed multiple times. Once repeating is enabled, the input
231
         * handler should read a number from the keyboard.
232
         */
233
        public void setRepeatEnabled(boolean repeat)
234
        {
235
                this.repeat = repeat;
236
        }
237

    
238
        /**
239
         * Returns the number of times the next action will be repeated.
240
         */
241
        public int getRepeatCount()
242
        {
243
                return (repeat ? Math.max(1,repeatCount) : 1);
244
        }
245

    
246
        /**
247
         * Sets the number of times the next action will be repeated.
248
         * @param repeatCount The repeat count
249
         */
250
        public void setRepeatCount(int repeatCount)
251
        {
252
                this.repeatCount = repeatCount;
253
        }
254

    
255
        /**
256
         * Returns the macro recorder. If this is non-null, all executed
257
         * actions should be forwarded to the recorder.
258
         */
259
        public InputHandler.MacroRecorder getMacroRecorder()
260
        {
261
                return recorder;
262
        }
263

    
264
        /**
265
         * Sets the macro recorder. If this is non-null, all executed
266
         * actions should be forwarded to the recorder.
267
         * @param recorder The macro recorder
268
         */
269
        public void setMacroRecorder(InputHandler.MacroRecorder recorder)
270
        {
271
                this.recorder = recorder;
272
        }
273

    
274
        /**
275
         * Returns a copy of this input handler that shares the same
276
         * key bindings. Setting key bindings in the copy will also
277
         * set them in the original.
278
         */
279
        public abstract InputHandler copy();
280

    
281
        /**
282
         * Executes the specified action, repeating and recording it as
283
         * necessary.
284
         * @param listener The action listener
285
         * @param source The event source
286
         * @param actionCommand The action command
287
         */
288
        public void executeAction(ActionListener listener, Object source,
289
                String actionCommand)
290
        {
291
                // create event
292
                ActionEvent evt = new ActionEvent(source,
293
                        ActionEvent.ACTION_PERFORMED,
294
                        actionCommand);
295

    
296
                // don't do anything if the action is a wrapper
297
                // (like EditAction.Wrapper)
298
                if(listener instanceof Wrapper)
299
                {
300
                        listener.actionPerformed(evt);
301
                        return;
302
                }
303

    
304
                // remember old values, in case action changes them
305
                boolean _repeat = repeat;
306
                int _repeatCount = getRepeatCount();
307

    
308
                // execute the action
309
                if(listener instanceof InputHandler.NonRepeatable)
310
                        listener.actionPerformed(evt);
311
                else
312
                {
313
                        for(int i = 0; i < Math.max(1,repeatCount); i++)
314
                                listener.actionPerformed(evt);
315
                }
316

    
317
                // do recording. Notice that we do no recording whatsoever
318
                // for actions that grab keys
319
                if(grabAction == null)
320
                {
321
                        if(recorder != null)
322
                        {
323
                                if(!(listener instanceof InputHandler.NonRecordable))
324
                                {
325
                                        if(_repeatCount != 1)
326
                                                recorder.actionPerformed(REPEAT,String.valueOf(_repeatCount));
327

    
328
                                        recorder.actionPerformed(listener,actionCommand);
329
                                }
330
                        }
331

    
332
                        // If repeat was true originally, clear it
333
                        // Otherwise it might have been set by the action, etc
334
                        if(_repeat)
335
                        {
336
                                repeat = false;
337
                                repeatCount = 0;
338
                        }
339
                }
340
        }
341

    
342
        /**
343
         * Returns the text area that fired the specified event.
344
         * @param evt The event
345
         */
346
        public static JEditTextArea getTextArea(EventObject evt)
347
        {
348
                if(evt != null)
349
                {
350
                        Object o = evt.getSource();
351
                        if(o instanceof Component)
352
                        {
353
                                // find the parent text area
354
                                Component c = (Component)o;
355
                                for(;;)
356
                                {
357
                                        if(c instanceof JEditTextArea)
358
                                                return (JEditTextArea)c;
359
                                        else if(c == null)
360
                                                break;
361
                                        if(c instanceof JPopupMenu)
362
                                                c = ((JPopupMenu)c)
363
                                                        .getInvoker();
364
                                        else
365
                                                c = c.getParent();
366
                                }
367
                        }
368
                }
369

    
370
                // this shouldn't happen
371
                System.err.println("BUG: getTextArea() returning null");
372
                System.err.println("Report this to Slava Pestov <sp@gjt.org>");
373
                return null;
374
        }
375

    
376
        // protected members
377

    
378
        /**
379
         * If a key is being grabbed, this method should be called with
380
         * the appropriate key event. It executes the grab action with
381
         * the typed character as the parameter.
382
         */
383
        protected void handleGrabAction(KeyEvent evt)
384
        {
385
                // Clear it *before* it is executed so that executeAction()
386
                // resets the repeat count
387
                ActionListener _grabAction = grabAction;
388
                grabAction = null;
389
                executeAction(_grabAction,evt.getSource(),
390
                        String.valueOf(evt.getKeyChar()));
391
        }
392

    
393
        // protected members
394
        protected ActionListener grabAction;
395
        protected boolean repeat;
396
        protected int repeatCount;
397
        protected InputHandler.MacroRecorder recorder;
398

    
399
        /**
400
         * If an action implements this interface, it should not be repeated.
401
         * Instead, it will handle the repetition itself.
402
         */
403
        public interface NonRepeatable {}
404

    
405
        /**
406
         * If an action implements this interface, it should not be recorded
407
         * by the macro recorder. Instead, it will do its own recording.
408
         */
409
        public interface NonRecordable {}
410

    
411
        /**
412
         * For use by EditAction.Wrapper only.
413
         * @since jEdit 2.2final
414
         */
415
        public interface Wrapper {}
416

    
417
        /**
418
         * Macro recorder.
419
         */
420
        public interface MacroRecorder
421
        {
422
                void actionPerformed(ActionListener listener,
423
                        String actionCommand);
424
        }
425

    
426
        public static class backspace implements ActionListener
427
        {
428
                public void actionPerformed(ActionEvent evt)
429
                {
430
                        JEditTextArea textArea = getTextArea(evt);
431

    
432
                        if(!textArea.isEditable())
433
                        {
434
                                textArea.getToolkit().beep();
435
                                return;
436
                        }
437

    
438
                        if(textArea.getSelectionStart()
439
                           != textArea.getSelectionEnd())
440
                        {
441
                                textArea.setSelectedText("");
442
                        }
443
                        else
444
                        {
445
                                int caret = textArea.getCaretPosition();
446
                                if(caret == 0)
447
                                {
448
                                        textArea.getToolkit().beep();
449
                                        return;
450
                                }
451
                                try
452
                                {
453
                                        textArea.getDocument().remove(caret - 1,1);
454
                                }
455
                                catch(BadLocationException bl)
456
                                {
457
                                        bl.printStackTrace();
458
                                }
459
                        }
460
                }
461
        }
462

    
463
        public static class backspace_word implements ActionListener
464
        {
465
                public void actionPerformed(ActionEvent evt)
466
                {
467
                        JEditTextArea textArea = getTextArea(evt);
468
                        int start = textArea.getSelectionStart();
469
                        if(start != textArea.getSelectionEnd())
470
                        {
471
                                textArea.setSelectedText("");
472
                        }
473

    
474
                        int line = textArea.getCaretLine();
475
                        int lineStart = textArea.getLineStartOffset(line);
476
                        int caret = start - lineStart;
477

    
478
                        String lineText = textArea.getLineText(textArea
479
                                .getCaretLine());
480

    
481
                        if(caret == 0)
482
                        {
483
                                if(lineStart == 0)
484
                                {
485
                                        textArea.getToolkit().beep();
486
                                        return;
487
                                }
488
                                caret--;
489
                        }
490
                        else
491
                        {
492
                                String noWordSep = (String)textArea.getDocument().getProperty("noWordSep");
493
                                caret = TextUtilities.findWordStart(lineText,caret,noWordSep);
494
                        }
495

    
496
                        try
497
                        {
498
                                textArea.getDocument().remove(
499
                                                caret + lineStart,
500
                                                start - (caret + lineStart));
501
                        }
502
                        catch(BadLocationException bl)
503
                        {
504
                                bl.printStackTrace();
505
                        }
506
                }
507
        }
508

    
509
        public static class delete implements ActionListener
510
        {
511
                public void actionPerformed(ActionEvent evt)
512
                {
513
                        JEditTextArea textArea = getTextArea(evt);
514

    
515
                        if(!textArea.isEditable())
516
                        {
517
                                textArea.getToolkit().beep();
518
                                return;
519
                        }
520

    
521
                        if(textArea.getSelectionStart()
522
                           != textArea.getSelectionEnd())
523
                        {
524
                                textArea.setSelectedText("");
525
                        }
526
                        else
527
                        {
528
                                int caret = textArea.getCaretPosition();
529
                                if(caret == textArea.getDocumentLength())
530
                                {
531
                                        textArea.getToolkit().beep();
532
                                        return;
533
                                }
534
                                try
535
                                {
536
                                        textArea.getDocument().remove(caret,1);
537
                                }
538
                                catch(BadLocationException bl)
539
                                {
540
                                        bl.printStackTrace();
541
                                }
542
                        }
543
                }
544
        }
545

    
546
        public static class delete_word implements ActionListener
547
        {
548
                public void actionPerformed(ActionEvent evt)
549
                {
550
                        JEditTextArea textArea = getTextArea(evt);
551
                        int start = textArea.getSelectionStart();
552
                        if(start != textArea.getSelectionEnd())
553
                        {
554
                                textArea.setSelectedText("");
555
                        }
556

    
557
                        int line = textArea.getCaretLine();
558
                        int lineStart = textArea.getLineStartOffset(line);
559
                        int caret = start - lineStart;
560

    
561
                        String lineText = textArea.getLineText(textArea
562
                                .getCaretLine());
563

    
564
                        if(caret == lineText.length())
565
                        {
566
                                if(lineStart + caret == textArea.getDocumentLength())
567
                                {
568
                                        textArea.getToolkit().beep();
569
                                        return;
570
                                }
571
                                caret++;
572
                        }
573
                        else
574
                        {
575
                                String noWordSep = (String)textArea.getDocument().getProperty("noWordSep");
576
                                caret = TextUtilities.findWordEnd(lineText,caret,noWordSep);
577
                        }
578

    
579
                        try
580
                        {
581
                                textArea.getDocument().remove(start,
582
                                        (caret + lineStart) - start);
583
                        }
584
                        catch(BadLocationException bl)
585
                        {
586
                                bl.printStackTrace();
587
                        }
588
                }
589
        }
590

    
591
        public static class end implements ActionListener
592
        {
593
                private boolean select;
594

    
595
                public end(boolean select)
596
                {
597
                        this.select = select;
598
                }
599

    
600
                public void actionPerformed(ActionEvent evt)
601
                {
602
                        JEditTextArea textArea = getTextArea(evt);
603

    
604
                        int caret = textArea.getCaretPosition();
605

    
606
                        int lastOfLine = textArea.getLineEndOffset(
607
                                textArea.getCaretLine()) - 1;
608
                        int lastVisibleLine = textArea.getFirstLine()
609
                                + textArea.getVisibleLines();
610
                        if(lastVisibleLine >= textArea.getLineCount())
611
                        {
612
                                lastVisibleLine = Math.min(textArea.getLineCount() - 1,
613
                                        lastVisibleLine);
614
                        }
615
                        else
616
                                lastVisibleLine -= (textArea.getElectricScroll() + 1);
617

    
618
                        int lastVisible = textArea.getLineEndOffset(lastVisibleLine) - 1;
619
                        int lastDocument = textArea.getDocumentLength();
620

    
621
                        if(caret == lastDocument)
622
                        {
623
                                textArea.getToolkit().beep();
624
                                return;
625
                        }
626
                        else if(!Boolean.TRUE.equals(textArea.getClientProperty(
627
                                SMART_HOME_END_PROPERTY)))
628
                                caret = lastOfLine;
629
                        else if(caret == lastVisible)
630
                                caret = lastDocument;
631
                        else if(caret == lastOfLine)
632
                                caret = lastVisible;
633
                        else
634
                                caret = lastOfLine;
635

    
636
                        if(select)
637
                                textArea.select(textArea.getMarkPosition(),caret);
638
                        else
639
                                textArea.setCaretPosition(caret);
640
                }
641
        }
642

    
643
        public static class document_end implements ActionListener
644
        {
645
                private boolean select;
646

    
647
                public document_end(boolean select)
648
                {
649
                        this.select = select;
650
                }
651

    
652
                public void actionPerformed(ActionEvent evt)
653
                {
654
                        JEditTextArea textArea = getTextArea(evt);
655
                        if(select)
656
                                textArea.select(textArea.getMarkPosition(),
657
                                        textArea.getDocumentLength());
658
                        else
659
                                textArea.setCaretPosition(textArea
660
                                        .getDocumentLength());
661
                }
662
        }
663

    
664
        public static class home implements ActionListener
665
        {
666
                private boolean select;
667

    
668
                public home(boolean select)
669
                {
670
                        this.select = select;
671
                }
672

    
673
                public void actionPerformed(ActionEvent evt)
674
                {
675
                        JEditTextArea textArea = getTextArea(evt);
676

    
677
                        int caret = textArea.getCaretPosition();
678

    
679
                        int firstLine = textArea.getFirstLine();
680

    
681
                        int firstOfLine = textArea.getLineStartOffset(
682
                                textArea.getCaretLine());
683
                        int firstVisibleLine = (firstLine == 0 ? 0 :
684
                                firstLine + textArea.getElectricScroll());
685
                        int firstVisible = textArea.getLineStartOffset(
686
                                firstVisibleLine);
687

    
688
                        if(caret == 0)
689
                        {
690
                                textArea.getToolkit().beep();
691
                                return;
692
                        }
693
                        else if(!Boolean.TRUE.equals(textArea.getClientProperty(
694
                                SMART_HOME_END_PROPERTY)))
695
                                caret = firstOfLine;
696
                        else if(caret == firstVisible)
697
                                caret = 0;
698
                        else if(caret == firstOfLine)
699
                                caret = firstVisible;
700
                        else
701
                                caret = firstOfLine;
702

    
703
                        if(select)
704
                                textArea.select(textArea.getMarkPosition(),caret);
705
                        else
706
                                textArea.setCaretPosition(caret);
707
                }
708
        }
709

    
710
        public static class document_home implements ActionListener
711
        {
712
                private boolean select;
713

    
714
                public document_home(boolean select)
715
                {
716
                        this.select = select;
717
                }
718

    
719
                public void actionPerformed(ActionEvent evt)
720
                {
721
                        JEditTextArea textArea = getTextArea(evt);
722
                        if(select)
723
                                textArea.select(textArea.getMarkPosition(),0);
724
                        else
725
                                textArea.setCaretPosition(0);
726
                }
727
        }
728

    
729
        public static class insert_break implements ActionListener
730
        {
731
                public void actionPerformed(ActionEvent evt)
732
                {
733
                        JEditTextArea textArea = getTextArea(evt);
734

    
735
                        if(!textArea.isEditable())
736
                        {
737
                                textArea.getToolkit().beep();
738
                                return;
739
                        }
740

    
741
                        textArea.setSelectedText("\n");
742
                }
743
        }
744

    
745
        public static class insert_tab implements ActionListener
746
        {
747
                public void actionPerformed(ActionEvent evt)
748
                {
749
                        JEditTextArea textArea = getTextArea(evt);
750

    
751
                        if(!textArea.isEditable())
752
                        {
753
                                textArea.getToolkit().beep();
754
                                return;
755
                        }
756

    
757
                        textArea.overwriteSetSelectedText("\t");
758
                }
759
        }
760

    
761
        public static class next_char implements ActionListener
762
        {
763
                private boolean select;
764

    
765
                public next_char(boolean select)
766
                {
767
                        this.select = select;
768
                }
769

    
770
                public void actionPerformed(ActionEvent evt)
771
                {
772
                        JEditTextArea textArea = getTextArea(evt);
773
                        int caret = textArea.getCaretPosition();
774
                        if(caret == textArea.getDocumentLength())
775
                        {
776
                                textArea.getToolkit().beep();
777
                                return;
778
                        }
779

    
780
                        if(select)
781
                                textArea.select(textArea.getMarkPosition(),
782
                                        caret + 1);
783
                        else
784
                                textArea.setCaretPosition(caret + 1);
785
                }
786
        }
787

    
788
        public static class next_line implements ActionListener
789
        {
790
                private boolean select;
791

    
792
                public next_line(boolean select)
793
                {
794
                        this.select = select;
795
                }
796

    
797
                public void actionPerformed(ActionEvent evt)
798
                {
799
                        JEditTextArea textArea = getTextArea(evt);
800
                        int caret = textArea.getCaretPosition();
801
                        int line = textArea.getCaretLine();
802

    
803
                        if(line == textArea.getLineCount() - 1)
804
                        {
805
                                textArea.getToolkit().beep();
806
                                return;
807
                        }
808

    
809
                        int magic = textArea.getMagicCaretPosition();
810
                        if(magic == -1)
811
                        {
812
                                magic = textArea.offsetToX(line,
813
                                        caret - textArea.getLineStartOffset(line));
814
                        }
815

    
816
                        caret = textArea.getLineStartOffset(line + 1)
817
                                + textArea.xToOffset(line + 1,magic);
818
                        if(select)
819
                                textArea.select(textArea.getMarkPosition(),caret);
820
                        else
821
                                textArea.setCaretPosition(caret);
822
                        textArea.setMagicCaretPosition(magic);
823
                }
824
        }
825

    
826
        public static class next_page implements ActionListener
827
        {
828
                private boolean select;
829

    
830
                public next_page(boolean select)
831
                {
832
                        this.select = select;
833
                }
834

    
835
                public void actionPerformed(ActionEvent evt)
836
                {
837
                        JEditTextArea textArea = getTextArea(evt);
838
                        int lineCount = textArea.getLineCount();
839
                        int firstLine = textArea.getFirstLine();
840
                        int visibleLines = textArea.getVisibleLines();
841
                        int line = textArea.getCaretLine();
842

    
843
                        firstLine += visibleLines;
844

    
845
                        if(firstLine + visibleLines >= lineCount - 1)
846
                                firstLine = lineCount - visibleLines;
847

    
848
                        textArea.setFirstLine(firstLine);
849

    
850
                        int caret = textArea.getLineStartOffset(
851
                                Math.min(textArea.getLineCount() - 1,
852
                                line + visibleLines));
853
                        if(select)
854
                                textArea.select(textArea.getMarkPosition(),caret);
855
                        else
856
                                textArea.setCaretPosition(caret);
857
                }
858
        }
859

    
860
        public static class next_word implements ActionListener
861
        {
862
                private boolean select;
863

    
864
                public next_word(boolean select)
865
                {
866
                        this.select = select;
867
                }
868

    
869
                public void actionPerformed(ActionEvent evt)
870
                {
871
                        JEditTextArea textArea = getTextArea(evt);
872
                        int caret = textArea.getCaretPosition();
873
                        int line = textArea.getCaretLine();
874
                        int lineStart = textArea.getLineStartOffset(line);
875
                        caret -= lineStart;
876

    
877
                        String lineText = textArea.getLineText(textArea
878
                                .getCaretLine());
879

    
880
                        if(caret == lineText.length())
881
                        {
882
                                if(lineStart + caret == textArea.getDocumentLength())
883
                                {
884
                                        textArea.getToolkit().beep();
885
                                        return;
886
                                }
887
                                caret++;
888
                        }
889
                        else
890
                        {
891
                                String noWordSep = (String)textArea.getDocument().getProperty("noWordSep");
892
                                caret = TextUtilities.findWordEnd(lineText,caret,noWordSep);
893
                        }
894

    
895
                        if(select)
896
                                textArea.select(textArea.getMarkPosition(),
897
                                        lineStart + caret);
898
                        else
899
                                textArea.setCaretPosition(lineStart + caret);
900
                }
901
        }
902

    
903
        public static class overwrite implements ActionListener
904
        {
905
                public void actionPerformed(ActionEvent evt)
906
                {
907
                        JEditTextArea textArea = getTextArea(evt);
908
                        textArea.setOverwriteEnabled(
909
                                !textArea.isOverwriteEnabled());
910
                }
911
        }
912

    
913
        public static class prev_char implements ActionListener
914
        {
915
                private boolean select;
916

    
917
                public prev_char(boolean select)
918
                {
919
                        this.select = select;
920
                }
921

    
922
                public void actionPerformed(ActionEvent evt)
923
                {
924
                        JEditTextArea textArea = getTextArea(evt);
925
                        int caret = textArea.getCaretPosition();
926
                        if(caret == 0)
927
                        {
928
                                textArea.getToolkit().beep();
929
                                return;
930
                        }
931

    
932
                        if(select)
933
                                textArea.select(textArea.getMarkPosition(),
934
                                        caret - 1);
935
                        else
936
                                textArea.setCaretPosition(caret - 1);
937
                }
938
        }
939

    
940
        public static class prev_line implements ActionListener
941
        {
942
                private boolean select;
943

    
944
                public prev_line(boolean select)
945
                {
946
                        this.select = select;
947
                }
948

    
949
                public void actionPerformed(ActionEvent evt)
950
                {
951
                        JEditTextArea textArea = getTextArea(evt);
952
                        int caret = textArea.getCaretPosition();
953
                        int line = textArea.getCaretLine();
954

    
955
                        if(line == 0)
956
                        {
957
                                textArea.getToolkit().beep();
958
                                return;
959
                        }
960

    
961
                        int magic = textArea.getMagicCaretPosition();
962
                        if(magic == -1)
963
                        {
964
                                magic = textArea.offsetToX(line,
965
                                        caret - textArea.getLineStartOffset(line));
966
                        }
967

    
968
                        caret = textArea.getLineStartOffset(line - 1)
969
                                + textArea.xToOffset(line - 1,magic);
970
                        if(select)
971
                                textArea.select(textArea.getMarkPosition(),caret);
972
                        else
973
                                textArea.setCaretPosition(caret);
974
                        textArea.setMagicCaretPosition(magic);
975
                }
976
        }
977

    
978
        public static class prev_page implements ActionListener
979
        {
980
                private boolean select;
981

    
982
                public prev_page(boolean select)
983
                {
984
                        this.select = select;
985
                }
986

    
987
                public void actionPerformed(ActionEvent evt)
988
                {
989
                        JEditTextArea textArea = getTextArea(evt);
990
                        int firstLine = textArea.getFirstLine();
991
                        int visibleLines = textArea.getVisibleLines();
992
                        int line = textArea.getCaretLine();
993

    
994
                        if(firstLine < visibleLines)
995
                                firstLine = visibleLines;
996

    
997
                        textArea.setFirstLine(firstLine - visibleLines);
998

    
999
                        int caret = textArea.getLineStartOffset(
1000
                                Math.max(0,line - visibleLines));
1001
                        if(select)
1002
                                textArea.select(textArea.getMarkPosition(),caret);
1003
                        else
1004
                                textArea.setCaretPosition(caret);
1005
                }
1006
        }
1007

    
1008
        public static class prev_word implements ActionListener
1009
        {
1010
                private boolean select;
1011

    
1012
                public prev_word(boolean select)
1013
                {
1014
                        this.select = select;
1015
                }
1016

    
1017
                public void actionPerformed(ActionEvent evt)
1018
                {
1019
                        JEditTextArea textArea = getTextArea(evt);
1020
                        int caret = textArea.getCaretPosition();
1021
                        int line = textArea.getCaretLine();
1022
                        int lineStart = textArea.getLineStartOffset(line);
1023
                        caret -= lineStart;
1024

    
1025
                        String lineText = textArea.getLineText(textArea
1026
                                .getCaretLine());
1027

    
1028
                        if(caret == 0)
1029
                        {
1030
                                if(lineStart == 0)
1031
                                {
1032
                                        textArea.getToolkit().beep();
1033
                                        return;
1034
                                }
1035
                                caret--;
1036
                        }
1037
                        else
1038
                        {
1039
                                String noWordSep = (String)textArea.getDocument().getProperty("noWordSep");
1040
                                caret = TextUtilities.findWordStart(lineText,caret,noWordSep);
1041
                        }
1042

    
1043
                        if(select)
1044
                                textArea.select(textArea.getMarkPosition(),
1045
                                        lineStart + caret);
1046
                        else
1047
                                textArea.setCaretPosition(lineStart + caret);
1048
                }
1049
        }
1050

    
1051
        public static class repeat implements ActionListener,
1052
                InputHandler.NonRecordable
1053
        {
1054
                public void actionPerformed(ActionEvent evt)
1055
                {
1056
                        JEditTextArea textArea = getTextArea(evt);
1057
                        textArea.getInputHandler().setRepeatEnabled(true);
1058
                        String actionCommand = evt.getActionCommand();
1059
                        if(actionCommand != null)
1060
                        {
1061
                                textArea.getInputHandler().setRepeatCount(
1062
                                        Integer.parseInt(actionCommand));
1063
                        }
1064
                }
1065
        }
1066

    
1067
        public static class toggle_rect implements ActionListener
1068
        {
1069
                public void actionPerformed(ActionEvent evt)
1070
                {
1071
                        JEditTextArea textArea = getTextArea(evt);
1072
                        textArea.setSelectionRectangular(
1073
                                !textArea.isSelectionRectangular());
1074
                }
1075
        }
1076

    
1077
        public static class insert_char implements ActionListener,
1078
                InputHandler.NonRepeatable
1079
        {
1080
                public void actionPerformed(ActionEvent evt)
1081
                {
1082
                        JEditTextArea textArea = getTextArea(evt);
1083
                        String str = evt.getActionCommand();
1084
                        int repeatCount = textArea.getInputHandler().getRepeatCount();
1085

    
1086
                        if(textArea.isEditable())
1087
                        {
1088
                                StringBuffer buf = new StringBuffer();
1089
                                for(int i = 0; i < repeatCount; i++)
1090
                                        buf.append(str);
1091
                                textArea.overwriteSetSelectedText(buf.toString());
1092
                        }
1093
                        else
1094
                        {
1095
                                textArea.getToolkit().beep();
1096
                        }
1097
                }
1098
        }
1099
}