KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > editor > ActionFactory


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.editor;
21
22 import java.awt.Component JavaDoc;
23 import java.awt.Cursor JavaDoc;
24 import java.awt.Rectangle JavaDoc;
25 import java.awt.event.ActionEvent JavaDoc;
26 import java.beans.PropertyChangeEvent JavaDoc;
27 import java.beans.PropertyChangeListener JavaDoc;
28 import java.util.Map JavaDoc;
29 import java.util.HashMap JavaDoc;
30 import java.util.HashSet JavaDoc;
31 import javax.swing.Action JavaDoc;
32 import javax.swing.ActionMap JavaDoc;
33 import javax.swing.ButtonModel JavaDoc;
34 import javax.swing.event.ChangeEvent JavaDoc;
35 import javax.swing.text.BadLocationException JavaDoc;
36 import javax.swing.text.DefaultEditorKit JavaDoc;
37 import javax.swing.text.JTextComponent JavaDoc;
38 import javax.swing.text.Document JavaDoc;
39 import javax.swing.text.Caret JavaDoc;
40 import javax.swing.text.Position JavaDoc;
41 import javax.swing.undo.UndoableEdit JavaDoc;
42 import javax.swing.undo.CannotUndoException JavaDoc;
43 import javax.swing.undo.CannotRedoException JavaDoc;
44 import java.awt.Toolkit JavaDoc;
45 import java.util.Date JavaDoc;
46 import java.text.SimpleDateFormat JavaDoc;
47 import javax.swing.JMenuItem JavaDoc;
48 import javax.swing.JCheckBoxMenuItem JavaDoc;
49 import java.awt.event.ItemListener JavaDoc;
50 import java.awt.event.ItemEvent JavaDoc;
51 import javax.swing.ImageIcon JavaDoc;
52 import javax.swing.JToggleButton JavaDoc;
53 import javax.swing.event.ChangeListener JavaDoc;
54 import javax.swing.text.AbstractDocument JavaDoc;
55 import javax.swing.text.View JavaDoc;
56 import org.netbeans.api.editor.fold.Fold;
57 import org.netbeans.api.editor.fold.FoldHierarchy;
58 import org.netbeans.api.editor.fold.FoldUtilities;
59 import org.netbeans.modules.editor.lib2.search.EditorFindSupport;
60 import org.netbeans.lib.editor.util.swing.DocumentUtilities;
61 import org.openide.util.ContextAwareAction;
62 import org.openide.util.Lookup;
63 import org.openide.util.NbBundle;
64 import org.openide.util.WeakListeners;
65 import org.openide.util.actions.Presenter;
66
67 /**
68 * Actions that are not considered basic and therefore
69 * they are not included directly in BaseKit, but here.
70 * Their names however are still part of BaseKit.
71 *
72 * @author Miloslav Metelka
73 * @version 1.00
74 *
75 * TODO: I18N in RunMacroAction errors
76 */

77
78 public class ActionFactory {
79
80     private ActionFactory() {
81         // no instantiation
82
}
83     
84     public static class RemoveTabAction extends LocalBaseAction {
85
86         static final long serialVersionUID =-1537748600593395706L;
87
88         public RemoveTabAction() {
89             super(BaseKit.removeTabAction, MAGIC_POSITION_RESET | ABBREV_RESET | WORD_MATCH_RESET);
90         }
91
92         public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
93             if (target != null) {
94                 if (!target.isEditable() || !target.isEnabled()) {
95                     target.getToolkit().beep();
96                     return;
97                 }
98                 Caret JavaDoc caret = target.getCaret();
99                 BaseDocument doc = (BaseDocument)target.getDocument();
100                 doc.atomicLock();
101                 DocumentUtilities.setTypingModification(doc, true);
102                 try {
103                 if (caret.isSelectionVisible()) { // block selected
104
try {
105                         doc.getFormatter().changeBlockIndent(doc,
106                                 target.getSelectionStart(), target.getSelectionEnd(), -1);
107                     } catch (GuardedException e) {
108                         target.getToolkit().beep();
109                     } catch (BadLocationException JavaDoc e) {
110                         e.printStackTrace();
111                     }
112                 } else { // no selected text
113
try {
114                         int startOffset = Utilities.getRowStart(doc, caret.getDot());
115                         int firstNW = Utilities.getRowFirstNonWhite(doc, caret.getDot());
116                         int endOffset = Utilities.getRowEnd(doc, caret.getDot());
117                         if (firstNW == -1 || (firstNW >= caret.getDot()))
118                             doc.getFormatter().changeBlockIndent(doc, startOffset, endOffset, -1);
119                         else {
120                             // TODO:
121
// after we will have action which will do opposite to "tab" action
122
// means it check whether before the caret is whole tab which can
123
// be removed, this action will be called here
124
}
125                     } catch (GuardedException e) {
126                         target.getToolkit().beep();
127                     } catch (BadLocationException JavaDoc e) {
128                         e.printStackTrace();
129                     }
130                 }
131                 } finally {
132                     DocumentUtilities.setTypingModification(doc, false);
133                     doc.atomicUnlock();
134                 }
135             }
136
137         }
138
139     }
140
141     /* #47709
142     public static class RemoveWordAction extends LocalBaseAction {
143
144         static final long serialVersionUID =9193117196412195554L;
145
146         public RemoveWordAction() {
147             super(BaseKit.removeWordAction, MAGIC_POSITION_RESET
148                   | ABBREV_RESET | UNDO_MERGE_RESET | WORD_MATCH_RESET);
149         }
150
151         public void actionPerformed(ActionEvent evt, JTextComponent target) {
152             if (target != null) {
153                 if (!target.isEditable() || !target.isEnabled()) {
154                     target.getToolkit().beep();
155                     return;
156                 }
157
158                 Caret caret = target.getCaret();
159                 try {
160                     BaseDocument doc = (BaseDocument)target.getDocument();
161                     int dotPos = caret.getDot();
162                     int [] identBlock = Utilities.getIdentifierBlock(doc,dotPos);
163                     if (identBlock != null){
164                         doc.remove(identBlock[0], identBlock[1] - identBlock[0]);
165                     }
166                 } catch (BadLocationException e) {
167                     target.getToolkit().beep();
168                 }
169             }
170         }
171     }
172      */

173
174     public static class RemoveWordPreviousAction extends LocalBaseAction {
175
176         public RemoveWordPreviousAction() {
177             super(BaseKit.removePreviousWordAction, MAGIC_POSITION_RESET
178                   | ABBREV_RESET | UNDO_MERGE_RESET | WORD_MATCH_RESET);
179         }
180
181         public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
182             if (target != null) {
183                 if (!target.isEditable() || !target.isEnabled()) {
184                     target.getToolkit().beep();
185                     return;
186                 }
187
188                 Caret JavaDoc caret = target.getCaret();
189                 BaseDocument doc = (BaseDocument)target.getDocument();
190                 doc.atomicLock();
191                 DocumentUtilities.setTypingModification(doc, true);
192                 try {
193                     int dotPos = caret.getDot();
194                     int bolPos = Utilities.getRowStart(doc, dotPos);
195                     int wsPos = Utilities.getPreviousWord(target, dotPos);
196                     wsPos = (dotPos == bolPos) ? wsPos : Math.max(bolPos, wsPos);
197                     doc.remove(wsPos, dotPos - wsPos);
198                 } catch (BadLocationException JavaDoc e) {
199                     target.getToolkit().beep();
200                 } finally {
201                     DocumentUtilities.setTypingModification(doc, false);
202                     doc.atomicUnlock();
203                 }
204             }
205         }
206     }
207
208     
209     public static class RemoveWordNextAction extends LocalBaseAction {
210
211         public RemoveWordNextAction() {
212             super(BaseKit.removeNextWordAction, MAGIC_POSITION_RESET
213                   | ABBREV_RESET | UNDO_MERGE_RESET | WORD_MATCH_RESET);
214         }
215
216         public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
217             if (target != null) {
218                 if (!target.isEditable() || !target.isEnabled()) {
219                     target.getToolkit().beep();
220                     return;
221                 }
222
223                 Caret JavaDoc caret = target.getCaret();
224                 BaseDocument doc = (BaseDocument)target.getDocument();
225                 doc.atomicLock();
226                 DocumentUtilities.setTypingModification(doc, true);
227                 try {
228                     int dotPos = caret.getDot();
229                     int eolPos = Utilities.getRowEnd(doc, dotPos);
230                     int wsPos = Utilities.getNextWord(target, dotPos);
231                     wsPos = (dotPos == eolPos) ? wsPos : Math.min(eolPos, wsPos);
232                     doc.remove(dotPos , wsPos - dotPos);
233                 } catch (BadLocationException JavaDoc e) {
234                     target.getToolkit().beep();
235                 } finally {
236                     DocumentUtilities.setTypingModification(doc, false);
237                     doc.atomicUnlock();
238                 }
239             }
240         }
241     }
242
243     
244     public static class RemoveLineBeginAction extends LocalBaseAction {
245
246         static final long serialVersionUID =9193117196412195554L;
247
248         public RemoveLineBeginAction() {
249             super(BaseKit.removeLineBeginAction, MAGIC_POSITION_RESET
250                   | ABBREV_RESET | UNDO_MERGE_RESET | WORD_MATCH_RESET);
251         }
252
253         public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
254             if (target != null) {
255                 if (!target.isEditable() || !target.isEnabled()) {
256                     target.getToolkit().beep();
257                     return;
258                 }
259
260                 Caret JavaDoc caret = target.getCaret();
261                 BaseDocument doc = (BaseDocument)target.getDocument();
262                 doc.atomicLock();
263                 DocumentUtilities.setTypingModification(doc, true);
264                 try {
265                     int dotPos = caret.getDot();
266                     int bolPos = Utilities.getRowStart(doc, dotPos);
267                     if (dotPos == bolPos) { // at begining of the line
268
if (dotPos > 0) {
269                             doc.remove(dotPos - 1, 1); // remove previous new-line
270
}
271                     } else { // not at the line begining
272
char[] chars = doc.getChars(bolPos, dotPos - bolPos);
273                         if (Analyzer.isWhitespace(chars, 0, chars.length)) {
274                             doc.remove(bolPos, dotPos - bolPos); // remove whitespace
275
} else {
276                             int firstNW = Utilities.getRowFirstNonWhite(doc, bolPos);
277                             if (firstNW >= 0 && firstNW < dotPos) {
278                                 doc.remove(firstNW, dotPos - firstNW);
279                             }
280                         }
281                     }
282                 } catch (BadLocationException JavaDoc e) {
283                     target.getToolkit().beep();
284                 } finally {
285                     DocumentUtilities.setTypingModification(doc, false);
286                     doc.atomicUnlock();
287                 }
288             }
289         }
290     }
291
292     public static class RemoveLineAction extends LocalBaseAction {
293
294         static final long serialVersionUID =-536315497241419877L;
295
296         public RemoveLineAction() {
297             super(BaseKit.removeLineAction, MAGIC_POSITION_RESET
298                   | ABBREV_RESET | UNDO_MERGE_RESET | WORD_MATCH_RESET);
299         }
300
301         public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
302             if (target != null) {
303                 if (!target.isEditable() || !target.isEnabled()) {
304                     target.getToolkit().beep();
305                     return;
306                 }
307
308                 Caret JavaDoc caret = target.getCaret();
309                 BaseDocument doc = (BaseDocument)target.getDocument();
310                 doc.atomicLock();
311                 DocumentUtilities.setTypingModification(doc, true);
312                 try {
313                     int dotPos = caret.getDot();
314                     int bolPos = Utilities.getRowStart(target, dotPos);
315                     int eolPos = Utilities.getRowEnd(target, dotPos);
316                     eolPos = Math.min(eolPos + 1, doc.getLength()); // include '\n'
317
doc.remove(bolPos, eolPos - bolPos);
318                 } catch (BadLocationException JavaDoc e) {
319                     target.getToolkit().beep();
320                 } finally {
321                     DocumentUtilities.setTypingModification(doc, false);
322                     doc.atomicUnlock();
323                 }
324             }
325         }
326     }
327
328     /* Useful for popup menu - remove selected block or do nothing */
329     public static class RemoveSelectionAction extends LocalBaseAction {
330
331         static final long serialVersionUID =-1419424594746686573L;
332
333         public RemoveSelectionAction() {
334             super(BaseKit.removeSelectionAction, MAGIC_POSITION_RESET
335                   | ABBREV_RESET | UNDO_MERGE_RESET | WORD_MATCH_RESET);
336             //#54893 putValue ("helpID", RemoveSelectionAction.class.getName ()); // NOI18N
337
}
338
339         public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
340             if (target != null) {
341                 if (!target.isEditable() || !target.isEnabled()) {
342                     target.getToolkit().beep();
343                     return;
344                 }
345
346                 BaseDocument doc = (BaseDocument)target.getDocument();
347                 doc.atomicLock();
348                 DocumentUtilities.setTypingModification(doc, true);
349                 try {
350                     target.replaceSelection(null);
351                 } finally {
352                     DocumentUtilities.setTypingModification(doc, false);
353                     doc.atomicUnlock();
354                 }
355             }
356         }
357     }
358
359     /** Switch to overwrite mode or back to insert mode */
360     public static class ToggleTypingModeAction extends LocalBaseAction {
361
362         static final long serialVersionUID =-2431132686507799723L;
363
364         public ToggleTypingModeAction() {
365             super(BaseKit.toggleTypingModeAction);
366         }
367
368         public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
369             if (target != null) {
370                 EditorUI editorUI = Utilities.getEditorUI(target);
371                 Boolean JavaDoc overwriteMode = (Boolean JavaDoc)editorUI.getProperty(EditorUI.OVERWRITE_MODE_PROPERTY);
372                 // Now toggle
373
overwriteMode = (overwriteMode == null || !overwriteMode.booleanValue())
374                                 ? Boolean.TRUE : Boolean.FALSE;
375                 editorUI.putProperty(EditorUI.OVERWRITE_MODE_PROPERTY, overwriteMode);
376             }
377         }
378     }
379
380     public static class RunMacroAction extends BaseAction {
381
382         static final long serialVersionUID =1L;
383
384         static HashSet JavaDoc runningActions = new HashSet JavaDoc();
385         private String JavaDoc macroName;
386
387         public RunMacroAction( String JavaDoc name ) {
388             super( BaseKit.macroActionPrefix + name);
389             this.macroName = name;
390         }
391
392         protected void error( JTextComponent JavaDoc target, String JavaDoc messageKey ) {
393             Utilities.setStatusText( target, LocaleSupport.getString(
394                 messageKey, "Error in macro: " + messageKey ) // NOI18N
395
);
396             Toolkit.getDefaultToolkit().beep();
397         }
398         
399         public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
400             if( !runningActions.add( macroName ) ) { // this macro is already running, beware of loops
401
error( target, "loop" ); // NOI18N
402
return;
403             }
404
405             if( target == null ) return;
406            
407             BaseKit kit = Utilities.getKit(target);
408             if( kit == null ) return;
409             
410             Map JavaDoc macroMap = (Map JavaDoc)Settings.getValue( kit.getClass(), SettingsNames.MACRO_MAP);
411             
412             String JavaDoc commandString = (String JavaDoc)macroMap.get( macroName );
413
414             if( commandString == null ) {
415                 error( target, "macro-not-found" ); // NOI18N
416
runningActions.remove( macroName );
417                 return;
418             }
419
420             StringBuffer JavaDoc actionName = new StringBuffer JavaDoc();
421             char[] command = commandString.toCharArray();
422             int len = command.length;
423
424             BaseDocument doc = (BaseDocument)target.getDocument();
425             doc.atomicLock();
426             try {
427                 for( int i = 0; i < len; i++ ) {
428                     if( Character.isWhitespace( command[i] ) ) continue;
429                     if( command[i] == '"' ) {
430                         while( ++i < len && command[i] != '"' ) {
431                             char ch = command[i];
432                             if( ch == '\\' ) {
433                                 if( ++i >= len ) { // '\' at the end
434
error( target, "macro-malformed" ); // NOI18N
435
return;
436                                 }
437                                 ch = command[i];
438                                 if( ch != '"' && ch != '\\' ) { // neither \\ nor \" // NOI18N
439
error( target, "macro-malformed" ); // NOI18N
440
return;
441                                 } // else fall through
442
}
443                             Action JavaDoc a = target.getKeymap().getDefaultAction();
444
445                             if (a != null) {
446                                 ActionEvent JavaDoc newEvt = new ActionEvent JavaDoc( target, 0, new String JavaDoc( new char[] { ch } ) );
447                                 if( a instanceof BaseAction ) {
448                                     ((BaseAction)a).updateComponent(target);
449                                     ((BaseAction)a).actionPerformed( newEvt, target );
450                                 } else {
451                                     a.actionPerformed( newEvt );
452                                 }
453                             }
454                         }
455                     } else { // parse the action name
456
actionName.setLength( 0 );
457                         while( i < len && ! Character.isWhitespace( command[i] ) ) {
458                             char ch = command[i++];
459                             if( ch == '\\' ) {
460                                 if( i >= len ) { // macro ending with single '\'
461
error( target, "macro-malformed" ); // NOI18N
462
return;
463                                 };
464                                 ch = command[i++];
465                                 if( ch != '\\' && ! Character.isWhitespace( ch ) ) {//
466
error( target, "macro-malformed" ); // neither "\\" nor "\ " // NOI18N
467
return;
468                                 } // else fall through
469
}
470                             actionName.append( ch );
471                         }
472                         // execute the action
473
Action JavaDoc a = kit.getActionByName( actionName.toString() );
474                         if (a != null) {
475                             ActionEvent JavaDoc fakeEvt = new ActionEvent JavaDoc( target, 0, "" );
476                             if( a instanceof BaseAction ) {
477                                 ((BaseAction)a).updateComponent(target);
478                                 ((BaseAction)a).actionPerformed( fakeEvt, target );
479                             } else {
480                                 a.actionPerformed( fakeEvt );
481                             }
482                             if(DefaultEditorKit.insertBreakAction.equals(actionName.toString())){
483                                 Action JavaDoc def = target.getKeymap().getDefaultAction();
484                                 ActionEvent JavaDoc fakeEvt10 = new ActionEvent JavaDoc( target, 0, new String JavaDoc(new byte[]{10}) );
485                                 if( def instanceof BaseAction ) {
486                                     ((BaseAction)def).updateComponent(target);
487                                     ((BaseAction)def).actionPerformed( fakeEvt10, target );
488                                 } else {
489                                     def.actionPerformed( fakeEvt10 );
490                                 }
491                             }
492                         } else {
493                             error( target, "macro-unknown-action" ); // NOI18N
494
return;
495                         }
496                     }
497                 }
498             } finally {
499                 doc.atomicUnlock();
500                 runningActions.remove( macroName );
501             }
502         }
503     }
504     
505     
506     public static class StartMacroRecordingAction extends LocalBaseAction {
507
508         static final long serialVersionUID =1L;
509
510         public StartMacroRecordingAction() {
511             super( BaseKit.startMacroRecordingAction, NO_RECORDING );
512             putValue(BaseAction.ICON_RESOURCE_PROPERTY,
513                 "org/netbeans/modules/editor/resources/start_macro_recording.png"); // NOI18N
514
}
515         
516         public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
517             if (target != null) {
518                 if( !startRecording(target) ) target.getToolkit().beep();
519             }
520         }
521     }
522
523     public static class StopMacroRecordingAction extends LocalBaseAction {
524
525         static final long serialVersionUID =1L;
526
527         public StopMacroRecordingAction() {
528             super( BaseKit.stopMacroRecordingAction, NO_RECORDING );
529             putValue(BaseAction.ICON_RESOURCE_PROPERTY,
530                 "org/netbeans/modules/editor/resources/stop_macro_recording.png"); // NOI18N
531
}
532         
533         protected MacroDialogSupport getMacroDialogSupport(Class JavaDoc kitClass){
534             return new MacroDialogSupport(kitClass);
535         }
536         
537         public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
538             if (target != null) {
539                 String JavaDoc macro = stopRecording(target);
540                 if( macro == null ) { // not recording
541
target.getToolkit().beep();
542                 } else {
543                     // popup a macro dialog
544
BaseKit kit = Utilities.getKit(target);
545                     MacroDialogSupport support = getMacroDialogSupport(kit.getClass());
546                     support.setBody( macro );
547                     support.showMacroDialog();
548                 }
549             }
550         }
551     }
552
553     
554     public static class AbbrevExpandAction extends LocalBaseAction {
555
556         static final long serialVersionUID =-2124569510083544403L;
557
558         public AbbrevExpandAction() {
559             super(BaseKit.abbrevExpandAction,
560                   MAGIC_POSITION_RESET | UNDO_MERGE_RESET | WORD_MATCH_RESET);
561             putValue(BaseAction.NO_KEYBINDING, Boolean.TRUE);
562         }
563
564         public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
565             if (target != null) {
566                 if (!target.isEditable() || !target.isEnabled()) {
567                     target.getToolkit().beep();
568                     return;
569                 }
570
571                 EditorUI editorUI = ((BaseTextUI)target.getUI()).getEditorUI();
572                 try {
573                     editorUI.getAbbrev().checkAndExpand(evt);
574                 } catch (BadLocationException JavaDoc e) {
575                     target.getToolkit().beep();
576                 }
577             }
578         }
579     }
580
581     public static class AbbrevResetAction extends LocalBaseAction {
582
583         static final long serialVersionUID =-2807497346060448395L;
584
585         public AbbrevResetAction() {
586             super(BaseKit.abbrevResetAction, ABBREV_RESET);
587         }
588
589         public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
590         }
591
592     }
593
594     public static class ChangeCaseAction extends LocalBaseAction {
595
596         int changeCaseMode;
597
598         static final long serialVersionUID =5680212865619897402L;
599
600         public ChangeCaseAction(String JavaDoc name, int changeCaseMode) {
601             super(name, ABBREV_RESET
602                   | MAGIC_POSITION_RESET | UNDO_MERGE_RESET | WORD_MATCH_RESET);
603             this.changeCaseMode = changeCaseMode;
604         }
605
606         public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
607             if (target != null) {
608                 if (!target.isEditable() || !target.isEnabled()) {
609                     target.getToolkit().beep();
610                     return;
611                 }
612
613                 try {
614                     Caret JavaDoc caret = target.getCaret();
615                     BaseDocument doc = (BaseDocument)target.getDocument();
616                     if (caret.isSelectionVisible()) { // valid selection
617
int startPos = target.getSelectionStart();
618                         int endPos = target.getSelectionEnd();
619                         Utilities.changeCase(doc, startPos, endPos - startPos, changeCaseMode);
620                         caret.setSelectionVisible(false);
621                         caret.setDot(endPos);
622                     } else { // no selection - change current char
623
int dotPos = caret.getDot();
624                         Utilities.changeCase(doc, dotPos, 1, changeCaseMode);
625                         caret.setDot(dotPos + 1);
626                     }
627                 } catch (BadLocationException JavaDoc e) {
628                     target.getToolkit().beep();
629                 }
630             }
631         }
632     }
633
634
635     public static class FindNextAction extends LocalBaseAction {
636
637         static final long serialVersionUID =6878814427731642684L;
638
639         public FindNextAction() {
640             super(BaseKit.findNextAction, ABBREV_RESET
641                   | MAGIC_POSITION_RESET | UNDO_MERGE_RESET | WORD_MATCH_RESET);
642             putValue(BaseAction.ICON_RESOURCE_PROPERTY,
643                 "org/netbeans/modules/editor/resources/find_next.png"); // NOI18N
644
}
645
646         public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
647             if (target != null) {
648                 EditorFindSupport.getInstance().find(null, false);
649             }
650         }
651     }
652
653     public static class FindPreviousAction extends LocalBaseAction {
654
655         static final long serialVersionUID =-43746947902694926L;
656
657         public FindPreviousAction() {
658             super(BaseKit.findPreviousAction, ABBREV_RESET
659                   | MAGIC_POSITION_RESET | UNDO_MERGE_RESET | WORD_MATCH_RESET);
660             putValue(BaseAction.ICON_RESOURCE_PROPERTY,
661                 "org/netbeans/modules/editor/resources/find_previous.png"); // NOI18N
662
}
663
664         public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
665             if (target != null) {
666                 EditorFindSupport.getInstance().find(null, true);
667             }
668         }
669     }
670
671     /** Finds either selection or if there's no selection it finds
672     * the word where the cursor is standing.
673     */

674     public static class FindSelectionAction extends LocalBaseAction {
675
676         static final long serialVersionUID =-5601618936504699565L;
677
678         public FindSelectionAction() {
679             super(BaseKit.findSelectionAction);
680             putValue(BaseAction.ICON_RESOURCE_PROPERTY,
681                 "org/netbeans/modules/editor/resources/find_selection.png"); // NOI18N
682
}
683
684         public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
685             if (target != null) {
686                 EditorFindSupport findSupport = EditorFindSupport.getInstance();
687                 Caret JavaDoc caret = target.getCaret();
688                 int dotPos = caret.getDot();
689                 HashMap JavaDoc props = new HashMap JavaDoc(findSupport.getFindProperties());
690                 String JavaDoc searchWord = null;
691                 boolean revert = false;
692                 Boolean JavaDoc originalValue = null;
693                 Map JavaDoc revertMap = (Map JavaDoc)props.get(EditorFindSupport.REVERT_MAP);
694                 Boolean JavaDoc revertValue = revertMap != null ? (Boolean JavaDoc)revertMap.get(SettingsNames.FIND_WHOLE_WORDS) : null;
695
696                 if (caret.isSelectionVisible()) { // valid selection
697
searchWord = target.getSelectedText();
698                     originalValue = (Boolean JavaDoc)props.put(SettingsNames.FIND_WHOLE_WORDS, Boolean.FALSE);
699                     if (Boolean.FALSE.equals(revertValue)) {
700                         revertMap.remove(SettingsNames.FIND_WHOLE_WORDS);
701                     } else {
702                         revert = !Boolean.FALSE.equals(originalValue);
703                     }
704                 } else { // no selection, get current word
705
try {
706                         searchWord = Utilities.getIdentifier((BaseDocument)target.getDocument(),
707                                                              dotPos);
708                         originalValue = (Boolean JavaDoc)props.put(SettingsNames.FIND_WHOLE_WORDS, Boolean.TRUE);
709                         if (Boolean.TRUE.equals(revertValue)) {
710                             revertMap.remove(SettingsNames.FIND_WHOLE_WORDS);
711                         } else {
712                             revert = !Boolean.TRUE.equals(originalValue);
713                         }
714
715                     } catch (BadLocationException JavaDoc e) {
716                         e.printStackTrace();
717                     }
718                 }
719
720                 if (searchWord != null) {
721                     int n = searchWord.indexOf( '\n' );
722                     if (n >= 0 )
723                         searchWord = searchWord.substring(0, n);
724                     props.put(SettingsNames.FIND_WHAT, searchWord);
725                 
726                     if (revert){
727                         revertMap = new HashMap JavaDoc();
728                         revertMap.put(SettingsNames.FIND_WHOLE_WORDS, originalValue != null ? originalValue : Boolean.FALSE);
729                         props.put(EditorFindSupport.REVERT_MAP, revertMap);
730                     }
731
732                     findSupport.putFindProperties(props);
733                     findSupport.find(null, false);
734                 }
735             }
736         }
737     }
738
739     public static class ToggleHighlightSearchAction extends LocalBaseAction implements Presenter.Toolbar {
740
741         static final long serialVersionUID =4603809175771743200L;
742
743         public ToggleHighlightSearchAction() {
744             super(BaseKit.toggleHighlightSearchAction, CLEAR_STATUS_TEXT);
745             putValue(Action.SMALL_ICON, new ImageIcon JavaDoc(org.openide.util.Utilities.loadImage(
746                 "org/netbeans/modules/editor/resources/toggle_highlight.png"))); // NOI18N
747
}
748
749         public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
750             if (target != null) {
751                 Boolean JavaDoc cur = (Boolean JavaDoc)EditorFindSupport.getInstance().getFindProperty(
752                                   SettingsNames.FIND_HIGHLIGHT_SEARCH);
753                 if (cur == null || cur.booleanValue() == false) {
754                     cur = Boolean.TRUE;
755                 } else {
756                     cur = Boolean.FALSE;
757                 }
758                 EditorFindSupport.getInstance().putFindProperty(
759                     SettingsNames.FIND_HIGHLIGHT_SEARCH, cur);
760             }
761         }
762
763         public Component JavaDoc getToolbarPresenter() {
764             JToggleButton JavaDoc b = new MyGaGaButton();
765             b.setModel(new HighlightButtonModel());
766             b.putClientProperty("hideActionText", Boolean.TRUE); //NOI18N
767
b.setAction(this);
768             
769             return b;
770         }
771         
772         private static final class HighlightButtonModel extends JToggleButton.ToggleButtonModel JavaDoc implements PropertyChangeListener JavaDoc {
773             
774             public HighlightButtonModel() {
775                 EditorFindSupport efs = EditorFindSupport.getInstance();
776                 efs.addPropertyChangeListener(WeakListeners.propertyChange(this, efs));
777                 propertyChange(null);
778             }
779         
780             public void propertyChange(PropertyChangeEvent JavaDoc evt) {
781                 if (evt == null || evt.getPropertyName() == null || evt.getPropertyName().equals(EditorFindSupport.FIND_HIGHLIGHT_SEARCH)) {
782                     Boolean JavaDoc value = (Boolean JavaDoc) EditorFindSupport.getInstance().getFindProperty(EditorFindSupport.FIND_HIGHLIGHT_SEARCH);
783                     setSelected(value == null ? false : value.booleanValue());
784                 }
785             }
786         } // End of HighlightButtonModel class
787

788         private static final class MyGaGaButton extends JToggleButton JavaDoc implements ChangeListener JavaDoc {
789             
790             public MyGaGaButton() {
791                 
792             }
793             
794             @Override JavaDoc
795             public void setModel(ButtonModel JavaDoc model) {
796                 ButtonModel JavaDoc oldModel = getModel();
797                 if (oldModel != null) {
798                     oldModel.removeChangeListener(this);
799                 }
800                 
801                 super.setModel(model);
802                 
803                 ButtonModel JavaDoc newModel = getModel();
804                 if (newModel != null) {
805                     newModel.addChangeListener(this);
806                 }
807                 
808                 stateChanged(null);
809             }
810
811             public void stateChanged(ChangeEvent JavaDoc evt) {
812                 boolean selected = isSelected();
813                 super.setContentAreaFilled(selected);
814                 super.setBorderPainted(selected);
815             }
816
817             @Override JavaDoc
818             public void setBorderPainted(boolean arg0) {
819                 if (!isSelected()) {
820                     super.setBorderPainted(arg0);
821                 }
822             }
823
824             @Override JavaDoc
825             public void setContentAreaFilled(boolean arg0) {
826                 if (!isSelected()) {
827                     super.setContentAreaFilled(arg0);
828                 }
829             }
830         }
831     } // End of ToggleHighlightSearchAction class
832

833     public static class UndoAction extends LocalBaseAction {
834
835         static final long serialVersionUID =8628586205035497612L;
836
837         public UndoAction() {
838             super(BaseKit.undoAction, ABBREV_RESET
839                   | MAGIC_POSITION_RESET | UNDO_MERGE_RESET | WORD_MATCH_RESET);
840         }
841
842         public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
843             if (!target.isEditable() || !target.isEnabled()) {
844                 target.getToolkit().beep();
845                 return;
846             }
847
848             Document JavaDoc doc = target.getDocument();
849             UndoableEdit JavaDoc undoMgr = (UndoableEdit JavaDoc)doc.getProperty(
850                                        BaseDocument.UNDO_MANAGER_PROP);
851             if (target != null && undoMgr != null) {
852                 try {
853                     undoMgr.undo();
854                 } catch (CannotUndoException JavaDoc e) {
855                     target.getToolkit().beep();
856                 }
857             }
858         }
859     }
860
861     public static class RedoAction extends LocalBaseAction {
862
863         static final long serialVersionUID =6048125996333769202L;
864
865         public RedoAction() {
866             super(BaseKit.redoAction, ABBREV_RESET
867                   | MAGIC_POSITION_RESET | UNDO_MERGE_RESET | WORD_MATCH_RESET);
868         }
869
870         public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
871             if (!target.isEditable() || !target.isEnabled()) {
872                 target.getToolkit().beep();
873                 return;
874             }
875
876             Document JavaDoc doc = target.getDocument();
877             UndoableEdit JavaDoc undoMgr = (UndoableEdit JavaDoc)doc.getProperty(
878                                        BaseDocument.UNDO_MANAGER_PROP);
879             if (target != null && undoMgr != null) {
880                 try {
881                     undoMgr.redo();
882                 } catch (CannotRedoException JavaDoc e) {
883                     target.getToolkit().beep();
884                 }
885             }
886         }
887     }
888
889     public static class WordMatchAction extends LocalBaseAction {
890
891         private boolean direction;
892
893         static final long serialVersionUID =595571114685133170L;
894
895         public WordMatchAction(String JavaDoc name, boolean direction) {
896             super(name, ABBREV_RESET
897                   | MAGIC_POSITION_RESET | UNDO_MERGE_RESET);
898             this.direction = direction;
899             putValue(BaseAction.ICON_RESOURCE_PROPERTY,
900                 direction
901                     ? "org/netbeans/modules/editor/resources/next_matching.png" // NOI18N
902
: "org/netbeans/modules/editor/resources/previous_matching.png" // NOI18N
903
);
904                         
905         }
906
907         public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
908             if (target != null) {
909                 if (!target.isEditable() || !target.isEnabled()) {
910                     target.getToolkit().beep();
911                     return;
912                 }
913
914                 EditorUI editorUI = Utilities.getEditorUI(target);
915                 Caret JavaDoc caret = target.getCaret();
916                 final BaseDocument doc = Utilities.getDocument(target);
917
918                 // Possibly remove selection
919
if (caret.isSelectionVisible()) {
920                     target.replaceSelection(null);
921                 }
922
923                 int dotPos = caret.getDot();
924                 String JavaDoc s = editorUI.getWordMatch().getMatchWord(dotPos, direction);
925                 String JavaDoc prevWord = editorUI.getWordMatch().getPreviousWord();
926                 if (s != null) {
927                     doc.atomicLock();
928                     DocumentUtilities.setTypingModification(doc, true);
929                     try {
930                         int pos = dotPos;
931                         if (prevWord != null && prevWord.length() > 0) {
932                             pos -= prevWord.length();
933                             doc.remove(pos, prevWord.length());
934                         }
935                         doc.insertString(pos, s, null);
936                     } catch (BadLocationException JavaDoc e) {
937                         target.getToolkit().beep();
938                     } finally {
939                         doc.atomicUnlock();
940                         DocumentUtilities.setTypingModification(doc, false);
941                     }
942                 }
943             }
944         }
945     }
946
947
948     public static class ShiftLineAction extends LocalBaseAction {
949
950         boolean right;
951
952         static final long serialVersionUID =-5124732597493699582L;
953
954         public ShiftLineAction(String JavaDoc name, boolean right) {
955             super(name, MAGIC_POSITION_RESET | UNDO_MERGE_RESET);
956             this.right = right;
957             putValue(BaseAction.ICON_RESOURCE_PROPERTY,
958                 right
959                     ? "org/netbeans/modules/editor/resources/shift_line_right.png" // NOI18N
960
: "org/netbeans/modules/editor/resources/shift_line_left.png" // NOI18N
961
);
962
963         }
964
965         public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
966             if (target != null) {
967                 if (!target.isEditable() || !target.isEnabled()) {
968                     target.getToolkit().beep();
969                     return;
970                 }
971
972                 Caret JavaDoc caret = target.getCaret();
973                 BaseDocument doc = Utilities.getDocument(target);
974                 doc.atomicLock();
975                 DocumentUtilities.setTypingModification(doc, true);
976                 try {
977                     if (caret.isSelectionVisible()) {
978                         doc.getFormatter().changeBlockIndent(doc,
979                         target.getSelectionStart(), target.getSelectionEnd(),
980                         right ? +1 : -1);
981                     } else {
982                         doc.getFormatter().shiftLine(doc, caret.getDot(), right);
983                     }
984                 } catch (GuardedException e) {
985                     target.getToolkit().beep();
986                 } catch (BadLocationException JavaDoc e) {
987                     e.printStackTrace();
988                 } finally {
989                     DocumentUtilities.setTypingModification(doc, false);
990                     doc.atomicUnlock();
991                 }
992             }
993         }
994     }
995
996     public static class ReindentLineAction extends LocalBaseAction {
997
998         static final long serialVersionUID =1L;
999
1000        public ReindentLineAction() {
1001            // TODO: figure out what these flags are all about
1002
super(BaseKit.reindentLineAction,
1003                  ABBREV_RESET | MAGIC_POSITION_RESET | UNDO_MERGE_RESET);
1004            //putValue ("helpID", ReindentLineAction.class.getName ());
1005
}
1006
1007        public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
1008            if (target != null) {
1009                if (!target.isEditable() || !target.isEnabled()) {
1010                    target.getToolkit().beep();
1011                    return;
1012                }
1013
1014                Caret JavaDoc caret = target.getCaret();
1015                BaseDocument doc = (BaseDocument)target.getDocument();
1016                GuardedDocument gdoc = (doc instanceof GuardedDocument)
1017                                       ? (GuardedDocument)doc : null;
1018
1019                doc.atomicLock();
1020                try {
1021                    int caretLine = Utilities.getLineOffset(doc, caret.getDot());
1022                    int startPos;
1023                    Position JavaDoc endPosition;
1024
1025                    if (caret.isSelectionVisible()) {
1026                        startPos = target.getSelectionStart();
1027                        endPosition = doc.createPosition(target.getSelectionEnd());
1028                    } else {
1029                        startPos = Utilities.getRowStart(doc, caret.getDot());
1030                        endPosition = doc.createPosition(Utilities.getRowEnd(doc, caret.getDot()));
1031                    }
1032
1033                    int pos = startPos;
1034                    if (gdoc != null) {
1035                        pos = gdoc.getGuardedBlockChain().adjustToBlockEnd(pos);
1036                    }
1037
1038                    while (pos < endPosition.getOffset()) {
1039                        int stopPos = endPosition.getOffset();
1040                        if (gdoc != null) { // adjust to start of the next guarded block
1041
stopPos = gdoc.getGuardedBlockChain().adjustToNextBlockStart(pos);
1042                            if (stopPos == -1 || stopPos > endPosition.getOffset()) {
1043                                stopPos = endPosition.getOffset();
1044                            }
1045                        }
1046
1047                        int reformattedLen = doc.getFormatter().reformat(doc, pos, stopPos);
1048                        pos = pos + reformattedLen;
1049
1050                        if (gdoc != null) { // adjust to end of current block
1051
pos = gdoc.getGuardedBlockChain().adjustToBlockEnd(pos);
1052                        }
1053                    }
1054                } catch (GuardedException e) {
1055                    target.getToolkit().beep();
1056                } catch (BadLocationException JavaDoc e) {
1057                    Utilities.annotateLoggable(e);
1058                } finally {
1059                    doc.atomicUnlock();
1060                }
1061            }
1062        }
1063    }
1064
1065    
1066    public static class AdjustWindowAction extends LocalBaseAction {
1067
1068        int percentFromWindowTop;
1069
1070        static final long serialVersionUID =8864278998999643292L;
1071
1072        public AdjustWindowAction(String JavaDoc name, int percentFromWindowTop) {
1073            super(name);
1074            this.percentFromWindowTop = percentFromWindowTop;
1075        }
1076
1077        public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
1078            if (target != null) {
1079                Utilities.getEditorUI(target).adjustWindow(percentFromWindowTop);
1080            }
1081        }
1082    }
1083
1084    public static class AdjustCaretAction extends LocalBaseAction {
1085
1086        int percentFromWindowTop;
1087
1088        static final long serialVersionUID =3223383913531191066L;
1089
1090        public AdjustCaretAction(String JavaDoc name, int percentFromWindowTop) {
1091            super(name);
1092            this.percentFromWindowTop = percentFromWindowTop;
1093        }
1094
1095        public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
1096            if (target != null) {
1097                Utilities.getEditorUI(target).adjustCaret(percentFromWindowTop);
1098            }
1099        }
1100    }
1101
1102    public static class FormatAction extends LocalBaseAction {
1103
1104        static final long serialVersionUID =-7666172828961171865L;
1105
1106        public FormatAction() {
1107            super(BaseKit.formatAction,
1108                  ABBREV_RESET | MAGIC_POSITION_RESET | UNDO_MERGE_RESET);
1109            //#54893 putValue ("helpID", FormatAction.class.getName ()); // NOI18N
1110
}
1111
1112        public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
1113            if (target != null) {
1114                if (!target.isEditable() || !target.isEnabled()) {
1115                    target.getToolkit().beep();
1116                    return;
1117                }
1118
1119                Caret JavaDoc caret = target.getCaret();
1120                BaseDocument doc = (BaseDocument)target.getDocument();
1121                GuardedDocument gdoc = (doc instanceof GuardedDocument)
1122                                       ? (GuardedDocument)doc : null;
1123                
1124                // Set hourglass cursor
1125
Cursor JavaDoc origCursor = target.getCursor();
1126                target.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
1127
1128                doc.atomicLock();
1129                try {
1130
1131                    int startPos;
1132                    Position JavaDoc endPosition;
1133                    if (caret.isSelectionVisible()) {
1134                        startPos = target.getSelectionStart();
1135                        endPosition = doc.createPosition(target.getSelectionEnd());
1136                    } else {
1137                        startPos = 0;
1138                        endPosition = doc.createPosition(doc.getLength());
1139                    }
1140
1141                    int pos = startPos;
1142                    if (gdoc != null) {
1143                        pos = gdoc.getGuardedBlockChain().adjustToBlockEnd(pos);
1144                    }
1145
1146                    while (pos < endPosition.getOffset()) {
1147                        int stopPos = endPosition.getOffset();
1148                        if (gdoc != null) { // adjust to start of the next guarded block
1149
stopPos = gdoc.getGuardedBlockChain().adjustToNextBlockStart(pos);
1150                            if (stopPos == -1 || stopPos > endPosition.getOffset()) {
1151                                stopPos = endPosition.getOffset();
1152                            }
1153                        }
1154
1155                        int reformattedLen = doc.getFormatter().reformat(doc, pos, stopPos);
1156                        pos = pos + reformattedLen;
1157
1158                        if (gdoc != null) { // adjust to end of current block
1159
pos = gdoc.getGuardedBlockChain().adjustToBlockEnd(pos);
1160                        }
1161                    }
1162
1163                } catch (GuardedException e) {
1164                    target.getToolkit().beep();
1165                } catch (BadLocationException JavaDoc e) {
1166                    Utilities.annotateLoggable(e);
1167                } finally {
1168                    doc.atomicUnlock();
1169                    target.setCursor(origCursor);
1170                }
1171            }
1172        }
1173        
1174    }
1175
1176    public static class FirstNonWhiteAction extends LocalBaseAction {
1177
1178        boolean select;
1179
1180        static final long serialVersionUID =-5888439539790901158L;
1181
1182        public FirstNonWhiteAction(String JavaDoc nm, boolean select) {
1183            super(nm, MAGIC_POSITION_RESET | ABBREV_RESET | UNDO_MERGE_RESET
1184                  | WORD_MATCH_RESET);
1185            this.select = select;
1186        }
1187
1188        public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
1189            if (target != null) {
1190                Caret JavaDoc caret = target.getCaret();
1191                try {
1192                    int pos = Utilities.getRowFirstNonWhite((BaseDocument)target.getDocument(),
1193                                                            caret.getDot());
1194                    if (pos >= 0) {
1195                        if (select) {
1196                            caret.moveDot(pos);
1197                        } else {
1198                            caret.setDot(pos);
1199                        }
1200                    }
1201                } catch (BadLocationException JavaDoc e) {
1202                    target.getToolkit().beep();
1203                }
1204            }
1205        }
1206    }
1207
1208    public static class LastNonWhiteAction extends LocalBaseAction {
1209
1210        boolean select;
1211
1212        static final long serialVersionUID =4503533041729712917L;
1213
1214        public LastNonWhiteAction(String JavaDoc nm, boolean select) {
1215            super(nm, MAGIC_POSITION_RESET | ABBREV_RESET | UNDO_MERGE_RESET
1216                  | WORD_MATCH_RESET);
1217            this.select = select;
1218        }
1219
1220        public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
1221            if (target != null) {
1222                Caret JavaDoc caret = target.getCaret();
1223                try {
1224                    int pos = Utilities.getRowLastNonWhite((BaseDocument)target.getDocument(),
1225                                                           caret.getDot());
1226                    if (pos >= 0) {
1227                        if (select) {
1228                            caret.moveDot(pos);
1229                        } else {
1230                            caret.setDot(pos);
1231                        }
1232                    }
1233                } catch (BadLocationException JavaDoc e) {
1234                    target.getToolkit().beep();
1235                }
1236            }
1237        }
1238    }
1239
1240    public static class SelectIdentifierAction extends LocalBaseAction {
1241
1242        static final long serialVersionUID =-7288216961333147873L;
1243
1244        public SelectIdentifierAction() {
1245            super(BaseKit.selectIdentifierAction, MAGIC_POSITION_RESET);
1246        }
1247
1248        public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
1249            if (target != null) {
1250                Caret JavaDoc caret = target.getCaret();
1251                try {
1252                    if (caret.isSelectionVisible()) {
1253                        caret.setSelectionVisible(false); // unselect if anything selected
1254
} else { // selection not visible
1255
int block[] = Utilities.getIdentifierBlock((BaseDocument)target.getDocument(),
1256                                      caret.getDot());
1257                        if (block != null) {
1258                            caret.setDot(block[0]);
1259                            caret.moveDot(block[1]);
1260                        }
1261                    }
1262                } catch (BadLocationException JavaDoc e) {
1263                    target.getToolkit().beep();
1264                }
1265            }
1266        }
1267    }
1268
1269    public static class SelectNextParameterAction extends LocalBaseAction {
1270
1271        static final long serialVersionUID =8045372985336370934L;
1272
1273        public SelectNextParameterAction() {
1274            super(BaseKit.selectNextParameterAction, MAGIC_POSITION_RESET | CLEAR_STATUS_TEXT);
1275            putValue(BaseAction.NO_KEYBINDING, Boolean.TRUE);
1276        }
1277
1278        public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
1279            if (target != null) {
1280                Caret JavaDoc caret = target.getCaret();
1281                BaseDocument doc = (BaseDocument)target.getDocument();
1282                int dotPos = caret.getDot();
1283                int selectStartPos = -1;
1284                try {
1285                    if (dotPos > 0) {
1286                        if (doc.getChars(dotPos - 1, 1)[0] == ',') { // right after the comma
1287
selectStartPos = dotPos;
1288                        }
1289                    }
1290                    if (dotPos < doc.getLength()) {
1291                        char dotChar = doc.getChars(dotPos, 1)[0];
1292                        if (dotChar == ',') {
1293                            selectStartPos = dotPos + 1;
1294                        } else if (dotChar == ')') {
1295                            caret.setDot(dotPos + 1);
1296                        }
1297                    }
1298                    if (selectStartPos >= 0) {
1299                        int selectEndPos = doc.find(
1300                                               new FinderFactory.CharArrayFwdFinder( new char[] { ',', ')' }),
1301                                               selectStartPos, -1
1302                                           );
1303                        if (selectEndPos >= 0) {
1304                            target.select(selectStartPos, selectEndPos);
1305                        }
1306                    }
1307                } catch (BadLocationException JavaDoc e) {
1308                    target.getToolkit().beep();
1309                }
1310            }
1311        }
1312    }
1313
1314    public static class JumpListNextAction extends LocalBaseAction {
1315
1316        static final long serialVersionUID =6891721278404990446L;
1317        PropertyChangeListener JavaDoc pcl;
1318
1319        public JumpListNextAction() {
1320            super(BaseKit.jumpListNextAction);
1321            putValue(BaseAction.ICON_RESOURCE_PROPERTY,
1322                "org/netbeans/modules/editor/resources/edit_next.png"); // NOI18N
1323
JumpList.addPropertyChangeListener(pcl = new PropertyChangeListener JavaDoc() {
1324                public void propertyChange(PropertyChangeEvent JavaDoc evt) {
1325                    setEnabled(JumpList.hasNext());
1326                }
1327            });
1328            setEnabled(JumpList.hasNext());
1329        }
1330
1331        public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
1332            if (target != null) {
1333                JumpList.jumpNext(target);
1334            }
1335        }
1336    }
1337
1338    public static class JumpListPrevAction extends LocalBaseAction {
1339
1340        static final long serialVersionUID =7174907031986424265L;
1341        PropertyChangeListener JavaDoc pcl;
1342
1343        public JumpListPrevAction() {
1344            super(BaseKit.jumpListPrevAction);
1345            putValue(BaseAction.ICON_RESOURCE_PROPERTY,
1346                "org/netbeans/modules/editor/resources/edit_previous.png"); // NOI18N
1347
JumpList.addPropertyChangeListener(pcl = new PropertyChangeListener JavaDoc() {
1348                public void propertyChange(PropertyChangeEvent JavaDoc evt) {
1349                    setEnabled(JumpList.hasPrev());
1350                }
1351            });
1352            setEnabled(JumpList.hasPrev());
1353        }
1354
1355        public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
1356            if (target != null) {
1357                JumpList.jumpPrev(target);
1358            }
1359        }
1360    }
1361
1362    public static class JumpListNextComponentAction extends LocalBaseAction {
1363
1364        static final long serialVersionUID =-2059070050865876892L;
1365
1366        public JumpListNextComponentAction() {
1367            super(BaseKit.jumpListNextComponentAction);
1368        }
1369
1370        public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
1371            if (target != null) {
1372                JumpList.jumpNextComponent(target);
1373            }
1374        }
1375    }
1376
1377    public static class JumpListPrevComponentAction extends LocalBaseAction {
1378
1379        static final long serialVersionUID =2032230534727849525L;
1380
1381        public JumpListPrevComponentAction() {
1382            super(BaseKit.jumpListPrevComponentAction);
1383        }
1384
1385        public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
1386            if (target != null) {
1387                JumpList.jumpPrevComponent(target);
1388            }
1389        }
1390    }
1391
1392    public static class ScrollUpAction extends LocalBaseAction {
1393
1394        public ScrollUpAction() {
1395            super(BaseKit.scrollUpAction);
1396        }
1397
1398        public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
1399            if (target != null) {
1400                EditorUI editorUI = Utilities.getEditorUI(target);
1401                Rectangle JavaDoc bounds = editorUI.getExtentBounds();
1402                bounds.y += editorUI.getLineHeight();
1403                bounds.x += editorUI.getTextMargin().left;
1404                editorUI.scrollRectToVisible(bounds, EditorUI.SCROLL_SMALLEST);
1405            }
1406        }
1407
1408    }
1409
1410    public static class ScrollDownAction extends LocalBaseAction {
1411
1412        public ScrollDownAction() {
1413            super(BaseKit.scrollDownAction);
1414        }
1415
1416        public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
1417            if (target != null) {
1418                EditorUI editorUI = Utilities.getEditorUI(target);
1419                Rectangle JavaDoc bounds = editorUI.getExtentBounds();
1420                bounds.y -= editorUI.getLineHeight();
1421                bounds.x += editorUI.getTextMargin().left;
1422                editorUI.scrollRectToVisible(bounds, EditorUI.SCROLL_SMALLEST);
1423            }
1424        }
1425
1426    }
1427
1428    public static class InsertDateTimeAction extends LocalBaseAction {
1429        
1430        static final long serialVersionUID =2865619897402L;
1431        
1432        public InsertDateTimeAction() {
1433            super(BaseKit.insertDateTimeAction,
1434            ABBREV_RESET | MAGIC_POSITION_RESET | UNDO_MERGE_RESET | WORD_MATCH_RESET);
1435        }
1436        
1437        public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
1438            if (target != null) {
1439                if (!target.isEditable() || !target.isEnabled()) {
1440                    target.getToolkit().beep();
1441                    return;
1442                }
1443                
1444                try {
1445                    Caret JavaDoc caret = target.getCaret();
1446                    BaseDocument doc = (BaseDocument)target.getDocument();
1447                    
1448                    // Format the current time.
1449
SimpleDateFormat JavaDoc formatter = new SimpleDateFormat JavaDoc();
1450                    Date JavaDoc currentTime = new Date JavaDoc();
1451                    String JavaDoc dateString = formatter.format(currentTime);
1452                    
1453                    doc.insertString(caret.getDot(), dateString, null);
1454                } catch (BadLocationException JavaDoc e) {
1455                    target.getToolkit().beep();
1456                }
1457            }
1458        }
1459    }
1460    
1461    /** Select text of whole document */
1462    public static class GenerateGutterPopupAction extends LocalBaseAction {
1463
1464        static final long serialVersionUID =-3502499718130556525L;
1465
1466        public GenerateGutterPopupAction() {
1467            super(BaseKit.generateGutterPopupAction);
1468            putValue(BaseAction.NO_KEYBINDING, Boolean.TRUE);
1469        }
1470
1471        public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
1472        }
1473
1474        public JMenuItem JavaDoc getPopupMenuItem(JTextComponent JavaDoc target) {
1475            EditorUI ui = Utilities.getEditorUI(target);
1476            try {
1477                return ui.getDocument().getAnnotations().createMenu(Utilities.getKit(target), Utilities.getLineOffset(ui.getDocument(),target.getCaret().getDot()));
1478            } catch (BadLocationException JavaDoc ex) {
1479                return null;
1480            }
1481        }
1482    
1483    }
1484
1485    /** Switch visibility of line numbers in editor */
1486    public static class ToggleLineNumbersAction extends LocalBaseAction {
1487
1488        static final long serialVersionUID =-3502499718130556526L;
1489        
1490        private JCheckBoxMenuItem JavaDoc item = null;
1491
1492        public ToggleLineNumbersAction() {
1493            super(BaseKit.toggleLineNumbersAction);
1494        }
1495
1496        public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
1497            toggleLineNumbers();
1498        }
1499        
1500        public JMenuItem JavaDoc getPopupMenuItem(JTextComponent JavaDoc target) {
1501            
1502            item = new JCheckBoxMenuItem JavaDoc(NbBundle.getBundle(BaseKit.class).
1503                    getString("line-numbers-menuitem"), isLineNumbersVisible());
1504            item.addItemListener( new ItemListener JavaDoc() {
1505                public void itemStateChanged(ItemEvent JavaDoc e) {
1506                    actionPerformed(null,null);
1507                }
1508            });
1509            return item;
1510        }
1511        
1512        protected boolean isLineNumbersVisible() {
1513            return false;
1514        }
1515        
1516        protected void toggleLineNumbers() {
1517        }
1518        
1519    }
1520    
1521    /** Cycle through annotations on the current line */
1522    public static class AnnotationsCyclingAction extends LocalBaseAction {
1523        
1524        public AnnotationsCyclingAction() {
1525            super(BaseKit.annotationsCyclingAction);
1526            putValue(BaseAction.NO_KEYBINDING, Boolean.TRUE);
1527        }
1528
1529        public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
1530            if (target != null) {
1531                try {
1532                    Caret JavaDoc caret = target.getCaret();
1533                    BaseDocument doc = Utilities.getDocument(target);
1534                    int caretLine = Utilities.getLineOffset(doc, caret.getDot());
1535                    AnnotationDesc aDesc = doc.getAnnotations().activateNextAnnotation(caretLine);
1536                } catch (BadLocationException JavaDoc e) {
1537                    e.printStackTrace();
1538                }
1539            }
1540        }
1541    }
1542
1543
1544    /** Returns the fold that should be collapsed/expanded in the caret row
1545     * @param hierarchy hierarchy under which all folds should be collapsed/expanded.
1546     * @param dot caret position offset
1547     * @param lineStart offset of the start of line
1548     * @param lineEnd offset of the end of line
1549     * @return the fold that meet common criteria in accordance with the caret position
1550     */

1551    private static Fold getLineFold(FoldHierarchy hierarchy, int dot, int lineStart, int lineEnd){
1552        Fold caretOffsetFold = FoldUtilities.findOffsetFold(hierarchy, dot);
1553
1554        // beginning searching from the lineStart
1555
Fold fold = FoldUtilities.findNearestFold(hierarchy, lineStart);
1556        
1557        while (fold!=null &&
1558                  (fold.getEndOffset()<=dot || // find next available fold if the 'fold' is one-line
1559
// or it has children and the caret is in the fold body
1560
// i.e. class A{ |public void method foo(){}}
1561
(!fold.isCollapsed() && fold.getFoldCount() > 0 && fold.getStartOffset()+1<dot)
1562                   )
1563               ){
1564
1565                   // look for next fold in forward direction
1566
Fold nextFold = FoldUtilities.findNearestFold(hierarchy,
1567                       (fold.getFoldCount()>0) ? fold.getStartOffset()+1 : fold.getEndOffset());
1568                   if (nextFold!=null && nextFold.getStartOffset()<lineEnd){
1569                       if (nextFold == fold) return fold;
1570                       fold = nextFold;
1571                   }else{
1572                       break;
1573                   }
1574        }
1575
1576        
1577        // a fold on the next line was found, returning fold at offset (in most cases inner class)
1578
if (fold == null || fold.getStartOffset()>lineEnd) {
1579
1580            // in the case:
1581
// class A{
1582
// } |
1583
// try to find an offset fold on the offset of the line beginning
1584
if (caretOffsetFold == null){
1585                caretOffsetFold = FoldUtilities.findOffsetFold(hierarchy, lineStart);
1586            }
1587            
1588            return caretOffsetFold;
1589        }
1590        
1591        // no fold at offset found, in this case return the fold
1592
if (caretOffsetFold == null) return fold;
1593        
1594        // skip possible inner class members validating if the innerclass fold is collapsed
1595
if (caretOffsetFold.isCollapsed()) return caretOffsetFold;
1596        
1597        // in the case:
1598
// class A{
1599
// public vo|id foo(){} }
1600
// 'fold' (in this case fold of the method foo) will be returned
1601
if ( caretOffsetFold.getEndOffset()>fold.getEndOffset() &&
1602             fold.getEndOffset()>dot){
1603            return fold;
1604        }
1605        
1606        // class A{
1607
// |} public void method foo(){}
1608
// inner class fold will be returned
1609
if (fold.getStartOffset()>caretOffsetFold.getEndOffset()) return caretOffsetFold;
1610        
1611        // class A{
1612
// public void foo(){} |}
1613
// returning innerclass fold
1614
if (fold.getEndOffset()<dot) return caretOffsetFold;
1615        
1616        return fold;
1617    }
1618    
1619    /** Collapse a fold. Depends on the current caret position. */
1620    public static class CollapseFold extends LocalBaseAction {
1621        public CollapseFold(){
1622            super(BaseKit.collapseFoldAction);
1623        }
1624        
1625        private boolean dotInFoldArea(JTextComponent JavaDoc target, Fold fold, int dot) throws BadLocationException JavaDoc{
1626            int foldStart = fold.getStartOffset();
1627            int foldEnd = fold.getEndOffset();
1628            int foldRowStart = javax.swing.text.Utilities.getRowStart(target, foldStart);
1629            int foldRowEnd = javax.swing.text.Utilities.getRowEnd(target, foldEnd);
1630            if (foldRowStart > dot || foldRowEnd < dot) return false; // it's not fold encapsulating dot
1631
return true;
1632            }
1633
1634        
1635        public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
1636            FoldHierarchy hierarchy = FoldHierarchy.get(target);
1637            int dot = target.getCaret().getDot();
1638            hierarchy.lock();
1639            try{
1640                try{
1641                    int rowStart = javax.swing.text.Utilities.getRowStart(target, dot);
1642                    int rowEnd = javax.swing.text.Utilities.getRowEnd(target, dot);
1643                    Fold fold = FoldUtilities.findNearestFold(hierarchy, rowStart);
1644                    fold = getLineFold(hierarchy, dot, rowStart, rowEnd);
1645                    if (fold==null){
1646                        return; // no success
1647
}
1648                    // ensure we' got the right fold
1649
if (dotInFoldArea(target, fold, dot)){
1650                        hierarchy.collapse(fold);
1651                    }
1652                }catch(BadLocationException JavaDoc ble){
1653                    ble.printStackTrace();
1654                }
1655            }finally {
1656                hierarchy.unlock();
1657            }
1658        }
1659    }
1660    
1661    /** Expand a fold. Depends on the current caret position. */
1662    public static class ExpandFold extends LocalBaseAction {
1663        public ExpandFold(){
1664            super(BaseKit.expandFoldAction);
1665        }
1666        
1667        public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
1668            FoldHierarchy hierarchy = FoldHierarchy.get(target);
1669            int dot = target.getCaret().getDot();
1670            hierarchy.lock();
1671            try{
1672                try{
1673                    int rowStart = javax.swing.text.Utilities.getRowStart(target, dot);
1674                    int rowEnd = javax.swing.text.Utilities.getRowEnd(target, dot);
1675                    Fold fold = getLineFold(hierarchy, dot, rowStart, rowEnd);
1676                    if (fold!=null){
1677                        hierarchy.expand(fold);
1678                    }
1679                }catch(BadLocationException JavaDoc ble){
1680                    ble.printStackTrace();
1681                }
1682            }finally {
1683                hierarchy.unlock();
1684            }
1685        }
1686    }
1687    
1688    /** Collapse all existing folds in the document. */
1689    public static class CollapseAllFolds extends LocalBaseAction {
1690        public CollapseAllFolds(){
1691            super(BaseKit.collapseAllFoldsAction);
1692        }
1693        
1694        public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
1695            FoldHierarchy hierarchy = FoldHierarchy.get(target);
1696            // Hierarchy locking done in the utility method
1697
FoldUtilities.collapseAll(hierarchy);
1698        }
1699    }
1700
1701    /** Expand all existing folds in the document. */
1702    public static class ExpandAllFolds extends LocalBaseAction {
1703        public ExpandAllFolds(){
1704            super(BaseKit.expandAllFoldsAction);
1705        }
1706        
1707        public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
1708            FoldHierarchy hierarchy = FoldHierarchy.get(target);
1709            // Hierarchy locking done in the utility method
1710
FoldUtilities.expandAll(hierarchy);
1711        }
1712    }
1713
1714    /** Expand all existing folds in the document. */
1715    public static class DumpViewHierarchyAction extends LocalBaseAction {
1716
1717        public DumpViewHierarchyAction() {
1718            super("dump-view-hierarchy"); // NOI18N
1719
putValue(BaseAction.NO_KEYBINDING, Boolean.TRUE);
1720        }
1721        
1722        public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
1723            DrawEngineDocView rootView = (DrawEngineDocView)Utilities.getDocumentView(target);
1724            AbstractDocument JavaDoc adoc = (AbstractDocument JavaDoc)target.getDocument();
1725
1726            // Dump fold hierarchy
1727
FoldHierarchy hierarchy = FoldHierarchy.get(target);
1728            adoc.readLock();
1729            try {
1730                hierarchy.lock();
1731                try {
1732                    /*DEBUG*/System.err.println("FOLD HIERARCHY DUMP:\n" + hierarchy); // NOI18N
1733
} finally {
1734                    hierarchy.unlock();
1735                }
1736            } finally {
1737                adoc.readUnlock();
1738            }
1739
1740            /*DEBUG*/System.err.println("DOCUMENT VIEW: " + System.identityHashCode(rootView) // NOI18N
1741
+ ", " + rootView // NOI18N
1742
+ "\nLINE VIEWS:\n" + rootView.childrenToString() // NOI18N
1743
);
1744            
1745            int caretOffset = target.getCaretPosition();
1746            int caretViewIndex = rootView.getViewIndex(caretOffset, Position.Bias.Forward);
1747            /*DEBUG*/System.err.println("caretOffset=" + caretOffset + ", caretViewIndex=" + caretViewIndex); // NOI18N
1748
if (caretViewIndex >= 0 && caretViewIndex < rootView.getViewCount()) {
1749                View JavaDoc caretView = rootView.getView(caretViewIndex);
1750                /*DEBUG*/System.err.println("caretView: " + caretView); // NOI18N
1751
}
1752            /*DEBUG*/System.err.println(FixLineSyntaxState.lineInfosToString(adoc));
1753            
1754            // Check the hierarchy correctness
1755
org.netbeans.editor.view.spi.ViewUtilities.checkViewHierarchy(rootView);
1756            
1757            if (adoc instanceof BaseDocument) {
1758                /*DEBUG*/System.err.println("DOCUMENT:\n" + ((BaseDocument)adoc).toStringDetail()); // NOI18N
1759
}
1760        }
1761    }
1762    
1763    /** Starts a new line in code. */
1764    public static class StartNewLine extends LocalBaseAction {
1765        public StartNewLine(){
1766            super( BaseKit.startNewLineAction, ABBREV_RESET
1767                  | MAGIC_POSITION_RESET | UNDO_MERGE_RESET);
1768        }
1769        
1770        public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
1771            // shift-enter while editing aka startNewLineAction
1772
if (!target.isEditable() || !target.isEnabled()) {
1773                target.getToolkit().beep();
1774                return;
1775            }
1776            
1777            
1778            BaseDocument doc = (BaseDocument)target.getDocument();
1779            
1780            doc.atomicLock();
1781            try {
1782                //target.replaceSelection(""); //NOI18N -fix of issue #52485
1783
Caret JavaDoc caret = target.getCaret();
1784                
1785                // insert and remove '-' to remember caret
1786
// position
1787
int dotpos = caret.getDot();
1788                doc.insertString(dotpos,"-",null); //NOI18N
1789
doc.remove(dotpos,1);
1790                int eolDot = Utilities.getRowEnd(target, caret.getDot());
1791                int newDotPos = doc.getFormatter().indentNewLine(doc,eolDot);
1792                caret.setDot(newDotPos);
1793            } catch (BadLocationException JavaDoc ex) {
1794                ex.printStackTrace();
1795            } finally{
1796                doc.atomicUnlock();
1797            }
1798        }
1799    }
1800    
1801    /**
1802     * Cut text from the caret position to either begining or end
1803     * of the line with the caret.
1804     */

1805    public static class CutToLineBeginOrEndAction extends LocalBaseAction {
1806        
1807        /**
1808         * Whether cutting to line end instead of line begin.
1809         */

1810        private final boolean toLineEnd;
1811        
1812        /**
1813         * Construct new action.
1814         *
1815         * @param toLineEnd whether cutting to line end instead of line begin.
1816         */

1817        public CutToLineBeginOrEndAction(boolean toLineEnd) {
1818            super(toLineEnd ? BaseKit.cutToLineEndAction : BaseKit.cutToLineBeginAction,
1819                ABBREV_RESET | MAGIC_POSITION_RESET | UNDO_MERGE_RESET);
1820            this.toLineEnd = toLineEnd;
1821        }
1822        
1823        public void actionPerformed(ActionEvent JavaDoc evt, JTextComponent JavaDoc target) {
1824            // shift-enter while editing aka startNewLineAction
1825
if (!target.isEditable() || !target.isEnabled()) {
1826                target.getToolkit().beep();
1827                return;
1828            }
1829            
1830            BaseDocument doc = (BaseDocument)target.getDocument();
1831            
1832            doc.atomicLock();
1833            DocumentUtilities.setTypingModification(doc, true);
1834            try {
1835                ActionMap JavaDoc actionMap = target.getActionMap();
1836                Action JavaDoc cutAction;
1837                if (actionMap != null && (cutAction = actionMap.get(DefaultEditorKit.cutAction)) != null) {
1838                    Caret JavaDoc caret = target.getCaret();
1839                    int caretOffset = caret.getDot();
1840                    int boundOffset = toLineEnd
1841                            ? Utilities.getRowEnd(target, caretOffset)
1842                            : Utilities.getRowStart(target, caretOffset);
1843                    
1844                    // Check whether there is only whitespace from caret position
1845
// till end of line
1846
if (toLineEnd) {
1847                        String JavaDoc text = target.getText(caretOffset, boundOffset - caretOffset);
1848                        if (boundOffset < doc.getLength() && text != null && text.matches("^[\\s]*$")) { // NOI18N
1849
boundOffset += 1; // Include line separator
1850
}
1851                    }
1852
1853                    caret.moveDot(boundOffset);
1854                    
1855                    // Call the cut action to cut out the selection
1856
cutAction.actionPerformed(evt);
1857                }
1858            } catch (BadLocationException JavaDoc ex) {
1859                ex.printStackTrace();
1860            } finally{
1861                DocumentUtilities.setTypingModification(doc, false);
1862                doc.atomicUnlock();
1863            }
1864        }
1865    }
1866    
1867    
1868}
1869
Popular Tags