001package com.ganteater.ae.desktop.editor;
002
003import java.awt.event.KeyAdapter;
004import java.awt.event.KeyEvent;
005import java.lang.reflect.Constructor;
006
007import javax.swing.JTextArea;
008import javax.swing.text.Document;
009import javax.swing.undo.UndoManager;
010
011import org.apache.commons.lang.StringUtils;
012
013import com.ganteater.ae.CommandException;
014import com.ganteater.ae.util.xml.easyparser.Node;
015
016public class TextEditor extends JTextArea implements Editor {
017
018        private static final long serialVersionUID = -298735473495909314L;
019        private final UndoManager undo = new UndoManager();
020        private TaskEditor recipePanel;
021        private Node editorNode;
022
023        public TextEditor() {
024                super();
025                setTabSize(4);
026                Document doc = getDocument();
027                doc.addUndoableEditListener((evt) -> undo.addEdit(evt.getEdit()));
028                addKeyListener(new KeyAdapter() {
029                        @Override
030                        public void keyPressed(KeyEvent e) {
031                                if (e.getKeyCode() == KeyEvent.VK_Z && e.isControlDown()) {
032                                        undo();
033                                } else if (e.getKeyCode() == KeyEvent.VK_Y && e.isControlDown()) {
034                                        redo();
035                                }
036                        }
037                });
038        }
039
040        @Override
041        public void init(TaskEditor taskEditor) throws CommandException {
042                this.recipePanel = taskEditor;
043                setFont(TaskEditor.font);
044
045                String helper = null;
046                if (editorNode != null) {
047                        helper = taskEditor.getTaskProcessor().attr(editorNode, "helper");
048                }
049                if (helper == null) {
050                        helper = CodeHelper.class.getName();
051                }
052                if (!helper.startsWith(TaskEditor.EDITOR_STD_PACKAGE)) {
053                        helper = TaskEditor.EDITOR_STD_PACKAGE + helper;
054                }
055
056                try {
057                        @SuppressWarnings("unchecked")
058                        Class<? extends CodeHelper> filterClass = (Class<? extends CodeHelper>) Class.forName(helper);
059                        Constructor<? extends CodeHelper> constructor = filterClass.getConstructor(TextEditor.class);
060                        CodeHelper codeHelper = constructor.newInstance(this);
061                        codeHelper.applyListeners(this);
062                } catch (Exception e) {
063                        throw new IllegalArgumentException(e);
064                }
065        }
066
067        public void redo() {
068                try {
069                        int caretPosition = getCaretPosition();
070                        if (undo.canRedo()) {
071                                undo.redo();
072                                if (getDocument().getLength() == 0) {
073                                        if (undo.canRedo()) {
074                                                undo.redo();
075                                        } else if (undo.canUndo()) {
076                                                undo.undo();
077                                        }
078                                }
079                        }
080                        setCaretPosition(caretPosition);
081                } catch (Exception e) {
082                        // no nothing.
083                }
084        }
085
086        public void undo() {
087                try {
088                        int caretPosition = getCaretPosition();
089                        if (undo.canUndo()) {
090                                undo.undo();
091                                if (getDocument().getLength() == 0) {
092                                        if (undo.canUndo()) {
093                                                undo.undo();
094                                        } else if (undo.canRedo()) {
095                                                undo.redo();
096                                        }
097                                }
098                        }
099                        setCaretPosition(caretPosition);
100                } catch (Exception e) {
101                        // no nothing.
102                }
103        }
104
105        public void removeLine() {
106                int caretPosition = getCaretPosition();
107                String text = getText();
108                int start = StringUtils.lastIndexOf(text, "\n", caretPosition - 1);
109                start = start < 0 ? 0 : start + 1;
110                int end = StringUtils.indexOf(text, "\n", caretPosition);
111                end = end < 0 ? text.length() - 1 : end + 1;
112                start = start < end ? start : end;
113                replaceRange("", start, end);
114                setCaretPosition(start == 0 ? 0 : start);
115        }
116
117        public void setOriginalText(String xmlText) {
118                setText(xmlText);
119        }
120
121        public TaskEditor getRecipePanel() {
122                return recipePanel;
123        }
124
125        public Node getEditorNode() {
126                return editorNode;
127        }
128
129        public void setEditorNode(Node editorNode) {
130                this.editorNode = editorNode;
131        }
132
133}