Source Code Cross Referenced for BaseKit.java in  » IDE-Netbeans » editor » org » netbeans » editor » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » editor » org.netbeans.editor 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common
0008:         * Development and Distribution License("CDDL") (collectively, the
0009:         * "License"). You may not use this file except in compliance with the
0010:         * License. You can obtain a copy of the License at
0011:         * http://www.netbeans.org/cddl-gplv2.html
0012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013:         * specific language governing permissions and limitations under the
0014:         * License.  When distributing the software, include this License Header
0015:         * Notice in each file and include the License file at
0016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
0017:         * particular file as subject to the "Classpath" exception as provided
0018:         * by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code. If applicable, add the following below the
0020:         * License Header, with the fields enclosed by brackets [] replaced by
0021:         * your own identifying information:
0022:         * "Portions Copyrighted [year] [name of copyright owner]"
0023:         *
0024:         * Contributor(s):
0025:         *
0026:         * The Original Software is NetBeans. The Initial Developer of the Original
0027:         * Software is Sun Picrosystems, Inc. Portions Copyright 1997-2006 Sun
0028:         * Microsystems, Inc. All Rights Reserved.
0029:         *
0030:         * If you wish your version of this file to be governed by only the CDDL
0031:         * or only the GPL Version 2, indicate your decision by adding
0032:         * "[Contributor] elects to include this software in this distribution
0033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034:         * single choice of license, a recipient has the option to distribute
0035:         * your version of this file under either the CDDL, the GPL Version 2 or
0036:         * to extend the choice of license to its licensees as provided above.
0037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
0038:         * Version 2 license, then the option applies only if the new code is
0039:         * made subject to such option by the copyright holder.
0040:         */
0041:
0042:        package org.netbeans.editor;
0043:
0044:        import java.awt.Point;
0045:        import java.awt.Rectangle;
0046:        import java.awt.event.ActionEvent;
0047:        import java.io.Reader;
0048:        import java.io.Writer;
0049:        import java.io.IOException;
0050:        import java.util.Map;
0051:        import java.util.HashMap;
0052:        import java.util.Iterator;
0053:        import java.util.List;
0054:        import java.util.ArrayList;
0055:        import java.util.Collections;
0056:        import javax.swing.Action;
0057:        import javax.swing.JEditorPane;
0058:        import javax.swing.SwingConstants;
0059:        import javax.swing.SwingUtilities;
0060:        import javax.swing.text.Document;
0061:        import javax.swing.text.DefaultEditorKit;
0062:        import javax.swing.text.BadLocationException;
0063:        import javax.swing.text.Element;
0064:        import javax.swing.text.ViewFactory;
0065:        import javax.swing.text.Caret;
0066:        import javax.swing.text.JTextComponent;
0067:        import java.io.CharArrayWriter;
0068:        import java.lang.reflect.Method;
0069:        import java.util.Vector;
0070:        import java.util.logging.Level;
0071:        import java.util.logging.Logger;
0072:        import javax.swing.text.EditorKit;
0073:        import javax.swing.text.Position;
0074:        import org.netbeans.api.editor.mimelookup.MimeLookup;
0075:        import org.netbeans.api.editor.mimelookup.MimePath;
0076:        import org.netbeans.lib.editor.util.swing.DocumentUtilities;
0077:        import org.netbeans.modules.editor.lib.NavigationHistory;
0078:        import org.openide.awt.StatusDisplayer;
0079:        import org.openide.util.HelpCtx;
0080:        import org.openide.util.Lookup;
0081:        import org.openide.util.NbBundle;
0082:
0083:        /**
0084:         * Editor kit implementation for base document
0085:         *
0086:         * @author Miloslav Metelka
0087:         * @version 1.00
0088:         */
0089:
0090:        public class BaseKit extends DefaultEditorKit {
0091:
0092:            private static final Logger LOG = Logger.getLogger(BaseKit.class
0093:                    .getName());
0094:
0095:            /** split the current line at cursor position */
0096:            public static final String splitLineAction = "split-line"; // NOI18N
0097:
0098:            /** Cycle through annotations on the current line */
0099:            public static final String annotationsCyclingAction = "annotations-cycling"; // NOI18N
0100:
0101:            /** Collapse a fold. Depends on the current caret position. */
0102:            public static final String collapseFoldAction = "collapse-fold"; //NOI18N
0103:
0104:            /** Expand a fold. Depends on the current caret position. */
0105:            public static final String expandFoldAction = "expand-fold"; //NOI18N
0106:
0107:            /** Collapse all existing folds in the document. */
0108:            public static final String collapseAllFoldsAction = "collapse-all-folds"; //NOI18N
0109:
0110:            /** Expand all existing folds in the document. */
0111:            public static final String expandAllFoldsAction = "expand-all-folds"; //NOI18N
0112:
0113:            /** Move one page up and make or extend selection */
0114:            public static final String selectionPageUpAction = "selection-page-up"; // NOI18N
0115:
0116:            /** Move one page down and make or extend selection */
0117:            public static final String selectionPageDownAction = "selection-page-down"; // NOI18N
0118:
0119:            /** Remove indentation */
0120:            public static final String removeTabAction = "remove-tab"; // NOI18N
0121:
0122:            /** Remove selected block or do nothing - useful for popup menu */
0123:            public static final String removeSelectionAction = "remove-selection"; // NOI18N
0124:
0125:            /** Expand the abbreviation */
0126:            public static final String abbrevExpandAction = "abbrev-expand"; // NOI18N
0127:
0128:            /** Reset the abbreviation accounting string */
0129:            public static final String abbrevResetAction = "abbrev-reset"; // NOI18N
0130:
0131:            /** Remove the word */
0132:            //public static final String removeWordAction = "remove-word"; #47709
0133:            /** Remove characters to the begining of the word or 
0134:             *  the previous word if caret is not directly at word */
0135:            public static final String removePreviousWordAction = "remove-word-previous"; // NOI18N
0136:
0137:            /** Remove characters to the end of the word or 
0138:             *  the next word if caret is not directly at word */
0139:            public static final String removeNextWordAction = "remove-word-next"; // NOI18N
0140:
0141:            /** Remove to the begining of the line */
0142:            public static final String removeLineBeginAction = "remove-line-begin"; // NOI18N
0143:
0144:            /** Remove line */
0145:            public static final String removeLineAction = "remove-line"; // NOI18N
0146:
0147:            /** Move selection else line up */
0148:            /* package */static final String moveSelectionElseLineUpAction = "move-selection-else-line-up"; // NOI18N
0149:
0150:            /** Move selection else line down */
0151:            /* package */static final String moveSelectionElseLineDownAction = "move-selection-else-line-down"; // NOI18N
0152:
0153:            /** Copy selection else line up */
0154:            /* package */static final String copySelectionElseLineUpAction = "copy-selection-else-line-up"; // NOI18N
0155:
0156:            /** Copy selection else line down */
0157:            /* package */static final String copySelectionElseLineDownAction = "copy-selection-else-line-down"; // NOI18N
0158:
0159:            /** Toggle the typing mode to overwrite mode or back to insert mode */
0160:            public static final String toggleTypingModeAction = "toggle-typing-mode"; // NOI18N
0161:
0162:            /** Change the selected text or current character to uppercase */
0163:            public static final String toUpperCaseAction = "to-upper-case"; // NOI18N
0164:
0165:            /** Change the selected text or current character to lowercase */
0166:            public static final String toLowerCaseAction = "to-lower-case"; // NOI18N
0167:
0168:            /** Switch the case of the selected text or current character */
0169:            public static final String switchCaseAction = "switch-case"; // NOI18N
0170:
0171:            /** Find next occurence action */
0172:            public static final String findNextAction = "find-next"; // NOI18N
0173:
0174:            /** Find previous occurence action */
0175:            public static final String findPreviousAction = "find-previous"; // NOI18N
0176:
0177:            /** Toggle highlight search action */
0178:            public static final String toggleHighlightSearchAction = "toggle-highlight-search"; // NOI18N
0179:
0180:            /** Find current word */
0181:            public static final String findSelectionAction = "find-selection"; // NOI18N
0182:
0183:            /** Undo action */
0184:            public static final String undoAction = "undo"; // NOI18N
0185:
0186:            /** Redo action */
0187:            public static final String redoAction = "redo"; // NOI18N
0188:
0189:            /** Word match next */
0190:            public static final String wordMatchNextAction = "word-match-next"; // NOI18N
0191:
0192:            /** Word match prev */
0193:            public static final String wordMatchPrevAction = "word-match-prev"; // NOI18N
0194:
0195:            /** Reindent Line action */
0196:            public static final String reindentLineAction = "reindent-line"; // NOI18N
0197:
0198:            /** Shift line right action */
0199:            public static final String shiftLineRightAction = "shift-line-right"; // NOI18N
0200:
0201:            /** Shift line left action */
0202:            public static final String shiftLineLeftAction = "shift-line-left"; // NOI18N
0203:
0204:            /** Action that scrolls the window so that caret is at the center of the window */
0205:            public static final String adjustWindowCenterAction = "adjust-window-center"; // NOI18N
0206:
0207:            /** Action that scrolls the window so that caret is at the top of the window */
0208:            public static final String adjustWindowTopAction = "adjust-window-top"; // NOI18N
0209:
0210:            /** Action that scrolls the window so that caret is at the bottom of the window */
0211:            public static final String adjustWindowBottomAction = "adjust-window-bottom"; // NOI18N
0212:
0213:            /** Action that moves the caret so that caret is at the center of the window */
0214:            public static final String adjustCaretCenterAction = "adjust-caret-center"; // NOI18N
0215:
0216:            /** Action that moves the caret so that caret is at the top of the window */
0217:            public static final String adjustCaretTopAction = "adjust-caret-top"; // NOI18N
0218:
0219:            /** Action that moves the caret so that caret is at the bottom of the window */
0220:            public static final String adjustCaretBottomAction = "adjust-caret-bottom"; // NOI18N
0221:
0222:            /** Format part of the document text using Indent */
0223:            public static final String formatAction = "format"; // NOI18N
0224:
0225:            /** First non-white character on the line */
0226:            public static final String firstNonWhiteAction = "first-non-white"; // NOI18N
0227:
0228:            /** Last non-white character on the line */
0229:            public static final String lastNonWhiteAction = "last-non-white"; // NOI18N
0230:
0231:            /** First non-white character on the line */
0232:            public static final String selectionFirstNonWhiteAction = "selection-first-non-white"; // NOI18N
0233:
0234:            /** Last non-white character on the line */
0235:            public static final String selectionLastNonWhiteAction = "selection-last-non-white"; // NOI18N
0236:
0237:            /** Select the nearest identifier around caret */
0238:            public static final String selectIdentifierAction = "select-identifier"; // NOI18N
0239:
0240:            /** Select the next parameter (after the comma) in the given context */
0241:            public static final String selectNextParameterAction = "select-next-parameter"; // NOI18N
0242:
0243:            /** Go to the previous position stored in the jump-list */
0244:            public static final String jumpListNextAction = "jump-list-next"; // NOI18N
0245:
0246:            /** Go to the next position stored in the jump-list */
0247:            public static final String jumpListPrevAction = "jump-list-prev"; // NOI18N
0248:
0249:            /** Go to the last position in the previous component stored in the jump-list */
0250:            public static final String jumpListNextComponentAction = "jump-list-next-component"; // NOI18N
0251:
0252:            /** Go to the next position in the previous component stored in the jump-list */
0253:            public static final String jumpListPrevComponentAction = "jump-list-prev-component"; // NOI18N
0254:
0255:            /** Scroll window one line up */
0256:            public static final String scrollUpAction = "scroll-up"; // NOI18N
0257:
0258:            /** Scroll window one line down */
0259:            public static final String scrollDownAction = "scroll-down"; // NOI18N
0260:
0261:            /** Prefix of all macro-based actions */
0262:            public static final String macroActionPrefix = "macro-"; // NOI18N
0263:
0264:            /** Start recording of macro. Only one macro recording can be active at the time */
0265:            public static final String startMacroRecordingAction = "start-macro-recording"; //NOI18N
0266:
0267:            /** Stop the active recording */
0268:            public static final String stopMacroRecordingAction = "stop-macro-recording"; //NOI18N
0269:
0270:            /** Name of the action moving caret to the first column on the line */
0271:            public static final String lineFirstColumnAction = "caret-line-first-column"; // NOI18N
0272:
0273:            /** Insert the current Date and Time  */
0274:            public static final String insertDateTimeAction = "insert-date-time"; // NOI18N
0275:
0276:            /** Name of the action moving caret to the first 
0277:             * column on the line and extending the selection
0278:             */
0279:            public static final String selectionLineFirstColumnAction = "selection-line-first-column"; // NOI18N
0280:
0281:            /** Name of the action for generating of Glyph Gutter popup menu*/
0282:            public static final String generateGutterPopupAction = "generate-gutter-popup"; // NOI18N
0283:
0284:            /** Toggle visibility of line numbers*/
0285:            public static final String toggleLineNumbersAction = "toggle-line-numbers"; // NOI18N
0286:
0287:            /** Paste and reformat code */
0288:            public static final String pasteFormatedAction = "paste-formated"; // NOI18N
0289:
0290:            /** Starts a new line in code */
0291:            public static final String startNewLineAction = "start-new-line"; // NOI18N    
0292:
0293:            /** Cut text from caret position to line begining action. */
0294:            public static final String cutToLineBeginAction = "cut-to-line-begin"; // NOI18N    
0295:
0296:            /** Cut text from caret position to line end action. */
0297:            public static final String cutToLineEndAction = "cut-to-line-end"; // NOI18N
0298:
0299:            /** Remove all trailing spaces in the document. */
0300:            public static final String removeTrailingSpacesAction = "remove-trailing-spaces"; //NOI18N
0301:
0302:            public static final String DOC_REPLACE_SELECTION_PROPERTY = "doc-replace-selection-property"; //NOI18N
0303:
0304:            private static final int KIT_CNT_PREALLOC = 7;
0305:
0306:            static final long serialVersionUID = -8570495408376659348L;
0307:
0308:            /** [kit-class, kit-instance] pairs are stored here */
0309:            private static final Map kits = new HashMap(KIT_CNT_PREALLOC);
0310:
0311:            /** [kit-class, keymap] pairs */
0312:            private static final Map kitKeymaps = new HashMap(KIT_CNT_PREALLOC);
0313:
0314:            /** [kit, action[]] pairs */
0315:            private static final Map kitActions = new HashMap(KIT_CNT_PREALLOC);
0316:
0317:            /** [kit, action-map] pairs */
0318:            private static final Map kitActionMaps = new HashMap(
0319:                    KIT_CNT_PREALLOC);
0320:
0321:            private static CopyAction copyActionDef = new CopyAction();
0322:            private static CutAction cutActionDef = new CutAction();
0323:            private static PasteAction pasteActionDef = new PasteAction(false);
0324:            private static DeleteCharAction deletePrevCharActionDef = new DeleteCharAction(
0325:                    deletePrevCharAction, false);
0326:            private static DeleteCharAction deleteNextCharActionDef = new DeleteCharAction(
0327:                    deleteNextCharAction, true);
0328:            private static ActionFactory.RemoveSelectionAction removeSelectionActionDef = new ActionFactory.RemoveSelectionAction();
0329:
0330:            private static ActionFactory.UndoAction undoActionDef = new ActionFactory.UndoAction();
0331:            private static ActionFactory.RedoAction redoActionDef = new ActionFactory.RedoAction();
0332:
0333:            public static final int MAGIC_POSITION_MAX = Integer.MAX_VALUE - 1;
0334:
0335:            static SettingsChangeListener settingsListener = new SettingsChangeListener() {
0336:                public void settingsChange(SettingsChangeEvent evt) {
0337:                    String settingName = (evt != null) ? evt.getSettingName()
0338:                            : null;
0339:
0340:                    boolean clearActions = (settingName == null
0341:                            || SettingsNames.CUSTOM_ACTION_LIST
0342:                                    .equals(settingName) || SettingsNames.MACRO_MAP
0343:                            .equals(settingName));
0344:
0345:                    if (clearActions
0346:                            || SettingsNames.KEY_BINDING_LIST
0347:                                    .equals(settingName)) {
0348:                        kitKeymaps.clear();
0349:                    }
0350:
0351:                    if (clearActions) {
0352:                        kitActions.clear();
0353:                        kitActionMaps.clear();
0354:                    } else { // only refresh action settings
0355:                        Iterator i = kitActions.entrySet().iterator();
0356:                        while (i.hasNext()) {
0357:                            Map.Entry me = (Map.Entry) i.next();
0358:                            updateActionSettings((Action[]) me.getValue(), evt,
0359:                                    (Class) me.getKey());
0360:                        }
0361:                    }
0362:                }
0363:            };
0364:
0365:            static {
0366:                Settings.addSettingsChangeListener(settingsListener);
0367:            }
0368:
0369:            private static void updateActionSettings(Action[] actions,
0370:                    SettingsChangeEvent evt, Class kitClass) {
0371:                for (int i = 0; i < actions.length; i++) {
0372:                    if (actions[i] instanceof  BaseAction) {
0373:                        ((BaseAction) actions[i]).settingsChange(evt, kitClass);
0374:                    }
0375:                }
0376:            }
0377:
0378:            /**
0379:             * Gets an editor kit from its implemetation class.
0380:             * 
0381:             * <p>Please be careful when using this method and make sure that you understand
0382:             * how it works and what the deference is from using <code>MimeLookup</code>.
0383:             * This method simply creates an instance of <code>BaseKit</code> from
0384:             * its implementation class passed in as a parameter. It completely ignores
0385:             * the registry of editor kits in <code>MimeLookup</code>, which has severe
0386:             * consequences.
0387:             * 
0388:             * <div class="nonnormative">
0389:             * <p>The usuall pattern for using editor kits is to start with a mime type
0390:             * of a document (ie. file) that you want to edit, then use some registry
0391:             * for editor kits to look up the kit for your mime type and finally set the
0392:             * kit in a <code>JTextComponent</code>, let it create a <code>Document</code>
0393:             * and load it with data. The registry can generally be anything, but in Netbeans
0394:             * we use <code>MimeLookup</code> (JDK for example uses 
0395:             * <code>JEditorPane.createEditorKitForContentType</code>).
0396:             * 
0397:             * <p>The editor kits are registered in <code>MimeLookup</code> for each
0398:             * particular mime type and the registry itself does not impose any rules on
0399:             * the editor kit implementations other than extending the <code>EditorKit</code>
0400:             * class. This for example means that the same implemantation of <code>EditorKit</code>
0401:             * can be used for multiple mime types. This is exactly how XML editor kit
0402:             * is reused for various flavors of XML documents (e.g. ant build scripts,
0403:             * web app descriptors, etc).
0404:             * 
0405:             * <p>Netbeans did not always have <code>MimeLookup</code>
0406:             * and it also used a different approach for registering and retrieving
0407:             * editor kits. This old approach was based on implemetation classes rather than on mime
0408:             * types and while it is still more or less functional for the old kit
0409:             * implementations, it is fundamentally broken and should not be used any more.
0410:             * The code below demonstrates probably the biggest mistake when thinking
0411:             * in the old ways.
0412:             * 
0413:             * <pre>
0414:             * // WARNING: The code below is a demonstration of a common mistake that
0415:             * // people do when using <code>BaseKit.getKit</code>.
0416:             * 
0417:             * JTextComponent component = ...; // Let's say we have a component
0418:             * Class kitClass = Utilities.getKitClass(component);
0419:             * String mimeType = BaseKit.getKit(kitClass).getContentType();
0420:             * </pre>
0421:             * 
0422:             * <p>The problem with the above code is that it blindely assumes that each
0423:             * kit class can be uniquely mapped to a mime type. This is not true! The
0424:             * same can be achieved in much easier way, which always works.
0425:             * 
0426:             * <pre>
0427:             * JTextComponent component = ...; // Let's say we have a component
0428:             * String mimeType = component.getUI().getEditorKit(component).getContentType();
0429:             * </pre>
0430:             * </div>
0431:             * 
0432:             * @param kitClass An implementation class of the editor kit that should
0433:             * be returned. If the <code>kitClass</code> is not <code>BaseKit</code> or
0434:             * its subclass the instance of bare <code>BaseKit</code> will be returned.
0435:             * 
0436:             * @return An instance of the <code>kitClass</code> or <code>BaseKit</code>.
0437:             * @deprecated Use <code>CloneableEditorSupport.getEditorKit</code> or
0438:             * <code>MimeLookup</code> instead to find <code>EditorKit</code> for a mime
0439:             * type.
0440:             */
0441:            public static BaseKit getKit(Class kitClass) {
0442:                if (kitClass != null
0443:                        && BaseKit.class.isAssignableFrom(kitClass)
0444:                        && BaseKit.class != kitClass) {
0445:                    if (!noKitsTracker) {
0446:                        String mimeType = kitsTracker_FindMimeType(kitClass);
0447:                        if (mimeType != null) {
0448:                            EditorKit kit = MimeLookup.getLookup(
0449:                                    MimePath.parse(mimeType)).lookup(
0450:                                    EditorKit.class);
0451:                            if (kit instanceof  BaseKit) {
0452:                                return (BaseKit) kit;
0453:                            }
0454:                        }
0455:                    }
0456:                } else {
0457:                    kitClass = BaseKit.class;
0458:                }
0459:
0460:                synchronized (kits) {
0461:                    BaseKit kit = (BaseKit) kits.get(kitClass);
0462:                    if (kit == null) {
0463:                        try {
0464:                            kit = (BaseKit) kitClass.newInstance();
0465:                        } catch (IllegalAccessException e) {
0466:                            LOG.log(Level.WARNING, null, e);
0467:                        } catch (InstantiationException e) {
0468:                            LOG.log(Level.WARNING, null, e);
0469:                        }
0470:                        kits.put(kitClass, kit);
0471:                    }
0472:                    return kit;
0473:                }
0474:            }
0475:
0476:            private static volatile boolean noKitsTracker = false;
0477:
0478:            /* package */static String kitsTracker_FindMimeType(Class kitClass) {
0479:                String mimeType = null;
0480:
0481:                if (!noKitsTracker) {
0482:                    try {
0483:                        ClassLoader cl = Lookup.getDefault().lookup(
0484:                                ClassLoader.class);
0485:                        Class clazz = cl
0486:                                .loadClass("org.netbeans.modules.editor.impl.KitsTracker"); //NOI18N
0487:                        Method getInstanceMethod = clazz
0488:                                .getDeclaredMethod("getInstance"); //NOI18N
0489:                        Method findMimeTypeMethod = clazz.getDeclaredMethod(
0490:                                "findMimeType", Class.class); //NOI18N
0491:                        Object kitsTracker = getInstanceMethod.invoke(null);
0492:                        mimeType = (String) findMimeTypeMethod.invoke(
0493:                                kitsTracker, kitClass);
0494:                    } catch (Exception e) {
0495:                        // ignore
0496:                        noKitsTracker = true;
0497:                    }
0498:                }
0499:
0500:                return mimeType;
0501:            }
0502:
0503:            /**
0504:             * Creates a new instance of <code>BaseKit</code>.
0505:             * 
0506:             * <div class="nonnormative">
0507:             * <p>You should not need to instantiate editor kits
0508:             * directly under normal circumstances. There is a few ways how you can get
0509:             * instance of <code>EditorKit</code> depending on what you already have
0510:             * available:
0511:             * 
0512:             * <ul>
0513:             * <li><b>mime type</b> - Use <code>CloneableEditorSupport.getEditorKit(yourMimeType)</code>
0514:             * to get the <code>EditorKit</code> registered for your mime type or use
0515:             * the following code <code>MimeLookup.getLookup(MimePath.parse(yourMimeType)).lookup(EditorKit.class)</code>
0516:             * and check for <code>null</code>.
0517:             * <li><b>JTextComponent</b> - Simply call
0518:             * <code>JTextComponent.getUI().getEditorKit(JTextComponent)</code> passing
0519:             * in the same component.
0520:             * </ul>
0521:             * </div>
0522:             */
0523:            public BaseKit() {
0524:                // possibly register
0525:                synchronized (kits) {
0526:                    if (kits.get(this .getClass()) == null) {
0527:                        kits.put(this .getClass(), this ); // register itself
0528:                    }
0529:                }
0530:            }
0531:
0532:            /** Clone this editor kit */
0533:            public Object clone() {
0534:                return this ; // no need to create another instance
0535:            }
0536:
0537:            /** Fetches a factory that is suitable for producing
0538:             * views of any models that are produced by this
0539:             * kit.  The default is to have the UI produce the
0540:             * factory, so this method has no implementation.
0541:             *
0542:             * @return the view factory
0543:             */
0544:            public ViewFactory getViewFactory() {
0545:                return null;
0546:            }
0547:
0548:            /** Create caret to navigate through document */
0549:            public Caret createCaret() {
0550:                return new BaseCaret();
0551:            }
0552:
0553:            /** Create empty document */
0554:            public Document createDefaultDocument() {
0555:                return new BaseDocument(this .getClass(), true);
0556:            }
0557:
0558:            /** Create new instance of syntax coloring scanner
0559:             * @param doc document to operate on. It can be null in the cases the syntax
0560:             *   creation is not related to the particular document
0561:             */
0562:            public Syntax createSyntax(Document doc) {
0563:                return new DefaultSyntax();
0564:            }
0565:
0566:            /** Create the syntax used for formatting */
0567:            public Syntax createFormatSyntax(Document doc) {
0568:                return createSyntax(doc);
0569:            }
0570:
0571:            /** Create syntax support */
0572:            public SyntaxSupport createSyntaxSupport(BaseDocument doc) {
0573:                return new SyntaxSupport(doc);
0574:            }
0575:
0576:            /** Create the formatter appropriate for this kit */
0577:            public Formatter createFormatter() {
0578:                return new Formatter(this .getClass());
0579:            }
0580:
0581:            /** Create text UI */
0582:            protected BaseTextUI createTextUI() {
0583:                return new BaseTextUI();
0584:            }
0585:
0586:            /** Create extended UI */
0587:            protected EditorUI createEditorUI() {
0588:                return new EditorUI();
0589:            }
0590:
0591:            /**
0592:             * Create extended UI for printing a document.
0593:             * @deprecated this method is no longer being called by {@link EditorUI}.
0594:             *  {@link #createPrintEditorUI(BaseDocument, boolean, boolean)} is being
0595:             *  called instead.
0596:             */
0597:            protected EditorUI createPrintEditorUI(BaseDocument doc) {
0598:                return new EditorUI(doc);
0599:            }
0600:
0601:            /**
0602:             * Create extended UI for printing a document.
0603:             *
0604:             * @param doc document for which the extended UI is being created.
0605:             * @param usePrintColoringMap use printing coloring settings instead
0606:             *  of the regular ones.
0607:             * @param lineNumberEnabled if set to false the line numbers will not be printed.
0608:             *  If set to true the visibility of line numbers depends on the settings
0609:             *  for the line number visibility.
0610:             */
0611:            protected EditorUI createPrintEditorUI(BaseDocument doc,
0612:                    boolean usePrintColoringMap, boolean lineNumberEnabled) {
0613:
0614:                return new EditorUI(doc, usePrintColoringMap, lineNumberEnabled);
0615:            }
0616:
0617:            public MultiKeymap getKeymap() {
0618:                synchronized (Settings.class) {
0619:                    MultiKeymap km = (MultiKeymap) kitKeymaps.get(this 
0620:                            .getClass());
0621:                    if (km == null) { // keymap not yet constructed
0622:                        // construct new keymap
0623:                        km = new MultiKeymap("Keymap for " + this .getClass()); // NOI18N
0624:                        // retrieve key bindings for this kit and super kits
0625:                        Settings.KitAndValue kv[] = Settings
0626:                                .getValueHierarchy(this .getClass(),
0627:                                        SettingsNames.KEY_BINDING_LIST);
0628:                        // go through all levels and collect key bindings
0629:                        for (int i = kv.length - 1; i >= 0; i--) {
0630:                            List keyList = (List) kv[i].value;
0631:                            JTextComponent.KeyBinding[] keys = new JTextComponent.KeyBinding[keyList
0632:                                    .size()];
0633:                            keyList.toArray(keys);
0634:                            km.load(keys, getActionMap());
0635:                        }
0636:
0637:                        km.setDefaultAction((Action) getActionMap().get(
0638:                                defaultKeyTypedAction));
0639:
0640:                        kitKeymaps.put(this .getClass(), km);
0641:                    }
0642:                    return km;
0643:                }
0644:            }
0645:
0646:            /** Inserts content from the given stream. */
0647:            public void read(Reader in, Document doc, int pos)
0648:                    throws IOException, BadLocationException {
0649:                if (doc instanceof  BaseDocument) {
0650:                    ((BaseDocument) doc).read(in, pos); // delegate it to document
0651:                } else {
0652:                    super .read(in, doc, pos);
0653:                }
0654:            }
0655:
0656:            /** Writes content from a document to the given stream */
0657:            public void write(Writer out, Document doc, int pos, int len)
0658:                    throws IOException, BadLocationException {
0659:                if (doc instanceof  BaseDocument) {
0660:                    ((BaseDocument) doc).write(out, pos, len);
0661:                } else {
0662:                    super .write(out, doc, pos, len);
0663:                }
0664:            }
0665:
0666:            /** Creates map with [name, action] pairs from the given
0667:             * array of actions.
0668:             */
0669:            public static Map actionsToMap(Action[] actions) {
0670:                Map map = new HashMap();
0671:                for (int i = 0; i < actions.length; i++) {
0672:                    Action a = actions[i];
0673:                    String name = (String) a.getValue(Action.NAME);
0674:                    map.put(((name != null) ? name : ""), a); // NOI18N
0675:                }
0676:                return map;
0677:            }
0678:
0679:            /** Converts map with [name, action] back
0680:             * to array of actions.
0681:             */
0682:            public static Action[] mapToActions(Map map) {
0683:                Action[] actions = new Action[map.size()];
0684:                int i = 0;
0685:                for (Iterator iter = map.values().iterator(); iter.hasNext();) {
0686:                    actions[i++] = (Action) iter.next();
0687:                }
0688:                return actions;
0689:            }
0690:
0691:            /** Called after the kit is installed into JEditorPane */
0692:            public void install(JEditorPane c) {
0693:
0694:                assert (SwingUtilities.isEventDispatchThread()) // expected in AWT only
0695:                : "BaseKit.install() incorrectly called from non-AWT thread."; // NOI18N
0696:
0697:                BaseTextUI ui = createTextUI();
0698:                c.setUI(ui);
0699:
0700:                String propName = "netbeans.editor.noinputmethods"; // NOI18N
0701:                Object noInputMethods = System.getProperty(propName);
0702:                boolean enableIM;
0703:                if (noInputMethods != null) {
0704:                    enableIM = !Boolean.getBoolean(propName);
0705:                } else {
0706:                    enableIM = SettingsUtil.getBoolean(this .getClass(),
0707:                            SettingsNames.INPUT_METHODS_ENABLED, true);
0708:                }
0709:
0710:                c.enableInputMethods(enableIM);
0711:                executeInstallActions(c);
0712:
0713:                c.putClientProperty("hyperlink-operation", // NOI18N
0714:                        org.netbeans.lib.editor.hyperlink.HyperlinkOperation
0715:                                .create(c, getContentType()));
0716:
0717:                // Mark that the editor's multi keymap adheres to context API in status displayer
0718:                c.putClientProperty("context-api-aware", Boolean.TRUE); // NOI18N
0719:
0720:                // Add default help IDs derived from the kit's mime type, #61618.
0721:                // If the kit itself is HelpCtx.Provider it will be called from CloneableEditor.getHelpCtx()
0722:                if (!(this  instanceof  HelpCtx.Provider)) {
0723:                    HelpCtx.setHelpIDString(c, getContentType().replace('/',
0724:                            '.').replace('+', '.')); //NOI18N
0725:                }
0726:            }
0727:
0728:            protected void executeInstallActions(JEditorPane c) {
0729:                Settings.KitAndValue[] kv = Settings
0730:                        .getValueHierarchy(this .getClass(),
0731:                                SettingsNames.KIT_INSTALL_ACTION_NAME_LIST);
0732:                for (int i = kv.length - 1; i >= 0; i--) {
0733:                    List actList = (List) kv[i].value;
0734:                    actList = translateActionNameList(actList); // translate names to actions
0735:                    if (actList != null) {
0736:                        for (Iterator iter = actList.iterator(); iter.hasNext();) {
0737:                            Action a = (Action) iter.next();
0738:                            a.actionPerformed(new ActionEvent(c,
0739:                                    ActionEvent.ACTION_PERFORMED, "")); // NOI18N
0740:                        }
0741:                    }
0742:                }
0743:            }
0744:
0745:            public void deinstall(JEditorPane c) {
0746:
0747:                assert (SwingUtilities.isEventDispatchThread()); // expected in AWT only
0748:
0749:                BaseTextUI.uninstallUIWatcher(c);
0750:                executeDeinstallActions(c);
0751:                c.updateUI();
0752:
0753:                // #41209: reset ancestor override flag if previously set
0754:                if (c.getClientProperty("ancestorOverride") != null) { // NOI18N
0755:                    c.putClientProperty("ancestorOverride", Boolean.FALSE); // NOI18N
0756:                }
0757:            }
0758:
0759:            protected void executeDeinstallActions(JEditorPane c) {
0760:                Settings.KitAndValue[] kv = Settings.getValueHierarchy(this 
0761:                        .getClass(),
0762:                        SettingsNames.KIT_DEINSTALL_ACTION_NAME_LIST);
0763:                for (int i = kv.length - 1; i >= 0; i--) {
0764:                    List actList = (List) kv[i].value;
0765:                    actList = translateActionNameList(actList); // translate names to actions
0766:                    if (actList != null) {
0767:                        for (Iterator iter = actList.iterator(); iter.hasNext();) {
0768:                            Action a = (Action) iter.next();
0769:                            a.actionPerformed(new ActionEvent(c,
0770:                                    ActionEvent.ACTION_PERFORMED, "")); // NOI18N
0771:                        }
0772:                    }
0773:                }
0774:            }
0775:
0776:            /** Initialize document by adding the draw-layers for example. */
0777:            protected void initDocument(BaseDocument doc) {
0778:            }
0779:
0780:            /** Create actions that this kit supports. To use the actions of the parent kit
0781:             * it's better instead of using super.createActions() to use
0782:             * getKit(super.getClass()).getActions() because it can reuse existing
0783:             * parent actions.
0784:             */
0785:            protected Action[] createActions() {
0786:                return new Action[] {
0787:                        new DefaultKeyTypedAction(),
0788:                        new InsertContentAction(),
0789:                        new InsertBreakAction(),
0790:                        new SplitLineAction(),
0791:                        new InsertTabAction(),
0792:                        deletePrevCharActionDef,
0793:                        deleteNextCharActionDef,
0794:                        new ReadOnlyAction(),
0795:                        new WritableAction(),
0796:                        cutActionDef,
0797:                        copyActionDef,
0798:                        pasteActionDef,
0799:                        new PasteAction(true),
0800:                        new BeepAction(),
0801:                        new UpAction(upAction, false),
0802:                        new UpAction(selectionUpAction, true),
0803:                        new PageUpAction(pageUpAction, false),
0804:                        new PageUpAction(selectionPageUpAction, true),
0805:                        new DownAction(downAction, false),
0806:                        new DownAction(selectionDownAction, true),
0807:                        new PageDownAction(selectionPageDownAction, true),
0808:                        new PageDownAction(pageDownAction, false),
0809:                        new ForwardAction(forwardAction, false),
0810:                        new ForwardAction(selectionForwardAction, true),
0811:                        new BackwardAction(backwardAction, false),
0812:                        new BackwardAction(selectionBackwardAction, true),
0813:                        new BeginLineAction(lineFirstColumnAction, false, true),
0814:                        new BeginLineAction(selectionLineFirstColumnAction,
0815:                                true, true),
0816:                        new BeginLineAction(beginLineAction, false),
0817:                        new BeginLineAction(selectionBeginLineAction, true),
0818:                        new EndLineAction(endLineAction, false),
0819:                        new EndLineAction(selectionEndLineAction, true),
0820:                        new BeginAction(beginAction, false),
0821:                        new BeginAction(selectionBeginAction, true),
0822:                        new EndAction(endAction, false),
0823:                        new EndAction(selectionEndAction, true),
0824:                        new NextWordAction(nextWordAction, false),
0825:                        new NextWordAction(selectionNextWordAction, true),
0826:                        new PreviousWordAction(previousWordAction, false),
0827:                        new PreviousWordAction(selectionPreviousWordAction,
0828:                                true),
0829:                        new BeginWordAction(beginWordAction, false),
0830:                        new BeginWordAction(selectionBeginWordAction, true),
0831:                        new EndWordAction(endWordAction, false),
0832:                        new EndWordAction(selectionEndWordAction, true),
0833:                        new SelectWordAction(),
0834:                        new SelectLineAction(),
0835:                        new SelectAllAction(),
0836:                        new RemoveTrailingSpacesAction(),
0837:                        new ActionFactory.RemoveTabAction(),
0838:                        //new ActionFactory.RemoveWordAction(), #47709
0839:                        new ActionFactory.RemoveWordPreviousAction(),
0840:                        new ActionFactory.RemoveWordNextAction(),
0841:                        new ActionFactory.RemoveLineBeginAction(),
0842:                        new ActionFactory.RemoveLineAction(),
0843:                        new ActionFactory.MoveSelectionElseLineUpAction(),
0844:                        new ActionFactory.MoveSelectionElseLineDownAction(),
0845:                        new ActionFactory.CopySelectionElseLineUpAction(),
0846:                        new ActionFactory.CopySelectionElseLineDownAction(),
0847:                        removeSelectionActionDef,
0848:                        new ActionFactory.ToggleTypingModeAction(),
0849:                        new ActionFactory.ChangeCaseAction(toUpperCaseAction,
0850:                                Utilities.CASE_UPPER),
0851:                        new ActionFactory.ChangeCaseAction(toLowerCaseAction,
0852:                                Utilities.CASE_LOWER),
0853:                        new ActionFactory.ChangeCaseAction(switchCaseAction,
0854:                                Utilities.CASE_SWITCH),
0855:                        new ActionFactory.FindNextAction(),
0856:                        new ActionFactory.FindPreviousAction(),
0857:                        new ActionFactory.FindSelectionAction(),
0858:                        new ActionFactory.ToggleHighlightSearchAction(),
0859:                        undoActionDef,
0860:                        redoActionDef,
0861:                        new ActionFactory.WordMatchAction(wordMatchNextAction,
0862:                                true),
0863:                        new ActionFactory.WordMatchAction(wordMatchPrevAction,
0864:                                false),
0865:                        new ActionFactory.ReindentLineAction(),
0866:                        new ActionFactory.ShiftLineAction(shiftLineLeftAction,
0867:                                false),
0868:                        new ActionFactory.ShiftLineAction(shiftLineRightAction,
0869:                                true),
0870:                        new ActionFactory.AdjustWindowAction(
0871:                                adjustWindowTopAction, 0),
0872:                        new ActionFactory.AdjustWindowAction(
0873:                                adjustWindowCenterAction, 50),
0874:                        new ActionFactory.AdjustWindowAction(
0875:                                adjustWindowBottomAction, 100),
0876:                        new ActionFactory.AdjustCaretAction(
0877:                                adjustCaretTopAction, 0),
0878:                        new ActionFactory.AdjustCaretAction(
0879:                                adjustCaretCenterAction, 50),
0880:                        new ActionFactory.AdjustCaretAction(
0881:                                adjustCaretBottomAction, 100),
0882:                        new ActionFactory.FormatAction(),
0883:                        new ActionFactory.FirstNonWhiteAction(
0884:                                firstNonWhiteAction, false),
0885:                        new ActionFactory.FirstNonWhiteAction(
0886:                                selectionFirstNonWhiteAction, true),
0887:                        new ActionFactory.LastNonWhiteAction(
0888:                                lastNonWhiteAction, false),
0889:                        new ActionFactory.LastNonWhiteAction(
0890:                                selectionLastNonWhiteAction, true),
0891:                        new ActionFactory.SelectIdentifierAction(),
0892:                        new ActionFactory.SelectNextParameterAction(),
0893:                        new ActionFactory.ScrollUpAction(),
0894:                        new ActionFactory.ScrollDownAction(),
0895:                        new ActionFactory.InsertDateTimeAction(),
0896:                        new ActionFactory.GenerateGutterPopupAction(),
0897:                        new ActionFactory.ToggleLineNumbersAction(),
0898:                        new ActionFactory.AnnotationsCyclingAction(),
0899:                        new ActionFactory.CollapseFold(),
0900:                        new ActionFactory.ExpandFold(),
0901:                        new ActionFactory.CollapseAllFolds(),
0902:                        new ActionFactory.ExpandAllFolds(),
0903:                        new ActionFactory.DumpViewHierarchyAction(),
0904:                        new ActionFactory.StartNewLine(),
0905:                        new ActionFactory.CutToLineBeginOrEndAction(false),
0906:                        new ActionFactory.CutToLineBeginOrEndAction(true),
0907:
0908:                // Self test actions
0909:                //      new EditorDebug.SelfTestAction(),
0910:                //      new EditorDebug.DumpPlanesAction(),
0911:                //      new EditorDebug.DumpSyntaxMarksAction()
0912:                };
0913:            }
0914:
0915:            protected Action[] getCustomActions() {
0916:                Settings.KitAndValue kv[] = Settings.getValueHierarchy(this 
0917:                        .getClass(), SettingsNames.CUSTOM_ACTION_LIST);
0918:                if (kv.length == 0) {
0919:                    return null;
0920:                }
0921:                if (kv.length == 1) {
0922:                    List l = (List) kv[0].value;
0923:                    return (Action[]) l.toArray(new Action[l.size()]);
0924:                }
0925:                // more than one list of actions
0926:                List l = new ArrayList();
0927:                for (int i = kv.length - 1; i >= 0; i--) { // from BaseKit down
0928:                    l.addAll((List) kv[i].value);
0929:                }
0930:                return (Action[]) l.toArray(new Action[l.size()]);
0931:            }
0932:
0933:            /**
0934:             * @deprecated Without any replacement. 
0935:             */
0936:            protected Action[] getMacroActions() {
0937:                return new Action[0];
0938:            }
0939:
0940:            /** Get actions associated with this kit. createActions() is called
0941:             * to get basic list and then customActions are added.
0942:             */
0943:            public final Action[] getActions() {
0944:                synchronized (Settings.class) { // possibly long running code follows
0945:                    Class this Class = this .getClass();
0946:                    Action[] actions = (Action[]) kitActions.get(this Class);
0947:                    if (actions == null) {
0948:                        // create map of actions
0949:                        Action[] createdActions = createActions();
0950:                        updateActionSettings(createdActions, null, this Class);
0951:                        Map actionMap = actionsToMap(createdActions);
0952:                        // add custom actions
0953:                        Action[] customActions = getCustomActions();
0954:                        if (customActions != null) {
0955:                            updateActionSettings(customActions, null, this Class);
0956:                            actionMap.putAll(actionsToMap(customActions));
0957:                        }
0958:
0959:                        // store for later use
0960:                        kitActionMaps.put(this Class, actionMap);
0961:                        // create action array and store for later use
0962:                        actions = mapToActions(actionMap);
0963:                        kitActions.put(this Class, actions);
0964:
0965:                        // At this moment the actions are constructed completely
0966:                        // The actions will be updated now if necessary
0967:                        updateActions();
0968:                    }
0969:                    return actions;
0970:                }
0971:            }
0972:
0973:            Map getActionMap() {
0974:                Map actionMap = (Map) kitActionMaps.get(this .getClass());
0975:                if (actionMap == null) {
0976:                    getActions(); // init action map
0977:                    actionMap = (Map) kitActionMaps.get(this .getClass());
0978:
0979:                    // Fix of #27418
0980:                    if (actionMap == null) {
0981:                        actionMap = Collections.EMPTY_MAP;
0982:                    }
0983:                }
0984:                return actionMap;
0985:            }
0986:
0987:            /** Update the actions right after their creation was finished.
0988:             * The <code>getActions()</code> and <code>getActionByName()</code>
0989:             * can be used safely in this method.
0990:             * The implementation must call <code>super.updateActions()</code> so that
0991:             * the updating in parent is performed too.
0992:             */
0993:            protected void updateActions() {
0994:            }
0995:
0996:            /** Get action from its name. */
0997:            public Action getActionByName(String name) {
0998:                return (name != null) ? (Action) getActionMap().get(name)
0999:                        : null;
1000:            }
1001:
1002:            public List translateActionNameList(List actionNameList) {
1003:                List ret = new ArrayList();
1004:                if (actionNameList != null) {
1005:                    Iterator i = actionNameList.iterator();
1006:                    while (i.hasNext()) {
1007:                        Action a = getActionByName((String) i.next());
1008:                        if (a != null) {
1009:                            ret.add(a);
1010:                        }
1011:                    }
1012:                }
1013:                return ret;
1014:            }
1015:
1016:            /** Default typed action */
1017:            public static class DefaultKeyTypedAction extends LocalBaseAction {
1018:
1019:                static final long serialVersionUID = 3069164318144463899L;
1020:
1021:                public DefaultKeyTypedAction() {
1022:                    super (defaultKeyTypedAction, MAGIC_POSITION_RESET
1023:                            | CLEAR_STATUS_TEXT);
1024:                    putValue(BaseAction.NO_KEYBINDING, Boolean.TRUE);
1025:                }
1026:
1027:                private static final boolean isMac = System
1028:                        .getProperty("mrj.version") != null; //NOI18N
1029:
1030:                public void actionPerformed(ActionEvent evt,
1031:                        JTextComponent target) {
1032:                    if ((target != null) && (evt != null)) {
1033:
1034:                        // Check whether the modifiers are OK
1035:                        int mod = evt.getModifiers();
1036:                        boolean ctrl = ((mod & ActionEvent.CTRL_MASK) != 0);
1037:                        // On the mac, norwegian and french keyboards use Alt to do bracket characters.
1038:                        // This replicates Apple's modification DefaultEditorKit.DefaultKeyTypedAction
1039:                        boolean alt = isMac ? ((mod & ActionEvent.META_MASK) != 0)
1040:                                : ((mod & ActionEvent.ALT_MASK) != 0);
1041:
1042:                        if (alt || ctrl) {
1043:                            return;
1044:                        }
1045:
1046:                        // Check whether the target is enabled and editable
1047:                        if (!target.isEditable() || !target.isEnabled()) {
1048:                            target.getToolkit().beep();
1049:                            return;
1050:                        }
1051:
1052:                        Caret caret = target.getCaret();
1053:                        BaseDocument doc = (BaseDocument) target.getDocument();
1054:                        EditorUI editorUI = Utilities.getEditorUI(target);
1055:                        // determine if typed char is valid
1056:                        String cmd = evt.getActionCommand();
1057:                        if ((cmd != null) && (cmd.length() == 1)) {
1058:                            //          Utilities.clearStatusText(target);
1059:
1060:                            try {
1061:                                NavigationHistory.getEdits().markWaypoint(
1062:                                        target, caret.getDot(), false, true);
1063:                            } catch (BadLocationException e) {
1064:                                LOG
1065:                                        .log(
1066:                                                Level.WARNING,
1067:                                                "Can't add position to the history of edits.",
1068:                                                e); //NOI18N
1069:                            }
1070:
1071:                            doc.atomicLock();
1072:                            DocumentUtilities.setTypingModification(doc, true);
1073:                            try {
1074:                                char ch = cmd.charAt(0);
1075:                                if ((ch >= 0x20) && (ch != 0x7F)) { // valid character
1076:                                    editorUI.getWordMatch().clear(); // reset word matching
1077:                                    Boolean overwriteMode = (Boolean) editorUI
1078:                                            .getProperty(EditorUI.OVERWRITE_MODE_PROPERTY);
1079:                                    try {
1080:                                        boolean doInsert = true; // editorUI.getAbbrev().checkAndExpand(ch, evt);
1081:                                        if (doInsert) {
1082:                                            if (Utilities
1083:                                                    .isSelectionShowing(caret)) { // valid selection
1084:                                                boolean ovr = (overwriteMode != null && overwriteMode
1085:                                                        .booleanValue());
1086:                                                try {
1087:                                                    doc
1088:                                                            .putProperty(
1089:                                                                    DOC_REPLACE_SELECTION_PROPERTY,
1090:                                                                    true);
1091:                                                    replaceSelection(target,
1092:                                                            caret.getDot(),
1093:                                                            caret, cmd, ovr);
1094:                                                } finally {
1095:                                                    doc
1096:                                                            .putProperty(
1097:                                                                    DOC_REPLACE_SELECTION_PROPERTY,
1098:                                                                    null);
1099:                                                }
1100:                                            } else { // no selection
1101:                                                int dotPos = caret.getDot();
1102:                                                if (overwriteMode != null
1103:                                                        && overwriteMode
1104:                                                                .booleanValue()
1105:                                                        && dotPos < doc
1106:                                                                .getLength()
1107:                                                        && doc.getChars(dotPos,
1108:                                                                1)[0] != '\n') { // overwrite current char
1109:                                                    doc.atomicLock();
1110:                                                    try {
1111:                                                        insertString(doc,
1112:                                                                dotPos, caret,
1113:                                                                cmd, true);
1114:                                                    } finally {
1115:                                                        doc.atomicUnlock();
1116:                                                    }
1117:                                                } else { // insert mode
1118:                                                    doc.atomicLock();
1119:                                                    try {
1120:                                                        insertString(doc,
1121:                                                                dotPos, caret,
1122:                                                                cmd, false);
1123:                                                    } finally {
1124:                                                        doc.atomicUnlock();
1125:                                                    }
1126:                                                }
1127:                                            }
1128:                                        }
1129:                                    } catch (BadLocationException e) {
1130:                                        target.getToolkit().beep();
1131:                                    }
1132:                                }
1133:
1134:                                checkIndent(target, cmd);
1135:                            } finally {
1136:                                DocumentUtilities.setTypingModification(doc,
1137:                                        false);
1138:                                doc.atomicUnlock();
1139:                            }
1140:                        }
1141:
1142:                    }
1143:                }
1144:
1145:                /** 
1146:                 * Hook to insert the given string at the given position into
1147:                 * the given document in insert-mode, no selection, writeable
1148:                 * document. Designed to be overridden by subclasses that want
1149:                 * to intercept inserted characters.
1150:                 */
1151:                protected void insertString(BaseDocument doc, int dotPos,
1152:                        Caret caret, String str, boolean overwrite)
1153:                        throws BadLocationException {
1154:                    if (overwrite)
1155:                        doc.remove(dotPos, 1);
1156:                    doc.insertString(dotPos, str, null);
1157:                }
1158:
1159:                /** 
1160:                 * Hook to insert the given string at the given position into
1161:                 * the given document in insert-mode with selection visible
1162:                 * Designed to be overridden by subclasses that want
1163:                 * to intercept inserted characters.
1164:                 */
1165:                protected void replaceSelection(JTextComponent target,
1166:                        int dotPos, Caret caret, String str, boolean overwrite)
1167:                        throws BadLocationException {
1168:                    target.replaceSelection(str);
1169:                }
1170:
1171:                /** Check whether there was any important character typed
1172:                 * so that the line should be possibly reformatted.
1173:                 */
1174:                protected void checkIndent(JTextComponent target,
1175:                        String typedText) {
1176:                }
1177:
1178:            }
1179:
1180:            public static class InsertBreakAction extends LocalBaseAction {
1181:
1182:                static final long serialVersionUID = 7966576342334158659L;
1183:
1184:                public InsertBreakAction() {
1185:                    super (insertBreakAction, MAGIC_POSITION_RESET
1186:                            | ABBREV_RESET | WORD_MATCH_RESET);
1187:                }
1188:
1189:                public void actionPerformed(ActionEvent evt,
1190:                        JTextComponent target) {
1191:                    if (target != null) {
1192:                        if (!target.isEditable() || !target.isEnabled()) {
1193:                            target.getToolkit().beep();
1194:                            return;
1195:                        }
1196:
1197:                        BaseDocument doc = (BaseDocument) target.getDocument();
1198:                        Formatter formatter = doc.getFormatter();
1199:                        formatter.indentLock();
1200:                        try {
1201:                            doc.atomicLock();
1202:                            DocumentUtilities.setTypingModification(doc, true);
1203:                            try {
1204:                                target.replaceSelection("");
1205:                                Caret caret = target.getCaret();
1206:                                Object cookie = beforeBreak(target, doc, caret);
1207:
1208:                                int dotPos = caret.getDot();
1209:                                int newDotPos = formatter.indentNewLine(doc,
1210:                                        dotPos);
1211:                                caret.setDot(newDotPos);
1212:
1213:                                afterBreak(target, doc, caret, cookie);
1214:                            } finally {
1215:                                DocumentUtilities.setTypingModification(doc,
1216:                                        false);
1217:                                doc.atomicUnlock();
1218:                            }
1219:                        } finally {
1220:                            formatter.indentUnlock();
1221:                        }
1222:                    }
1223:                }
1224:
1225:                /**
1226:                 * Hook called before any changes to the document. The value
1227:                 * returned is passed intact to the other hook.
1228:                 */
1229:                protected Object beforeBreak(JTextComponent target,
1230:                        BaseDocument doc, Caret caret) {
1231:                    return null;
1232:                }
1233:
1234:                /**
1235:                 * Hook called after the enter was inserted and cursor
1236:                 * repositioned. *data* is the object returned previously by
1237:                 * *beforeBreak* hook. By default null.
1238:                 */
1239:                protected void afterBreak(JTextComponent target,
1240:                        BaseDocument doc, Caret caret, Object data) {
1241:                }
1242:            }
1243:
1244:            public static class SplitLineAction extends LocalBaseAction {
1245:
1246:                static final long serialVersionUID = 7966576342334158659L;
1247:
1248:                public SplitLineAction() {
1249:                    super (splitLineAction, MAGIC_POSITION_RESET | ABBREV_RESET
1250:                            | WORD_MATCH_RESET);
1251:                }
1252:
1253:                public void actionPerformed(ActionEvent evt,
1254:                        JTextComponent target) {
1255:                    if (target != null) {
1256:                        if (!target.isEditable() || !target.isEnabled()) {
1257:                            target.getToolkit().beep();
1258:                            return;
1259:                        }
1260:
1261:                        BaseDocument doc = (BaseDocument) target.getDocument();
1262:                        Caret caret = target.getCaret();
1263:
1264:                        Formatter formatter = doc.getFormatter();
1265:                        formatter.indentLock();
1266:                        doc.atomicLock();
1267:                        DocumentUtilities.setTypingModification(doc, true);
1268:                        try {
1269:                            target.replaceSelection("");
1270:                            final int dotPos = caret.getDot(); // dot stays where it was
1271:                            formatter.indentNewLine(doc, dotPos); // newline
1272:                            caret.setDot(dotPos);
1273:                        } finally {
1274:                            DocumentUtilities.setTypingModification(doc, false);
1275:                            doc.atomicUnlock();
1276:                            formatter.indentUnlock();
1277:                        }
1278:                    }
1279:                }
1280:
1281:            }
1282:
1283:            public static class InsertTabAction extends LocalBaseAction {
1284:
1285:                static final long serialVersionUID = -3379768531715989243L;
1286:
1287:                public InsertTabAction() {
1288:                    super (insertTabAction, MAGIC_POSITION_RESET | ABBREV_RESET
1289:                            | WORD_MATCH_RESET);
1290:                }
1291:
1292:                public void actionPerformed(ActionEvent evt,
1293:                        JTextComponent target) {
1294:                    if (target != null) {
1295:                        if (!target.isEditable() || !target.isEnabled()) {
1296:                            target.getToolkit().beep();
1297:                            return;
1298:                        }
1299:
1300:                        Caret caret = target.getCaret();
1301:                        BaseDocument doc = (BaseDocument) target.getDocument();
1302:                        doc.atomicLock();
1303:                        DocumentUtilities.setTypingModification(doc, true);
1304:                        try {
1305:                            if (Utilities.isSelectionShowing(caret)) { // block selected
1306:                                try {
1307:                                    doc.getFormatter().changeBlockIndent(doc,
1308:                                            target.getSelectionStart(),
1309:                                            target.getSelectionEnd(), +1);
1310:                                } catch (GuardedException e) {
1311:                                    target.getToolkit().beep();
1312:                                } catch (BadLocationException e) {
1313:                                    e.printStackTrace();
1314:                                }
1315:                            } else { // no selected text
1316:                                int dotPos = caret.getDot();
1317:                                int caretCol;
1318:                                // find caret column
1319:                                try {
1320:                                    caretCol = doc.getVisColFromPos(dotPos);
1321:                                } catch (BadLocationException e) {
1322:                                    LOG.log(Level.WARNING, null, e);
1323:                                    caretCol = 0;
1324:                                }
1325:
1326:                                try {
1327:                                    // find indent of the first previous non-white row
1328:                                    int upperCol = Utilities.getRowIndent(doc,
1329:                                            dotPos, false);
1330:                                    if (upperCol == -1) { // no prev line with  indent
1331:                                        upperCol = 0;
1332:                                    }
1333:                                    // is there any char on this line before cursor?
1334:                                    int indent = Utilities.getRowIndent(doc,
1335:                                            dotPos);
1336:                                    // test whether we should indent
1337:                                    if (indent == -1) {
1338:                                        if (upperCol > caretCol) { // upper indent is greater
1339:                                            indent = upperCol;
1340:                                        } else { // simulate insert tab by changing indent
1341:                                            indent = Utilities
1342:                                                    .getNextTabColumn(doc,
1343:                                                            dotPos);
1344:                                        }
1345:
1346:                                        // Fix of #32240 - #1 of 2
1347:                                        int rowStart = Utilities.getRowStart(
1348:                                                doc, dotPos);
1349:
1350:                                        doc.getFormatter().changeRowIndent(doc,
1351:                                                dotPos, indent);
1352:
1353:                                        // Fix of #32240 - #2 of 2
1354:                                        int newDotPos = doc
1355:                                                .getOffsetFromVisCol(indent,
1356:                                                        rowStart);
1357:                                        if (newDotPos >= 0) {
1358:                                            caret.setDot(newDotPos);
1359:                                        }
1360:
1361:                                    } else { // already chars on the line
1362:                                        doc.getFormatter().insertTabString(doc,
1363:                                                dotPos);
1364:
1365:                                    }
1366:                                } catch (BadLocationException e) {
1367:                                    // use the same pos
1368:                                }
1369:                            }
1370:                        } finally {
1371:                            DocumentUtilities.setTypingModification(doc, false);
1372:                            doc.atomicUnlock();
1373:                        }
1374:                    }
1375:
1376:                }
1377:
1378:            }
1379:
1380:            /** Compound action that encapsulates several actions */
1381:            public static class CompoundAction extends LocalBaseAction {
1382:
1383:                Action[] actions;
1384:
1385:                static final long serialVersionUID = 1649688300969753758L;
1386:
1387:                public CompoundAction(String nm, Action actions[]) {
1388:                    this (nm, 0, actions);
1389:                }
1390:
1391:                public CompoundAction(String nm, int resetMask,
1392:                        Action actions[]) {
1393:                    super (nm, resetMask);
1394:                    this .actions = actions;
1395:                }
1396:
1397:                public void actionPerformed(ActionEvent evt,
1398:                        JTextComponent target) {
1399:                    if (target != null) {
1400:                        for (int i = 0; i < actions.length; i++) {
1401:                            Action a = actions[i];
1402:                            if (a instanceof  BaseAction) {
1403:                                ((BaseAction) a).actionPerformed(evt, target);
1404:                            } else {
1405:                                a.actionPerformed(evt);
1406:                            }
1407:                        }
1408:                    }
1409:                }
1410:            }
1411:
1412:            /** Compound action that gets and executes its actions
1413:             * depending on the kit of the component.
1414:             * The other advantage is that it doesn't create additional
1415:             * instances of compound actions.
1416:             */
1417:            public static class KitCompoundAction extends LocalBaseAction {
1418:
1419:                private String[] actionNames;
1420:
1421:                static final long serialVersionUID = 8415246475764264835L;
1422:
1423:                public KitCompoundAction(String nm, String actionNames[]) {
1424:                    this (nm, 0, actionNames);
1425:                }
1426:
1427:                public KitCompoundAction(String nm, int resetMask,
1428:                        String actionNames[]) {
1429:                    super (nm, resetMask);
1430:                    this .actionNames = actionNames;
1431:                }
1432:
1433:                public void actionPerformed(ActionEvent evt,
1434:                        JTextComponent target) {
1435:                    if (target != null) {
1436:                        BaseKit kit = Utilities.getKit(target);
1437:                        if (kit != null) {
1438:                            for (int i = 0; i < actionNames.length; i++) {
1439:                                Action a = kit.getActionByName(actionNames[i]);
1440:                                if (a != null) {
1441:                                    if (a instanceof  BaseAction) {
1442:                                        ((BaseAction) a).actionPerformed(evt,
1443:                                                target);
1444:                                    } else {
1445:                                        a.actionPerformed(evt);
1446:                                    }
1447:                                }
1448:                            }
1449:                        }
1450:                    }
1451:                }
1452:            }
1453:
1454:            public static class InsertContentAction extends LocalBaseAction {
1455:
1456:                static final long serialVersionUID = 5647751370952797218L;
1457:
1458:                public InsertContentAction() {
1459:                    super (insertContentAction, MAGIC_POSITION_RESET
1460:                            | ABBREV_RESET | WORD_MATCH_RESET);
1461:                    putValue(BaseAction.NO_KEYBINDING, Boolean.TRUE);
1462:                }
1463:
1464:                public void actionPerformed(ActionEvent evt,
1465:                        JTextComponent target) {
1466:                    if ((target != null) && (evt != null)) {
1467:                        if (!target.isEditable() || !target.isEnabled()) {
1468:                            target.getToolkit().beep();
1469:                            return;
1470:                        }
1471:
1472:                        String content = evt.getActionCommand();
1473:                        if (content != null) {
1474:                            target.replaceSelection(content);
1475:                        } else {
1476:                            target.getToolkit().beep();
1477:                        }
1478:                    }
1479:                }
1480:            }
1481:
1482:            /** Insert text specified in constructor */
1483:            public static class InsertStringAction extends LocalBaseAction {
1484:
1485:                String text;
1486:
1487:                static final long serialVersionUID = -2755852016584693328L;
1488:
1489:                public InsertStringAction(String nm, String text) {
1490:                    super (nm, MAGIC_POSITION_RESET | ABBREV_RESET
1491:                            | WORD_MATCH_RESET);
1492:                    this .text = text;
1493:                }
1494:
1495:                public void actionPerformed(ActionEvent evt,
1496:                        JTextComponent target) {
1497:                    if (target != null) {
1498:                        if (!target.isEditable() || !target.isEnabled()) {
1499:                            target.getToolkit().beep();
1500:                            return;
1501:                        }
1502:
1503:                        target.replaceSelection(text);
1504:                    }
1505:                }
1506:            }
1507:
1508:            /** Remove previous or next character */
1509:            public static class DeleteCharAction extends LocalBaseAction {
1510:
1511:                protected boolean nextChar;
1512:
1513:                static final long serialVersionUID = -4321971925753148556L;
1514:
1515:                public DeleteCharAction(String nm, boolean nextChar) {
1516:                    super (nm, MAGIC_POSITION_RESET | ABBREV_RESET
1517:                            | WORD_MATCH_RESET);
1518:                    this .nextChar = nextChar;
1519:                }
1520:
1521:                public void actionPerformed(ActionEvent evt,
1522:                        JTextComponent target) {
1523:                    if (target != null) {
1524:                        if (!target.isEditable() || !target.isEnabled()) {
1525:                            target.getToolkit().beep();
1526:                            return;
1527:                        }
1528:
1529:                        BaseDocument doc = (BaseDocument) target.getDocument();
1530:                        Caret caret = target.getCaret();
1531:                        int dot = caret.getDot();
1532:                        int mark = caret.getMark();
1533:
1534:                        doc.atomicLock();
1535:                        DocumentUtilities.setTypingModification(doc, true);
1536:
1537:                        try {
1538:                            if (dot != mark) { // remove selection
1539:                                doc.remove(Math.min(dot, mark), Math.abs(dot
1540:                                        - mark));
1541:                            } else {
1542:                                if (nextChar) { // remove next char
1543:                                    char ch = doc.getChars(dot, 1)[0];
1544:                                    doc.remove(dot, 1);
1545:                                    charDeleted(doc, dot, caret, ch);
1546:                                } else { // remove previous char
1547:                                    char ch = doc.getChars(dot - 1, 1)[0];
1548:                                    doc.remove(dot - 1, 1);
1549:                                    charBackspaced(doc, dot - 1, caret, ch);
1550:                                }
1551:                            }
1552:                        } catch (BadLocationException e) {
1553:                            target.getToolkit().beep();
1554:                        } finally {
1555:                            DocumentUtilities.setTypingModification(doc, false);
1556:                            doc.atomicUnlock();
1557:                        }
1558:
1559:                    }
1560:                }
1561:
1562:                protected void charBackspaced(BaseDocument doc, int dotPos,
1563:                        Caret caret, char ch) throws BadLocationException {
1564:                }
1565:
1566:                protected void charDeleted(BaseDocument doc, int dotPos,
1567:                        Caret caret, char ch) throws BadLocationException {
1568:                }
1569:            }
1570:
1571:            public static class ReadOnlyAction extends LocalBaseAction {
1572:
1573:                static final long serialVersionUID = 9204335480208463193L;
1574:
1575:                public ReadOnlyAction() {
1576:                    super (readOnlyAction);
1577:                    putValue(BaseAction.NO_KEYBINDING, Boolean.TRUE);
1578:                }
1579:
1580:                public void actionPerformed(ActionEvent evt,
1581:                        JTextComponent target) {
1582:                    if (target != null) {
1583:                        target.setEditable(false);
1584:                    }
1585:                }
1586:            }
1587:
1588:            public static class WritableAction extends LocalBaseAction {
1589:
1590:                static final long serialVersionUID = -5982547952800937954L;
1591:
1592:                public WritableAction() {
1593:                    super (writableAction);
1594:                    putValue(BaseAction.NO_KEYBINDING, Boolean.TRUE);
1595:                }
1596:
1597:                public void actionPerformed(ActionEvent evt,
1598:                        JTextComponent target) {
1599:                    if (target != null) {
1600:                        target.setEditable(true);
1601:                    }
1602:                }
1603:            }
1604:
1605:            public static class CutAction extends LocalBaseAction {
1606:
1607:                static final long serialVersionUID = 6377157040901778853L;
1608:
1609:                public CutAction() {
1610:                    super (cutAction, ABBREV_RESET | UNDO_MERGE_RESET
1611:                            | WORD_MATCH_RESET);
1612:                    setEnabled(false);
1613:                    //#54893 putValue ("helpID", CutAction.class.getName ()); // NOI18N
1614:                }
1615:
1616:                public void actionPerformed(ActionEvent evt,
1617:                        JTextComponent target) {
1618:                    if (target != null) {
1619:                        if (!target.isEditable() || !target.isEnabled()) {
1620:                            target.getToolkit().beep();
1621:                            return;
1622:                        }
1623:
1624:                        try {
1625:                            NavigationHistory.getEdits().markWaypoint(target,
1626:                                    target.getCaret().getDot(), false, true);
1627:                        } catch (BadLocationException e) {
1628:                            LOG
1629:                                    .log(
1630:                                            Level.WARNING,
1631:                                            "Can't add position to the history of edits.",
1632:                                            e); //NOI18N
1633:                        }
1634:
1635:                        BaseDocument doc = (BaseDocument) target.getDocument();
1636:                        doc.atomicLock();
1637:                        DocumentUtilities.setTypingModification(doc, true);
1638:                        try {
1639:                            target.cut();
1640:                        } finally {
1641:                            DocumentUtilities.setTypingModification(doc, false);
1642:                            doc.atomicUnlock();
1643:                        }
1644:                    }
1645:                }
1646:            }
1647:
1648:            public static class CopyAction extends LocalBaseAction {
1649:
1650:                static final long serialVersionUID = -5119779005431986964L;
1651:
1652:                public CopyAction() {
1653:                    super (copyAction, ABBREV_RESET | UNDO_MERGE_RESET
1654:                            | WORD_MATCH_RESET);
1655:                    setEnabled(false);
1656:                    //#54893 putValue ("helpID", CopyAction.class.getName ()); // NOI18N
1657:                }
1658:
1659:                public void actionPerformed(ActionEvent evt,
1660:                        JTextComponent target) {
1661:                    if (target != null) {
1662:                        target.copy();
1663:                    }
1664:                }
1665:            }
1666:
1667:            public static class PasteAction extends LocalBaseAction {
1668:
1669:                static final long serialVersionUID = 5839791453996432149L;
1670:                private boolean formatted;
1671:
1672:                public PasteAction(boolean formated) {
1673:                    super (formated ? pasteFormatedAction : pasteAction,
1674:                            ABBREV_RESET | UNDO_MERGE_RESET | WORD_MATCH_RESET);
1675:                    //#54893 putValue ("helpID", PasteAction.class.getName ()); // NOI18N
1676:                    this .formatted = formated;
1677:                }
1678:
1679:                public void actionPerformed(ActionEvent evt,
1680:                        JTextComponent target) {
1681:                    if (target != null) {
1682:                        if (!target.isEditable() || !target.isEnabled()) {
1683:                            target.getToolkit().beep();
1684:                            return;
1685:                        }
1686:
1687:                        BaseDocument doc = Utilities.getDocument(target);
1688:                        if (doc == null)
1689:                            return;
1690:
1691:                        try {
1692:                            NavigationHistory.getEdits().markWaypoint(target,
1693:                                    target.getCaret().getDot(), false, true);
1694:                        } catch (BadLocationException e) {
1695:                            LOG
1696:                                    .log(
1697:                                            Level.WARNING,
1698:                                            "Can't add position to the history of edits.",
1699:                                            e); //NOI18N
1700:                        }
1701:
1702:                        Formatter formatter = doc.getFormatter();
1703:                        if (formatted) {
1704:                            formatter.reformatLock();
1705:                        }
1706:                        try {
1707:                            doc.atomicLock();
1708:                            DocumentUtilities.setTypingModification(doc, true);
1709:                            try {
1710:                                Caret caret = target.getCaret();
1711:                                int startOffset = target.getSelectionStart();
1712:                                target.paste();
1713:                                int endOffset = caret.getDot();
1714:                                if (formatted) {
1715:                                    formatter.reformat(doc, startOffset,
1716:                                            endOffset);
1717:                                }
1718:                            } catch (Exception e) {
1719:                                target.getToolkit().beep();
1720:                            } finally {
1721:                                DocumentUtilities.setTypingModification(doc,
1722:                                        false);
1723:                                doc.atomicUnlock();
1724:                            }
1725:                        } finally {
1726:                            if (formatted) {
1727:                                formatter.reformatUnlock();
1728:                            }
1729:                        }
1730:                    }
1731:                }
1732:
1733:                public static void indentBlock(BaseDocument doc,
1734:                        int startOffset, int endOffset)
1735:                        throws BadLocationException {
1736:                    char[] text = doc.getChars(startOffset, endOffset
1737:                            - startOffset);
1738:                    String[] lines = toLines(new String(text));
1739:
1740:                    doc.remove(startOffset, endOffset - startOffset);
1741:                    //	System.out.println("Lines:\n"); // NOI18N
1742:                    //	for (int j = 0 ; j < lines.length; j++) System.out.println(lines[j] + "<"); // NOI18N
1743:
1744:                    int offset = startOffset;
1745:                    // handle the full lines
1746:                    for (int i = 0; i < lines.length - 1; i++) {
1747:                        String indent = getIndentString(doc, offset, lines[i]);
1748:                        String fragment = indent + lines[i].trim() + '\n';
1749:                        //	  System.out.println(fragment + "|"); // NOI18N
1750:                        doc.insertString(offset, fragment, null);
1751:                        offset += fragment.length();
1752:                    }
1753:
1754:                    // the rest just paste without indenting
1755:                    doc.insertString(offset, lines[lines.length - 1], null);
1756:
1757:                }
1758:
1759:                /** Break string to lines */
1760:                private static String[] toLines(String str) {
1761:                    Vector v = new Vector();
1762:                    int p = 0, p0 = 0;
1763:                    for (; p < str.length(); p++) {
1764:                        if (str.charAt(p) == '\n') {
1765:                            v.add(str.substring(p0, p + 1));
1766:                            p0 = p + 1;
1767:                        }
1768:                    }
1769:                    if (p0 < str.length())
1770:                        v.add(str.substring(p0, str.length()));
1771:                    else
1772:                        v.add("");
1773:
1774:                    return (String[]) v.toArray(new String[0]);
1775:                }
1776:
1777:                private static String getIndentString(BaseDocument doc,
1778:                        int startOffset, String str) {
1779:                    try {
1780:                        Formatter f = doc.getFormatter();
1781:                        CharArrayWriter cw = new CharArrayWriter();
1782:                        Writer w = f.createWriter(doc, startOffset, cw);
1783:                        w.write(str, 0, str.length());
1784:                        w.close();
1785:                        String out = new String(cw.toCharArray());
1786:                        int i = 0;
1787:                        for (; i < out.length(); i++) {
1788:                            if (out.charAt(i) != ' ' && out.charAt(i) != '\t')
1789:                                break;
1790:                        }
1791:                        //	  System.out.println(out+"|"); // NOI18N
1792:                        //	  System.out.println(out.substring(0,i)+"^"); // NOI18N
1793:
1794:                        return out.substring(0, i);
1795:                    } catch (java.io.IOException e) {
1796:                        return "";
1797:                    }
1798:                }
1799:            }
1800:
1801:            public static class BeepAction extends LocalBaseAction {
1802:
1803:                static final long serialVersionUID = -4474054576633223968L;
1804:
1805:                public BeepAction() {
1806:                    super (beepAction);
1807:                    putValue(BaseAction.NO_KEYBINDING, Boolean.TRUE);
1808:                }
1809:
1810:                public void actionPerformed(ActionEvent evt,
1811:                        JTextComponent target) {
1812:                    if (target != null) {
1813:                        target.getToolkit().beep();
1814:                    }
1815:                }
1816:            }
1817:
1818:            public static class UpAction extends LocalBaseAction {
1819:
1820:                boolean select;
1821:
1822:                static final long serialVersionUID = 4621760742646981563L;
1823:
1824:                public UpAction(String nm, boolean select) {
1825:                    super (nm, ABBREV_RESET | UNDO_MERGE_RESET
1826:                            | WORD_MATCH_RESET | CLEAR_STATUS_TEXT);
1827:                    this .select = select;
1828:                }
1829:
1830:                public void actionPerformed(ActionEvent evt,
1831:                        JTextComponent target) {
1832:                    if (target != null) {
1833:                        try {
1834:                            Caret caret = target.getCaret();
1835:                            int dot = caret.getDot();
1836:                            Point p = caret.getMagicCaretPosition();
1837:                            if (p == null) {
1838:                                Rectangle r = target.modelToView(dot);
1839:                                if (r != null) {
1840:                                    p = new Point(r.x, r.y);
1841:                                    caret.setMagicCaretPosition(p);
1842:                                } else {
1843:                                    return; // model to view failed
1844:                                }
1845:                            }
1846:                            try {
1847:                                dot = Utilities.getPositionAbove(target, dot,
1848:                                        p.x);
1849:                                if (select) {
1850:                                    caret.moveDot(dot);
1851:                                } else {
1852:                                    caret.setDot(dot);
1853:                                }
1854:                            } catch (BadLocationException e) {
1855:                                // the position stays the same
1856:                            }
1857:                        } catch (BadLocationException ex) {
1858:                            target.getToolkit().beep();
1859:                        }
1860:                    }
1861:                }
1862:            }
1863:
1864:            public static class DownAction extends LocalBaseAction {
1865:
1866:                boolean select;
1867:
1868:                static final long serialVersionUID = -5635702355125266822L;
1869:
1870:                public DownAction(String nm, boolean select) {
1871:                    super (nm, ABBREV_RESET | UNDO_MERGE_RESET
1872:                            | WORD_MATCH_RESET | CLEAR_STATUS_TEXT);
1873:                    this .select = select;
1874:                }
1875:
1876:                public void actionPerformed(ActionEvent evt,
1877:                        JTextComponent target) {
1878:                    if (target != null) {
1879:                        try {
1880:                            Caret caret = target.getCaret();
1881:                            int dot = caret.getDot();
1882:                            Point p = caret.getMagicCaretPosition();
1883:                            if (p == null) {
1884:                                Rectangle r = target.modelToView(dot);
1885:                                if (r != null) {
1886:                                    p = new Point(r.x, r.y);
1887:                                    caret.setMagicCaretPosition(p);
1888:                                } else {
1889:                                    return; // model to view failed
1890:                                }
1891:                            }
1892:                            try {
1893:                                dot = Utilities.getPositionBelow(target, dot,
1894:                                        p.x);
1895:                                if (select) {
1896:                                    caret.moveDot(dot);
1897:                                } else {
1898:                                    caret.setDot(dot);
1899:                                }
1900:                            } catch (BadLocationException e) {
1901:                                // position stays the same
1902:                            }
1903:                        } catch (BadLocationException ex) {
1904:                            target.getToolkit().beep();
1905:                        }
1906:                    }
1907:                }
1908:            }
1909:
1910:            /** Go one page up */
1911:            public static class PageUpAction extends LocalBaseAction {
1912:
1913:                boolean select;
1914:
1915:                static final long serialVersionUID = -3107382148581661079L;
1916:
1917:                public PageUpAction(String nm, boolean select) {
1918:                    super (nm, ABBREV_RESET | UNDO_MERGE_RESET
1919:                            | WORD_MATCH_RESET | CLEAR_STATUS_TEXT);
1920:                    this .select = select;
1921:                }
1922:
1923:                public void actionPerformed(ActionEvent evt,
1924:                        JTextComponent target) {
1925:                    if (target != null) {
1926:                        try {
1927:                            Caret caret = target.getCaret();
1928:                            BaseDocument doc = (BaseDocument) target
1929:                                    .getDocument();
1930:                            int caretOffset = caret.getDot();
1931:                            Rectangle caretBounds = ((BaseTextUI) target
1932:                                    .getUI()).modelToView(target, caretOffset);
1933:                            if (caretBounds == null) {
1934:                                return; // Cannot continue reasonably
1935:                            }
1936:
1937:                            // Retrieve caret magic position and attempt to retain
1938:                            // the x-coordinate information and use it
1939:                            // for setting of the new caret position
1940:                            Point magicCaretPosition = caret
1941:                                    .getMagicCaretPosition();
1942:                            if (magicCaretPosition == null) {
1943:                                magicCaretPosition = new Point(caretBounds.x,
1944:                                        caretBounds.y);
1945:                            }
1946:
1947:                            Rectangle visibleBounds = target.getVisibleRect();
1948:                            int newCaretOffset;
1949:                            Rectangle newCaretBounds;
1950:
1951:                            // Check whether caret was contained in the original visible window
1952:                            if (visibleBounds.contains(caretBounds)) {
1953:                                // Clone present view bounds
1954:                                Rectangle newVisibleBounds = new Rectangle(
1955:                                        visibleBounds);
1956:                                // Do viewToModel() and modelToView() with the left top corner
1957:                                // of the currently visible view. If that line is not fully visible
1958:                                // then it should be the bottom line of the previous page
1959:                                // (if it's fully visible then the line above it).
1960:                                int topLeftOffset = target
1961:                                        .viewToModel(new Point(visibleBounds.x,
1962:                                                visibleBounds.y));
1963:                                Rectangle topLeftLineBounds = target
1964:                                        .modelToView(topLeftOffset);
1965:
1966:                                // newVisibleBounds.y will hold bottom of new view
1967:                                if (topLeftLineBounds.y != visibleBounds.y) {
1968:                                    newVisibleBounds.y = topLeftLineBounds.y
1969:                                            + topLeftLineBounds.height;
1970:                                } // Component view starts right at the line boundary
1971:                                // Go back by the view height
1972:                                newVisibleBounds.y -= visibleBounds.height;
1973:
1974:                                // Find the new caret bounds by using relative y position
1975:                                // on the original caret bounds. If the caret's new relative bounds
1976:                                // would be visually above the old bounds
1977:                                // the view should be shifted so that the relative bounds
1978:                                // are the same (user's eyes do not need to move).
1979:                                int caretRelY = caretBounds.y - visibleBounds.y;
1980:                                int caretNewY = newVisibleBounds.y + caretRelY;
1981:                                newCaretOffset = target.viewToModel(new Point(
1982:                                        magicCaretPosition.x, caretNewY));
1983:                                newCaretBounds = target
1984:                                        .modelToView(newCaretOffset);
1985:                                if (newCaretBounds.y < caretNewY) {
1986:                                    // Need to go one line down to retain the top line
1987:                                    // of the present newVisibleBounds to be fully visible.
1988:                                    // Attempt to go forward by height of caret
1989:                                    newCaretOffset = target
1990:                                            .viewToModel(new Point(
1991:                                                    magicCaretPosition.x,
1992:                                                    newCaretBounds.y
1993:                                                            + newCaretBounds.height));
1994:                                    newCaretBounds = target
1995:                                            .modelToView(newCaretOffset);
1996:                                }
1997:
1998:                                // Shift the new visible bounds so that the caret
1999:                                // does not visually move
2000:                                newVisibleBounds.y = newCaretBounds.y
2001:                                        - caretRelY;
2002:
2003:                                // Scroll the window to the requested rectangle
2004:                                target.scrollRectToVisible(newVisibleBounds);
2005:
2006:                            } else { // Caret outside of originally visible window
2007:                                // Shift the dot by the visible bounds height
2008:                                Point newCaretPoint = new Point(
2009:                                        magicCaretPosition.x, caretBounds.y
2010:                                                - visibleBounds.height);
2011:                                newCaretOffset = target
2012:                                        .viewToModel(newCaretPoint);
2013:                                newCaretBounds = target
2014:                                        .modelToView(newCaretOffset);
2015:                            }
2016:
2017:                            if (select) {
2018:                                caret.moveDot(newCaretOffset);
2019:                            } else {
2020:                                caret.setDot(newCaretOffset);
2021:                            }
2022:
2023:                            // Update magic caret position
2024:                            magicCaretPosition.y = newCaretBounds.y;
2025:                            caret.setMagicCaretPosition(magicCaretPosition);
2026:
2027:                        } catch (BadLocationException ex) {
2028:                            target.getToolkit().beep();
2029:                        }
2030:                    }
2031:                }
2032:            }
2033:
2034:            public static class ForwardAction extends LocalBaseAction {
2035:
2036:                boolean select;
2037:
2038:                static final long serialVersionUID = 8007293230193334414L;
2039:
2040:                public ForwardAction(String nm, boolean select) {
2041:                    super (nm, MAGIC_POSITION_RESET | ABBREV_RESET
2042:                            | UNDO_MERGE_RESET | WORD_MATCH_RESET
2043:                            | CLEAR_STATUS_TEXT);
2044:                    this .select = select;
2045:                }
2046:
2047:                public void actionPerformed(ActionEvent evt,
2048:                        JTextComponent target) {
2049:                    if (target != null) {
2050:                        Caret caret = target.getCaret();
2051:                        try {
2052:                            int pos;
2053:                            if (!select && Utilities.isSelectionShowing(caret)) {
2054:                                pos = target.getSelectionEnd();
2055:                                if (pos != caret.getDot()) {
2056:                                    pos--;
2057:                                } else {
2058:                                    // clear the selection, but do not move the cursor
2059:                                    caret.setDot(pos);
2060:                                    return;
2061:                                }
2062:                            } else
2063:                                pos = caret.getDot();
2064:                            int dot = target.getUI().getNextVisualPositionFrom(
2065:                                    target, pos, Position.Bias.Forward,
2066:                                    SwingConstants.EAST, null);
2067:                            if (select) {
2068:                                caret.moveDot(dot);
2069:                            } else {
2070:                                caret.setDot(dot);
2071:                            }
2072:                        } catch (BadLocationException ex) {
2073:                            target.getToolkit().beep();
2074:                        }
2075:                    }
2076:                }
2077:            }
2078:
2079:            /** Go one page down */
2080:            public static class PageDownAction extends LocalBaseAction {
2081:
2082:                boolean select;
2083:
2084:                static final long serialVersionUID = 8942534850985048862L;
2085:
2086:                public PageDownAction(String nm, boolean select) {
2087:                    super (nm, ABBREV_RESET | UNDO_MERGE_RESET
2088:                            | WORD_MATCH_RESET | CLEAR_STATUS_TEXT);
2089:                    this .select = select;
2090:                }
2091:
2092:                public void actionPerformed(ActionEvent evt,
2093:                        JTextComponent target) {
2094:                    if (target != null) {
2095:                        try {
2096:                            Caret caret = target.getCaret();
2097:                            BaseDocument doc = (BaseDocument) target
2098:                                    .getDocument();
2099:                            int caretOffset = caret.getDot();
2100:                            Rectangle caretBounds = ((BaseTextUI) target
2101:                                    .getUI()).modelToView(target, caretOffset);
2102:                            if (caretBounds == null) {
2103:                                return; // Cannot continue reasonably
2104:                            }
2105:
2106:                            // Retrieve caret magic position and attempt to retain
2107:                            // the x-coordinate information and use it
2108:                            // for setting of the new caret position
2109:                            Point magicCaretPosition = caret
2110:                                    .getMagicCaretPosition();
2111:                            if (magicCaretPosition == null) {
2112:                                magicCaretPosition = new Point(caretBounds.x,
2113:                                        caretBounds.y);
2114:                            }
2115:
2116:                            Rectangle visibleBounds = target.getVisibleRect();
2117:                            int newCaretOffset;
2118:                            Rectangle newCaretBounds;
2119:
2120:                            // Check whether caret was contained in the original visible window
2121:                            if (visibleBounds.contains(caretBounds)) {
2122:                                // Clone present view bounds
2123:                                Rectangle newVisibleBounds = new Rectangle(
2124:                                        visibleBounds);
2125:                                // Do viewToModel() and modelToView() with the left bottom corner
2126:                                // of the currently visible view.
2127:                                // That line should be the top line of the next page.
2128:                                int bottomLeftOffset = target
2129:                                        .viewToModel(new Point(visibleBounds.x,
2130:                                                visibleBounds.y
2131:                                                        + visibleBounds.height));
2132:                                Rectangle bottomLeftLineBounds = target
2133:                                        .modelToView(bottomLeftOffset);
2134:
2135:                                // newVisibleBounds.y will hold bottom of new view
2136:                                newVisibleBounds.y = bottomLeftLineBounds.y;
2137:
2138:                                // Find the new caret bounds by using relative y position
2139:                                // on the original caret bounds. If the caret's new relative bounds
2140:                                // would be visually below the old bounds
2141:                                // the view should be shifted so that the relative bounds
2142:                                // are the same (user's eyes do not need to move).
2143:                                int caretRelY = caretBounds.y - visibleBounds.y;
2144:                                int caretNewY = newVisibleBounds.y + caretRelY;
2145:                                newCaretOffset = target.viewToModel(new Point(
2146:                                        magicCaretPosition.x, caretNewY));
2147:                                newCaretBounds = target
2148:                                        .modelToView(newCaretOffset);
2149:                                if (newCaretBounds.y > caretNewY) {
2150:                                    // Need to go one line above to retain the top line
2151:                                    // of the present newVisibleBounds to be fully visible.
2152:                                    // Attempt to go up by height of caret.
2153:                                    newCaretOffset = target
2154:                                            .viewToModel(new Point(
2155:                                                    magicCaretPosition.x,
2156:                                                    newCaretBounds.y
2157:                                                            - newCaretBounds.height));
2158:                                    newCaretBounds = target
2159:                                            .modelToView(newCaretOffset);
2160:                                }
2161:
2162:                                // Shift the new visible bounds so that the caret
2163:                                // does not visually move
2164:                                newVisibleBounds.y = newCaretBounds.y
2165:                                        - caretRelY;
2166:
2167:                                // Scroll the window to the requested rectangle
2168:                                target.scrollRectToVisible(newVisibleBounds);
2169:
2170:                            } else { // Caret outside of originally visible window
2171:                                // Shift the dot by the visible bounds height
2172:                                Point newCaretPoint = new Point(
2173:                                        magicCaretPosition.x, caretBounds.y
2174:                                                + visibleBounds.height);
2175:                                newCaretOffset = target
2176:                                        .viewToModel(newCaretPoint);
2177:                                newCaretBounds = target
2178:                                        .modelToView(newCaretOffset);
2179:                            }
2180:
2181:                            if (select) {
2182:                                caret.moveDot(newCaretOffset);
2183:                            } else {
2184:                                caret.setDot(newCaretOffset);
2185:                            }
2186:
2187:                            // Update magic caret position
2188:                            magicCaretPosition.y = newCaretBounds.y;
2189:                            caret.setMagicCaretPosition(magicCaretPosition);
2190:
2191:                        } catch (BadLocationException ex) {
2192:                            target.getToolkit().beep();
2193:                        }
2194:                    }
2195:                }
2196:            }
2197:
2198:            public static class BackwardAction extends LocalBaseAction {
2199:
2200:                boolean select;
2201:
2202:                static final long serialVersionUID = -3048379822817847356L;
2203:
2204:                public BackwardAction(String nm, boolean select) {
2205:                    super (nm, MAGIC_POSITION_RESET | ABBREV_RESET
2206:                            | UNDO_MERGE_RESET | WORD_MATCH_RESET
2207:                            | CLEAR_STATUS_TEXT);
2208:                    this .select = select;
2209:                }
2210:
2211:                public void actionPerformed(ActionEvent evt,
2212:                        JTextComponent target) {
2213:                    if (target != null) {
2214:                        Caret caret = target.getCaret();
2215:                        try {
2216:                            int pos;
2217:                            if (!select && Utilities.isSelectionShowing(caret)) {
2218:                                pos = target.getSelectionStart();
2219:                                if (pos != caret.getDot()) {
2220:                                    pos++;
2221:                                } else {
2222:                                    // clear the selection, but do not move the cursor
2223:                                    caret.setDot(pos);
2224:                                    return;
2225:                                }
2226:                            } else
2227:                                pos = caret.getDot();
2228:                            int dot = target.getUI().getNextVisualPositionFrom(
2229:                                    target, pos, Position.Bias.Backward,
2230:                                    SwingConstants.WEST, null);
2231:                            if (select) {
2232:                                caret.moveDot(dot);
2233:                            } else {
2234:                                caret.setDot(dot);
2235:                            }
2236:                        } catch (BadLocationException ex) {
2237:                            target.getToolkit().beep();
2238:                        }
2239:                    }
2240:                }
2241:            }
2242:
2243:            public static class BeginLineAction extends LocalBaseAction {
2244:
2245:                protected boolean select;
2246:
2247:                /** Whether the action should go to the begining of
2248:                 * the text on the line or to the first column on the line*/
2249:                boolean homeKeyColumnOne;
2250:
2251:                static final long serialVersionUID = 3269462923524077779L;
2252:
2253:                public BeginLineAction(String nm, boolean select) {
2254:                    super (nm, MAGIC_POSITION_RESET | ABBREV_RESET
2255:                            | UNDO_MERGE_RESET | WORD_MATCH_RESET
2256:                            | CLEAR_STATUS_TEXT);
2257:                    this .select = select;
2258:                    homeKeyColumnOne = false;
2259:                }
2260:
2261:                public BeginLineAction(String nm, boolean select,
2262:                        boolean columnOne) {
2263:                    this (nm, select);
2264:                    homeKeyColumnOne = columnOne;
2265:                }
2266:
2267:                public void actionPerformed(ActionEvent evt,
2268:                        JTextComponent target) {
2269:                    if (target != null) {
2270:                        Caret caret = target.getCaret();
2271:                        BaseDocument doc = (BaseDocument) target.getDocument();
2272:                        try {
2273:                            int dot = caret.getDot();
2274:                            int lineStartPos = Utilities.getRowStart(target,
2275:                                    dot);
2276:                            if (homeKeyColumnOne) { // to first column
2277:                                dot = lineStartPos;
2278:                            } else { // either to line start or text start
2279:                                int textStartPos = Utilities
2280:                                        .getRowFirstNonWhite(doc, lineStartPos);
2281:                                if (textStartPos < 0) { // no text on the line
2282:                                    textStartPos = Utilities.getRowEnd(target,
2283:                                            lineStartPos);
2284:                                }
2285:                                if (dot == lineStartPos) { // go to the text start pos
2286:                                    dot = textStartPos;
2287:                                } else if (dot <= textStartPos) {
2288:                                    dot = lineStartPos;
2289:                                } else {
2290:                                    dot = textStartPos;
2291:                                }
2292:                            }
2293:                            if (select) {
2294:                                caret.moveDot(dot);
2295:                            } else {
2296:                                caret.setDot(dot);
2297:                            }
2298:                        } catch (BadLocationException e) {
2299:                            target.getToolkit().beep();
2300:                        }
2301:                    }
2302:                }
2303:            }
2304:
2305:            public static class EndLineAction extends LocalBaseAction {
2306:
2307:                protected boolean select;
2308:
2309:                static final long serialVersionUID = 5216077634055190170L;
2310:
2311:                public EndLineAction(String nm, boolean select) {
2312:                    super (nm, MAGIC_POSITION_RESET | ABBREV_RESET
2313:                            | UNDO_MERGE_RESET | WORD_MATCH_RESET
2314:                            | CLEAR_STATUS_TEXT);
2315:                    this .select = select;
2316:                }
2317:
2318:                public void actionPerformed(ActionEvent evt,
2319:                        JTextComponent target) {
2320:                    if (target != null) {
2321:                        Caret caret = target.getCaret();
2322:                        try {
2323:                            int dot = Utilities.getRowEnd(target, caret
2324:                                    .getDot());
2325:                            if (select) {
2326:                                caret.moveDot(dot);
2327:                            } else {
2328:                                caret.setDot(dot);
2329:                            }
2330:                            // now move the magic caret position far to the right
2331:                            Rectangle r = target.modelToView(dot);
2332:                            if (r != null) {
2333:                                Point p = new Point(MAGIC_POSITION_MAX, r.y);
2334:                                caret.setMagicCaretPosition(p);
2335:                            }
2336:                        } catch (BadLocationException e) {
2337:                            e.printStackTrace();
2338:                            target.getToolkit().beep();
2339:                        }
2340:                    }
2341:                }
2342:            }
2343:
2344:            public static class BeginAction extends LocalBaseAction {
2345:
2346:                boolean select;
2347:
2348:                static final long serialVersionUID = 3463563396210234361L;
2349:
2350:                public BeginAction(String nm, boolean select) {
2351:                    super (nm, MAGIC_POSITION_RESET | ABBREV_RESET
2352:                            | UNDO_MERGE_RESET | WORD_MATCH_RESET
2353:                            | SAVE_POSITION | CLEAR_STATUS_TEXT);
2354:                    this .select = select;
2355:                }
2356:
2357:                public void actionPerformed(ActionEvent evt,
2358:                        JTextComponent target) {
2359:                    if (target != null) {
2360:                        Caret caret = target.getCaret();
2361:                        int dot = 0; // begin of document
2362:                        if (select) {
2363:                            caret.moveDot(dot);
2364:                        } else {
2365:                            caret.setDot(dot);
2366:                        }
2367:                    }
2368:                }
2369:            }
2370:
2371:            public static class EndAction extends LocalBaseAction {
2372:
2373:                boolean select;
2374:
2375:                static final long serialVersionUID = 8547506353130203657L;
2376:
2377:                public EndAction(String nm, boolean select) {
2378:                    super (nm, MAGIC_POSITION_RESET | ABBREV_RESET
2379:                            | UNDO_MERGE_RESET | WORD_MATCH_RESET
2380:                            | SAVE_POSITION | CLEAR_STATUS_TEXT);
2381:                    this .select = select;
2382:                }
2383:
2384:                public void actionPerformed(ActionEvent evt,
2385:                        JTextComponent target) {
2386:                    if (target != null) {
2387:                        Caret caret = target.getCaret();
2388:                        int dot = target.getDocument().getLength(); // end of document
2389:                        if (select) {
2390:                            caret.moveDot(dot);
2391:                        } else {
2392:                            caret.setDot(dot);
2393:                        }
2394:                    }
2395:                }
2396:            }
2397:
2398:            public static class NextWordAction extends LocalBaseAction {
2399:
2400:                boolean select;
2401:
2402:                static final long serialVersionUID = -5909906947175434032L;
2403:
2404:                public NextWordAction(String nm, boolean select) {
2405:                    super (nm, MAGIC_POSITION_RESET | ABBREV_RESET
2406:                            | UNDO_MERGE_RESET | WORD_MATCH_RESET
2407:                            | CLEAR_STATUS_TEXT);
2408:                    this .select = select;
2409:                }
2410:
2411:                public void actionPerformed(ActionEvent evt,
2412:                        JTextComponent target) {
2413:                    if (target != null) {
2414:                        Caret caret = target.getCaret();
2415:                        try {
2416:                            int dotPos = caret.getDot();
2417:                            dotPos = Utilities.getNextWord(target, dotPos);
2418:                            if (caret instanceof  BaseCaret) {
2419:                                BaseCaret bCaret = (BaseCaret) caret;
2420:                                if (select) {
2421:                                    bCaret.moveDot(dotPos);
2422:                                } else {
2423:                                    bCaret.setDot(dotPos, false);
2424:                                }
2425:                            } else {
2426:                                if (select) {
2427:                                    caret.moveDot(dotPos);
2428:                                } else {
2429:                                    caret.setDot(dotPos);
2430:                                }
2431:                            }
2432:                        } catch (BadLocationException ex) {
2433:                            target.getToolkit().beep();
2434:                        }
2435:                    }
2436:                }
2437:            }
2438:
2439:            public static class PreviousWordAction extends LocalBaseAction {
2440:
2441:                boolean select;
2442:
2443:                static final long serialVersionUID = -5465143382669785799L;
2444:
2445:                public PreviousWordAction(String nm, boolean select) {
2446:                    super (nm, MAGIC_POSITION_RESET | ABBREV_RESET
2447:                            | UNDO_MERGE_RESET | WORD_MATCH_RESET
2448:                            | CLEAR_STATUS_TEXT);
2449:                    this .select = select;
2450:                }
2451:
2452:                public void actionPerformed(ActionEvent evt,
2453:                        JTextComponent target) {
2454:                    if (target != null) {
2455:                        Caret caret = target.getCaret();
2456:                        try {
2457:                            int dot = Utilities.getPreviousWord(target, caret
2458:                                    .getDot());
2459:                            if (caret instanceof  BaseCaret) {
2460:                                BaseCaret bCaret = (BaseCaret) caret;
2461:                                if (select) {
2462:                                    bCaret.moveDot(dot);
2463:                                } else {
2464:                                    bCaret.setDot(dot, false);
2465:                                }
2466:                            } else {
2467:                                if (select) {
2468:                                    caret.moveDot(dot);
2469:                                } else {
2470:                                    caret.setDot(dot);
2471:                                }
2472:                            }
2473:                        } catch (BadLocationException ex) {
2474:                            target.getToolkit().beep();
2475:                        }
2476:                    }
2477:                }
2478:            }
2479:
2480:            public static class BeginWordAction extends LocalBaseAction {
2481:
2482:                boolean select;
2483:
2484:                static final long serialVersionUID = 3991338381212491110L;
2485:
2486:                public BeginWordAction(String nm, boolean select) {
2487:                    super (nm, MAGIC_POSITION_RESET | ABBREV_RESET
2488:                            | UNDO_MERGE_RESET | WORD_MATCH_RESET
2489:                            | CLEAR_STATUS_TEXT);
2490:                    this .select = select;
2491:                }
2492:
2493:                public void actionPerformed(ActionEvent evt,
2494:                        JTextComponent target) {
2495:                    if (target != null) {
2496:                        Caret caret = target.getCaret();
2497:                        try {
2498:                            int dot = Utilities.getWordStart(target, caret
2499:                                    .getDot());
2500:                            if (select) {
2501:                                caret.moveDot(dot);
2502:                            } else {
2503:                                caret.setDot(dot);
2504:                            }
2505:                        } catch (BadLocationException ex) {
2506:                            target.getToolkit().beep();
2507:                        }
2508:                    }
2509:                }
2510:            }
2511:
2512:            public static class EndWordAction extends LocalBaseAction {
2513:
2514:                boolean select;
2515:
2516:                static final long serialVersionUID = 3812523676620144633L;
2517:
2518:                public EndWordAction(String nm, boolean select) {
2519:                    super (nm, MAGIC_POSITION_RESET | ABBREV_RESET
2520:                            | UNDO_MERGE_RESET | WORD_MATCH_RESET
2521:                            | CLEAR_STATUS_TEXT);
2522:                    this .select = select;
2523:                }
2524:
2525:                public void actionPerformed(ActionEvent evt,
2526:                        JTextComponent target) {
2527:                    if (target != null) {
2528:                        Caret caret = target.getCaret();
2529:                        try {
2530:                            int dot = Utilities.getWordEnd(target, caret
2531:                                    .getDot());
2532:                            if (select) {
2533:                                caret.moveDot(dot);
2534:                            } else {
2535:                                caret.setDot(dot);
2536:                            }
2537:                        } catch (BadLocationException ex) {
2538:                            target.getToolkit().beep();
2539:                        }
2540:                    }
2541:                }
2542:            }
2543:
2544:            /** Select word around caret */
2545:            public static class SelectWordAction extends KitCompoundAction {
2546:
2547:                static final long serialVersionUID = 7678848538073016357L;
2548:
2549:                public SelectWordAction() {
2550:                    super (selectWordAction, new String[] { beginWordAction,
2551:                            selectionEndWordAction });
2552:                }
2553:
2554:            }
2555:
2556:            /** Select line around caret */
2557:            public static class SelectLineAction extends LocalBaseAction {
2558:
2559:                static final long serialVersionUID = -7407681863035740281L;
2560:
2561:                public SelectLineAction() {
2562:                    super (selectLineAction);
2563:                }
2564:
2565:                public void actionPerformed(ActionEvent evt,
2566:                        JTextComponent target) {
2567:                    if (target != null) {
2568:                        Caret caret = target.getCaret();
2569:                        BaseDocument doc = (BaseDocument) target.getDocument();
2570:                        doc.atomicLock();
2571:                        DocumentUtilities.setTypingModification(doc, true);
2572:                        try {
2573:                            int dotPos = caret.getDot();
2574:                            int bolPos = Utilities.getRowStart(target, dotPos);
2575:                            int eolPos = Utilities.getRowEnd(target, dotPos);
2576:                            eolPos = Math.min(eolPos + 1, doc.getLength()); // include '\n'
2577:                            caret.setDot(bolPos);
2578:                            caret.moveDot(eolPos);
2579:                        } catch (BadLocationException e) {
2580:                            target.getToolkit().beep();
2581:                        } finally {
2582:                            DocumentUtilities.setTypingModification(doc, false);
2583:                            doc.atomicUnlock();
2584:                        }
2585:                    }
2586:                }
2587:            }
2588:
2589:            /** Select text of whole document */
2590:            public static class SelectAllAction extends KitCompoundAction {
2591:
2592:                static final long serialVersionUID = -3502499718130556524L;
2593:
2594:                public SelectAllAction() {
2595:                    super (selectAllAction, new String[] { beginAction,
2596:                            selectionEndAction });
2597:                }
2598:
2599:            }
2600:
2601:            public static class RemoveTrailingSpacesAction extends
2602:                    LocalBaseAction {
2603:
2604:                public RemoveTrailingSpacesAction() {
2605:                    super (removeTrailingSpacesAction);
2606:                }
2607:
2608:                protected boolean asynchonous() {
2609:                    return true;
2610:                }
2611:
2612:                public void actionPerformed(ActionEvent evt,
2613:                        final JTextComponent target) {
2614:                    if (target != null) {
2615:                        final BaseDocument doc = (BaseDocument) target
2616:                                .getDocument();
2617:                        doc.runAtomic(new Runnable() {
2618:                            public void run() {
2619:                                try {
2620:                                    Element lineRootElem = doc
2621:                                            .getDefaultRootElement();
2622:                                    int count = lineRootElem.getElementCount();
2623:                                    for (int x = 0; x < count; x++) {
2624:                                        Element elem = lineRootElem
2625:                                                .getElement(x);
2626:                                        int start = elem.getStartOffset();
2627:                                        int end = elem.getEndOffset();
2628:                                        CharSequence line = DocumentUtilities
2629:                                                .getText(doc, start, end
2630:                                                        - start);
2631:                                        int endIndex = line.length() - 1;
2632:                                        if (endIndex >= 0
2633:                                                && line.charAt(endIndex) == '\n') {
2634:                                            endIndex--;
2635:                                            if (endIndex >= 0
2636:                                                    && line.charAt(endIndex) == '\r') {
2637:                                                endIndex--;
2638:                                            }
2639:                                        }
2640:                                        int index = endIndex;
2641:                                        while (index >= 0
2642:                                                && Character.isWhitespace(line
2643:                                                        .charAt(index))
2644:                                                && line.charAt(index) != '\n') {
2645:                                            index--;
2646:                                        }
2647:                                        if (index < endIndex) {
2648:                                            doc.remove(start + index + 1,
2649:                                                    endIndex - index);
2650:                                        }
2651:                                    } // for
2652:                                    StatusDisplayer
2653:                                            .getDefault()
2654:                                            .setStatusText(
2655:                                                    NbBundle
2656:                                                            .getMessage(
2657:                                                                    BaseKit.class,
2658:                                                                    "TrailingSpacesWereRemoved_Lbl")); // NOI18N
2659:                                } catch (BadLocationException e) {
2660:                                    e.printStackTrace();
2661:                                    target.getToolkit().beep();
2662:                                }
2663:                            }
2664:                        });
2665:                    }
2666:                }
2667:            }
2668:
2669:            private static final class DefaultSyntax extends Syntax {
2670:
2671:                private static final int ISI_TEXT = 0;
2672:
2673:                public DefaultSyntax() {
2674:                    tokenContextPath = DefaultSyntaxTokenContext.CONTEXT
2675:                            .getContextPath();
2676:                }
2677:
2678:                protected TokenID parseToken() {
2679:                    // The main loop that reads characters one by one follows
2680:                    while (offset < stopOffset) {
2681:                        char ch = buffer[offset]; // get the current character
2682:
2683:                        switch (state) { // switch by the current internal state
2684:                        case INIT:
2685:                            switch (ch) {
2686:                            case '\n':
2687:                                offset++;
2688:                                return DefaultSyntaxTokenContext.EOL;
2689:                            default:
2690:                                state = ISI_TEXT;
2691:                                break;
2692:                            }
2693:                            break;
2694:
2695:                        case ISI_TEXT:
2696:                            switch (ch) {
2697:                            case '\n':
2698:                                state = INIT;
2699:                                return DefaultSyntaxTokenContext.TEXT;
2700:                            }
2701:                            break;
2702:
2703:                        } // end of switch(state)
2704:
2705:                        offset++; // move to the next char
2706:                    }
2707:
2708:                    switch (state) {
2709:                    case ISI_TEXT:
2710:                        state = INIT;
2711:                        return DefaultSyntaxTokenContext.TEXT;
2712:                    }
2713:
2714:                    // need to continue on another buffer
2715:                    return null;
2716:                }
2717:            } // End of DefaultSyntax class
2718:
2719:            private static final class DefaultSyntaxTokenContext extends
2720:                    TokenContext {
2721:
2722:                // Numeric-ids for token-ids
2723:                public static final int TEXT_ID = 1;
2724:                public static final int EOL_ID = 2;
2725:
2726:                public static final BaseTokenID TEXT = new BaseTokenID("text",
2727:                        TEXT_ID); // NOI18N
2728:                public static final BaseImageTokenID EOL = new BaseImageTokenID(
2729:                        "EOL", EOL_ID, "\n"); // NOI18N
2730:
2731:                // Context declaration
2732:                public static final DefaultSyntaxTokenContext CONTEXT = new DefaultSyntaxTokenContext();
2733:
2734:                private DefaultSyntaxTokenContext() {
2735:                    super ("defaultSyntax-token-"); // NOI18N
2736:
2737:                    try {
2738:                        addDeclaredTokenIDs();
2739:                    } catch (Exception e) {
2740:                        LOG.log(Level.WARNING, "Can't load token IDs", e); //NOI18N
2741:                    }
2742:                }
2743:            } // End of DefaultSyntaxTokenContext class
2744:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.