001: package net.xoetrope.builder.editor;
002:
003: import java.awt.Event;
004: import java.awt.datatransfer.Clipboard;
005: import java.awt.datatransfer.DataFlavor;
006: import java.awt.event.ActionEvent;
007: import java.awt.event.KeyEvent;
008: import javax.swing.AbstractAction;
009: import javax.swing.Action;
010: import javax.swing.JMenu;
011: import javax.swing.JMenuItem;
012: import javax.swing.JPopupMenu;
013: import javax.swing.KeyStroke;
014: import javax.swing.event.MenuEvent;
015: import javax.swing.event.MenuListener;
016: import javax.swing.text.BadLocationException;
017:
018: import net.xoetrope.builder.editor.syntaxhighlight.JEditTextArea;
019: import net.xoetrope.builder.editor.syntaxhighlight.JavaTokenMarker;
020: import net.xoetrope.builder.editor.syntaxhighlight.SyntaxDocument;
021: import net.xoetrope.builder.editor.syntaxhighlight.TextAreaDefaults;
022: import net.xoetrope.builder.editor.syntaxhighlight.XMLTokenMarker;
023: import net.xoetrope.builder.editor.helper.ForCodeHelper;
024: import net.xoetrope.builder.editor.helper.CodeHelper;
025: import net.xoetrope.xui.XProjectManager;
026: import java.util.ArrayList;
027:
028: /**
029: * A wrapper for the syntax highlighter, including some additional methods for
030: * access source code and location of methods
031: * <p>Copyright: Copyright (c) Xoetrope Ltd., 1998-2003</p>
032: * $Revision: 1.15 $
033: * License: see license.txt
034: */
035: public class XSourceEditor extends JEditTextArea implements
036: MenuListener {
037: public static final int JAVA_FILE = 0;
038: public static final int XML_FILE = 1;
039:
040: protected XPageResource currentScreen;
041: protected TextAreaDefaults defs;
042: protected XEditorProject currentProject;
043: protected JPopupMenu popupMenu;
044: protected int fileType;
045:
046: protected AbstractAction codeTemplateAction;
047:
048: private XSourceEditor sourceEditor;
049:
050: /**
051: * Construct a new source code editor
052: * @param project the project that owns the resource being edited
053: * @param defaults the defaults for the editor
054: * @param fileType the type of file being edited as defined by this class's public constants
055: */
056: public XSourceEditor(XEditorProject project,
057: TextAreaDefaults defaults, int type) {
058: super (defaults);
059: sourceEditor = this ;
060: currentProject = project;
061:
062: defs = defaults;
063: fileType = type;
064: try {
065: defs.document = new SyntaxDocument();
066: if (fileType == XML_FILE)
067: setTokenMarker(new XMLTokenMarker());
068: else
069: setTokenMarker(new JavaTokenMarker());
070: setDocument(defs.document);
071: setRightClickPopup(buildPopupMenu());
072: } catch (Exception ex) {
073: }
074: }
075:
076: /**
077: * Build the popup menu
078: * @return the new popup menu
079: */
080: protected JPopupMenu buildPopupMenu() {
081: if (fileType == XML_FILE)
082: return null;
083:
084: if (popupMenu == null) {
085: popupMenu = new JPopupMenu();
086:
087: ArrayList resources = XEditorProjectManager
088: .getStaticResources();
089: int numResources = resources.size();
090: for (int i = 0; i < numResources; i++) {
091: Object obj = resources.get(i);
092: if (obj instanceof CodeHelper) {
093: CodeHelper helper = (CodeHelper) resources.get(i);
094: CodeAction action = new CodeAction(helper);
095: JMenuItem jmi = new JMenuItem(action);
096: popupMenu.add(jmi);
097: }
098: }
099: }
100:
101: return popupMenu;
102: }
103:
104: /**
105: * First set the current source in the Project. Get the screen
106: * specified by the parameter 'name'. If there is no source defined create
107: * a template file if the create parameter is true. Set the text of the
108: * JEditTextArea and set it to visible.
109: * @param name The name of the screen we are trying to load
110: * @param create If true create a template file for the source if not found.
111: */
112: public void setScreen(String name, boolean create) {
113: if (currentScreen != null)
114: currentScreen.setJavaSource(getText());
115: currentScreen = currentProject.getPageResource(name);
116: String src = currentScreen.getJavaSource();
117: setText(src);
118:
119: int length = src.length();
120: if (length == 0) {
121: if (create) {
122: openFile(name);
123: src = currentScreen.getJavaSource();
124: setText(src);
125: } else
126: setVisible(false);
127: } else
128: setVisible(true);
129: }
130:
131: /**
132: * First set the current source in the Project. Get the screen
133: * specified by the parameter 'name'. If there is no source defined create
134: * a template file if the create parameter is true. Set the text of the
135: * JEditTextArea and set it to visible.
136: * @param name The name of the screen we are trying to load
137: * @param create If true create a template file for the source if not found.
138: */
139: public void setXml(String xml) {
140: setTokenMarker(new XMLTokenMarker());
141: setText(xml);
142: setCaretPosition(0);
143: }
144:
145: /**
146: * Open the file specified by the parameter screenName. Set the JEditTextArea
147: * to the content of the file. Create a template file if not found.
148: * @param screenName The name of the screen to be opened.
149: */
150: public void openFile(String screenName) {
151: currentScreen.openSourceFile(true);
152: }
153:
154: /**
155: * Locates the method specified by the parameter methodName. if the
156: * addNewMethod is true the method specified by methodName is created. The
157: * cursor is position at the start of the method.
158: * @param methodName The name of the method we are looking for.
159: * @param addNewMethod If true create the method if not found.
160: * @return true if a new method was added
161: */
162: public boolean locateMethod(String methodName, boolean addNewMethod) {
163: String searchText = "public void " + methodName + "()";
164:
165: int pos = getText().indexOf(searchText);
166: if (pos >= 0)
167: setCaretPosition(pos);
168: else if (addNewMethod) {
169: setCaretPosition(0);
170: String source = getText();
171: pos = source.lastIndexOf('}') - 1;
172: String newMethod = "\n\n\t" + searchText
173: + "\n\t{\n\t\t\n\t}\n";
174: if (pos < 0)
175: pos = 0;
176: setText(source.substring(0, pos) + newMethod
177: + source.substring(pos));
178: setCaretPosition(pos + 4);
179: currentScreen.setJavaSource(getText());
180: return true;
181: }
182:
183: return false;
184: }
185:
186: /**
187: * Update the source for the specified screen
188: * @param newScreen the new screens name or null for the existing screen
189: */
190: public void updateSource(String newScreen) {
191: if (newScreen != null) {
192: currentScreen = currentProject.getPageResource(newScreen);
193: String sourceCode = currentScreen.getJavaSource();
194: setText(sourceCode);
195: setTokenMarker(new JavaTokenMarker());
196: setCaretPosition(0);
197: } else if (currentScreen != null)
198: currentScreen.setJavaSource(getText());
199: }
200:
201: /**
202: * Updates the editor's text
203: * @param txt the new text/content
204: * @param scrName the name of the screen to which the code corresponds
205: */
206: public void setText(String txt, String scrName) {
207: super .setText(txt);
208: setTokenMarker(new JavaTokenMarker());
209: }
210:
211: public void menuCanceled(MenuEvent e) {
212: }
213:
214: public void menuDeselected(MenuEvent e) {
215: }
216:
217: public void menuSelected(MenuEvent e) {
218: initMenu((XEditorMenu) ((JMenu) e.getSource()).getParent());
219: }
220:
221: public void processMetaKey(KeyEvent e) {
222: initMenu(currentProject.getEditor().getMenu());
223: super .processMetaKey(e);
224: }
225:
226: private void initMenu(XEditorMenu editorMenu) {
227: boolean hasPasteItems = false;
228:
229: if (isEditable()) {
230: Clipboard clipboard = getToolkit().getSystemClipboard();
231: try {
232: // The MacOS MRJ doesn't convert \r to \n,
233: // so do it here
234: String selection = ((String) clipboard
235: .getContents(this ).getTransferData(
236: DataFlavor.stringFlavor)).replace('\r',
237: '\n');
238: if ((selection != null) && (selection.length() > 0))
239: hasPasteItems = true;
240: } catch (Exception ex) {
241: }
242: }
243:
244: String selText = getSelectedText();
245: boolean hasSelection = false;
246: if (selText != null)
247: hasSelection = selText.length() > 0;
248: editorMenu.initEditMenu(hasSelection, hasSelection,
249: hasPasteItems, hasSelection);
250: }
251:
252: class CodeAction extends AbstractAction {
253: public CodeHelper helper;
254:
255: public CodeAction(CodeHelper ch) {
256: super (ch.getCaption());
257: helper = ch;
258: putValue(Action.MNEMONIC_KEY, helper.getMnemonic());
259: }
260:
261: public void actionPerformed(ActionEvent e) {
262: helper
263: .doInsert(sourceEditor, currentProject,
264: currentScreen);
265: }
266:
267: public CodeHelper getHelper() {
268: return helper;
269: }
270: }
271: }
|