0001: /*
0002: * Sun Public License Notice
0003: *
0004: * The contents of this file are subject to the Sun Public License
0005: * Version 1.0 (the "License"). You may not use this file except in
0006: * compliance with the License. A copy of the License is available at
0007: * http://www.sun.com/
0008: *
0009: * The Original Code is NetBeans. The Initial Developer of the Original
0010: * Code is Sun Microsystems, Inc. Portions Copyright 1997-2000 Sun
0011: * Microsystems, Inc. All Rights Reserved.
0012: */
0013:
0014: package org.netbeans.editor;
0015:
0016: import java.awt.Rectangle;
0017: import java.awt.Toolkit;
0018: import java.awt.event.ActionEvent;
0019: import java.awt.event.ItemEvent;
0020: import java.awt.event.ItemListener;
0021: import java.text.SimpleDateFormat;
0022: import java.util.Date;
0023: import java.util.HashMap;
0024: import java.util.HashSet;
0025: import java.util.Map;
0026:
0027: import javax.swing.Action;
0028: import javax.swing.JCheckBoxMenuItem;
0029: import javax.swing.JMenuItem;
0030: import javax.swing.text.BadLocationException;
0031: import javax.swing.text.Caret;
0032: import javax.swing.text.Document;
0033: import javax.swing.text.JTextComponent;
0034: import javax.swing.text.Position;
0035: import javax.swing.undo.CannotRedoException;
0036: import javax.swing.undo.CannotUndoException;
0037: import javax.swing.undo.UndoableEdit;
0038:
0039: /**
0040: * Actions that are not considered basic and therefore they are not included
0041: * directly in BaseKit, but here. Their names however are still part of BaseKit.
0042: *
0043: * @author Miloslav Metelka
0044: * @version 1.00
0045: *
0046: * TODO: I18N in RunMacroAction errors
0047: */
0048:
0049: public class ActionFactory {
0050:
0051: private ActionFactory() {
0052: // no instantiation
0053: }
0054:
0055: public static class RemoveTabAction extends BaseAction {
0056:
0057: static final long serialVersionUID = -1537748600593395706L;
0058:
0059: public RemoveTabAction() {
0060: super (BaseKit.removeTabAction, MAGIC_POSITION_RESET
0061: | ABBREV_RESET | WORD_MATCH_RESET);
0062: }
0063:
0064: public void actionPerformed(ActionEvent evt,
0065: JTextComponent target) {
0066: if (target != null) {
0067: if (!target.isEditable() || !target.isEnabled()) {
0068: target.getToolkit().beep();
0069: return;
0070: }
0071: Caret caret = target.getCaret();
0072: BaseDocument doc = (BaseDocument) target.getDocument();
0073: if (caret.isSelectionVisible()) { // block selected
0074: try {
0075: doc.getFormatter().changeBlockIndent(doc,
0076: target.getSelectionStart(),
0077: target.getSelectionEnd(), -1);
0078: } catch (GuardedException e) {
0079: target.getToolkit().beep();
0080: } catch (BadLocationException e) {
0081: e.printStackTrace();
0082: }
0083: } else { // no selected text
0084: try {
0085: int startOffset = Utilities.getRowStart(doc,
0086: caret.getDot());
0087: int firstNW = Utilities.getRowFirstNonWhite(
0088: doc, caret.getDot());
0089: int endOffset = Utilities.getRowEnd(doc, caret
0090: .getDot());
0091: if (firstNW == -1
0092: || (firstNW >= caret.getDot()))
0093: doc.getFormatter().changeBlockIndent(doc,
0094: startOffset, endOffset, -1);
0095: else {
0096: // TODO:
0097: // after we will have action which will do opposite
0098: // to "tab" action
0099: // means it check whether before the caret is whole
0100: // tab which can
0101: // be removed, this action will be called here
0102: }
0103: } catch (GuardedException e) {
0104: target.getToolkit().beep();
0105: } catch (BadLocationException e) {
0106: e.printStackTrace();
0107: }
0108: }
0109: }
0110:
0111: }
0112:
0113: }
0114:
0115: public static class RemoveWordAction extends BaseAction {
0116:
0117: static final long serialVersionUID = 9193117196412195554L;
0118:
0119: public RemoveWordAction() {
0120: super (BaseKit.removeWordAction, MAGIC_POSITION_RESET
0121: | ABBREV_RESET | UNDO_MERGE_RESET
0122: | WORD_MATCH_RESET);
0123: }
0124:
0125: public void actionPerformed(ActionEvent evt,
0126: JTextComponent target) {
0127: if (target != null) {
0128: if (!target.isEditable() || !target.isEnabled()) {
0129: target.getToolkit().beep();
0130: return;
0131: }
0132:
0133: Caret caret = target.getCaret();
0134: try {
0135: BaseDocument doc = (BaseDocument) target
0136: .getDocument();
0137: int dotPos = caret.getDot();
0138: int bolPos = Utilities.getRowStart(doc, dotPos);
0139: int wsPos = Utilities.getPreviousWord(target,
0140: dotPos);
0141: wsPos = (dotPos == bolPos) ? wsPos : Math.max(
0142: bolPos, wsPos);
0143: doc.remove(wsPos, dotPos - wsPos);
0144: } catch (BadLocationException e) {
0145: target.getToolkit().beep();
0146: }
0147: }
0148: }
0149: }
0150:
0151: public static class RemoveLineBeginAction extends BaseAction {
0152:
0153: static final long serialVersionUID = 9193117196412195554L;
0154:
0155: public RemoveLineBeginAction() {
0156: super (BaseKit.removeLineBeginAction, MAGIC_POSITION_RESET
0157: | ABBREV_RESET | UNDO_MERGE_RESET
0158: | WORD_MATCH_RESET);
0159: }
0160:
0161: public void actionPerformed(ActionEvent evt,
0162: JTextComponent target) {
0163: if (target != null) {
0164: if (!target.isEditable() || !target.isEnabled()) {
0165: target.getToolkit().beep();
0166: return;
0167: }
0168:
0169: Caret caret = target.getCaret();
0170: try {
0171: BaseDocument doc = (BaseDocument) target
0172: .getDocument();
0173: int dotPos = caret.getDot();
0174: int bolPos = Utilities.getRowStart(doc, dotPos);
0175: if (dotPos == bolPos) { // at begining of the line
0176: if (dotPos > 0) {
0177: doc.remove(dotPos - 1, 1); // remove previous
0178: // new-line
0179: }
0180: } else { // not at the line begining
0181: char[] chars = doc.getChars(bolPos, dotPos
0182: - bolPos);
0183: if (Analyzer.isWhitespace(chars, 0,
0184: chars.length)) {
0185: doc.remove(bolPos, dotPos - bolPos); // remove
0186: // whitespace
0187: } else {
0188: int firstNW = Utilities
0189: .getRowFirstNonWhite(doc, bolPos);
0190: if (firstNW >= 0 && firstNW < dotPos) {
0191: doc.remove(firstNW, dotPos - firstNW);
0192: }
0193: }
0194: }
0195: } catch (BadLocationException e) {
0196: target.getToolkit().beep();
0197: }
0198: }
0199: }
0200: }
0201:
0202: public static class RemoveLineAction extends BaseAction {
0203:
0204: static final long serialVersionUID = -536315497241419877L;
0205:
0206: public RemoveLineAction() {
0207: super (BaseKit.removeLineAction, MAGIC_POSITION_RESET
0208: | ABBREV_RESET | UNDO_MERGE_RESET
0209: | WORD_MATCH_RESET);
0210: }
0211:
0212: public void actionPerformed(ActionEvent evt,
0213: JTextComponent target) {
0214: if (target != null) {
0215: if (!target.isEditable() || !target.isEnabled()) {
0216: target.getToolkit().beep();
0217: return;
0218: }
0219:
0220: Caret caret = target.getCaret();
0221: try {
0222: BaseDocument doc = (BaseDocument) target
0223: .getDocument();
0224: int dotPos = caret.getDot();
0225: int bolPos = Utilities.getRowStart(target, dotPos);
0226: int eolPos = Utilities.getRowEnd(target, dotPos);
0227: eolPos = Math.min(eolPos + 1, doc.getLength()); // include
0228: // '\n'
0229: doc.remove(bolPos, eolPos - bolPos);
0230: } catch (BadLocationException e) {
0231: target.getToolkit().beep();
0232: }
0233: }
0234: }
0235: }
0236:
0237: /* Useful for popup menu - remove selected block or do nothing */
0238: public static class RemoveSelectionAction extends BaseAction {
0239:
0240: static final long serialVersionUID = -1419424594746686573L;
0241:
0242: public RemoveSelectionAction() {
0243: super (BaseKit.removeSelectionAction, MAGIC_POSITION_RESET
0244: | ABBREV_RESET | UNDO_MERGE_RESET
0245: | WORD_MATCH_RESET);
0246: putValue("helpID", RemoveSelectionAction.class.getName());
0247: }
0248:
0249: public void actionPerformed(ActionEvent evt,
0250: JTextComponent target) {
0251: if (target != null) {
0252: if (!target.isEditable() || !target.isEnabled()) {
0253: target.getToolkit().beep();
0254: return;
0255: }
0256:
0257: target.replaceSelection(null);
0258: }
0259: }
0260: }
0261:
0262: /** Switch to overwrite mode or back to insert mode */
0263: public static class ToggleTypingModeAction extends BaseAction {
0264:
0265: static final long serialVersionUID = -2431132686507799723L;
0266:
0267: public ToggleTypingModeAction() {
0268: super (BaseKit.toggleTypingModeAction);
0269: }
0270:
0271: public void actionPerformed(ActionEvent evt,
0272: JTextComponent target) {
0273: if (target != null) {
0274: EditorUI editorUI = Utilities.getEditorUI(target);
0275: Boolean overwriteMode = (Boolean) editorUI
0276: .getProperty(EditorUI.OVERWRITE_MODE_PROPERTY);
0277: // Now toggle
0278: overwriteMode = (overwriteMode == null || !overwriteMode
0279: .booleanValue()) ? Boolean.TRUE : Boolean.FALSE;
0280: editorUI.putProperty(EditorUI.OVERWRITE_MODE_PROPERTY,
0281: overwriteMode);
0282: }
0283: }
0284: }
0285:
0286: public static class ToggleBookmarkAction extends BaseAction {
0287:
0288: static final long serialVersionUID = -8438899482709646741L;
0289:
0290: public ToggleBookmarkAction() {
0291: super (BaseKit.toggleBookmarkAction);
0292: }
0293:
0294: public void actionPerformed(ActionEvent evt,
0295: JTextComponent target) {
0296: if (target != null) {
0297: Caret caret = target.getCaret();
0298: try {
0299: BaseDocument doc = (BaseDocument) target
0300: .getDocument();
0301: doc.toggleBookmark(caret.getDot());
0302: } catch (BadLocationException e) {
0303: target.getToolkit().beep();
0304: }
0305: }
0306: }
0307: }
0308:
0309: public static class GotoNextBookmarkAction extends BaseAction {
0310:
0311: boolean select;
0312:
0313: static final long serialVersionUID = -5169554640178645108L;
0314:
0315: public GotoNextBookmarkAction(String nm, boolean select) {
0316: super (BaseKit.gotoNextBookmarkAction, ABBREV_RESET
0317: | MAGIC_POSITION_RESET | UNDO_MERGE_RESET
0318: | WORD_MATCH_RESET);
0319: this .select = select;
0320: }
0321:
0322: public void actionPerformed(ActionEvent evt,
0323: JTextComponent target) {
0324: if (target != null) {
0325: Caret caret = target.getCaret();
0326: try {
0327: BaseDocument doc = (BaseDocument) target
0328: .getDocument();
0329: int dotPos = doc.getNextBookmark(caret.getDot(),
0330: true); // wrap
0331: if (dotPos >= 0) {
0332: if (select) {
0333: caret.moveDot(dotPos);
0334: } else {
0335: caret.setDot(dotPos);
0336: }
0337: }
0338: } catch (BadLocationException e) {
0339: target.getToolkit().beep();
0340: }
0341: }
0342: }
0343: }
0344:
0345: public static class RunMacroAction extends BaseAction {
0346:
0347: static final long serialVersionUID = 1L;
0348:
0349: static HashSet runningActions = new HashSet();
0350: private String macroName;
0351:
0352: public RunMacroAction(String name) {
0353: super (BaseKit.macroActionPrefix + name);
0354: this .macroName = name;
0355: }
0356:
0357: protected void error(JTextComponent target, String messageKey) {
0358: Utilities.setStatusText(target, LocaleSupport.getString(
0359: messageKey, "Error in macro: " + messageKey));
0360: Toolkit.getDefaultToolkit().beep();
0361: }
0362:
0363: public void actionPerformed(ActionEvent evt,
0364: JTextComponent target) {
0365: if (!runningActions.add(macroName)) { // this macro is already
0366: // running, beware of loops
0367: error(target, "loop");
0368: return;
0369: }
0370:
0371: if (target == null)
0372: return;
0373:
0374: BaseKit kit = Utilities.getKit(target);
0375: if (kit == null)
0376: return;
0377:
0378: Map macroMap = (Map) Settings.getValue(kit.getClass(),
0379: SettingsNames.MACRO_MAP);
0380:
0381: String commandString = (String) macroMap.get(macroName);
0382:
0383: if (commandString == null) {
0384: error(target, "macro-not-found");
0385: runningActions.remove(macroName);
0386: return;
0387: }
0388:
0389: StringBuffer actionName = new StringBuffer();
0390: char[] command = commandString.toCharArray();
0391: int len = command.length;
0392:
0393: BaseDocument doc = (BaseDocument) target.getDocument();
0394: try {
0395: doc.atomicLock();
0396:
0397: for (int i = 0; i < len; i++) {
0398: if (Character.isWhitespace(command[i]))
0399: continue;
0400: if (command[i] == '"') {
0401: while (++i < len && command[i] != '"') {
0402: char ch = command[i];
0403: if (ch == '\\') {
0404: if (++i >= len) { // '\' at the end
0405: error(target, "macro-malformed");
0406: return;
0407: }
0408: ch = command[i];
0409: if (ch != '"' && ch != '\\') { // neither \\
0410: // nor \"
0411: error(target, "macro-malformed");
0412: return;
0413: } // else fall through
0414: }
0415: Action a = target.getKeymap()
0416: .getDefaultAction();
0417:
0418: if (a != null) {
0419: ActionEvent newEvt = new ActionEvent(
0420: target, 0, new String(
0421: new char[] { ch }));
0422: if (a instanceof BaseAction) {
0423: ((BaseAction) a)
0424: .updateComponent(target);
0425: ((BaseAction) a).actionPerformed(
0426: newEvt, target);
0427: } else {
0428: a.actionPerformed(newEvt);
0429: }
0430: }
0431: }
0432: } else { // parse the action name
0433: actionName.setLength(0);
0434: while (i < len
0435: && !Character.isWhitespace(command[i])) {
0436: char ch = command[i++];
0437: if (ch == '\\') {
0438: if (i >= len) { // macro ending with single '\'
0439: error(target, "macro-malformed");
0440: return;
0441: }
0442: ;
0443: ch = command[i++];
0444: if (ch != '\\'
0445: && !Character.isWhitespace(ch)) {//
0446: error(target, "macro-malformed"); // neither
0447: // "\\"
0448: // nor
0449: // "\ "
0450: return;
0451: } // else fall through
0452: }
0453: actionName.append(ch);
0454: }
0455: // execute the action
0456: Action a = kit.getActionByName(actionName
0457: .toString());
0458: if (a != null) {
0459: ActionEvent fakeEvt = new ActionEvent(
0460: target, 0, "");
0461: if (a instanceof BaseAction) {
0462: ((BaseAction) a)
0463: .updateComponent(target);
0464: ((BaseAction) a).actionPerformed(
0465: fakeEvt, target);
0466: } else {
0467: a.actionPerformed(fakeEvt);
0468: }
0469: } else {
0470: error(target, "macro-unknown-action");
0471: return;
0472: }
0473: }
0474: }
0475: } finally {
0476: doc.atomicUnlock();
0477: runningActions.remove(macroName);
0478: }
0479: }
0480: }
0481:
0482: public static class StartMacroRecordingAction extends BaseAction {
0483:
0484: static final long serialVersionUID = 1L;
0485:
0486: public StartMacroRecordingAction() {
0487: super (BaseKit.startMacroRecordingAction, NO_RECORDING);
0488: }
0489:
0490: public void actionPerformed(ActionEvent evt,
0491: JTextComponent target) {
0492: if (target != null) {
0493: if (!startRecording(target))
0494: target.getToolkit().beep();
0495: }
0496: }
0497: }
0498:
0499: public static class StopMacroRecordingAction extends BaseAction {
0500:
0501: static final long serialVersionUID = 1L;
0502:
0503: public StopMacroRecordingAction() {
0504: super (BaseKit.stopMacroRecordingAction, NO_RECORDING);
0505: }
0506:
0507: public void actionPerformed(ActionEvent evt,
0508: JTextComponent target) {
0509: if (target != null) {
0510: String macro = stopRecording(target);
0511: if (macro == null) { // not recording
0512: target.getToolkit().beep();
0513: } else {
0514: // popup a macro dialog
0515: BaseKit kit = Utilities.getKit(target);
0516: MacroDialogSupport support = new MacroDialogSupport(
0517: kit.getClass());
0518: support.setBody(macro);
0519: support.showMacroDialog();
0520: }
0521: }
0522: }
0523: }
0524:
0525: public static class AbbrevExpandAction extends BaseAction {
0526:
0527: static final long serialVersionUID = -2124569510083544403L;
0528:
0529: public AbbrevExpandAction() {
0530: super (BaseKit.abbrevExpandAction, MAGIC_POSITION_RESET
0531: | UNDO_MERGE_RESET | WORD_MATCH_RESET);
0532: }
0533:
0534: public void actionPerformed(ActionEvent evt,
0535: JTextComponent target) {
0536: if (target != null) {
0537: if (!target.isEditable() || !target.isEnabled()) {
0538: target.getToolkit().beep();
0539: return;
0540: }
0541:
0542: EditorUI editorUI = ((BaseTextUI) target.getUI())
0543: .getEditorUI();
0544: try {
0545: editorUI.getAbbrev().checkAndExpand(evt);
0546: } catch (BadLocationException e) {
0547: target.getToolkit().beep();
0548: }
0549: }
0550: }
0551: }
0552:
0553: public static class AbbrevResetAction extends BaseAction {
0554:
0555: static final long serialVersionUID = -2807497346060448395L;
0556:
0557: public AbbrevResetAction() {
0558: super (BaseKit.abbrevResetAction, ABBREV_RESET);
0559: }
0560:
0561: public void actionPerformed(ActionEvent evt,
0562: JTextComponent target) {
0563: }
0564:
0565: }
0566:
0567: public static class ChangeCaseAction extends BaseAction {
0568:
0569: int changeCaseMode;
0570:
0571: static final long serialVersionUID = 5680212865619897402L;
0572:
0573: public ChangeCaseAction(String name, int changeCaseMode) {
0574: super (name, ABBREV_RESET | MAGIC_POSITION_RESET
0575: | UNDO_MERGE_RESET | WORD_MATCH_RESET);
0576: this .changeCaseMode = changeCaseMode;
0577: }
0578:
0579: public void actionPerformed(ActionEvent evt,
0580: JTextComponent target) {
0581: if (target != null) {
0582: if (!target.isEditable() || !target.isEnabled()) {
0583: target.getToolkit().beep();
0584: return;
0585: }
0586:
0587: try {
0588: Caret caret = target.getCaret();
0589: BaseDocument doc = (BaseDocument) target
0590: .getDocument();
0591: if (caret.isSelectionVisible()) { // valid selection
0592: int startPos = target.getSelectionStart();
0593: int endPos = target.getSelectionEnd();
0594: Utilities.changeCase(doc, startPos, endPos
0595: - startPos, changeCaseMode);
0596: caret.setSelectionVisible(false);
0597: caret.setDot(endPos);
0598: } else { // no selection - change current char
0599: int dotPos = caret.getDot();
0600: Utilities.changeCase(doc, dotPos, 1,
0601: changeCaseMode);
0602: caret.setDot(dotPos + 1);
0603: }
0604: } catch (BadLocationException e) {
0605: target.getToolkit().beep();
0606: }
0607: }
0608: }
0609: }
0610:
0611: public static class FindNextAction extends BaseAction {
0612:
0613: static final long serialVersionUID = 6878814427731642684L;
0614:
0615: public FindNextAction() {
0616: super (BaseKit.findNextAction, ABBREV_RESET
0617: | MAGIC_POSITION_RESET | UNDO_MERGE_RESET
0618: | WORD_MATCH_RESET);
0619: }
0620:
0621: public void actionPerformed(ActionEvent evt,
0622: JTextComponent target) {
0623: if (target != null) {
0624: FindSupport.getFindSupport().find(null, false);
0625: }
0626: }
0627: }
0628:
0629: public static class FindPreviousAction extends BaseAction {
0630:
0631: static final long serialVersionUID = -43746947902694926L;
0632:
0633: public FindPreviousAction() {
0634: super (BaseKit.findPreviousAction, ABBREV_RESET
0635: | MAGIC_POSITION_RESET | UNDO_MERGE_RESET
0636: | WORD_MATCH_RESET);
0637: }
0638:
0639: public void actionPerformed(ActionEvent evt,
0640: JTextComponent target) {
0641: if (target != null) {
0642: FindSupport.getFindSupport().find(null, true);
0643: }
0644: }
0645: }
0646:
0647: /**
0648: * Finds either selection or if there's no selection it finds the word where
0649: * the cursor is standing.
0650: */
0651: public static class FindSelectionAction extends BaseAction {
0652:
0653: static final long serialVersionUID = -5601618936504699565L;
0654:
0655: public FindSelectionAction() {
0656: super (BaseKit.findSelectionAction);
0657: }
0658:
0659: public void actionPerformed(ActionEvent evt,
0660: JTextComponent target) {
0661: if (target != null) {
0662: FindSupport findSupport = FindSupport.getFindSupport();
0663: Caret caret = target.getCaret();
0664: int dotPos = caret.getDot();
0665: HashMap props = new HashMap(findSupport
0666: .getFindProperties());
0667: String searchWord = null;
0668:
0669: if (caret.isSelectionVisible()) { // valid selection
0670: searchWord = target.getSelectedText();
0671: props.put(SettingsNames.FIND_WHOLE_WORDS,
0672: Boolean.FALSE);
0673: } else { // no selection, get current word
0674: try {
0675: searchWord = Utilities.getIdentifier(
0676: (BaseDocument) target.getDocument(),
0677: dotPos);
0678: props.put(SettingsNames.FIND_WHOLE_WORDS,
0679: Boolean.TRUE);
0680: } catch (BadLocationException e) {
0681: e.printStackTrace();
0682: }
0683: }
0684:
0685: if (searchWord != null) {
0686: int n = searchWord.indexOf('\n');
0687: if (n >= 0)
0688: searchWord = searchWord.substring(0, n);
0689: props.put(SettingsNames.FIND_WHAT, searchWord);
0690: findSupport.putFindProperties(props);
0691: findSupport.find(null, false);
0692: }
0693: }
0694: }
0695: }
0696:
0697: public static class ToggleHighlightSearchAction extends BaseAction {
0698:
0699: static final long serialVersionUID = 4603809175771743200L;
0700:
0701: public ToggleHighlightSearchAction() {
0702: super (BaseKit.toggleHighlightSearchAction,
0703: CLEAR_STATUS_TEXT);
0704: }
0705:
0706: public void actionPerformed(ActionEvent evt,
0707: JTextComponent target) {
0708: if (target != null) {
0709: Boolean cur = (Boolean) FindSupport.getFindSupport()
0710: .getFindProperty(
0711: SettingsNames.FIND_HIGHLIGHT_SEARCH);
0712: if (cur == null || cur.booleanValue() == false) {
0713: cur = Boolean.TRUE;
0714: } else {
0715: cur = Boolean.FALSE;
0716: }
0717: FindSupport.getFindSupport().putFindProperty(
0718: SettingsNames.FIND_HIGHLIGHT_SEARCH, cur);
0719: }
0720: }
0721: }
0722:
0723: public static class UndoAction extends BaseAction {
0724:
0725: static final long serialVersionUID = 8628586205035497612L;
0726:
0727: public UndoAction() {
0728: super (BaseKit.undoAction, ABBREV_RESET
0729: | MAGIC_POSITION_RESET | UNDO_MERGE_RESET
0730: | WORD_MATCH_RESET);
0731: }
0732:
0733: public void actionPerformed(ActionEvent evt,
0734: JTextComponent target) {
0735: if (!target.isEditable() || !target.isEnabled()) {
0736: target.getToolkit().beep();
0737: return;
0738: }
0739:
0740: Document doc = target.getDocument();
0741: UndoableEdit undoMgr = (UndoableEdit) doc
0742: .getProperty(BaseDocument.UNDO_MANAGER_PROP);
0743: if (target != null && undoMgr != null) {
0744: try {
0745: undoMgr.undo();
0746: } catch (CannotUndoException e) {
0747: target.getToolkit().beep();
0748: }
0749: }
0750: }
0751: }
0752:
0753: public static class RedoAction extends BaseAction {
0754:
0755: static final long serialVersionUID = 6048125996333769202L;
0756:
0757: public RedoAction() {
0758: super (BaseKit.redoAction, ABBREV_RESET
0759: | MAGIC_POSITION_RESET | UNDO_MERGE_RESET
0760: | WORD_MATCH_RESET);
0761: }
0762:
0763: public void actionPerformed(ActionEvent evt,
0764: JTextComponent target) {
0765: if (!target.isEditable() || !target.isEnabled()) {
0766: target.getToolkit().beep();
0767: return;
0768: }
0769:
0770: Document doc = target.getDocument();
0771: UndoableEdit undoMgr = (UndoableEdit) doc
0772: .getProperty(BaseDocument.UNDO_MANAGER_PROP);
0773: if (target != null && undoMgr != null) {
0774: try {
0775: undoMgr.redo();
0776: } catch (CannotRedoException e) {
0777: target.getToolkit().beep();
0778: }
0779: }
0780: }
0781: }
0782:
0783: public static class WordMatchAction extends BaseAction {
0784:
0785: private boolean direction;
0786:
0787: static final long serialVersionUID = 595571114685133170L;
0788:
0789: public WordMatchAction(String name, boolean direction) {
0790: super (name, ABBREV_RESET | MAGIC_POSITION_RESET
0791: | UNDO_MERGE_RESET);
0792: this .direction = direction;
0793: }
0794:
0795: public void actionPerformed(ActionEvent evt,
0796: JTextComponent target) {
0797: if (target != null) {
0798: if (!target.isEditable() || !target.isEnabled()) {
0799: target.getToolkit().beep();
0800: return;
0801: }
0802:
0803: EditorUI editorUI = Utilities.getEditorUI(target);
0804: Caret caret = target.getCaret();
0805: final BaseDocument doc = Utilities.getDocument(target);
0806:
0807: // Possibly remove selection
0808: if (caret.isSelectionVisible()) {
0809: target.replaceSelection(null);
0810: }
0811:
0812: int dotPos = caret.getDot();
0813: String s = editorUI.getWordMatch().getMatchWord(dotPos,
0814: direction);
0815: String prevWord = editorUI.getWordMatch()
0816: .getPreviousWord();
0817: if (s != null) {
0818: doc.atomicLock();
0819: try {
0820: int pos = dotPos;
0821: if (prevWord != null && prevWord.length() > 0) {
0822: pos -= prevWord.length();
0823: doc.remove(pos, prevWord.length());
0824: }
0825: doc.insertString(pos, s, null);
0826: } catch (BadLocationException e) {
0827: target.getToolkit().beep();
0828: } finally {
0829: doc.atomicUnlock();
0830: }
0831: }
0832: }
0833: }
0834: }
0835:
0836: public static class ShiftLineAction extends BaseAction {
0837:
0838: boolean right;
0839:
0840: static final long serialVersionUID = -5124732597493699582L;
0841:
0842: public ShiftLineAction(String name, boolean right) {
0843: super (name, MAGIC_POSITION_RESET | UNDO_MERGE_RESET);
0844: this .right = right;
0845: }
0846:
0847: public void actionPerformed(ActionEvent evt,
0848: JTextComponent target) {
0849: if (target != null) {
0850: if (!target.isEditable() || !target.isEnabled()) {
0851: target.getToolkit().beep();
0852: return;
0853: }
0854:
0855: try {
0856: Caret caret = target.getCaret();
0857: BaseDocument doc = Utilities.getDocument(target);
0858: if (caret.isSelectionVisible()) {
0859: doc.getFormatter().changeBlockIndent(doc,
0860: target.getSelectionStart(),
0861: target.getSelectionEnd(),
0862: right ? +1 : -1);
0863: } else {
0864: doc.getFormatter().shiftLine(doc,
0865: caret.getDot(), right);
0866: }
0867: } catch (GuardedException e) {
0868: target.getToolkit().beep();
0869: } catch (BadLocationException e) {
0870: e.printStackTrace();
0871: }
0872: }
0873: }
0874: }
0875:
0876: public static class AdjustWindowAction extends BaseAction {
0877:
0878: int percentFromWindowTop;
0879:
0880: static final long serialVersionUID = 8864278998999643292L;
0881:
0882: public AdjustWindowAction(String name, int percentFromWindowTop) {
0883: super (name);
0884: this .percentFromWindowTop = percentFromWindowTop;
0885: }
0886:
0887: public void actionPerformed(ActionEvent evt,
0888: JTextComponent target) {
0889: if (target != null) {
0890: Utilities.getEditorUI(target).adjustWindow(
0891: percentFromWindowTop);
0892: }
0893: }
0894: }
0895:
0896: public static class AdjustCaretAction extends BaseAction {
0897:
0898: int percentFromWindowTop;
0899:
0900: static final long serialVersionUID = 3223383913531191066L;
0901:
0902: public AdjustCaretAction(String name, int percentFromWindowTop) {
0903: super (name);
0904: this .percentFromWindowTop = percentFromWindowTop;
0905: }
0906:
0907: public void actionPerformed(ActionEvent evt,
0908: JTextComponent target) {
0909: if (target != null) {
0910: Utilities.getEditorUI(target).adjustCaret(
0911: percentFromWindowTop);
0912: }
0913: }
0914: }
0915:
0916: public static class FormatAction extends BaseAction {
0917:
0918: static final long serialVersionUID = -7666172828961171865L;
0919:
0920: public FormatAction() {
0921: super (BaseKit.formatAction, ABBREV_RESET
0922: | MAGIC_POSITION_RESET | UNDO_MERGE_RESET);
0923: putValue("helpID", FormatAction.class.getName());
0924: }
0925:
0926: public void actionPerformed(ActionEvent evt,
0927: JTextComponent target) {
0928: if (target != null) {
0929: if (!target.isEditable() || !target.isEnabled()) {
0930: target.getToolkit().beep();
0931: return;
0932: }
0933:
0934: Caret caret = target.getCaret();
0935: BaseDocument doc = (BaseDocument) target.getDocument();
0936: GuardedDocument gdoc = (doc instanceof GuardedDocument) ? (GuardedDocument) doc
0937: : null;
0938:
0939: doc.atomicLock();
0940: try {
0941:
0942: int caretLine = Utilities.getLineOffset(doc, caret
0943: .getDot());
0944: int startPos;
0945: Position endPosition;
0946: if (caret.isSelectionVisible()) {
0947: startPos = target.getSelectionStart();
0948: endPosition = doc.createPosition(target
0949: .getSelectionEnd());
0950: } else {
0951: startPos = 0;
0952: endPosition = doc.createPosition(doc
0953: .getLength());
0954: }
0955:
0956: int pos = startPos;
0957: if (gdoc != null) {
0958: pos = gdoc.getGuardedBlockChain()
0959: .adjustToBlockEnd(pos);
0960: }
0961:
0962: while (pos < endPosition.getOffset()) {
0963: int stopPos = endPosition.getOffset();
0964: if (gdoc != null) { // adjust to start of the next
0965: // guarded block
0966: stopPos = gdoc.getGuardedBlockChain()
0967: .adjustToNextBlockStart(pos);
0968: if (stopPos == -1) {
0969: stopPos = endPosition.getOffset();
0970: }
0971: }
0972:
0973: int reformattedLen = doc.getFormatter()
0974: .reformat(doc, pos, stopPos);
0975: pos = pos + reformattedLen;
0976:
0977: if (gdoc != null) { // adjust to end of current block
0978: pos = gdoc.getGuardedBlockChain()
0979: .adjustToBlockEnd(pos);
0980: }
0981: }
0982:
0983: // Restore the line
0984: pos = Utilities.getRowStartFromLineOffset(doc,
0985: caretLine);
0986: if (pos >= 0) {
0987: caret.setDot(pos);
0988: }
0989: } catch (GuardedException e) {
0990: target.getToolkit().beep();
0991: } catch (BadLocationException e) {
0992: if (System.getProperty("netbeans.debug.exceptions") != null) { // NOI18N
0993: e.printStackTrace();
0994: }
0995: } finally {
0996: doc.atomicUnlock();
0997: }
0998:
0999: }
1000: }
1001:
1002: }
1003:
1004: public static class FirstNonWhiteAction extends BaseAction {
1005:
1006: boolean select;
1007:
1008: static final long serialVersionUID = -5888439539790901158L;
1009:
1010: public FirstNonWhiteAction(String nm, boolean select) {
1011: super (nm, MAGIC_POSITION_RESET | ABBREV_RESET
1012: | UNDO_MERGE_RESET | WORD_MATCH_RESET);
1013: this .select = select;
1014: }
1015:
1016: public void actionPerformed(ActionEvent evt,
1017: JTextComponent target) {
1018: if (target != null) {
1019: Caret caret = target.getCaret();
1020: try {
1021: int pos = Utilities.getRowFirstNonWhite(
1022: (BaseDocument) target.getDocument(), caret
1023: .getDot());
1024: if (pos >= 0) {
1025: if (select) {
1026: caret.moveDot(pos);
1027: } else {
1028: caret.setDot(pos);
1029: }
1030: }
1031: } catch (BadLocationException e) {
1032: target.getToolkit().beep();
1033: }
1034: }
1035: }
1036: }
1037:
1038: public static class LastNonWhiteAction extends BaseAction {
1039:
1040: boolean select;
1041:
1042: static final long serialVersionUID = 4503533041729712917L;
1043:
1044: public LastNonWhiteAction(String nm, boolean select) {
1045: super (nm, MAGIC_POSITION_RESET | ABBREV_RESET
1046: | UNDO_MERGE_RESET | WORD_MATCH_RESET);
1047: this .select = select;
1048: }
1049:
1050: public void actionPerformed(ActionEvent evt,
1051: JTextComponent target) {
1052: if (target != null) {
1053: Caret caret = target.getCaret();
1054: try {
1055: int pos = Utilities.getRowLastNonWhite(
1056: (BaseDocument) target.getDocument(), caret
1057: .getDot());
1058: if (pos >= 0) {
1059: if (select) {
1060: caret.moveDot(pos);
1061: } else {
1062: caret.setDot(pos);
1063: }
1064: }
1065: } catch (BadLocationException e) {
1066: target.getToolkit().beep();
1067: }
1068: }
1069: }
1070: }
1071:
1072: public static class SelectIdentifierAction extends BaseAction {
1073:
1074: static final long serialVersionUID = -7288216961333147873L;
1075:
1076: public SelectIdentifierAction() {
1077: super (BaseKit.selectIdentifierAction, MAGIC_POSITION_RESET);
1078: }
1079:
1080: public void actionPerformed(ActionEvent evt,
1081: JTextComponent target) {
1082: if (target != null) {
1083: Caret caret = target.getCaret();
1084: try {
1085: if (caret.isSelectionVisible()) {
1086: caret.setSelectionVisible(false); // unselect if
1087: // anything selected
1088: } else { // selection not visible
1089: int block[] = Utilities.getIdentifierBlock(
1090: (BaseDocument) target.getDocument(),
1091: caret.getDot());
1092: if (block != null) {
1093: caret.setDot(block[0]);
1094: caret.moveDot(block[1]);
1095: }
1096: }
1097: } catch (BadLocationException e) {
1098: target.getToolkit().beep();
1099: }
1100: }
1101: }
1102: }
1103:
1104: public static class SelectNextParameterAction extends BaseAction {
1105:
1106: static final long serialVersionUID = 8045372985336370934L;
1107:
1108: public SelectNextParameterAction() {
1109: super (BaseKit.selectNextParameterAction,
1110: MAGIC_POSITION_RESET | CLEAR_STATUS_TEXT);
1111: }
1112:
1113: public void actionPerformed(ActionEvent evt,
1114: JTextComponent target) {
1115: if (target != null) {
1116: Caret caret = target.getCaret();
1117: BaseDocument doc = (BaseDocument) target.getDocument();
1118: int dotPos = caret.getDot();
1119: int selectStartPos = -1;
1120: try {
1121: if (dotPos > 0) {
1122: if (doc.getChars(dotPos - 1, 1)[0] == ',') { // right
1123: // after
1124: // the
1125: // comma
1126: selectStartPos = dotPos;
1127: }
1128: }
1129: if (dotPos < doc.getLength()) {
1130: char dotChar = doc.getChars(dotPos, 1)[0];
1131: if (dotChar == ',') {
1132: selectStartPos = dotPos + 1;
1133: } else if (dotChar == ')') {
1134: caret.setDot(dotPos + 1);
1135: }
1136: }
1137: if (selectStartPos >= 0) {
1138: int selectEndPos = doc.find(
1139: new FinderFactory.CharArrayFwdFinder(
1140: new char[] { ',', ')' }),
1141: selectStartPos, -1);
1142: if (selectEndPos >= 0) {
1143: target.select(selectStartPos, selectEndPos);
1144: }
1145: }
1146: } catch (BadLocationException e) {
1147: target.getToolkit().beep();
1148: }
1149: }
1150: }
1151: }
1152:
1153: public static class JumpListNextAction extends BaseAction {
1154:
1155: static final long serialVersionUID = 6891721278404990446L;
1156:
1157: public JumpListNextAction() {
1158: super (BaseKit.jumpListNextAction);
1159: }
1160:
1161: public void actionPerformed(ActionEvent evt,
1162: JTextComponent target) {
1163: if (target != null) {
1164: JumpList.jumpNext(target);
1165: }
1166: }
1167: }
1168:
1169: public static class JumpListPrevAction extends BaseAction {
1170:
1171: static final long serialVersionUID = 7174907031986424265L;
1172:
1173: public JumpListPrevAction() {
1174: super (BaseKit.jumpListPrevAction);
1175: }
1176:
1177: public void actionPerformed(ActionEvent evt,
1178: JTextComponent target) {
1179: if (target != null) {
1180: JumpList.jumpPrev(target);
1181: }
1182: }
1183: }
1184:
1185: public static class JumpListNextComponentAction extends BaseAction {
1186:
1187: static final long serialVersionUID = -2059070050865876892L;
1188:
1189: public JumpListNextComponentAction() {
1190: super (BaseKit.jumpListNextComponentAction);
1191: }
1192:
1193: public void actionPerformed(ActionEvent evt,
1194: JTextComponent target) {
1195: if (target != null) {
1196: JumpList.jumpNextComponent(target);
1197: }
1198: }
1199: }
1200:
1201: public static class JumpListPrevComponentAction extends BaseAction {
1202:
1203: static final long serialVersionUID = 2032230534727849525L;
1204:
1205: public JumpListPrevComponentAction() {
1206: super (BaseKit.jumpListPrevComponentAction);
1207: }
1208:
1209: public void actionPerformed(ActionEvent evt,
1210: JTextComponent target) {
1211: if (target != null) {
1212: JumpList.jumpPrevComponent(target);
1213: }
1214: }
1215: }
1216:
1217: public static class ScrollUpAction extends BaseAction {
1218:
1219: public ScrollUpAction() {
1220: super (BaseKit.scrollUpAction);
1221: }
1222:
1223: public void actionPerformed(ActionEvent evt,
1224: JTextComponent target) {
1225: if (target != null) {
1226: EditorUI editorUI = Utilities.getEditorUI(target);
1227: Rectangle bounds = editorUI.getExtentBounds();
1228: bounds.y += editorUI.getLineHeight();
1229: editorUI.scrollRectToVisible(bounds,
1230: EditorUI.SCROLL_SMALLEST);
1231: }
1232: }
1233:
1234: }
1235:
1236: public static class ScrollDownAction extends BaseAction {
1237:
1238: public ScrollDownAction() {
1239: super (BaseKit.scrollDownAction);
1240: }
1241:
1242: public void actionPerformed(ActionEvent evt,
1243: JTextComponent target) {
1244: if (target != null) {
1245: EditorUI editorUI = Utilities.getEditorUI(target);
1246: Rectangle bounds = editorUI.getExtentBounds();
1247: bounds.y -= editorUI.getLineHeight();
1248: editorUI.scrollRectToVisible(bounds,
1249: EditorUI.SCROLL_SMALLEST);
1250: }
1251: }
1252:
1253: }
1254:
1255: public static class InsertDateTimeAction extends BaseAction {
1256:
1257: static final long serialVersionUID = 2865619897402L;
1258:
1259: public InsertDateTimeAction() {
1260: super (BaseKit.insertDateTimeAction, ABBREV_RESET
1261: | MAGIC_POSITION_RESET | UNDO_MERGE_RESET
1262: | WORD_MATCH_RESET);
1263: }
1264:
1265: public void actionPerformed(ActionEvent evt,
1266: JTextComponent target) {
1267: if (target != null) {
1268: if (!target.isEditable() || !target.isEnabled()) {
1269: target.getToolkit().beep();
1270: return;
1271: }
1272:
1273: try {
1274: Caret caret = target.getCaret();
1275: BaseDocument doc = (BaseDocument) target
1276: .getDocument();
1277:
1278: // Format the current time.
1279: SimpleDateFormat formatter = new SimpleDateFormat();
1280: Date currentTime = new Date();
1281: String dateString = formatter.format(currentTime);
1282:
1283: doc.insertString(caret.getDot(), dateString, null);
1284: } catch (BadLocationException e) {
1285: target.getToolkit().beep();
1286: }
1287: }
1288: }
1289: }
1290:
1291: /** Select text of whole document */
1292: public static class GenerateGutterPopupAction extends BaseAction {
1293:
1294: static final long serialVersionUID = -3502499718130556525L;
1295:
1296: public GenerateGutterPopupAction() {
1297: super (BaseKit.generateGutterPopupAction);
1298: }
1299:
1300: public void actionPerformed(ActionEvent evt,
1301: JTextComponent target) {
1302: }
1303:
1304: public JMenuItem getPopupMenuItem(JTextComponent target) {
1305: EditorUI ui = Utilities.getEditorUI(target);
1306: try {
1307: return ui.getDocument().getAnnotations().createMenu(
1308: Utilities.getKit(target),
1309: Utilities.getLineOffset(ui.getDocument(),
1310: target.getCaret().getDot()));
1311: } catch (BadLocationException ex) {
1312: return null;
1313: }
1314: }
1315:
1316: }
1317:
1318: /** Switch visibility of line numbers in editor */
1319: public static class ToggleLineNumbersAction extends BaseAction {
1320:
1321: static final long serialVersionUID = -3502499718130556526L;
1322:
1323: private JCheckBoxMenuItem item = null;
1324:
1325: public ToggleLineNumbersAction() {
1326: super (BaseKit.toggleLineNumbersAction);
1327: }
1328:
1329: public void actionPerformed(ActionEvent evt,
1330: JTextComponent target) {
1331: toggleLineNumbers();
1332: }
1333:
1334: public JMenuItem getPopupMenuItem(JTextComponent target) {
1335: if (item != null) {
1336: return item;
1337: }
1338:
1339: item = new JCheckBoxMenuItem(LocaleSupport
1340: .getString("line-numbers-menuitem"),
1341: isLineNumbersVisible());
1342: item.addItemListener(new ItemListener() {
1343: public void itemStateChanged(ItemEvent e) {
1344: actionPerformed(null, null);
1345: }
1346: });
1347: return item;
1348: }
1349:
1350: protected boolean isLineNumbersVisible() {
1351: return false;
1352: }
1353:
1354: protected void toggleLineNumbers() {
1355: }
1356:
1357: }
1358:
1359: /** Cycle through annotations on the current line */
1360: public static class AnnotationsCyclingAction extends BaseAction {
1361:
1362: public AnnotationsCyclingAction() {
1363: super (BaseKit.annotationsCyclingAction);
1364: }
1365:
1366: public void actionPerformed(ActionEvent evt,
1367: JTextComponent target) {
1368: if (target != null) {
1369: try {
1370: Caret caret = target.getCaret();
1371: BaseDocument doc = Utilities.getDocument(target);
1372: int caretLine = Utilities.getLineOffset(doc, caret
1373: .getDot());
1374: AnnotationDesc aDesc = doc.getAnnotations()
1375: .activateNextAnnotation(caretLine);
1376: } catch (BadLocationException e) {
1377: e.printStackTrace();
1378: }
1379: }
1380: }
1381: }
1382:
1383: }
|