1 19 20 package org.netbeans.editor; 21 22 import java.awt.Point ; 23 import java.awt.Rectangle ; 24 import java.awt.event.ActionEvent ; 25 import java.io.Reader ; 26 import java.io.Writer ; 27 import java.io.IOException ; 28 import java.util.Map ; 29 import java.util.HashMap ; 30 import java.util.Iterator ; 31 import java.util.List ; 32 import java.util.ArrayList ; 33 import java.util.Collections ; 34 import javax.swing.Action ; 35 import javax.swing.JEditorPane ; 36 import javax.swing.SwingConstants ; 37 import javax.swing.SwingUtilities ; 38 import javax.swing.text.Document ; 39 import javax.swing.text.DefaultEditorKit ; 40 import javax.swing.text.BadLocationException ; 41 import javax.swing.text.Element ; 42 import javax.swing.text.ViewFactory ; 43 import javax.swing.text.Caret ; 44 import javax.swing.text.JTextComponent ; 45 import java.io.CharArrayWriter ; 46 import java.lang.reflect.Method ; 47 import java.util.Vector ; 48 import java.util.logging.Level ; 49 import java.util.logging.Logger ; 50 import javax.swing.text.EditorKit ; 51 import javax.swing.text.Position ; 52 import org.netbeans.api.editor.mimelookup.MimeLookup; 53 import org.netbeans.api.editor.mimelookup.MimePath; 54 import org.netbeans.lib.editor.util.swing.DocumentUtilities; 55 import org.openide.awt.StatusDisplayer; 56 import org.openide.util.Lookup; 57 import org.openide.util.NbBundle; 58 59 65 66 public class BaseKit extends DefaultEditorKit { 67 68 private static final Logger LOG = Logger.getLogger(BaseKit.class.getName()); 69 70 71 public static final String splitLineAction = "split-line"; 73 74 public static final String annotationsCyclingAction = "annotations-cycling"; 76 77 public static final String collapseFoldAction = "collapse-fold"; 79 80 public static final String expandFoldAction = "expand-fold"; 82 83 public static final String collapseAllFoldsAction = "collapse-all-folds"; 85 86 public static final String expandAllFoldsAction = "expand-all-folds"; 88 89 public static final String selectionPageUpAction = "selection-page-up"; 91 92 public static final String selectionPageDownAction = "selection-page-down"; 94 95 public static final String removeTabAction = "remove-tab"; 97 98 public static final String removeSelectionAction = "remove-selection"; 100 101 public static final String abbrevExpandAction = "abbrev-expand"; 103 104 public static final String abbrevResetAction = "abbrev-reset"; 106 107 109 111 public static final String removePreviousWordAction = "remove-word-previous"; 113 115 public static final String removeNextWordAction = "remove-word-next"; 117 118 public static final String removeLineBeginAction = "remove-line-begin"; 120 121 public static final String removeLineAction = "remove-line"; 123 124 public static final String toggleTypingModeAction = "toggle-typing-mode"; 126 127 public static final String toUpperCaseAction = "to-upper-case"; 129 130 public static final String toLowerCaseAction = "to-lower-case"; 132 133 public static final String switchCaseAction = "switch-case"; 135 136 public static final String findNextAction = "find-next"; 138 139 public static final String findPreviousAction = "find-previous"; 141 142 public static final String toggleHighlightSearchAction = "toggle-highlight-search"; 144 145 public static final String findSelectionAction = "find-selection"; 147 148 public static final String undoAction = "undo"; 150 151 public static final String redoAction = "redo"; 153 154 public static final String wordMatchNextAction = "word-match-next"; 156 157 public static final String wordMatchPrevAction = "word-match-prev"; 159 160 public static final String reindentLineAction = "reindent-line"; 162 163 public static final String shiftLineRightAction = "shift-line-right"; 165 166 public static final String shiftLineLeftAction = "shift-line-left"; 168 169 public static final String adjustWindowCenterAction = "adjust-window-center"; 171 172 public static final String adjustWindowTopAction = "adjust-window-top"; 174 175 public static final String adjustWindowBottomAction = "adjust-window-bottom"; 177 178 public static final String adjustCaretCenterAction = "adjust-caret-center"; 180 181 public static final String adjustCaretTopAction = "adjust-caret-top"; 183 184 public static final String adjustCaretBottomAction = "adjust-caret-bottom"; 186 187 public static final String formatAction = "format"; 189 190 public static final String firstNonWhiteAction = "first-non-white"; 192 193 public static final String lastNonWhiteAction = "last-non-white"; 195 196 public static final String selectionFirstNonWhiteAction = "selection-first-non-white"; 198 199 public static final String selectionLastNonWhiteAction = "selection-last-non-white"; 201 202 public static final String selectIdentifierAction = "select-identifier"; 204 205 public static final String selectNextParameterAction = "select-next-parameter"; 207 208 public static final String jumpListNextAction = "jump-list-next"; 210 211 public static final String jumpListPrevAction = "jump-list-prev"; 213 214 public static final String jumpListNextComponentAction = "jump-list-next-component"; 216 217 public static final String jumpListPrevComponentAction = "jump-list-prev-component"; 219 220 public static final String scrollUpAction = "scroll-up"; 222 223 public static final String scrollDownAction = "scroll-down"; 225 226 public static final String macroActionPrefix = "macro-"; 228 229 public static final String startMacroRecordingAction = "start-macro-recording"; 231 232 public static final String stopMacroRecordingAction = "stop-macro-recording"; 234 235 public static final String lineFirstColumnAction = "caret-line-first-column"; 237 238 public static final String insertDateTimeAction = "insert-date-time"; 240 243 public static final String selectionLineFirstColumnAction = "selection-line-first-column"; 245 246 public static final String generateGutterPopupAction = "generate-gutter-popup"; 248 249 public static final String toggleLineNumbersAction = "toggle-line-numbers"; 251 252 public static final String pasteFormatedAction = "paste-formated"; 254 255 public static final String startNewLineAction = "start-new-line"; 257 258 public static final String cutToLineBeginAction = "cut-to-line-begin"; 260 261 public static final String cutToLineEndAction = "cut-to-line-end"; 263 264 public static final String removeTrailingSpacesAction = "remove-trailing-spaces"; 266 public static final String DOC_REPLACE_SELECTION_PROPERTY = "doc-replace-selection-property"; 268 private static final int KIT_CNT_PREALLOC = 7; 269 270 static final long serialVersionUID = -8570495408376659348L; 271 272 273 private static final Map kits = new HashMap (KIT_CNT_PREALLOC); 274 275 276 private static final Map kitKeymaps = new HashMap (KIT_CNT_PREALLOC); 277 278 279 private static final Map kitActions = new HashMap (KIT_CNT_PREALLOC); 280 281 282 private static final Map kitActionMaps = new HashMap (KIT_CNT_PREALLOC); 283 284 private static CopyAction copyActionDef = new CopyAction(); 285 private static CutAction cutActionDef = new CutAction(); 286 private static PasteAction pasteActionDef = new PasteAction(false); 287 private static DeleteCharAction deletePrevCharActionDef = new DeleteCharAction(deletePrevCharAction, false); 288 private static DeleteCharAction deleteNextCharActionDef = new DeleteCharAction(deleteNextCharAction, true); 289 private static ActionFactory.RemoveSelectionAction removeSelectionActionDef = new ActionFactory.RemoveSelectionAction(); 290 291 private static ActionFactory.UndoAction undoActionDef = new ActionFactory.UndoAction(); 292 private static ActionFactory.RedoAction redoActionDef = new ActionFactory.RedoAction(); 293 294 public static final int MAGIC_POSITION_MAX = Integer.MAX_VALUE - 1; 295 296 static SettingsChangeListener settingsListener = new SettingsChangeListener() { 297 public void settingsChange(SettingsChangeEvent evt) { 298 String settingName = (evt != null) ? evt.getSettingName() : null; 299 300 boolean clearActions = (settingName == null 301 || SettingsNames.CUSTOM_ACTION_LIST.equals(settingName) 302 || SettingsNames.MACRO_MAP.equals(settingName)); 303 304 if (clearActions || SettingsNames.KEY_BINDING_LIST.equals(settingName)) { 305 kitKeymaps.clear(); 306 } 307 308 if (clearActions) { 309 kitActions.clear(); 310 kitActionMaps.clear(); 311 } else { Iterator i = kitActions.entrySet().iterator(); 313 while (i.hasNext()) { 314 Map.Entry me = (Map.Entry )i.next(); 315 updateActionSettings((Action [])me.getValue(), evt, (Class )me.getKey()); 316 } 317 } 318 } 319 }; 320 321 static { 322 Settings.addSettingsChangeListener(settingsListener); 323 } 324 325 private static void updateActionSettings(Action [] actions, 326 SettingsChangeEvent evt, Class kitClass) { 327 for (int i = 0; i < actions.length; i++) { 328 if (actions[i] instanceof BaseAction) { 329 ((BaseAction)actions[i]).settingsChange(evt, kitClass); 330 } 331 } 332 } 333 334 397 public static BaseKit getKit(Class kitClass) { 398 if (kitClass != null && BaseKit.class.isAssignableFrom(kitClass) && BaseKit.class != kitClass) { 399 if (!noKitsTracker) { 400 String mimeType = kitsTracker_FindMimeType(kitClass); 401 if (mimeType != null) { 402 EditorKit kit = MimeLookup.getLookup(MimePath.parse(mimeType)).lookup(EditorKit .class); 403 if (kit instanceof BaseKit) { 404 return (BaseKit) kit; 405 } 406 } 407 } 408 } else { 409 kitClass = BaseKit.class; 410 } 411 412 synchronized (kits) { 413 BaseKit kit = (BaseKit)kits.get(kitClass); 414 if (kit == null) { 415 try { 416 kit = (BaseKit)kitClass.newInstance(); 417 } catch (IllegalAccessException e) { 418 LOG.log(Level.WARNING, null, e); 419 } catch (InstantiationException e) { 420 LOG.log(Level.WARNING, null, e); 421 } 422 kits.put(kitClass, kit); 423 } 424 return kit; 425 } 426 } 427 428 private static volatile boolean noKitsTracker = false; 429 private static String kitsTracker_FindMimeType(Class kitClass) { 430 String mimeType = null; 431 432 if (!noKitsTracker) { 433 try { 434 ClassLoader cl = Lookup.getDefault().lookup(ClassLoader .class); 435 Class clazz = cl.loadClass("org.netbeans.modules.editor.impl.KitsTracker"); Method getInstanceMethod = clazz.getDeclaredMethod("getInstance"); Method findMimeTypeMethod = clazz.getDeclaredMethod("findMimeType", Class .class); Object kitsTracker = getInstanceMethod.invoke(null); 439 mimeType = (String ) findMimeTypeMethod.invoke(kitsTracker, kitClass); 440 } catch (Exception e) { 441 noKitsTracker = true; 443 } 444 } 445 446 return mimeType; 447 } 448 449 469 public BaseKit() { 470 synchronized (kits) { 472 if (kits.get(this.getClass()) == null) { 473 kits.put(this.getClass(), this); } 475 } 476 } 477 478 479 public Object clone() { 480 return this; } 482 483 490 public ViewFactory getViewFactory() { 491 return null; 492 } 493 494 495 public Caret createCaret() { 496 return new BaseCaret(); 497 } 498 499 500 public Document createDefaultDocument() { 501 return new BaseDocument(this.getClass(), true); 502 } 503 504 508 public Syntax createSyntax(Document doc) { 509 return new DefaultSyntax(); 510 } 511 512 513 public Syntax createFormatSyntax(Document doc) { 514 return createSyntax(doc); 515 } 516 517 518 public SyntaxSupport createSyntaxSupport(BaseDocument doc) { 519 return new SyntaxSupport(doc); 520 } 521 522 523 public Formatter createFormatter() { 524 return new Formatter(this.getClass()); 525 } 526 527 528 protected BaseTextUI createTextUI() { 529 return new BaseTextUI(); 530 } 531 532 533 protected EditorUI createEditorUI() { 534 return new EditorUI(); 535 } 536 537 543 protected EditorUI createPrintEditorUI(BaseDocument doc) { 544 return new EditorUI(doc); 545 } 546 547 557 protected EditorUI createPrintEditorUI(BaseDocument doc, 558 boolean usePrintColoringMap, boolean lineNumberEnabled) { 559 560 return new EditorUI(doc, usePrintColoringMap, lineNumberEnabled); 561 } 562 563 public MultiKeymap getKeymap() { 564 synchronized (Settings.class) { 565 MultiKeymap km = (MultiKeymap)kitKeymaps.get(this.getClass()); 566 if (km == null) { km = new MultiKeymap("Keymap for " + this.getClass()); Settings.KitAndValue kv[] = Settings.getValueHierarchy( 571 this.getClass(), SettingsNames.KEY_BINDING_LIST); 572 for (int i = kv.length - 1; i >= 0; i--) { 574 List keyList = (List )kv[i].value; 575 JTextComponent.KeyBinding [] keys = new JTextComponent.KeyBinding [keyList.size()]; 576 keyList.toArray(keys); 577 km.load(keys, getActionMap()); 578 } 579 580 km.setDefaultAction((Action )getActionMap().get(defaultKeyTypedAction)); 581 582 kitKeymaps.put(this.getClass(), km); 583 } 584 return km; 585 } 586 } 587 588 589 public void read(Reader in, Document doc, int pos) 590 throws IOException , BadLocationException { 591 if (doc instanceof BaseDocument) { 592 ((BaseDocument)doc).read(in, pos); } else { 594 super.read(in, doc, pos); 595 } 596 } 597 598 599 public void write(Writer out, Document doc, int pos, int len) 600 throws IOException , BadLocationException { 601 if (doc instanceof BaseDocument) { 602 ((BaseDocument)doc).write(out, pos, len); 603 } else { 604 super.write(out, doc, pos, len); 605 } 606 } 607 608 611 public static Map actionsToMap(Action [] actions) { 612 Map map = new HashMap (); 613 for (int i = 0; i < actions.length; i++) { 614 Action a = actions[i]; 615 String name = (String )a.getValue(Action.NAME); 616 map.put(((name != null) ? name : ""), a); } 618 return map; 619 } 620 621 624 public static Action [] mapToActions(Map map) { 625 Action [] actions = new Action [map.size()]; 626 int i = 0; 627 for (Iterator iter = map.values().iterator() ; iter.hasNext() ;) { 628 actions[i++] = (Action )iter.next(); 629 } 630 return actions; 631 } 632 633 634 public void install(JEditorPane c) { 635 636 assert (SwingUtilities.isEventDispatchThread()) : "BaseKit.install() incorrectly called from non-AWT thread."; 639 BaseTextUI ui = createTextUI(); 640 c.setUI(ui); 641 642 String propName = "netbeans.editor.noinputmethods"; Object noInputMethods = System.getProperty(propName); 644 boolean enableIM; 645 if (noInputMethods != null) { 646 enableIM = !Boolean.getBoolean(propName); 647 } else { 648 enableIM = SettingsUtil.getBoolean(this.getClass(), 649 SettingsNames.INPUT_METHODS_ENABLED, true); 650 } 651 652 c.enableInputMethods(enableIM); 653 executeInstallActions(c); 654 655 c.putClientProperty("hyperlink-operation", org.netbeans.lib.editor.hyperlink.HyperlinkOperation.create(c, getContentType())); 657 658 c.putClientProperty("context-api-aware", Boolean.TRUE); } 661 662 protected void executeInstallActions(JEditorPane c) { 663 Settings.KitAndValue[] kv = Settings.getValueHierarchy(this.getClass(), 664 SettingsNames.KIT_INSTALL_ACTION_NAME_LIST); 665 for (int i = kv.length - 1; i >= 0; i--) { 666 List actList = (List )kv[i].value; 667 actList = translateActionNameList(actList); if (actList != null) { 669 for (Iterator iter = actList.iterator(); iter.hasNext();) { 670 Action a = (Action )iter.next(); 671 a.actionPerformed(new ActionEvent (c, ActionEvent.ACTION_PERFORMED, "")); } 673 } 674 } 675 } 676 677 public void deinstall(JEditorPane c) { 678 679 assert (SwingUtilities.isEventDispatchThread()); 681 BaseTextUI.uninstallUIWatcher(c); 682 executeDeinstallActions(c); 683 c.updateUI(); 684 685 if (c.getClientProperty("ancestorOverride") != null) { c.putClientProperty("ancestorOverride", Boolean.FALSE); } 689 } 690 691 protected void executeDeinstallActions(JEditorPane c) { 692 Settings.KitAndValue[] kv = Settings.getValueHierarchy(this.getClass(), 693 SettingsNames.KIT_DEINSTALL_ACTION_NAME_LIST); 694 for (int i = kv.length - 1; i >= 0; i--) { 695 List actList = (List )kv[i].value; 696 actList = translateActionNameList(actList); if (actList != null) { 698 for (Iterator iter = actList.iterator(); iter.hasNext();) { 699 Action a = (Action )iter.next(); 700 a.actionPerformed(new ActionEvent (c, ActionEvent.ACTION_PERFORMED, "")); } 702 } 703 } 704 } 705 706 707 protected void initDocument(BaseDocument doc) { 708 } 709 710 715 protected Action [] createActions() { 716 return new Action [] { 717 new DefaultKeyTypedAction(), 718 new InsertContentAction(), 719 new InsertBreakAction(), 720 new SplitLineAction(), 721 new InsertTabAction(), 722 deletePrevCharActionDef, 723 deleteNextCharActionDef, 724 new ReadOnlyAction(), 725 new WritableAction(), 726 cutActionDef, 727 copyActionDef, 728 pasteActionDef, 729 new PasteAction(true), 730 new BeepAction(), 731 new UpAction(upAction, false), 732 new UpAction(selectionUpAction, true), 733 new PageUpAction(pageUpAction, false), 734 new PageUpAction(selectionPageUpAction, true), 735 new DownAction(downAction, false), 736 new DownAction(selectionDownAction, true), 737 new PageDownAction(selectionPageDownAction, true), 738 new PageDownAction(pageDownAction, false), 739 new ForwardAction(forwardAction, false), 740 new ForwardAction(selectionForwardAction, true), 741 new BackwardAction(backwardAction, false), 742 new BackwardAction(selectionBackwardAction, true), 743 new BeginLineAction(lineFirstColumnAction, false, true), 744 new BeginLineAction(selectionLineFirstColumnAction, true, true), 745 new BeginLineAction(beginLineAction, false), 746 new BeginLineAction(selectionBeginLineAction, true), 747 new EndLineAction(endLineAction, false), 748 new EndLineAction(selectionEndLineAction, true), 749 new BeginAction(beginAction, false), 750 new BeginAction(selectionBeginAction, true), 751 new EndAction(endAction, false), 752 new EndAction(selectionEndAction, true), 753 new NextWordAction(nextWordAction, false), 754 new NextWordAction(selectionNextWordAction, true), 755 new PreviousWordAction(previousWordAction, false), 756 new PreviousWordAction(selectionPreviousWordAction, true), 757 new BeginWordAction(beginWordAction, false), 758 new BeginWordAction(selectionBeginWordAction, true), 759 new EndWordAction(endWordAction, false), 760 new EndWordAction(selectionEndWordAction, true), 761 new SelectWordAction(), 762 new SelectLineAction(), 763 new SelectAllAction(), 764 new RemoveTrailingSpacesAction(), 765 new ActionFactory.RemoveTabAction(), 766 new ActionFactory.RemoveWordPreviousAction(), 768 new ActionFactory.RemoveWordNextAction(), 769 new ActionFactory.RemoveLineBeginAction(), 770 new ActionFactory.RemoveLineAction(), 771 removeSelectionActionDef, 772 new ActionFactory.ToggleTypingModeAction(), 773 new ActionFactory.AbbrevExpandAction(), 774 new ActionFactory.AbbrevResetAction(), 775 new ActionFactory.ChangeCaseAction(toUpperCaseAction, Utilities.CASE_UPPER), 776 new ActionFactory.ChangeCaseAction(toLowerCaseAction, Utilities.CASE_LOWER), 777 new ActionFactory.ChangeCaseAction(switchCaseAction, Utilities.CASE_SWITCH), 778 new ActionFactory.FindNextAction(), 779 new ActionFactory.FindPreviousAction(), 780 new ActionFactory.FindSelectionAction(), 781 new ActionFactory.ToggleHighlightSearchAction(), 782 undoActionDef, 783 redoActionDef, 784 new ActionFactory.WordMatchAction(wordMatchNextAction, true), 785 new ActionFactory.WordMatchAction(wordMatchPrevAction, false), 786 new ActionFactory.ReindentLineAction(), 787 new ActionFactory.ShiftLineAction(shiftLineLeftAction, false), 788 new ActionFactory.ShiftLineAction(shiftLineRightAction, true), 789 new ActionFactory.AdjustWindowAction(adjustWindowTopAction, 0), 790 new ActionFactory.AdjustWindowAction(adjustWindowCenterAction, 50), 791 new ActionFactory.AdjustWindowAction(adjustWindowBottomAction, 100), 792 new ActionFactory.AdjustCaretAction(adjustCaretTopAction, 0), 793 new ActionFactory.AdjustCaretAction(adjustCaretCenterAction, 50), 794 new ActionFactory.AdjustCaretAction(adjustCaretBottomAction, 100), 795 new ActionFactory.FormatAction(), 796 new ActionFactory.FirstNonWhiteAction(firstNonWhiteAction, false), 797 new ActionFactory.FirstNonWhiteAction(selectionFirstNonWhiteAction, true), 798 new ActionFactory.LastNonWhiteAction(lastNonWhiteAction, false), 799 new ActionFactory.LastNonWhiteAction(selectionLastNonWhiteAction, true), 800 new ActionFactory.SelectIdentifierAction(), 801 new ActionFactory.SelectNextParameterAction(), 802 new ActionFactory.JumpListPrevAction(), 803 new ActionFactory.JumpListNextAction(), 804 new ActionFactory.JumpListPrevComponentAction(), 805 new ActionFactory.JumpListNextComponentAction(), 806 new ActionFactory.ScrollUpAction(), 807 new ActionFactory.ScrollDownAction(), 808 new ActionFactory.StartMacroRecordingAction(), 809 new ActionFactory.StopMacroRecordingAction(), 810 new ActionFactory.InsertDateTimeAction(), 811 new ActionFactory.GenerateGutterPopupAction(), 812 new ActionFactory.ToggleLineNumbersAction(), 813 new ActionFactory.AnnotationsCyclingAction(), 814 new ActionFactory.CollapseFold(), 815 new ActionFactory.ExpandFold(), 816 new ActionFactory.CollapseAllFolds(), 817 new ActionFactory.ExpandAllFolds(), 818 new ActionFactory.DumpViewHierarchyAction(), 819 new ActionFactory.StartNewLine(), 820 new ActionFactory.CutToLineBeginOrEndAction(false), 821 new ActionFactory.CutToLineBeginOrEndAction(true), 822 823 }; 828 } 829 830 protected Action [] getCustomActions() { 831 Settings.KitAndValue kv[] = Settings.getValueHierarchy( 832 this.getClass(), SettingsNames.CUSTOM_ACTION_LIST); 833 if (kv.length == 0) { 834 return null; 835 } 836 if (kv.length == 1) { 837 List l = (List )kv[0].value; 838 return (Action [])l.toArray(new Action [l.size()]); 839 } 840 List l = new ArrayList (); 842 for (int i = kv.length - 1; i >= 0; i--) { l.addAll((List )kv[i].value); 844 } 845 return (Action [])l.toArray(new Action [l.size()]); 846 } 847 848 protected Action [] getMacroActions() { 849 Class kitClass = this.getClass(); 850 Map macroMap = (Map )Settings.getValue( kitClass, SettingsNames.MACRO_MAP); 851 if( macroMap == null ) return null; 852 List actions = new ArrayList (); 853 for( Iterator it = macroMap.keySet().iterator(); it.hasNext(); ) { 854 String macroName = (String )it.next(); 855 actions.add( new ActionFactory.RunMacroAction( macroName ) ); 856 } 857 return (Action [])actions.toArray( new Action [ actions.size() ] ); 858 } 859 860 863 public final Action [] getActions() { 864 synchronized (Settings.class) { Class thisClass = this.getClass(); 866 Action [] actions = (Action [])kitActions.get(thisClass); 867 if (actions == null) { 868 Action [] createdActions = createActions(); 870 updateActionSettings(createdActions, null, thisClass); 871 Map actionMap = actionsToMap(createdActions); 872 Action [] customActions = getCustomActions(); 874 if (customActions != null) { 875 updateActionSettings(customActions, null, thisClass); 876 actionMap.putAll(actionsToMap(customActions)); 877 } 878 Action [] macroActions = getMacroActions(); 879 if (macroActions != null) { 880 updateActionSettings(macroActions, null, thisClass); 881 actionMap.putAll(actionsToMap(macroActions)); 882 } 883 884 kitActionMaps.put(thisClass, actionMap); 886 actions = mapToActions(actionMap); 888 kitActions.put(thisClass, actions); 889 890 updateActions(); 893 } 894 return actions; 895 } 896 } 897 898 Map getActionMap() { 899 Map actionMap = (Map )kitActionMaps.get(this.getClass()); 900 if (actionMap == null) { 901 getActions(); actionMap = (Map )kitActionMaps.get(this.getClass()); 903 904 if (actionMap == null) { 906 actionMap = Collections.EMPTY_MAP; 907 } 908 } 909 return actionMap; 910 } 911 912 918 protected void updateActions() { 919 } 920 921 922 public Action getActionByName(String name) { 923 return (name != null) ? (Action )getActionMap().get(name) : null; 924 } 925 926 public List translateActionNameList(List actionNameList) { 927 List ret = new ArrayList (); 928 if (actionNameList != null) { 929 Iterator i = actionNameList.iterator(); 930 while (i.hasNext()) { 931 Action a = getActionByName((String )i.next()); 932 if (a != null) { 933 ret.add(a); 934 } 935 } 936 } 937 return ret; 938 } 939 940 941 942 943 public static class DefaultKeyTypedAction extends LocalBaseAction { 944 945 static final long serialVersionUID =3069164318144463899L; 946 947 public DefaultKeyTypedAction() { 948 super(defaultKeyTypedAction, MAGIC_POSITION_RESET | SAVE_POSITION 949 | CLEAR_STATUS_TEXT); 950 putValue(BaseAction.NO_KEYBINDING, Boolean.TRUE); 951 } 952 953 private static final boolean isMac = System.getProperty("mrj.version") != null; public void actionPerformed(ActionEvent evt, JTextComponent target) { 955 if ((target != null) && (evt != null)) { 956 957 int mod = evt.getModifiers(); 959 boolean ctrl = ((mod & ActionEvent.CTRL_MASK) != 0); 960 boolean alt = isMac ? ((mod & ActionEvent.META_MASK) != 0) : 963 ((mod & ActionEvent.ALT_MASK) != 0); 964 965 966 if (alt || ctrl) { 967 return; 968 } 969 970 if (!target.isEditable() || !target.isEnabled()) { 972 target.getToolkit().beep(); 973 return; 974 } 975 976 Caret caret = target.getCaret(); 977 BaseDocument doc = (BaseDocument)target.getDocument(); 978 EditorUI editorUI = Utilities.getEditorUI(target); 979 String cmd = evt.getActionCommand(); 981 if ((cmd != null) && (cmd.length() == 1)) { 982 984 doc.atomicLock(); 985 DocumentUtilities.setTypingModification(doc, true); 986 try { 987 char ch = cmd.charAt(0); 988 if ((ch >= 0x20) && (ch != 0x7F)) { editorUI.getWordMatch().clear(); Boolean overwriteMode = (Boolean )editorUI.getProperty( 991 EditorUI.OVERWRITE_MODE_PROPERTY); 992 try { 993 boolean doInsert = true; if (doInsert) { 995 if (caret.isSelectionVisible()) { boolean ovr = (overwriteMode != null && overwriteMode.booleanValue()); 997 try { 998 doc.putProperty(DOC_REPLACE_SELECTION_PROPERTY, true); 999 replaceSelection(target, caret.getDot(), caret, cmd, ovr); 1000 } finally { 1001 doc.putProperty(DOC_REPLACE_SELECTION_PROPERTY, null); 1002 } 1003 } else { int dotPos = caret.getDot(); 1005 if (overwriteMode != null && overwriteMode.booleanValue() 1006 && dotPos < doc.getLength() && doc.getChars(dotPos, 1)[0] != '\n' 1007 ) { doc.atomicLock(); 1009 try { 1010 insertString(doc, dotPos, caret, cmd, true); 1011 } finally { 1012 doc.atomicUnlock(); 1013 } 1014 } else { doc.atomicLock(); 1016 try { 1017 insertString(doc, dotPos, caret, cmd, false); 1018 } finally { 1019 doc.atomicUnlock(); 1020 } 1021 } 1022 } 1023 } 1024 } catch (BadLocationException e) { 1025 target.getToolkit().beep(); 1026 } 1027 } 1028 1029 checkIndent(target, cmd); 1030 } finally { 1031 DocumentUtilities.setTypingModification(doc, false); 1032 doc.atomicUnlock(); 1033 } 1034 } 1035 1036 } 1037 } 1038 1039 1045 protected void insertString(BaseDocument doc, 1046 int dotPos, 1047 Caret caret, 1048 String str, 1049 boolean overwrite) 1050 throws BadLocationException 1051 { 1052 if (overwrite) doc.remove(dotPos, 1); 1053 doc.insertString(dotPos, str, null); 1054 } 1055 1056 1062 protected void replaceSelection(JTextComponent target, 1063 int dotPos, 1064 Caret caret, 1065 String str, 1066 boolean overwrite) 1067 throws BadLocationException 1068 { 1069 target.replaceSelection(str); 1070 } 1071 1072 1073 1076 protected void checkIndent(JTextComponent target, String typedText) { 1077 } 1078 1079 } 1080 1081 public static class InsertBreakAction extends LocalBaseAction { 1082 1083 static final long serialVersionUID =7966576342334158659L; 1084 1085 public InsertBreakAction() { 1086 super(insertBreakAction, MAGIC_POSITION_RESET | ABBREV_RESET | WORD_MATCH_RESET); 1087 } 1088 1089 public void actionPerformed(ActionEvent evt, JTextComponent target) { 1090 if (target != null) { 1091 if (!target.isEditable() || !target.isEnabled()) { 1092 target.getToolkit().beep(); 1093 return; 1094 } 1095 1096 BaseDocument doc = (BaseDocument)target.getDocument(); 1097 doc.atomicLock(); 1098 DocumentUtilities.setTypingModification(doc, true); 1099 try{ 1100 target.replaceSelection(""); 1101 Caret caret = target.getCaret(); 1102 Object cookie = beforeBreak(target, doc, caret); 1103 1104 int dotPos = caret.getDot(); 1105 int newDotPos = doc.getFormatter().indentNewLine(doc, dotPos); 1106 caret.setDot(newDotPos); 1107 1108 afterBreak(target, doc, caret, cookie); 1109 } finally { 1110 DocumentUtilities.setTypingModification(doc, false); 1111 doc.atomicUnlock(); 1112 } 1113 } 1114 } 1115 1116 1120 protected Object beforeBreak(JTextComponent target, BaseDocument doc, Caret caret) { 1121 return null; 1122 } 1123 1124 1129 protected void afterBreak(JTextComponent target, BaseDocument doc, Caret caret, Object data) { 1130 } 1131 } 1132 1133 public static class SplitLineAction extends LocalBaseAction { 1134 1135 static final long serialVersionUID =7966576342334158659L; 1136 1137 public SplitLineAction() { 1138 super(splitLineAction, MAGIC_POSITION_RESET | ABBREV_RESET | WORD_MATCH_RESET); 1139 } 1140 1141 public void actionPerformed(ActionEvent evt, JTextComponent target) { 1142 if (target != null) { 1143 if (!target.isEditable() || !target.isEnabled()) { 1144 target.getToolkit().beep(); 1145 return; 1146 } 1147 1148 BaseDocument doc = (BaseDocument)target.getDocument(); 1149 Caret caret = target.getCaret(); 1150 int dotPos = caret.getDot(); 1151 1152 doc.atomicLock(); 1153 DocumentUtilities.setTypingModification(doc, true); 1154 try{ 1155 target.replaceSelection(""); 1156 int newDotPos = dotPos; doc.getFormatter().indentNewLine(doc, dotPos); caret.setDot(newDotPos); 1159 } finally { 1160 DocumentUtilities.setTypingModification(doc, false); 1161 doc.atomicUnlock(); 1162 } 1163 } 1164 } 1165 1166 } 1167 1168 1169 public static class InsertTabAction extends LocalBaseAction { 1170 1171 static final long serialVersionUID =-3379768531715989243L; 1172 1173 public InsertTabAction() { 1174 super(insertTabAction, MAGIC_POSITION_RESET | ABBREV_RESET | WORD_MATCH_RESET); 1175 } 1176 1177 public void actionPerformed(ActionEvent evt, JTextComponent target) { 1178 if (target != null) { 1179 if (!target.isEditable() || !target.isEnabled()) { 1180 target.getToolkit().beep(); 1181 return; 1182 } 1183 1184 Caret caret = target.getCaret(); 1185 BaseDocument doc = (BaseDocument)target.getDocument(); 1186 doc.atomicLock(); 1187 DocumentUtilities.setTypingModification(doc, true); 1188 try { 1189 if (caret.isSelectionVisible()) { try { 1191 doc.getFormatter().changeBlockIndent(doc, 1192 target.getSelectionStart(), target.getSelectionEnd(), +1); 1193 } catch (GuardedException e) { 1194 target.getToolkit().beep(); 1195 } catch (BadLocationException e) { 1196 e.printStackTrace(); 1197 } 1198 } else { int dotPos = caret.getDot(); 1200 int caretCol; 1201 try { 1203 caretCol = doc.getVisColFromPos(dotPos); 1204 } catch (BadLocationException e) { 1205 LOG.log(Level.WARNING, null, e); 1206 caretCol = 0; 1207 } 1208 1209 try { 1210 int upperCol = Utilities.getRowIndent(doc, dotPos, false); 1212 if (upperCol == -1) { upperCol = 0; 1214 } 1215 int indent = Utilities.getRowIndent(doc, dotPos); 1217 if (indent == -1) { 1219 if (upperCol > caretCol) { indent = upperCol; 1221 } else { indent = Utilities.getNextTabColumn(doc, dotPos); 1223 } 1224 1225 int rowStart = Utilities.getRowStart(doc, dotPos); 1227 1228 doc.getFormatter().changeRowIndent(doc, dotPos, indent); 1229 1230 int newDotPos = doc.getOffsetFromVisCol(indent, rowStart); 1232 if (newDotPos >= 0) { 1233 caret.setDot(newDotPos); 1234 } 1235 1236 } else { doc.getFormatter().insertTabString(doc, dotPos); 1238 1239 } 1240 } catch (BadLocationException e) { 1241 } 1243 } 1244 } finally { 1245 DocumentUtilities.setTypingModification(doc, false); 1246 doc.atomicUnlock(); 1247 } 1248 } 1249 1250 } 1251 1252 } 1253 1254 1255 public static class CompoundAction extends LocalBaseAction { 1256 1257 Action [] actions; 1258 1259 static final long serialVersionUID =1649688300969753758L; 1260 1261 public CompoundAction(String nm, Action actions[]) { 1262 this(nm, 0, actions); 1263 } 1264 1265 public CompoundAction(String nm, int resetMask, Action actions[]) { 1266 super(nm, resetMask); 1267 this.actions = actions; 1268 } 1269 1270 public void actionPerformed(ActionEvent evt, JTextComponent target) { 1271 if (target != null) { 1272 for (int i = 0; i < actions.length; i++) { 1273 Action a = actions[i]; 1274 if (a instanceof BaseAction) { 1275 ((BaseAction)a).actionPerformed(evt, target); 1276 } else { 1277 a.actionPerformed(evt); 1278 } 1279 } 1280 } 1281 } 1282 } 1283 1284 1289 public static class KitCompoundAction extends LocalBaseAction { 1290 1291 private String [] actionNames; 1292 1293 static final long serialVersionUID =8415246475764264835L; 1294 1295 public KitCompoundAction(String nm, String actionNames[]) { 1296 this(nm, 0, actionNames); 1297 } 1298 1299 public KitCompoundAction(String nm, int resetMask, String actionNames[]) { 1300 super(nm, resetMask); 1301 this.actionNames = actionNames; 1302 } 1303 1304 public void actionPerformed(ActionEvent evt, JTextComponent target) { 1305 if (target != null) { 1306 BaseKit kit = Utilities.getKit(target); 1307 if (kit != null) { 1308 for (int i = 0; i < actionNames.length; i++) { 1309 Action a = kit.getActionByName(actionNames[i]); 1310 if (a != null) { 1311 if (a instanceof BaseAction) { 1312 ((BaseAction)a).actionPerformed(evt, target); 1313 } else { 1314 a.actionPerformed(evt); 1315 } 1316 } 1317 } 1318 } 1319 } 1320 } 1321 } 1322 1323 public static class InsertContentAction extends LocalBaseAction { 1324 1325 static final long serialVersionUID =5647751370952797218L; 1326 1327 public InsertContentAction() { 1328 super(insertContentAction, MAGIC_POSITION_RESET | ABBREV_RESET 1329 | WORD_MATCH_RESET); 1330 putValue(BaseAction.NO_KEYBINDING, Boolean.TRUE); 1331 } 1332 1333 public void actionPerformed(ActionEvent evt, JTextComponent target) { 1334 if ((target != null) && (evt != null)) { 1335 if (!target.isEditable() || !target.isEnabled()) { 1336 target.getToolkit().beep(); 1337 return; 1338 } 1339 1340 String content = evt.getActionCommand(); 1341 if (content != null) { 1342 target.replaceSelection(content); 1343 } else { 1344 target.getToolkit().beep(); 1345 } 1346 } 1347 } 1348 } 1349 1350 1351 public static class InsertStringAction extends LocalBaseAction { 1352 1353 String text; 1354 1355 static final long serialVersionUID =-2755852016584693328L; 1356 1357 public InsertStringAction(String nm, String text) { 1358 super(nm, MAGIC_POSITION_RESET | ABBREV_RESET | WORD_MATCH_RESET); 1359 this.text = text; 1360 } 1361 1362 public void actionPerformed(ActionEvent evt, JTextComponent target) { 1363 if (target != null) { 1364 if (!target.isEditable() || !target.isEnabled()) { 1365 target.getToolkit().beep(); 1366 return; 1367 } 1368 1369 target.replaceSelection(text); 1370 } 1371 } 1372 } 1373 1374 1375 public static class DeleteCharAction extends LocalBaseAction { 1376 1377 protected boolean nextChar; 1378 1379 static final long serialVersionUID =-4321971925753148556L; 1380 1381 public DeleteCharAction(String nm, boolean nextChar) { 1382 super(nm, MAGIC_POSITION_RESET | ABBREV_RESET | WORD_MATCH_RESET); 1383 this.nextChar = nextChar; 1384 } 1385 1386 public void actionPerformed(ActionEvent evt, JTextComponent target) { 1387 if (target != null) { 1388 if (!target.isEditable() || !target.isEnabled()) { 1389 target.getToolkit().beep(); 1390 return; 1391 } 1392 1393 BaseDocument doc = (BaseDocument)target.getDocument(); 1394 Caret caret = target.getCaret(); 1395 int dot = caret.getDot(); 1396 int mark = caret.getMark(); 1397 1398 doc.atomicLock(); 1399 DocumentUtilities.setTypingModification(doc, true); 1400 1401 try { 1402 if (dot != mark) { doc.remove(Math.min(dot, mark), Math.abs(dot - mark)); 1404 } else { 1405 if (nextChar) { doc.remove(dot, 1); 1407 } else { char ch = doc.getChars(dot-1, 1)[0]; 1409 doc.remove(dot - 1, 1); 1410 charBackspaced(doc, dot-1, caret, ch); 1411 } 1412 } 1413 } catch (BadLocationException e) { 1414 target.getToolkit().beep(); 1415 } finally { 1416 DocumentUtilities.setTypingModification(doc, false); 1417 doc.atomicUnlock(); 1418 } 1419 1420 } 1421 } 1422 1423 protected void charBackspaced(BaseDocument doc, int dotPos, Caret caret, char ch) 1424 throws BadLocationException 1425 { 1426 } 1427 } 1428 1429 public static class ReadOnlyAction extends LocalBaseAction { 1430 1431 static final long serialVersionUID =9204335480208463193L; 1432 1433 public ReadOnlyAction() { 1434 super(readOnlyAction); 1435 putValue(BaseAction.NO_KEYBINDING, Boolean.TRUE); 1436 } 1437 1438 public void actionPerformed(ActionEvent evt, JTextComponent target) { 1439 if (target != null) { 1440 target.setEditable(false); 1441 } 1442 } 1443 } 1444 1445 public static class WritableAction extends LocalBaseAction { 1446 1447 static final long serialVersionUID =-5982547952800937954L; 1448 1449 public WritableAction() { 1450 super(writableAction); 1451 putValue(BaseAction.NO_KEYBINDING, Boolean.TRUE); 1452 } 1453 1454 public void actionPerformed(ActionEvent evt, JTextComponent target) { 1455 if (target != null) { 1456 target.setEditable(true); 1457 } 1458 } 1459 } 1460 1461 public static class CutAction extends LocalBaseAction { 1462 1463 static final long serialVersionUID =6377157040901778853L; 1464 1465 public CutAction() { 1466 super(cutAction, ABBREV_RESET | UNDO_MERGE_RESET | WORD_MATCH_RESET); 1467 setEnabled(false); 1468 } 1470 1471 public void actionPerformed(ActionEvent evt, JTextComponent target) { 1472 if (target != null) { 1473 if (!target.isEditable() || !target.isEnabled()) { 1474 target.getToolkit().beep(); 1475 return; 1476 } 1477 1478 BaseDocument doc = (BaseDocument)target.getDocument(); 1479 doc.atomicLock(); 1480 DocumentUtilities.setTypingModification(doc, true); 1481 try { 1482 target.cut(); 1483 } finally { 1484 DocumentUtilities.setTypingModification(doc, false); 1485 doc.atomicUnlock(); 1486 } 1487 } 1488 } 1489 } 1490 1491 public static class CopyAction extends LocalBaseAction { 1492 1493 static final long serialVersionUID =-5119779005431986964L; 1494 1495 public CopyAction() { 1496 super(copyAction, ABBREV_RESET | UNDO_MERGE_RESET | WORD_MATCH_RESET); 1497 setEnabled(false); 1498 } 1500 1501 public void actionPerformed(ActionEvent evt, JTextComponent target) { 1502 if (target != null) { 1503 target.copy(); 1504 } 1505 } 1506 } 1507 1508 public static class PasteAction extends LocalBaseAction { 1509 1510 static final long serialVersionUID =5839791453996432149L; 1511 private boolean formated; 1512 1513 public PasteAction(boolean formated) { 1514 super(formated ? pasteFormatedAction : pasteAction, ABBREV_RESET | UNDO_MERGE_RESET | WORD_MATCH_RESET); 1515 this.formated = formated; 1517 } 1518 1519 public void actionPerformed(ActionEvent evt, JTextComponent target) { 1520 if (target != null) { 1521 if (!target.isEditable() || !target.isEnabled()) { 1522 target.getToolkit().beep(); 1523 return; 1524 } 1525 1526 1527 BaseDocument doc = Utilities.getDocument(target); 1528 if (doc==null) return; 1529 1530 doc.atomicLock(); 1531 DocumentUtilities.setTypingModification(doc, true); 1532 try{ 1533 if (formated) { 1534 Caret caret = target.getCaret(); 1535 int prevPos = target.getSelectionStart(); 1536 target.paste(); 1537 int postPos = caret.getDot(); 1538 indentBlock(doc, prevPos, postPos); 1539 } else { 1540 target.paste(); 1541 } 1542 }catch(Exception e){ 1543 target.getToolkit().beep(); 1544 } finally { 1546 DocumentUtilities.setTypingModification(doc, false); 1547 doc.atomicUnlock(); 1548 } 1549 } 1550 } 1551 1552 public static void indentBlock(BaseDocument doc, int startOffset, int endOffset) 1553 throws BadLocationException 1554 { 1555 char [] text = doc.getChars(startOffset, endOffset-startOffset); 1556 String [] lines = toLines(new String (text)); 1557 1558 doc.remove(startOffset, endOffset - startOffset); 1559 1562 int offset = startOffset; 1563 for (int i = 0; i < lines.length - 1; i++) { 1565 String indent = getIndentString(doc, offset, lines[i]); 1566 String fragment = indent + lines[i].trim() + '\n'; 1567 doc.insertString(offset, fragment, null); 1569 offset += fragment.length(); 1570 } 1571 1572 doc.insertString(offset, lines[lines.length-1], null); 1574 1575 } 1576 1577 1578 private static String [] toLines(String str) { 1579 Vector v = new Vector (); 1580 int p=0 , p0=0; 1581 for (; p < str.length() ; p++) { 1582 if (str.charAt(p) == '\n') { 1583 v.add(str.substring(p0, p+1)); 1584 p0 = p+1; 1585 } 1586 } 1587 if (p0 < str.length()) v.add(str.substring(p0, str.length())); else v.add(""); 1588 1589 return (String [])v.toArray(new String [0]); 1590 } 1591 1592 private static String getIndentString(BaseDocument doc, int startOffset, String str) { 1593 try { 1594 Formatter f = doc.getFormatter(); 1595 CharArrayWriter cw = new CharArrayWriter (); 1596 Writer w = f.createWriter(doc, startOffset, cw); 1597 w.write(str, 0, str.length()); 1598 w.close(); 1599 String out = new String (cw.toCharArray()); 1600 int i = 0; 1601 for (; i < out.length(); i++) { 1602 if (out.charAt(i) != ' ' && out.charAt(i) != '\t') break; 1603 } 1604 1607 return out.substring(0, i); 1608 } catch (java.io.IOException e) { 1609 return ""; 1610 } 1611 } 1612 } 1613 1614 1615 1616 public static class BeepAction extends LocalBaseAction { 1617 1618 static final long serialVersionUID =-4474054576633223968L; 1619 1620 public BeepAction() { 1621 super(beepAction); 1622 putValue(BaseAction.NO_KEYBINDING, Boolean.TRUE); 1623 } 1624 1625 public void actionPerformed(ActionEvent evt, JTextComponent target) { 1626 if (target != null) { 1627 target.getToolkit().beep(); 1628 } 1629 } 1630 } 1631 1632 1633 public static class UpAction extends LocalBaseAction { 1634 1635 boolean select; 1636 1637 static final long serialVersionUID =4621760742646981563L; 1638 1639 public UpAction(String nm, boolean select) { 1640 super(nm, ABBREV_RESET | UNDO_MERGE_RESET | WORD_MATCH_RESET 1641 | CLEAR_STATUS_TEXT); 1642 this.select = select; 1643 } 1644 1645 public void actionPerformed(ActionEvent evt, JTextComponent target) { 1646 if (target != null) { 1647 try { 1648 Caret caret = target.getCaret(); 1649 int dot = caret.getDot(); 1650 Point p = caret.getMagicCaretPosition(); 1651 if (p == null) { 1652 Rectangle r = target.modelToView(dot); 1653 if (r!=null){ 1654 p = new Point (r.x, r.y); 1655 caret.setMagicCaretPosition(p); 1656 }else{ 1657 return; } 1659 } 1660 try { 1661 dot = Utilities.getPositionAbove(target, dot, p.x); 1662 if (select) { 1663 caret.moveDot(dot); 1664 } else { 1665 caret.setDot(dot); 1666 } 1667 } catch (BadLocationException e) { 1668 } 1670 } catch (BadLocationException ex) { 1671 target.getToolkit().beep(); 1672 } 1673 } 1674 } 1675 } 1676 1677 public static class DownAction extends LocalBaseAction { 1678 1679 boolean select; 1680 1681 static final long serialVersionUID =-5635702355125266822L; 1682 1683 public DownAction(String nm, boolean select) { 1684 super(nm, ABBREV_RESET | UNDO_MERGE_RESET | WORD_MATCH_RESET 1685 | CLEAR_STATUS_TEXT); 1686 this.select = select; 1687 } 1688 1689 public void actionPerformed(ActionEvent evt, JTextComponent target) { 1690 if (target != null) { 1691 try { 1692 Caret caret = target.getCaret(); 1693 int dot = caret.getDot(); 1694 Point p = caret.getMagicCaretPosition(); 1695 if (p == null) { 1696 Rectangle r = target.modelToView(dot); 1697 if (r!=null){ 1698 p = new Point (r.x, r.y); 1699 caret.setMagicCaretPosition(p); 1700 }else{ 1701 return; } 1703 } 1704 try { 1705 dot = Utilities.getPositionBelow(target, dot, p.x); 1706 if (select) { 1707 caret.moveDot(dot); 1708 } else { 1709 caret.setDot(dot); 1710 } 1711 } catch (BadLocationException e) { 1712 } 1714 } catch (BadLocationException ex) { 1715 target.getToolkit().beep(); 1716 } 1717 } 1718 } 1719 } 1720 1721 1722 public static class PageUpAction extends LocalBaseAction { 1723 1724 boolean select; 1725 1726 static final long serialVersionUID =-3107382148581661079L; 1727 1728 public PageUpAction(String nm, boolean select) { 1729 super(nm, ABBREV_RESET | UNDO_MERGE_RESET | WORD_MATCH_RESET 1730 | CLEAR_STATUS_TEXT); 1731 this.select = select; 1732 } 1733 1734 public void actionPerformed(ActionEvent evt, JTextComponent target) { 1735 if (target != null) { 1736 try { 1737 Caret caret = target.getCaret(); 1738 BaseDocument doc = (BaseDocument)target.getDocument(); 1739 int caretOffset = caret.getDot(); 1740 Rectangle caretBounds = ((BaseTextUI)target.getUI()).modelToView(target, caretOffset); 1741 if (caretBounds == null) { 1742 return; } 1744 1745 Point magicCaretPosition = caret.getMagicCaretPosition(); 1749 if (magicCaretPosition == null) { 1750 magicCaretPosition = new Point (caretBounds.x, caretBounds.y); 1751 } 1752 1753 Rectangle visibleBounds = target.getVisibleRect(); 1754 int newCaretOffset; 1755 Rectangle newCaretBounds; 1756 1757 if (visibleBounds.contains(caretBounds)) { 1759 Rectangle newVisibleBounds = new Rectangle (visibleBounds); 1761 int topLeftOffset = target.viewToModel(new Point ( 1766 visibleBounds.x, visibleBounds.y)); 1767 Rectangle topLeftLineBounds = target.modelToView(topLeftOffset); 1768 1769 if (topLeftLineBounds.y != visibleBounds.y) { 1771 newVisibleBounds.y = topLeftLineBounds.y + topLeftLineBounds.height; 1772 } newVisibleBounds.y -= visibleBounds.height; 1775 1776 int caretRelY = caretBounds.y - visibleBounds.y; 1782 int caretNewY = newVisibleBounds.y + caretRelY; 1783 newCaretOffset = target.viewToModel(new Point (magicCaretPosition.x, caretNewY)); 1784 newCaretBounds = target.modelToView(newCaretOffset); 1785 if (newCaretBounds.y < caretNewY) { 1786 newCaretOffset = target.viewToModel(new Point (magicCaretPosition.x, 1790 newCaretBounds.y + newCaretBounds.height)); 1791 newCaretBounds = target.modelToView(newCaretOffset); 1792 } 1793 1794 newVisibleBounds.y = newCaretBounds.y - caretRelY; 1797 1798 target.scrollRectToVisible(newVisibleBounds); 1800 1801 } else { Point newCaretPoint = new Point (magicCaretPosition.x, 1804 caretBounds.y - visibleBounds.height); 1805 newCaretOffset = target.viewToModel(newCaretPoint); 1806 newCaretBounds = target.modelToView(newCaretOffset); 1807 } 1808 1809 if (select) { 1810 caret.moveDot(newCaretOffset); 1811 } else { 1812 caret.setDot(newCaretOffset); 1813 } 1814 1815 magicCaretPosition.y = newCaretBounds.y; 1817 caret.setMagicCaretPosition(magicCaretPosition); 1818 1819 } catch (BadLocationException ex) { 1820 target.getToolkit().beep(); 1821 } 1822 } 1823 } 1824 } 1825 1826 public static class ForwardAction extends LocalBaseAction { 1827 1828 boolean select; 1829 1830 static final long serialVersionUID =8007293230193334414L; 1831 1832 public ForwardAction(String nm, boolean select) { 1833 super(nm, MAGIC_POSITION_RESET | ABBREV_RESET | UNDO_MERGE_RESET 1834 | WORD_MATCH_RESET | CLEAR_STATUS_TEXT); 1835 this.select = select; 1836 } 1837 1838 public void actionPerformed(ActionEvent evt, JTextComponent target) { 1839 if (target != null) { 1840 Caret caret = target.getCaret(); 1841 try { 1842 int pos; 1843 if (!select && caret.isSelectionVisible()) 1844 { 1845 pos = target.getSelectionEnd(); 1846 if (pos != caret.getDot()) 1847 pos--; 1848 } 1849 else 1850 pos = caret.getDot(); 1851 int dot = target.getUI().getNextVisualPositionFrom(target, 1852 pos, Position.Bias.Forward, SwingConstants.EAST, null); 1853 if (select) { 1854 caret.moveDot(dot); 1855 } else { 1856 caret.setDot(dot); 1857 } 1858 } catch (BadLocationException ex) { 1859 target.getToolkit().beep(); 1860 } 1861 } 1862 } 1863 } 1864 1865 1866 public static class PageDownAction extends LocalBaseAction { 1867 1868 boolean select; 1869 1870 static final long serialVersionUID =8942534850985048862L; 1871 1872 public PageDownAction(String nm, boolean select) { 1873 super(nm, ABBREV_RESET | UNDO_MERGE_RESET | WORD_MATCH_RESET 1874 | CLEAR_STATUS_TEXT); 1875 this.select = select; 1876 } 1877 1878 public void actionPerformed(ActionEvent evt, JTextComponent target) { 1879 if (target != null) { 1880 try { 1881 Caret caret = target.getCaret(); 1882 BaseDocument doc = (BaseDocument)target.getDocument(); 1883 int caretOffset = caret.getDot(); 1884 Rectangle caretBounds = ((BaseTextUI)target.getUI()).modelToView(target, caretOffset); 1885 if (caretBounds == null) { 1886 return; } 1888 1889 Point magicCaretPosition = caret.getMagicCaretPosition(); 1893 if (magicCaretPosition == null) { 1894 magicCaretPosition = new Point (caretBounds.x, caretBounds.y); 1895 } 1896 1897 Rectangle visibleBounds = target.getVisibleRect(); 1898 int newCaretOffset; 1899 Rectangle newCaretBounds; 1900 1901 if (visibleBounds.contains(caretBounds)) { 1903 Rectangle newVisibleBounds = new Rectangle (visibleBounds); 1905 int bottomLeftOffset = target.viewToModel(new Point ( 1909 visibleBounds.x, visibleBounds.y + visibleBounds.height)); 1910 Rectangle bottomLeftLineBounds = target.modelToView(bottomLeftOffset); 1911 1912 newVisibleBounds.y = bottomLeftLineBounds.y; 1914 1915 int caretRelY = caretBounds.y - visibleBounds.y; 1921 int caretNewY = newVisibleBounds.y + caretRelY; 1922 newCaretOffset = target.viewToModel(new Point (magicCaretPosition.x, caretNewY)); 1923 newCaretBounds = target.modelToView(newCaretOffset); 1924 if (newCaretBounds.y > caretNewY) { 1925 newCaretOffset = target.viewToModel(new Point (magicCaretPosition.x, 1929 newCaretBounds.y - newCaretBounds.height)); 1930 newCaretBounds = target.modelToView(newCaretOffset); 1931 } 1932 1933 newVisibleBounds.y = newCaretBounds.y - caretRelY; 1936 1937 target.scrollRectToVisible(newVisibleBounds); 1939 1940 } else { Point newCaretPoint = new Point (magicCaretPosition.x, 1943 caretBounds.y + visibleBounds.height); 1944 newCaretOffset = target.viewToModel(newCaretPoint); 1945 newCaretBounds = target.modelToView(newCaretOffset); 1946 } 1947 1948 if (select) { 1949 caret.moveDot(newCaretOffset); 1950 } else { 1951 caret.setDot(newCaretOffset); 1952 } 1953 1954 magicCaretPosition.y = newCaretBounds.y; 1956 caret.setMagicCaretPosition(magicCaretPosition); 1957 1958 } catch (BadLocationException ex) { 1959 target.getToolkit().beep(); 1960 } 1961 } 1962 } 1963 } 1964 1965 public static class BackwardAction extends LocalBaseAction { 1966 1967 boolean select; 1968 1969 static final long serialVersionUID =-3048379822817847356L; 1970 1971 public BackwardAction(String nm, boolean select) { 1972 super(nm, MAGIC_POSITION_RESET | ABBREV_RESET | UNDO_MERGE_RESET 1973 | WORD_MATCH_RESET | CLEAR_STATUS_TEXT); 1974 this.select = select; 1975 } 1976 1977 public void actionPerformed(ActionEvent evt, JTextComponent target) { 1978 if (target != null) { 1979 Caret caret = target.getCaret(); 1980 try { 1981 int pos; 1982 if (!select && caret.isSelectionVisible()) 1983 { 1984 pos = target.getSelectionStart(); 1985 if (pos != caret.getDot()) 1986 pos++; 1987 } 1988 else 1989 pos = caret.getDot(); 1990 int dot = target.getUI().getNextVisualPositionFrom(target, 1991 pos, Position.Bias.Backward, SwingConstants.WEST, null); 1992 if (select) { 1993 caret.moveDot(dot); 1994 } else { 1995 caret.setDot(dot); 1996 } 1997 } catch (BadLocationException ex) { 1998 target.getToolkit().beep(); 1999 } 2000 } 2001 } 2002 } 2003 2004 public static class BeginLineAction extends LocalBaseAction { 2005 2006 protected boolean select; 2007 2008 2010 boolean homeKeyColumnOne; 2011 2012 static final long serialVersionUID =3269462923524077779L; 2013 2014 public BeginLineAction(String nm, boolean select) { 2015 super(nm, MAGIC_POSITION_RESET | ABBREV_RESET | UNDO_MERGE_RESET 2016 | WORD_MATCH_RESET | CLEAR_STATUS_TEXT); 2017 this.select = select; 2018 homeKeyColumnOne = false; 2019 } 2020 2021 public BeginLineAction(String nm, boolean select, boolean columnOne) { 2022 this(nm, select); 2023 homeKeyColumnOne = columnOne; 2024 } 2025 2026 public void actionPerformed(ActionEvent evt, JTextComponent target) { 2027 if (target != null) { 2028 Caret caret = target.getCaret(); 2029 BaseDocument doc = (BaseDocument)target.getDocument(); 2030 try { 2031 int dot = caret.getDot(); 2032 int lineStartPos = Utilities.getRowStart(target, dot); 2033 if (homeKeyColumnOne) { dot = lineStartPos; 2035 } else { int textStartPos = Utilities.getRowFirstNonWhite(doc, lineStartPos); 2037 if (textStartPos < 0) { textStartPos = Utilities.getRowEnd(target, lineStartPos); 2039 } 2040 if (dot == lineStartPos) { dot = textStartPos; 2042 } else if (dot <= textStartPos) { 2043 dot = lineStartPos; 2044 } else { 2045 dot = textStartPos; 2046 } 2047 } 2048 if (select) { 2049 caret.moveDot(dot); 2050 } else { 2051 caret.setDot(dot); 2052 } 2053 } catch (BadLocationException e) { 2054 target.getToolkit().beep(); 2055 } 2056 } 2057 } 2058 } 2059 2060 public static class EndLineAction extends LocalBaseAction { 2061 2062 protected boolean select; 2063 2064 static final long serialVersionUID =5216077634055190170L; 2065 2066 public EndLineAction(String nm, boolean select) { 2067 super(nm, MAGIC_POSITION_RESET | ABBREV_RESET | UNDO_MERGE_RESET 2068 | WORD_MATCH_RESET | CLEAR_STATUS_TEXT); 2069 this.select = select; 2070 } 2071 2072 public void actionPerformed(ActionEvent evt, JTextComponent target) { 2073 if (target != null) { 2074 Caret caret = target.getCaret(); 2075 try { 2076 int dot = Utilities.getRowEnd(target, caret.getDot()); 2077 if (select) { 2078 caret.moveDot(dot); 2079 } else { 2080 caret.setDot(dot); 2081 } 2082 Rectangle r = target.modelToView(dot); 2084 if (r!=null){ 2085 Point p = new Point (MAGIC_POSITION_MAX, r.y); 2086 caret.setMagicCaretPosition(p); 2087 } 2088 } catch (BadLocationException e) { 2089 e.printStackTrace(); 2090 target.getToolkit().beep(); 2091 } 2092 } 2093 } 2094 } 2095 2096 public static class BeginAction extends LocalBaseAction { 2097 2098 boolean select; 2099 2100 static final long serialVersionUID =3463563396210234361L; 2101 2102 public BeginAction(String nm, boolean select) { 2103 super(nm, MAGIC_POSITION_RESET | ABBREV_RESET | UNDO_MERGE_RESET 2104 | WORD_MATCH_RESET | SAVE_POSITION | CLEAR_STATUS_TEXT); 2105 this.select = select; 2106 } 2107 2108 public void actionPerformed(ActionEvent evt, JTextComponent target) { 2109 if (target != null) { 2110 Caret caret = target.getCaret(); 2111 int dot = 0; if (select) { 2113 caret.moveDot(dot); 2114 } else { 2115 caret.setDot(dot); 2116 } 2117 } 2118 } 2119 } 2120 2121 public static class EndAction extends LocalBaseAction { 2122 2123 boolean select; 2124 2125 static final long serialVersionUID =8547506353130203657L; 2126 2127 public EndAction(String nm, boolean select) { 2128 super(nm, MAGIC_POSITION_RESET | ABBREV_RESET | UNDO_MERGE_RESET 2129 | WORD_MATCH_RESET | SAVE_POSITION | CLEAR_STATUS_TEXT); 2130 this.select = select; 2131 } 2132 2133 public void actionPerformed(ActionEvent evt, JTextComponent target) { 2134 if (target != null) { 2135 Caret caret = target.getCaret(); 2136 int dot = target.getDocument().getLength(); if (select) { 2138 caret.moveDot(dot); 2139 } else { 2140 caret.setDot(dot); 2141 } 2142 } 2143 } 2144 } 2145 2146 public static class NextWordAction extends LocalBaseAction { 2147 2148 boolean select; 2149 2150 static final long serialVersionUID =-5909906947175434032L; 2151 2152 public NextWordAction(String nm, boolean select) { 2153 super(nm, MAGIC_POSITION_RESET | ABBREV_RESET | UNDO_MERGE_RESET 2154 | WORD_MATCH_RESET | CLEAR_STATUS_TEXT); 2155 this.select = select; 2156 } 2157 2158 public void actionPerformed(ActionEvent evt, JTextComponent target) { 2159 if (target != null) { 2160 Caret caret = target.getCaret(); 2161 try { 2162 int dotPos = caret.getDot(); 2163 dotPos = Utilities.getNextWord(target, dotPos); 2164 if (caret instanceof BaseCaret){ 2165 BaseCaret bCaret = (BaseCaret) caret; 2166 if (select) { 2167 bCaret.moveDot(dotPos); 2168 } else { 2169 bCaret.setDot(dotPos, false); 2170 } 2171 }else { 2172 if (select) { 2173 caret.moveDot(dotPos); 2174 } else { 2175 caret.setDot(dotPos); 2176 } 2177 } 2178 } catch (BadLocationException ex) { 2179 target.getToolkit().beep(); 2180 } 2181 } 2182 } 2183 } 2184 2185 public static class PreviousWordAction extends LocalBaseAction { 2186 2187 boolean select; 2188 2189 static final long serialVersionUID =-5465143382669785799L; 2190 2191 public PreviousWordAction(String nm, boolean select) { 2192 super(nm, MAGIC_POSITION_RESET | ABBREV_RESET | UNDO_MERGE_RESET 2193 | WORD_MATCH_RESET | CLEAR_STATUS_TEXT); 2194 this.select = select; 2195 } 2196 2197 public void actionPerformed(ActionEvent evt, JTextComponent target) { 2198 if (target != null) { 2199 Caret caret = target.getCaret(); 2200 try { 2201 int dot = Utilities.getPreviousWord(target, caret.getDot()); 2202 if (caret instanceof BaseCaret){ 2203 BaseCaret bCaret = (BaseCaret) caret; 2204 if (select) { 2205 bCaret.moveDot(dot); 2206 } else { 2207 bCaret.setDot(dot, false); 2208 } 2209 }else { 2210 if (select) { 2211 caret.moveDot(dot); 2212 } else { 2213 caret.setDot(dot); 2214 } 2215 } 2216 } catch (BadLocationException ex) { 2217 target.getToolkit().beep(); 2218 } 2219 } 2220 } 2221 } 2222 2223 public static class BeginWordAction extends LocalBaseAction { 2224 2225 boolean select; 2226 2227 static final long serialVersionUID =3991338381212491110L; 2228 2229 public BeginWordAction(String nm, boolean select) { 2230 super(nm, MAGIC_POSITION_RESET | ABBREV_RESET | UNDO_MERGE_RESET 2231 | WORD_MATCH_RESET | CLEAR_STATUS_TEXT); 2232 this.select = select; 2233 } 2234 2235 public void actionPerformed(ActionEvent evt, JTextComponent target) { 2236 if (target != null) { 2237 Caret caret = target.getCaret(); 2238 try { 2239 int dot = Utilities.getWordStart(target, caret.getDot()); 2240 if (select) { 2241 caret.moveDot(dot); 2242 } else { 2243 caret.setDot(dot); 2244 } 2245 } catch (BadLocationException ex) { 2246 target.getToolkit().beep(); 2247 } 2248 } 2249 } 2250 } 2251 2252 public static class EndWordAction extends LocalBaseAction { 2253 2254 boolean select; 2255 2256 static final long serialVersionUID =3812523676620144633L; 2257 2258 public EndWordAction(String nm, boolean select) { 2259 super(nm, MAGIC_POSITION_RESET | ABBREV_RESET | UNDO_MERGE_RESET 2260 | WORD_MATCH_RESET | CLEAR_STATUS_TEXT); 2261 this.select = select; 2262 } 2263 2264 public void actionPerformed(ActionEvent evt, JTextComponent target) { 2265 if (target != null) { 2266 Caret caret = target.getCaret(); 2267 try { 2268 int dot = Utilities.getWordEnd(target, caret.getDot()); 2269 if (select) { 2270 caret.moveDot(dot); 2271 } else { 2272 caret.setDot(dot); 2273 } 2274 } catch (BadLocationException ex) { 2275 target.getToolkit().beep(); 2276 } 2277 } 2278 } 2279 } 2280 2281 2282 public static class SelectWordAction extends KitCompoundAction { 2283 2284 static final long serialVersionUID =7678848538073016357L; 2285 2286 public SelectWordAction() { 2287 super(selectWordAction, 2288 new String [] { 2289 beginWordAction, 2290 selectionEndWordAction 2291 } 2292 ); 2293 } 2294 2295 } 2296 2297 2298 public static class SelectLineAction extends KitCompoundAction { 2299 2300 static final long serialVersionUID =-7407681863035740281L; 2301 2302 public SelectLineAction() { 2303 super(selectLineAction, 2304 new String [] { 2305 lineFirstColumnAction, 2306 selectionEndLineAction 2307 } 2309 ); 2310 } 2311 2312 } 2313 2314 2315 public static class SelectAllAction extends KitCompoundAction { 2316 2317 static final long serialVersionUID =-3502499718130556524L; 2318 2319 public SelectAllAction() { 2320 super(selectAllAction, 2321 new String [] { 2322 beginAction, 2323 selectionEndAction 2324 } 2325 ); 2326 } 2327 2328 } 2329 2330 public static class RemoveTrailingSpacesAction extends LocalBaseAction { 2331 2332 public RemoveTrailingSpacesAction() { 2333 super(removeTrailingSpacesAction); 2334 } 2335 2336 protected boolean asynchonous() { 2337 return true; 2338 } 2339 2340 public void actionPerformed(ActionEvent evt, final JTextComponent target) { 2341 if (target != null) { 2342 final BaseDocument doc = (BaseDocument)target.getDocument(); 2343 doc.runAtomic(new Runnable () { 2344 public void run() { 2345 try { 2346 Element lineRootElem = doc.getDefaultRootElement(); 2347 int count = lineRootElem.getElementCount(); 2348 for (int x = 0; x < count; x++) { 2349 Element elem = lineRootElem.getElement(x); 2350 int start = elem.getStartOffset(); 2351 int end = elem.getEndOffset(); 2352 CharSequence line = DocumentUtilities.getText(doc, start, end - start); 2353 int endIndex = line.length() - 1; 2354 if (endIndex >= 0 && line.charAt(endIndex) == '\n') { 2355 endIndex--; 2356 if (endIndex >= 0 && line.charAt(endIndex) == '\r') { 2357 endIndex--; 2358 } 2359 } 2360 int index = endIndex; 2361 while (index >= 0 && Character.isWhitespace(line.charAt(index)) && line.charAt(index) != '\n') { 2362 index--; 2363 } 2364 if (index < endIndex) { 2365 doc.remove(start + index + 1, endIndex - index); 2366 } 2367 } StatusDisplayer.getDefault().setStatusText(NbBundle.getMessage(BaseKit.class, "TrailingSpacesWereRemoved_Lbl")); } catch (BadLocationException e) { 2370 e.printStackTrace(); 2371 target.getToolkit().beep(); 2372 } 2373 } 2374 }); 2375 } 2376 } 2377 } 2378 2379 private static final class DefaultSyntax extends Syntax { 2380 2381 private static final int ISI_TEXT = 0; 2382 2383 public DefaultSyntax() { 2384 tokenContextPath = DefaultSyntaxTokenContext.CONTEXT.getContextPath(); 2385 } 2386 2387 protected TokenID parseToken() { 2388 while (offset < stopOffset) { 2390 char ch = buffer[offset]; 2392 switch (state) { case INIT: 2394 switch (ch) { 2395 case '\n': 2396 offset++; 2397 return DefaultSyntaxTokenContext.EOL; 2398 default: 2399 state = ISI_TEXT; 2400 break; 2401 } 2402 break; 2403 2404 case ISI_TEXT: 2405 switch (ch) { 2406 case '\n': 2407 state = INIT; 2408 return DefaultSyntaxTokenContext.TEXT; 2409 } 2410 break; 2411 2412 } 2414 offset++; } 2416 2417 switch (state) { 2418 case ISI_TEXT: 2419 state = INIT; 2420 return DefaultSyntaxTokenContext.TEXT; 2421 } 2422 2423 return null; 2425 } 2426 } 2428 private static final class DefaultSyntaxTokenContext extends TokenContext { 2429 2430 public static final int TEXT_ID = 1; 2432 public static final int EOL_ID = 2; 2433 2434 public static final BaseTokenID TEXT = new BaseTokenID("text", TEXT_ID); public static final BaseImageTokenID EOL = new BaseImageTokenID("EOL", EOL_ID, "\n"); 2437 public static final DefaultSyntaxTokenContext CONTEXT = new DefaultSyntaxTokenContext(); 2439 2440 private DefaultSyntaxTokenContext() { 2441 super("defaultSyntax-token-"); 2443 try { 2444 addDeclaredTokenIDs(); 2445 } catch (Exception e) { 2446 LOG.log(Level.WARNING, "Can't load token IDs", e); } 2448 } 2449 } } 2451 | Popular Tags |