diff --git a/app/src/processing/app/syntax/CTokenMarker.java b/app/src/processing/app/syntax/CTokenMarker.java deleted file mode 100644 index ccb9b0b48..000000000 --- a/app/src/processing/app/syntax/CTokenMarker.java +++ /dev/null @@ -1,273 +0,0 @@ -/* - * CTokenMarker.java - C token marker - * Copyright (C) 1998, 1999 Slava Pestov - * - * You may use and modify this package for any purpose. Redistribution is - * permitted, in both source and binary form, provided that this notice - * remains intact in all source distributions of this package. - */ - -package processing.app.syntax; - -import javax.swing.text.Segment; - -/** - * C token marker. - * - * @author Slava Pestov - */ -public class CTokenMarker extends TokenMarker -{ - public CTokenMarker() - { - this(true,getKeywords()); - } - - public CTokenMarker(boolean cpp, KeywordMap keywords) - { - this.cpp = cpp; - this.keywords = keywords; - } - - public byte markTokensImpl(byte token, Segment line, int lineIndex) - { - char[] array = line.array; - int offset = line.offset; - lastOffset = offset; - lastKeyword = offset; - int mlength = line.count + offset; - boolean backslash = false; - -loop: for(int i = offset; i < mlength; i++) - { - int i1 = (i+1); - - char c = array[i]; - if(c == '\\') - { - backslash = !backslash; - continue; - } - - switch(token) - { - case Token.NULL: - switch(c) - { - case '#': - if(backslash) - backslash = false; - else if(cpp) - { - if(doKeyword(line,i,c)) - break; - addToken(i - lastOffset,token); - addToken(mlength - i,Token.KEYWORD2); - lastOffset = lastKeyword = mlength; - break loop; - } - break; - case '"': - doKeyword(line,i,c); - if(backslash) - backslash = false; - else - { - addToken(i - lastOffset,token); - token = Token.LITERAL1; - lastOffset = lastKeyword = i; - } - break; - case '\'': - doKeyword(line,i,c); - if(backslash) - backslash = false; - else - { - addToken(i - lastOffset,token); - token = Token.LITERAL2; - lastOffset = lastKeyword = i; - } - break; - case ':': - if(lastKeyword == offset) - { - if(doKeyword(line,i,c)) - break; - backslash = false; - addToken(i1 - lastOffset,Token.LABEL); - lastOffset = lastKeyword = i1; - } - else if(doKeyword(line,i,c)) - break; - break; - case '/': - backslash = false; - doKeyword(line,i,c); - if(mlength - i > 1) - { - switch(array[i1]) - { - case '*': - addToken(i - lastOffset,token); - lastOffset = lastKeyword = i; - if(mlength - i > 2 && array[i+2] == '*') - token = Token.COMMENT2; - else - token = Token.COMMENT1; - break; - case '/': - addToken(i - lastOffset,token); - addToken(mlength - i,Token.COMMENT1); - lastOffset = lastKeyword = mlength; - break loop; - } - } - break; - default: - backslash = false; - if(!Character.isLetterOrDigit(c) - && c != '_') - doKeyword(line,i,c); - break; - } - break; - case Token.COMMENT1: - case Token.COMMENT2: - backslash = false; - if(c == '*' && mlength - i > 1) - { - if(array[i1] == '/') - { - i++; - addToken((i+1) - lastOffset,token); - token = Token.NULL; - lastOffset = lastKeyword = i+1; - } - } - break; - case Token.LITERAL1: - if(backslash) - backslash = false; - else if(c == '"') - { - addToken(i1 - lastOffset,token); - token = Token.NULL; - lastOffset = lastKeyword = i1; - } - break; - case Token.LITERAL2: - if(backslash) - backslash = false; - else if(c == '\'') - { - addToken(i1 - lastOffset,Token.LITERAL1); - token = Token.NULL; - lastOffset = lastKeyword = i1; - } - break; - default: - throw new InternalError("Invalid state: " - + token); - } - } - - if(token == Token.NULL) - doKeyword(line,mlength,'\0'); - - switch(token) - { - case Token.LITERAL1: - case Token.LITERAL2: - addToken(mlength - lastOffset,Token.INVALID); - token = Token.NULL; - break; - case Token.KEYWORD2: - addToken(mlength - lastOffset,token); - if (!backslash) token = Token.NULL; - addToken(mlength - lastOffset,token); - break; - default: - addToken(mlength - lastOffset,token); - break; - } - - return token; - } - - public static KeywordMap getKeywords() - { - if(cKeywords == null) - { - cKeywords = new KeywordMap(false); - cKeywords.add("char",Token.KEYWORD3); - cKeywords.add("double",Token.KEYWORD3); - cKeywords.add("enum",Token.KEYWORD3); - cKeywords.add("float",Token.KEYWORD3); - cKeywords.add("int",Token.KEYWORD3); - cKeywords.add("long",Token.KEYWORD3); - cKeywords.add("short",Token.KEYWORD3); - cKeywords.add("signed",Token.KEYWORD3); - cKeywords.add("struct",Token.KEYWORD3); - cKeywords.add("typedef",Token.KEYWORD3); - cKeywords.add("union",Token.KEYWORD3); - cKeywords.add("unsigned",Token.KEYWORD3); - cKeywords.add("void",Token.KEYWORD3); - cKeywords.add("auto",Token.KEYWORD1); - cKeywords.add("const",Token.KEYWORD1); - cKeywords.add("extern",Token.KEYWORD1); - cKeywords.add("register",Token.KEYWORD1); - cKeywords.add("static",Token.KEYWORD1); - cKeywords.add("volatile",Token.KEYWORD1); - cKeywords.add("break",Token.KEYWORD1); - cKeywords.add("case",Token.KEYWORD1); - cKeywords.add("continue",Token.KEYWORD1); - cKeywords.add("default",Token.KEYWORD1); - cKeywords.add("do",Token.KEYWORD1); - cKeywords.add("else",Token.KEYWORD1); - cKeywords.add("for",Token.KEYWORD1); - cKeywords.add("goto",Token.KEYWORD1); - cKeywords.add("if",Token.KEYWORD1); - cKeywords.add("return",Token.KEYWORD1); - cKeywords.add("sizeof",Token.KEYWORD1); - cKeywords.add("switch",Token.KEYWORD1); - cKeywords.add("while",Token.KEYWORD1); - cKeywords.add("asm",Token.KEYWORD2); - cKeywords.add("asmlinkage",Token.KEYWORD2); - cKeywords.add("far",Token.KEYWORD2); - cKeywords.add("huge",Token.KEYWORD2); - cKeywords.add("inline",Token.KEYWORD2); - cKeywords.add("near",Token.KEYWORD2); - cKeywords.add("pascal",Token.KEYWORD2); - cKeywords.add("true",Token.LITERAL2); - cKeywords.add("false",Token.LITERAL2); - cKeywords.add("NULL",Token.LITERAL2); - } - return cKeywords; - } - - // private members - private static KeywordMap cKeywords; - - private boolean cpp; - private KeywordMap keywords; - private int lastOffset; - private int lastKeyword; - - private boolean doKeyword(Segment line, int i, char c) - { - int i1 = i+1; - - int len = i - lastKeyword; - byte id = keywords.lookup(line,lastKeyword,len); - if(id != Token.NULL) - { - if(lastKeyword != lastOffset) - addToken(lastKeyword - lastOffset,Token.NULL); - addToken(len,id); - lastOffset = i; - } - lastKeyword = i1; - return false; - } -} diff --git a/app/src/processing/app/syntax/DefaultInputHandler.java b/app/src/processing/app/syntax/DefaultInputHandler.java deleted file mode 100644 index e9e23fea1..000000000 --- a/app/src/processing/app/syntax/DefaultInputHandler.java +++ /dev/null @@ -1,373 +0,0 @@ -/* - * DefaultInputHandler.java - Default implementation of an input handler - * Copyright (C) 1999 Slava Pestov - * - * You may use and modify this package for any purpose. Redistribution is - * permitted, in both source and binary form, provided that this notice - * remains intact in all source distributions of this package. - */ - -package processing.app.syntax; - -import javax.swing.KeyStroke; -import java.awt.event.*; -import java.awt.Toolkit; -import java.util.Hashtable; -import java.util.StringTokenizer; - -/** - * The default input handler. It maps sequences of keystrokes into actions - * and inserts key typed events into the text area. - * @author Slava Pestov - */ -public class DefaultInputHandler extends InputHandler -{ - /** - * Creates a new input handler with no key bindings defined. - */ - public DefaultInputHandler() - { - bindings = currentBindings = new Hashtable(); - } - - /** - * Sets up the default key bindings. - */ - public void addDefaultKeyBindings() - { - addKeyBinding("BACK_SPACE",BACKSPACE); - addKeyBinding("C+BACK_SPACE",BACKSPACE_WORD); - addKeyBinding("DELETE",DELETE); - addKeyBinding("C+DELETE",DELETE_WORD); - - addKeyBinding("ENTER",INSERT_BREAK); - addKeyBinding("TAB",INSERT_TAB); - - addKeyBinding("INSERT",OVERWRITE); - addKeyBinding("C+\\",TOGGLE_RECT); - - addKeyBinding("HOME",HOME); - addKeyBinding("END",END); - addKeyBinding("S+HOME",SELECT_HOME); - addKeyBinding("S+END",SELECT_END); - addKeyBinding("C+HOME",DOCUMENT_HOME); - addKeyBinding("C+END",DOCUMENT_END); - addKeyBinding("CS+HOME",SELECT_DOC_HOME); - addKeyBinding("CS+END",SELECT_DOC_END); - - addKeyBinding("PAGE_UP",PREV_PAGE); - addKeyBinding("PAGE_DOWN",NEXT_PAGE); - addKeyBinding("S+PAGE_UP",SELECT_PREV_PAGE); - addKeyBinding("S+PAGE_DOWN",SELECT_NEXT_PAGE); - - addKeyBinding("LEFT",PREV_CHAR); - addKeyBinding("S+LEFT",SELECT_PREV_CHAR); - addKeyBinding("C+LEFT",PREV_WORD); - addKeyBinding("CS+LEFT",SELECT_PREV_WORD); - addKeyBinding("RIGHT",NEXT_CHAR); - addKeyBinding("S+RIGHT",SELECT_NEXT_CHAR); - addKeyBinding("C+RIGHT",NEXT_WORD); - addKeyBinding("CS+RIGHT",SELECT_NEXT_WORD); - addKeyBinding("UP",PREV_LINE); - addKeyBinding("S+UP",SELECT_PREV_LINE); - addKeyBinding("DOWN",NEXT_LINE); - addKeyBinding("S+DOWN",SELECT_NEXT_LINE); - - addKeyBinding("C+ENTER",REPEAT); - } - - /** - * Adds a key binding to this input handler. The key binding is - * a list of white space separated key strokes of the form - * [modifiers+]key where modifier is C for Control, A for Alt, - * or S for Shift, and key is either a character (a-z) or a field - * name in the KeyEvent class prefixed with VK_ (e.g., BACK_SPACE) - * @param keyBinding The key binding - * @param action The action - */ - public void addKeyBinding(String keyBinding, ActionListener action) - { - Hashtable current = bindings; - - StringTokenizer st = new StringTokenizer(keyBinding); - while(st.hasMoreTokens()) - { - KeyStroke keyStroke = parseKeyStroke(st.nextToken()); - if(keyStroke == null) - return; - - if(st.hasMoreTokens()) - { - Object o = current.get(keyStroke); - if(o instanceof Hashtable) - current = (Hashtable)o; - else - { - o = new Hashtable(); - current.put(keyStroke,o); - current = (Hashtable)o; - } - } - else - current.put(keyStroke,action); - } - } - - /** - * Removes a key binding from this input handler. This is not yet - * implemented. - * @param keyBinding The key binding - */ - public void removeKeyBinding(String keyBinding) - { - throw new InternalError("Not yet implemented"); - } - - /** - * Removes all key bindings from this input handler. - */ - public void removeAllKeyBindings() - { - bindings.clear(); - } - - /** - * Returns a copy of this input handler that shares the same - * key bindings. Setting key bindings in the copy will also - * set them in the original. - */ - public InputHandler copy() - { - return new DefaultInputHandler(this); - } - - /** - * Handle a key pressed event. This will look up the binding for - * the key stroke and execute it. - */ - public void keyPressed(KeyEvent evt) - { - int keyCode = evt.getKeyCode(); - int modifiers = evt.getModifiers(); - - // moved this earlier so it doesn't get random meta clicks - if (keyCode == KeyEvent.VK_CONTROL || - keyCode == KeyEvent.VK_SHIFT || - keyCode == KeyEvent.VK_ALT || - keyCode == KeyEvent.VK_META) { - return; - } - - // don't get command-s or other menu key equivs on mac - // unless it's something that's specifically bound (cmd-left or right) - //if ((modifiers & KeyEvent.META_MASK) != 0) return; - if ((modifiers & KeyEvent.META_MASK) != 0) { - KeyStroke keyStroke = KeyStroke.getKeyStroke(keyCode, modifiers); - if (currentBindings.get(keyStroke) == null) { - return; - } - } - - /* - char keyChar = evt.getKeyChar(); - System.out.println("code=" + keyCode + " char=" + keyChar + - " charint=" + ((int)keyChar)); - System.out.println("other codes " + KeyEvent.VK_ALT + " " + - KeyEvent.VK_META); - */ - - if((modifiers & ~KeyEvent.SHIFT_MASK) != 0 - || evt.isActionKey() - || keyCode == KeyEvent.VK_BACK_SPACE - || keyCode == KeyEvent.VK_DELETE - || keyCode == KeyEvent.VK_ENTER - || keyCode == KeyEvent.VK_TAB - || keyCode == KeyEvent.VK_ESCAPE) - { - if(grabAction != null) - { - handleGrabAction(evt); - return; - } - - KeyStroke keyStroke = KeyStroke.getKeyStroke(keyCode, - modifiers); - Object o = currentBindings.get(keyStroke); - if(o == null) - { - // Don't beep if the user presses some - // key we don't know about unless a - // prefix is active. Otherwise it will - // beep when caps lock is pressed, etc. - if(currentBindings != bindings) - { - Toolkit.getDefaultToolkit().beep(); - // F10 should be passed on, but C+e F10 - // shouldn't - repeatCount = 0; - repeat = false; - evt.consume(); - } - currentBindings = bindings; - return; - } - else if(o instanceof ActionListener) - { - currentBindings = bindings; - - executeAction(((ActionListener)o), - evt.getSource(),null); - - evt.consume(); - return; - } - else if(o instanceof Hashtable) - { - currentBindings = (Hashtable)o; - evt.consume(); - return; - } - } - } - - /** - * Handle a key typed event. This inserts the key into the text area. - */ - public void keyTyped(KeyEvent evt) - { - int modifiers = evt.getModifiers(); - char c = evt.getKeyChar(); - - // this is the apple/cmd key on macosx.. so menu commands - // were being passed through as legit keys.. added this line - // in an attempt to prevent. - if ((modifiers & KeyEvent.META_MASK) != 0) return; - - if (c != KeyEvent.CHAR_UNDEFINED) // && - // (modifiers & KeyEvent.ALT_MASK) == 0) - { - if(c >= 0x20 && c != 0x7f) - { - KeyStroke keyStroke = KeyStroke.getKeyStroke( - Character.toUpperCase(c)); - Object o = currentBindings.get(keyStroke); - - if(o instanceof Hashtable) - { - currentBindings = (Hashtable)o; - return; - } - else if(o instanceof ActionListener) - { - currentBindings = bindings; - executeAction((ActionListener)o, - evt.getSource(), - String.valueOf(c)); - return; - } - - currentBindings = bindings; - - if(grabAction != null) - { - handleGrabAction(evt); - return; - } - - // 0-9 adds another 'digit' to the repeat number - if(repeat && Character.isDigit(c)) - { - repeatCount *= 10; - repeatCount += (c - '0'); - return; - } - - executeAction(INSERT_CHAR,evt.getSource(), - String.valueOf(evt.getKeyChar())); - - repeatCount = 0; - repeat = false; - } - } - } - - /** - * Converts a string to a keystroke. The string should be of the - * form modifiers+shortcut where modifiers - * is any combination of A for Alt, C for Control, S for Shift - * or M for Meta, and shortcut is either a single character, - * or a keycode name from the KeyEvent class, without - * the VK_ prefix. - * @param keyStroke A string description of the key stroke - */ - public static KeyStroke parseKeyStroke(String keyStroke) - { - if(keyStroke == null) - return null; - int modifiers = 0; - int index = keyStroke.indexOf('+'); - if(index != -1) - { - for(int i = 0; i < index; i++) - { - switch(Character.toUpperCase(keyStroke - .charAt(i))) - { - case 'A': - modifiers |= InputEvent.ALT_MASK; - break; - case 'C': - modifiers |= InputEvent.CTRL_MASK; - break; - case 'M': - modifiers |= InputEvent.META_MASK; - break; - case 'S': - modifiers |= InputEvent.SHIFT_MASK; - break; - } - } - } - String key = keyStroke.substring(index + 1); - if(key.length() == 1) - { - char ch = Character.toUpperCase(key.charAt(0)); - if(modifiers == 0) - return KeyStroke.getKeyStroke(ch); - else - return KeyStroke.getKeyStroke(ch,modifiers); - } - else if(key.length() == 0) - { - System.err.println("Invalid key stroke: " + keyStroke); - return null; - } - else - { - int ch; - - try - { - ch = KeyEvent.class.getField("VK_".concat(key)) - .getInt(null); - } - catch(Exception e) - { - System.err.println("Invalid key stroke: " - + keyStroke); - return null; - } - - return KeyStroke.getKeyStroke(ch,modifiers); - } - } - - // private members - private Hashtable bindings; - private Hashtable currentBindings; - - private DefaultInputHandler(DefaultInputHandler copy) - { - bindings = currentBindings = copy.bindings; - } -} diff --git a/app/src/processing/app/syntax/InputHandler.java b/app/src/processing/app/syntax/InputHandler.java deleted file mode 100644 index e14671348..000000000 --- a/app/src/processing/app/syntax/InputHandler.java +++ /dev/null @@ -1,1135 +0,0 @@ -/* - * InputHandler.java - Manages key bindings and executes actions - * Copyright (C) 1999 Slava Pestov - * - * You may use and modify this package for any purpose. Redistribution is - * permitted, in both source and binary form, provided that this notice - * remains intact in all source distributions of this package. - */ - -package processing.app.syntax; - -import javax.swing.text.*; -import javax.swing.JPopupMenu; -import java.awt.event.*; -import java.awt.Component; -import java.util.*; - -/** - * An input handler converts the user's key strokes into concrete actions. - * It also takes care of macro recording and action repetition.

- * - * This class provides all the necessary support code for an input - * handler, but doesn't actually do any key binding logic. It is up - * to the implementations of this class to do so. - * - * @author Slava Pestov - */ -public abstract class InputHandler extends KeyAdapter -{ - /** - * If this client property is set to Boolean.TRUE on the text area, - * the home/end keys will support 'smart' BRIEF-like behaviour - * (one press = start/end of line, two presses = start/end of - * viewscreen, three presses = start/end of document). By default, - * this property is not set. - */ - public static final String SMART_HOME_END_PROPERTY = "InputHandler.homeEnd"; - - public static final ActionListener BACKSPACE = new backspace(); - public static final ActionListener BACKSPACE_WORD = new backspace_word(); - public static final ActionListener DELETE = new delete(); - public static final ActionListener DELETE_WORD = new delete_word(); - public static final ActionListener END = new end(false); - public static final ActionListener DOCUMENT_END = new document_end(false); - public static final ActionListener SELECT_END = new end(true); - public static final ActionListener SELECT_DOC_END = new document_end(true); - public static final ActionListener INSERT_BREAK = new insert_break(); - public static final ActionListener INSERT_TAB = new insert_tab(); - public static final ActionListener HOME = new home(false); - public static final ActionListener DOCUMENT_HOME = new document_home(false); - public static final ActionListener SELECT_HOME = new home(true); - public static final ActionListener SELECT_DOC_HOME = new document_home(true); - public static final ActionListener NEXT_CHAR = new next_char(false); - public static final ActionListener NEXT_LINE = new next_line(false); - public static final ActionListener NEXT_PAGE = new next_page(false); - public static final ActionListener NEXT_WORD = new next_word(false); - public static final ActionListener SELECT_NEXT_CHAR = new next_char(true); - public static final ActionListener SELECT_NEXT_LINE = new next_line(true); - public static final ActionListener SELECT_NEXT_PAGE = new next_page(true); - public static final ActionListener SELECT_NEXT_WORD = new next_word(true); - public static final ActionListener OVERWRITE = new overwrite(); - public static final ActionListener PREV_CHAR = new prev_char(false); - public static final ActionListener PREV_LINE = new prev_line(false); - public static final ActionListener PREV_PAGE = new prev_page(false); - public static final ActionListener PREV_WORD = new prev_word(false); - public static final ActionListener SELECT_PREV_CHAR = new prev_char(true); - public static final ActionListener SELECT_PREV_LINE = new prev_line(true); - public static final ActionListener SELECT_PREV_PAGE = new prev_page(true); - public static final ActionListener SELECT_PREV_WORD = new prev_word(true); - public static final ActionListener REPEAT = new repeat(); - public static final ActionListener TOGGLE_RECT = new toggle_rect(); - public static final ActionListener CLIPBOARD_CUT = new clipboard_cut(); // [fry] - public static final ActionListener CLIPBOARD_COPY = new clipboard_copy(); - public static final ActionListener CLIPBOARD_PASTE = new clipboard_paste(); - - // Default action - public static final ActionListener INSERT_CHAR = new insert_char(); - - private static Hashtable actions; - - static - { - actions = new Hashtable(); - actions.put("backspace",BACKSPACE); - actions.put("backspace-word",BACKSPACE_WORD); - actions.put("delete",DELETE); - actions.put("delete-word",DELETE_WORD); - actions.put("end",END); - actions.put("select-end",SELECT_END); - actions.put("document-end",DOCUMENT_END); - actions.put("select-doc-end",SELECT_DOC_END); - actions.put("insert-break",INSERT_BREAK); - actions.put("insert-tab",INSERT_TAB); - actions.put("home",HOME); - actions.put("select-home",SELECT_HOME); - actions.put("document-home",DOCUMENT_HOME); - actions.put("select-doc-home",SELECT_DOC_HOME); - actions.put("next-char",NEXT_CHAR); - actions.put("next-line",NEXT_LINE); - actions.put("next-page",NEXT_PAGE); - actions.put("next-word",NEXT_WORD); - actions.put("select-next-char",SELECT_NEXT_CHAR); - actions.put("select-next-line",SELECT_NEXT_LINE); - actions.put("select-next-page",SELECT_NEXT_PAGE); - actions.put("select-next-word",SELECT_NEXT_WORD); - actions.put("overwrite",OVERWRITE); - actions.put("prev-char",PREV_CHAR); - actions.put("prev-line",PREV_LINE); - actions.put("prev-page",PREV_PAGE); - actions.put("prev-word",PREV_WORD); - actions.put("select-prev-char",SELECT_PREV_CHAR); - actions.put("select-prev-line",SELECT_PREV_LINE); - actions.put("select-prev-page",SELECT_PREV_PAGE); - actions.put("select-prev-word",SELECT_PREV_WORD); - actions.put("repeat",REPEAT); - actions.put("toggle-rect",TOGGLE_RECT); - actions.put("insert-char",INSERT_CHAR); - actions.put("clipboard-cut",CLIPBOARD_CUT); - actions.put("clipboard-copy",CLIPBOARD_COPY); - actions.put("clipboard-paste",CLIPBOARD_PASTE); - } - - /** - * Returns a named text area action. - * @param name The action name - */ - public static ActionListener getAction(String name) - { - return (ActionListener)actions.get(name); - } - - /** - * Returns the name of the specified text area action. - * @param listener The action - */ - public static String getActionName(ActionListener listener) - { - Enumeration en = getActions(); - while(en.hasMoreElements()) - { - String name = (String)en.nextElement(); - ActionListener _listener = getAction(name); - if(_listener == listener) { - return name; - } - } - return null; - } - - /** - * Returns an enumeration of all available actions. - */ - public static Enumeration getActions() - { - return actions.keys(); - } - - /** - * Adds the default key bindings to this input handler. - * This should not be called in the constructor of this - * input handler, because applications might load the - * key bindings from a file, etc. - */ - public abstract void addDefaultKeyBindings(); - - /** - * Adds a key binding to this input handler. - * @param keyBinding The key binding (the format of this is - * input-handler specific) - * @param action The action - */ - public abstract void addKeyBinding(String keyBinding, ActionListener action); - - /** - * Removes a key binding from this input handler. - * @param keyBinding The key binding - */ - public abstract void removeKeyBinding(String keyBinding); - - /** - * Removes all key bindings from this input handler. - */ - public abstract void removeAllKeyBindings(); - - /** - * Grabs the next key typed event and invokes the specified - * action with the key as a the action command. - */ - public void grabNextKeyStroke(ActionListener listener) - { - grabAction = listener; - } - - /** - * Returns if repeating is enabled. When repeating is enabled, - * actions will be executed multiple times. This is usually - * invoked with a special key stroke in the input handler. - */ - public boolean isRepeatEnabled() - { - return repeat; - } - - /** - * Enables repeating. When repeating is enabled, actions will be - * executed multiple times. Once repeating is enabled, the input - * handler should read a number from the keyboard. - */ - public void setRepeatEnabled(boolean repeat) - { - this.repeat = repeat; - } - - /** - * Returns the number of times the next action will be repeated. - */ - public int getRepeatCount() - { - return (repeat ? Math.max(1,repeatCount) : 1); - } - - /** - * Sets the number of times the next action will be repeated. - * @param repeatCount The repeat count - */ - public void setRepeatCount(int repeatCount) - { - this.repeatCount = repeatCount; - } - - /** - * Returns the macro recorder. If this is non-null, all executed - * actions should be forwarded to the recorder. - */ - public InputHandler.MacroRecorder getMacroRecorder() - { - return recorder; - } - - /** - * Sets the macro recorder. If this is non-null, all executed - * actions should be forwarded to the recorder. - * @param recorder The macro recorder - */ - public void setMacroRecorder(InputHandler.MacroRecorder recorder) - { - this.recorder = recorder; - } - - /** - * Returns a copy of this input handler that shares the same - * key bindings. Setting key bindings in the copy will also - * set them in the original. - */ - public abstract InputHandler copy(); - - /** - * Executes the specified action, repeating and recording it as - * necessary. - * @param listener The action listener - * @param source The event source - * @param actionCommand The action command - */ - public void executeAction(ActionListener listener, Object source, - String actionCommand) - { - // create event - ActionEvent evt = new ActionEvent(source, - ActionEvent.ACTION_PERFORMED, - actionCommand); - - // don't do anything if the action is a wrapper - // (like EditAction.Wrapper) - if(listener instanceof Wrapper) - { - listener.actionPerformed(evt); - return; - } - - // remember old values, in case action changes them - boolean _repeat = repeat; - int _repeatCount = getRepeatCount(); - - // execute the action - if(listener instanceof InputHandler.NonRepeatable) - listener.actionPerformed(evt); - else - { - for(int i = 0; i < Math.max(1,repeatCount); i++) - listener.actionPerformed(evt); - } - - // do recording. Notice that we do no recording whatsoever - // for actions that grab keys - if(grabAction == null) - { - if(recorder != null) - { - if(!(listener instanceof InputHandler.NonRecordable)) - { - if(_repeatCount != 1) - recorder.actionPerformed(REPEAT,String.valueOf(_repeatCount)); - - recorder.actionPerformed(listener,actionCommand); - } - } - - // If repeat was true originally, clear it - // Otherwise it might have been set by the action, etc - if(_repeat) - { - repeat = false; - repeatCount = 0; - } - } - } - - /** - * Returns the text area that fired the specified event. - * @param evt The event - */ - public static JEditTextArea getTextArea(EventObject evt) - { - if(evt != null) - { - Object o = evt.getSource(); - if(o instanceof Component) - { - // find the parent text area - Component c = (Component)o; - for(;;) - { - if(c instanceof JEditTextArea) - return (JEditTextArea)c; - else if(c == null) - break; - if(c instanceof JPopupMenu) - c = ((JPopupMenu)c) - .getInvoker(); - else - c = c.getParent(); - } - } - } - - // this shouldn't happen - System.err.println("BUG: getTextArea() returning null"); - System.err.println("Report this to Slava Pestov "); - return null; - } - - // protected members - - /** - * If a key is being grabbed, this method should be called with - * the appropriate key event. It executes the grab action with - * the typed character as the parameter. - */ - protected void handleGrabAction(KeyEvent evt) - { - // Clear it *before* it is executed so that executeAction() - // resets the repeat count - ActionListener _grabAction = grabAction; - grabAction = null; - executeAction(_grabAction,evt.getSource(), - String.valueOf(evt.getKeyChar())); - } - - // protected members - protected ActionListener grabAction; - protected boolean repeat; - protected int repeatCount; - protected InputHandler.MacroRecorder recorder; - - /** - * If an action implements this interface, it should not be repeated. - * Instead, it will handle the repetition itself. - */ - public interface NonRepeatable {} - - /** - * If an action implements this interface, it should not be recorded - * by the macro recorder. Instead, it will do its own recording. - */ - public interface NonRecordable {} - - /** - * For use by EditAction.Wrapper only. - * @since jEdit 2.2final - */ - public interface Wrapper {} - - /** - * Macro recorder. - */ - public interface MacroRecorder - { - void actionPerformed(ActionListener listener, - String actionCommand); - } - - public static class backspace implements ActionListener - { - public void actionPerformed(ActionEvent evt) - { - JEditTextArea textArea = getTextArea(evt); - - if(!textArea.isEditable()) - { - textArea.getToolkit().beep(); - return; - } - - if(textArea.getSelectionStart() - != textArea.getSelectionStop()) - { - textArea.setSelectedText(""); - } - else - { - int caret = textArea.getCaretPosition(); - if(caret == 0) - { - textArea.getToolkit().beep(); - return; - } - try - { - textArea.getDocument().remove(caret - 1,1); - } - catch(BadLocationException bl) - { - bl.printStackTrace(); - } - } - } - } - - public static class backspace_word implements ActionListener - { - public void actionPerformed(ActionEvent evt) - { - JEditTextArea textArea = getTextArea(evt); - int start = textArea.getSelectionStart(); - if(start != textArea.getSelectionStop()) - { - textArea.setSelectedText(""); - } - - int line = textArea.getCaretLine(); - int lineStart = textArea.getLineStartOffset(line); - int caret = start - lineStart; - - String lineText = textArea.getLineText(textArea - .getCaretLine()); - - if(caret == 0) - { - if(lineStart == 0) - { - textArea.getToolkit().beep(); - return; - } - caret--; - } - else - { - String noWordSep = (String)textArea.getDocument().getProperty("noWordSep"); - caret = TextUtilities.findWordStart(lineText,caret,noWordSep); - } - - try - { - textArea.getDocument().remove( - caret + lineStart, - start - (caret + lineStart)); - } - catch(BadLocationException bl) - { - bl.printStackTrace(); - } - } - } - - public static class delete implements ActionListener - { - public void actionPerformed(ActionEvent evt) - { - JEditTextArea textArea = getTextArea(evt); - - if(!textArea.isEditable()) - { - textArea.getToolkit().beep(); - return; - } - - if(textArea.getSelectionStart() - != textArea.getSelectionStop()) - { - textArea.setSelectedText(""); - } - else - { - int caret = textArea.getCaretPosition(); - if(caret == textArea.getDocumentLength()) - { - textArea.getToolkit().beep(); - return; - } - try - { - textArea.getDocument().remove(caret,1); - } - catch(BadLocationException bl) - { - bl.printStackTrace(); - } - } - } - } - - public static class delete_word implements ActionListener - { - public void actionPerformed(ActionEvent evt) - { - JEditTextArea textArea = getTextArea(evt); - int start = textArea.getSelectionStart(); - if(start != textArea.getSelectionStop()) - { - textArea.setSelectedText(""); - } - - int line = textArea.getCaretLine(); - int lineStart = textArea.getLineStartOffset(line); - int caret = start - lineStart; - - String lineText = textArea.getLineText(textArea - .getCaretLine()); - - if(caret == lineText.length()) - { - if(lineStart + caret == textArea.getDocumentLength()) - { - textArea.getToolkit().beep(); - return; - } - caret++; - } - else - { - String noWordSep = (String)textArea.getDocument().getProperty("noWordSep"); - caret = TextUtilities.findWordEnd(lineText,caret,noWordSep); - } - - try - { - textArea.getDocument().remove(start, - (caret + lineStart) - start); - } - catch(BadLocationException bl) - { - bl.printStackTrace(); - } - } - } - - public static class end implements ActionListener - { - private boolean select; - - public end(boolean select) - { - this.select = select; - } - - public void actionPerformed(ActionEvent evt) - { - JEditTextArea textArea = getTextArea(evt); - - int caret = textArea.getCaretPosition(); - - int lastOfLine = textArea.getLineStopOffset( - textArea.getCaretLine()) - 1; - int lastVisibleLine = textArea.getFirstLine() - + textArea.getVisibleLines(); - if(lastVisibleLine >= textArea.getLineCount()) - { - lastVisibleLine = Math.min(textArea.getLineCount() - 1, - lastVisibleLine); - } - else - lastVisibleLine -= (textArea.getElectricScroll() + 1); - - int lastVisible = textArea.getLineStopOffset(lastVisibleLine) - 1; - int lastDocument = textArea.getDocumentLength(); - - if(caret == lastDocument) - { - textArea.getToolkit().beep(); - return; - } - else if(!Boolean.TRUE.equals(textArea.getClientProperty( - SMART_HOME_END_PROPERTY))) - caret = lastOfLine; - else if(caret == lastVisible) - caret = lastDocument; - else if(caret == lastOfLine) - caret = lastVisible; - else - caret = lastOfLine; - - if(select) - textArea.select(textArea.getMarkPosition(),caret); - else - textArea.setCaretPosition(caret); - } - } - - public static class document_end implements ActionListener - { - private boolean select; - - public document_end(boolean select) - { - this.select = select; - } - - public void actionPerformed(ActionEvent evt) - { - JEditTextArea textArea = getTextArea(evt); - if(select) - textArea.select(textArea.getMarkPosition(), - textArea.getDocumentLength()); - else - textArea.setCaretPosition(textArea - .getDocumentLength()); - } - } - - public static class home implements ActionListener - { - private boolean select; - - public home(boolean select) - { - this.select = select; - } - - public void actionPerformed(ActionEvent evt) - { - JEditTextArea textArea = getTextArea(evt); - - int caret = textArea.getCaretPosition(); - - int firstLine = textArea.getFirstLine(); - - int firstOfLine = textArea.getLineStartOffset( - textArea.getCaretLine()); - int firstVisibleLine = (firstLine == 0 ? 0 : - firstLine + textArea.getElectricScroll()); - int firstVisible = textArea.getLineStartOffset( - firstVisibleLine); - - if(caret == 0) - { - textArea.getToolkit().beep(); - return; - } - else if(!Boolean.TRUE.equals(textArea.getClientProperty( - SMART_HOME_END_PROPERTY))) - caret = firstOfLine; - else if(caret == firstVisible) - caret = 0; - else if(caret == firstOfLine) - caret = firstVisible; - else - caret = firstOfLine; - - if(select) - textArea.select(textArea.getMarkPosition(),caret); - else - textArea.setCaretPosition(caret); - } - } - - public static class document_home implements ActionListener - { - private boolean select; - - public document_home(boolean select) - { - this.select = select; - } - - public void actionPerformed(ActionEvent evt) - { - JEditTextArea textArea = getTextArea(evt); - if(select) - textArea.select(textArea.getMarkPosition(),0); - else - textArea.setCaretPosition(0); - } - } - - public static class insert_break implements ActionListener - { - public void actionPerformed(ActionEvent evt) - { - JEditTextArea textArea = getTextArea(evt); - - if(!textArea.isEditable()) - { - textArea.getToolkit().beep(); - return; - } - - textArea.setSelectedText("\n"); - } - } - - public static class insert_tab implements ActionListener - { - public void actionPerformed(ActionEvent evt) - { - JEditTextArea textArea = getTextArea(evt); - - if(!textArea.isEditable()) - { - textArea.getToolkit().beep(); - return; - } - - textArea.overwriteSetSelectedText("\t"); - } - } - - public static class next_char implements ActionListener - { - private boolean select; - - public next_char(boolean select) - { - this.select = select; - } - - public void actionPerformed(ActionEvent evt) - { - JEditTextArea textArea = getTextArea(evt); - int caret = textArea.getCaretPosition(); - - if(caret == textArea.getDocumentLength()) - { - if (textArea.getSelectionStart() != - textArea.getSelectionStop()) { - // just move to the end of the selection - textArea.select(caret, caret); - } else { - // beep at the user for being annoying - textArea.getToolkit().beep(); - } - - } else if (select) { - textArea.select(textArea.getMarkPosition(), caret+1); - - } else { - int start = textArea.getSelectionStart(); - int end = textArea.getSelectionStop(); - if (start != end) { - textArea.select(end, end); - } else { - textArea.setCaretPosition(caret + 1); - } - } - } - } - - public static class next_line implements ActionListener - { - private boolean select; - - public next_line(boolean select) - { - this.select = select; - } - - public void actionPerformed(ActionEvent evt) - { - JEditTextArea textArea = getTextArea(evt); - int caret = textArea.getCaretPosition(); - int line = textArea.getCaretLine(); - - if(line == textArea.getLineCount() - 1) - { - //textArea.getToolkit().beep(); - int doc = textArea.getDocumentLength(); - if (select) { - textArea.select(textArea.getMarkPosition(), doc); - } else { - textArea.setCaretPosition(doc); - } - return; - } - - int magic = textArea.getMagicCaretPosition(); - if(magic == -1) - { - magic = textArea.offsetToX(line, - caret - textArea.getLineStartOffset(line)); - } - - caret = textArea.getLineStartOffset(line + 1) - + textArea.xToOffset(line + 1,magic); - if(select) - textArea.select(textArea.getMarkPosition(),caret); - else - textArea.setCaretPosition(caret); - textArea.setMagicCaretPosition(magic); - } - } - - public static class next_page implements ActionListener - { - private boolean select; - - public next_page(boolean select) - { - this.select = select; - } - - public void actionPerformed(ActionEvent evt) - { - JEditTextArea textArea = getTextArea(evt); - int lineCount = textArea.getLineCount(); - int firstLine = textArea.getFirstLine(); - int visibleLines = textArea.getVisibleLines(); - int line = textArea.getCaretLine(); - - firstLine += visibleLines; - - if(firstLine + visibleLines >= lineCount - 1) - firstLine = lineCount - visibleLines; - - textArea.setFirstLine(firstLine); - - int caret = textArea.getLineStartOffset( - Math.min(textArea.getLineCount() - 1, - line + visibleLines)); - if(select) - textArea.select(textArea.getMarkPosition(),caret); - else - textArea.setCaretPosition(caret); - } - } - - public static class next_word implements ActionListener - { - private boolean select; - - public next_word(boolean select) - { - this.select = select; - } - - public void actionPerformed(ActionEvent evt) - { - JEditTextArea textArea = getTextArea(evt); - int caret = textArea.getCaretPosition(); - int line = textArea.getCaretLine(); - int lineStart = textArea.getLineStartOffset(line); - caret -= lineStart; - - String lineText = textArea.getLineText(textArea - .getCaretLine()); - - if(caret == lineText.length()) - { - if(lineStart + caret == textArea.getDocumentLength()) - { - textArea.getToolkit().beep(); - return; - } - caret++; - } - else - { - String noWordSep = (String)textArea.getDocument().getProperty("noWordSep"); - caret = TextUtilities.findWordEnd(lineText,caret,noWordSep); - } - - if(select) - textArea.select(textArea.getMarkPosition(), - lineStart + caret); - else - textArea.setCaretPosition(lineStart + caret); - } - } - - public static class overwrite implements ActionListener - { - public void actionPerformed(ActionEvent evt) - { - JEditTextArea textArea = getTextArea(evt); - textArea.setOverwriteEnabled( - !textArea.isOverwriteEnabled()); - } - } - - public static class prev_char implements ActionListener - { - private boolean select; - - public prev_char(boolean select) - { - this.select = select; - } - - public void actionPerformed(ActionEvent evt) - { - JEditTextArea textArea = getTextArea(evt); - int caret = textArea.getCaretPosition(); - if(caret == 0) - { - textArea.getToolkit().beep(); - return; - } - - if (select) { - textArea.select(textArea.getMarkPosition(), caret-1); - } else { - int start = textArea.getSelectionStart(); - int end = textArea.getSelectionStop(); - if (start != end) { - textArea.select(start, start); - } else { - textArea.setCaretPosition(caret - 1); - } - } - } - } - - public static class prev_line implements ActionListener - { - private boolean select; - - public prev_line(boolean select) - { - this.select = select; - } - - public void actionPerformed(ActionEvent evt) - { - JEditTextArea textArea = getTextArea(evt); - int caret = textArea.getCaretPosition(); - int line = textArea.getCaretLine(); - - if(line == 0) - { - if (select) { - if (textArea.getSelectionStart() != 0) { - textArea.select(textArea.getMarkPosition(), 0); - } - } else { - textArea.setCaretPosition(0); - } - //textArea.getToolkit().beep(); - return; - } - - int magic = textArea.getMagicCaretPosition(); - if(magic == -1) - { - magic = textArea.offsetToX(line, - caret - textArea.getLineStartOffset(line)); - } - - caret = textArea.getLineStartOffset(line - 1) - + textArea.xToOffset(line - 1,magic); - if(select) - textArea.select(textArea.getMarkPosition(),caret); - else - textArea.setCaretPosition(caret); - textArea.setMagicCaretPosition(magic); - } - } - - public static class prev_page implements ActionListener - { - private boolean select; - - public prev_page(boolean select) - { - this.select = select; - } - - public void actionPerformed(ActionEvent evt) - { - JEditTextArea textArea = getTextArea(evt); - int firstLine = textArea.getFirstLine(); - int visibleLines = textArea.getVisibleLines(); - int line = textArea.getCaretLine(); - - if(firstLine < visibleLines) - firstLine = visibleLines; - - textArea.setFirstLine(firstLine - visibleLines); - - int caret = textArea.getLineStartOffset( - Math.max(0,line - visibleLines)); - if(select) - textArea.select(textArea.getMarkPosition(),caret); - else - textArea.setCaretPosition(caret); - } - } - - public static class prev_word implements ActionListener - { - private boolean select; - - public prev_word(boolean select) - { - this.select = select; - } - - public void actionPerformed(ActionEvent evt) - { - JEditTextArea textArea = getTextArea(evt); - int caret = textArea.getCaretPosition(); - int line = textArea.getCaretLine(); - int lineStart = textArea.getLineStartOffset(line); - caret -= lineStart; - - String lineText = textArea.getLineText(textArea - .getCaretLine()); - - if(caret == 0) - { - if(lineStart == 0) - { - textArea.getToolkit().beep(); - return; - } - caret--; - } - else - { - String noWordSep = (String)textArea.getDocument().getProperty("noWordSep"); - caret = TextUtilities.findWordStart(lineText,caret,noWordSep); - } - - if(select) - textArea.select(textArea.getMarkPosition(), - lineStart + caret); - else - textArea.setCaretPosition(lineStart + caret); - } - } - - public static class repeat implements ActionListener, - InputHandler.NonRecordable - { - public void actionPerformed(ActionEvent evt) - { - JEditTextArea textArea = getTextArea(evt); - textArea.getInputHandler().setRepeatEnabled(true); - String actionCommand = evt.getActionCommand(); - if(actionCommand != null) - { - textArea.getInputHandler().setRepeatCount( - Integer.parseInt(actionCommand)); - } - } - } - - public static class toggle_rect implements ActionListener - { - public void actionPerformed(ActionEvent evt) - { - JEditTextArea textArea = getTextArea(evt); - textArea.setSelectionRectangular( - !textArea.isSelectionRectangular()); - } - } - - - public static class clipboard_cut implements ActionListener - { - public void actionPerformed(ActionEvent evt) - { - getTextArea(evt).cut(); - } - } - - - public static class clipboard_copy implements ActionListener - { - public void actionPerformed(ActionEvent evt) - { - getTextArea(evt).copy(); - } - } - - - public static class clipboard_paste implements ActionListener - { - public void actionPerformed(ActionEvent evt) - { - getTextArea(evt).paste(); - } - } - - - public static class insert_char implements ActionListener, - InputHandler.NonRepeatable - { - public void actionPerformed(ActionEvent evt) - { - JEditTextArea textArea = getTextArea(evt); - String str = evt.getActionCommand(); - int repeatCount = textArea.getInputHandler().getRepeatCount(); - - if(textArea.isEditable()) - { - StringBuffer buf = new StringBuffer(); - for(int i = 0; i < repeatCount; i++) - buf.append(str); - textArea.overwriteSetSelectedText(buf.toString()); - } - else - { - textArea.getToolkit().beep(); - } - } - } -} diff --git a/app/src/processing/app/syntax/JEditTextArea.java b/app/src/processing/app/syntax/JEditTextArea.java deleted file mode 100644 index c12102038..000000000 --- a/app/src/processing/app/syntax/JEditTextArea.java +++ /dev/null @@ -1,2448 +0,0 @@ -/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ - -/* - * JEditTextArea.java - jEdit's text component - * Copyright (C) 1999 Slava Pestov - * - * You may use and modify this package for any purpose. Redistribution is - * permitted, in both source and binary form, provided that this notice - * remains intact in all source distributions of this package. - */ - -package processing.app.syntax; - -import processing.app.*; - -import javax.swing.event.*; -import javax.swing.text.*; -import javax.swing.undo.*; -import javax.swing.*; - -import java.awt.datatransfer.*; -import java.awt.event.*; -import java.awt.*; -import java.util.Enumeration; -import java.util.Vector; -import java.awt.im.InputMethodRequests; - -import processing.app.syntax.im.InputMethodSupport; - -/** - * jEdit's text area component. It is more suited for editing program - * source code than JEditorPane, because it drops the unnecessary features - * (images, variable-width lines, and so on) and adds a whole bunch of - * useful goodies such as: - *

- * It is also faster and doesn't have as many problems. It can be used - * in other applications; the only other part of jEdit it depends on is - * the syntax package.

- * - * To use it in your app, treat it like any other component, for example: - *

JEditTextArea ta = new JEditTextArea();
- * ta.setTokenMarker(new JavaTokenMarker());
- * ta.setText("public class Test {\n"
- *     + "    public static void main(String[] args) {\n"
- *     + "        System.out.println(\"Hello World\");\n"
- *     + "    }\n"
- *     + "}");
- * - * @author Slava Pestov - */ -public class JEditTextArea extends JComponent -{ - /** - * Adding components with this name to the text area will place - * them left of the horizontal scroll bar. In jEdit, the status - * bar is added this way. - */ - public static String LEFT_OF_SCROLLBAR = "los"; - - /** - * Creates a new JEditTextArea with the default settings. - */ - /* - public JEditTextArea() - { - this(TextAreaDefaults.getDefaults()); - } - */ - - /** - * Creates a new JEditTextArea with the specified settings. - * @param defaults The default settings - */ - public JEditTextArea(TextAreaDefaults defaults) - { - // Enable the necessary events - enableEvents(AWTEvent.KEY_EVENT_MASK); - - // Initialize some misc. stuff - painter = new TextAreaPainter(this,defaults); - editorLineNumbers = new TextAreaLineNumbers(this,defaults); - documentHandler = new DocumentHandler(); - eventListenerList = new EventListenerList(); - caretEvent = new MutableCaretEvent(); - lineSegment = new Segment(); - bracketLine = bracketPosition = -1; - blink = true; - - // Initialize the GUI - setLayout(new ScrollLayout()); - add(LEFT, editorLineNumbers); - add(CENTER, painter); - add(RIGHT, vertical = new JScrollBar(JScrollBar.VERTICAL)); - add(BOTTOM, horizontal = new JScrollBar(JScrollBar.HORIZONTAL)); - - // Add some event listeners - vertical.addAdjustmentListener(new AdjustHandler()); - horizontal.addAdjustmentListener(new AdjustHandler()); - painter.addComponentListener(new ComponentHandler()); - painter.addMouseListener(new MouseHandler()); - painter.addMouseMotionListener(new DragHandler()); - addFocusListener(new FocusHandler()); - // send tab keys through to the text area - // http://dev.processing.org/bugs/show_bug.cgi?id=1267 - setFocusTraversalKeysEnabled(false); - - // Load the defaults - setInputHandler(defaults.inputHandler); - setDocument(defaults.document); - editable = defaults.editable; - caretVisible = defaults.caretVisible; - caretBlinks = defaults.caretBlinks; - electricScroll = defaults.electricScroll; - - // We don't seem to get the initial focus event? - focusedComponent = this; - - addMouseWheelListener(new MouseWheelListener() { - public void mouseWheelMoved(MouseWheelEvent e) { - if (!scrollBarsInitialized) return; - int amt = e.getWheelRotation(); - vertical.setValue(vertical.getValue() + amt * 3); - } - }); - } - - /** - * Inline Input Method Support for Japanese. - */ - private InputMethodSupport inputMethodSupport = null; - public InputMethodRequests getInputMethodRequests() { - if (inputMethodSupport == null) { - inputMethodSupport = new InputMethodSupport(this); - } - return inputMethodSupport; - } - - /** - * Get current position of the vertical scroll bar. [fry] - */ - public int getScrollPosition() { - return vertical.getValue(); - } - - - /** - * Set position of the vertical scroll bar. [fry] - */ - public void setScrollPosition(int what) { - vertical.setValue(what); - } - - - /** - * Returns if this component can be traversed by pressing - * the Tab key. This returns false. - */ -// public final boolean isManagingFocus() { -// return true; -// } - - /** - * Returns the object responsible for painting this text area. - */ - public final TextAreaPainter getPainter() { - return painter; - } - - /** - * Returns the input handler. - */ - public final InputHandler getInputHandler() { - return inputHandler; - } - - /** - * Sets the input handler. - * @param inputHandler The new input handler - */ - public void setInputHandler(InputHandler inputHandler) { - this.inputHandler = inputHandler; - } - - /** - * Returns true if the caret is blinking, false otherwise. - */ - public final boolean isCaretBlinkEnabled() { - return caretBlinks; - } - - /** - * Toggles caret blinking. - * @param caretBlinks True if the caret should blink, false otherwise - */ - public void setCaretBlinkEnabled(boolean caretBlinks) { - this.caretBlinks = caretBlinks; - if(!caretBlinks) - blink = false; - - painter.invalidateSelectedLines(); - } - - /** - * Returns true if the caret is visible, false otherwise. - */ - public final boolean isCaretVisible() { - return (!caretBlinks || blink) && caretVisible; - } - - /** - * Sets if the caret should be visible. - * @param caretVisible True if the caret should be visible, false - * otherwise - */ - public void setCaretVisible(boolean caretVisible) { - this.caretVisible = caretVisible; - blink = true; - - painter.invalidateSelectedLines(); - } - - /** - * Blinks the caret. - */ - public final void blinkCaret() { - if (caretBlinks) { - blink = !blink; - painter.invalidateSelectedLines(); - } else { - blink = true; - } - } - - /** - * Returns the number of lines from the top and button of the - * text area that are always visible. - */ - public final int getElectricScroll() { - return electricScroll; - } - - /** - * Sets the number of lines from the top and bottom of the text - * area that are always visible - * @param electricScroll The number of lines always visible from - * the top or bottom - */ - public final void setElectricScroll(int electricScroll) { - this.electricScroll = electricScroll; - } - - - /** - * Updates the state of the scroll bars. This should be called - * if the number of lines in the document changes, or when the - * size of the text are changes. - */ - public void updateScrollBars() { - if (vertical != null && visibleLines != 0) { - vertical.setValues(firstLine,visibleLines,0,getLineCount()); - vertical.setUnitIncrement(2); - vertical.setBlockIncrement(visibleLines); - } - - //if (horizontal != null && width != 0) { - if ((horizontal != null) && (painter.getWidth() != 0)) { - //int value = horizontal.getValue(); - //System.out.println("updateScrollBars"); - //int width = painter.getWidth(); - int lineCount = getLineCount(); - int maxLineLength = 0; - for (int i = 0; i < lineCount; i++) { - int lineLength = getLineLength(i); - if (lineLength > maxLineLength) { - maxLineLength = lineLength; - } - } - int charWidth = painter.getFontMetrics().charWidth('w'); - int width = maxLineLength * charWidth; - int painterWidth = painter.getWidth(); - //System.out.println("max line len " + maxLineLength); - //System.out.println("width " + width); - //System.out.println("text area width " + painter.getWidth()); - - // this was the default, but it's enormous - //horizontal.setValues(-horizontalOffset,width,0,width * 5); - - // something more reasonable, though this is a bad solution - //horizontal.setValues(-horizontalOffset,width,0,width * 2); - - // in general.. time to start looking at that other syntax pkg - // since most code should fit the window horizontally, just use - // the default settings for the width, this is a nicer solution - // until a better update mechanism can be implemented [fry] - - //horizontal.setValues(0, width, 0, width); - //0, width - horizontalOffset); - // works, from pre-75 versions of p5 - //horizontal.setValues(-horizontalOffset, width, 0, width); - - // gets weird when writing to the end of lines - //horizontal.setValues(value, painterWidth, 0, width); - - // seems to work, implemented for 0075 - horizontal.setValues(-horizontalOffset, painterWidth, 0, width); - - //horizontal.setUnitIncrement(painter.getFontMetrics().charWidth('w')); - horizontal.setUnitIncrement(charWidth); - horizontal.setBlockIncrement(width / 2); - } - updateLineNumbers(); - } - - private void updateLineNumbers() { - if (editorLineNumbers != null) { - editorLineNumbers.updateLineNumbers(getFirstLine() + 1, Math.min(getFirstLine() + getVisibleLines() + 1, getLineCount())); - editorLineNumbers.updateWidthForNumDigits(String.valueOf(getLineCount()).length()); - } - } - - /** - * Returns the line displayed at the text area's origin. - */ - public final int getFirstLine() { - return firstLine; - } - - /** - * Sets the line displayed at the text area's origin without - * updating the scroll bars. - */ - public void setFirstLine(int firstLine) { - if (firstLine == this.firstLine) return; - - this.firstLine = firstLine; - if (firstLine != vertical.getValue()) { - updateScrollBars(); - } - repaintEditor(); - } - - /** - * Returns the number of lines visible in this text area. - */ - public final int getVisibleLines() { - return visibleLines; - } - - /** - * Recalculates the number of visible lines. This should not - * be called directly. - */ - public final void recalculateVisibleLines() { - if (painter == null) return; - - int height = painter.getHeight(); - int lineHeight = painter.getFontMetrics().getHeight(); - visibleLines = height / lineHeight; - updateScrollBars(); - } - - /** - * Returns the horizontal offset of drawn lines. - */ - public final int getHorizontalOffset() { - return horizontalOffset; - } - - /** - * Sets the horizontal offset of drawn lines. This can be used to - * implement horizontal scrolling. - * @param horizontalOffset offset The new horizontal offset - */ - public void setHorizontalOffset(int horizontalOffset) - { - if(horizontalOffset == this.horizontalOffset) - return; - this.horizontalOffset = horizontalOffset; - if(horizontalOffset != horizontal.getValue()) - updateScrollBars(); - repaintEditor(); - } - - /** - * A fast way of changing both the first line and horizontal - * offset. - * @param firstLine The new first line - * @param horizontalOffset The new horizontal offset - * @return True if any of the values were changed, false otherwise - */ - public boolean setOrigin(int firstLine, int horizontalOffset) - { - boolean changed = false; - //int oldFirstLine = this.firstLine; - - if(horizontalOffset != this.horizontalOffset) - { - this.horizontalOffset = horizontalOffset; - changed = true; - } - - if(firstLine != this.firstLine) - { - this.firstLine = firstLine; - changed = true; - } - - if(changed) - { - updateScrollBars(); - repaintEditor(); - } - - return changed; - } - - private void repaintEditor() { - painter.repaint(); - updateLineNumbers(); - } - - /** - * Ensures that the caret is visible by scrolling the text area if - * necessary. - * @return True if scrolling was actually performed, false if the - * caret was already visible - */ - public boolean scrollToCaret() - { - int line = getCaretLine(); - int lineStart = getLineStartOffset(line); - int offset = Math.max(0,Math.min(getLineLength(line) - 1, - getCaretPosition() - lineStart)); - - return scrollTo(line,offset); - } - - /** - * Ensures that the specified line and offset is visible by scrolling - * the text area if necessary. - * @param line The line to scroll to - * @param offset The offset in the line to scroll to - * @return True if scrolling was actually performed, false if the - * line and offset was already visible - */ - public boolean scrollTo(int line, int offset) - { - // visibleLines == 0 before the component is realized - // we can't do any proper scrolling then, so we have - // this hack... - if (visibleLines == 0) { - setFirstLine(Math.max(0,line - electricScroll)); - return true; - } - - int newFirstLine = firstLine; - int newHorizontalOffset = horizontalOffset; - - if(line < firstLine + electricScroll) { - newFirstLine = Math.max(0,line - electricScroll); - - } else if(line + electricScroll >= firstLine + visibleLines) { - newFirstLine = (line - visibleLines) + electricScroll + 1; - if(newFirstLine + visibleLines >= getLineCount()) - newFirstLine = getLineCount() - visibleLines; - if(newFirstLine < 0) - newFirstLine = 0; - } - - int x = _offsetToX(line,offset); - int width = painter.getFontMetrics().charWidth('w'); - - if(x < 0) { - newHorizontalOffset = Math.min(0,horizontalOffset - x + width + 5); - } else if(x + width >= painter.getWidth()) { - newHorizontalOffset = horizontalOffset + - (painter.getWidth() - x) - width - 5; - } - - return setOrigin(newFirstLine,newHorizontalOffset); - } - - /** - * Converts a line index to a y co-ordinate. - * @param line The line - */ - public int lineToY(int line) - { - FontMetrics fm = painter.getFontMetrics(); - return (line - firstLine) * fm.getHeight() - - (fm.getLeading() + fm.getMaxDescent()); - } - - /** - * Converts a y co-ordinate to a line index. - * @param y The y co-ordinate - */ - public int yToLine(int y) - { - FontMetrics fm = painter.getFontMetrics(); - int height = fm.getHeight(); - return Math.max(0,Math.min(getLineCount() - 1, - y / height + firstLine)); - } - - /** - * Converts an offset in a line into an x co-ordinate. This is a - * slow version that can be used any time. - * @param line The line - * @param offset The offset, from the start of the line - */ - public final int offsetToX(int line, int offset) - { - // don't use cached tokens - painter.currentLineTokens = null; - return _offsetToX(line,offset); - } - - /** - * Converts an offset in a line into an x co-ordinate. This is a - * fast version that should only be used if no changes were made - * to the text since the last repaint. - * @param line The line - * @param offset The offset, from the start of the line - */ - public int _offsetToX(int line, int offset) - { - TokenMarker tokenMarker = getTokenMarker(); - - /* Use painter's cached info for speed */ - FontMetrics fm = painter.getFontMetrics(); - - getLineText(line,lineSegment); - - int segmentOffset = lineSegment.offset; - int x = horizontalOffset; - - /* If syntax coloring is disabled, do simple translation */ - if(tokenMarker == null) - { - lineSegment.count = offset; - return x + Utilities.getTabbedTextWidth(lineSegment, - fm,x,painter,0); - } - /* If syntax coloring is enabled, we have to do this because - * tokens can vary in width */ - else - { - Token tokens; - if(painter.currentLineIndex == line - && painter.currentLineTokens != null) - tokens = painter.currentLineTokens; - else - { - painter.currentLineIndex = line; - tokens = painter.currentLineTokens - = tokenMarker.markTokens(lineSegment,line); - } - - //Toolkit toolkit = painter.getToolkit(); - Font defaultFont = painter.getFont(); - SyntaxStyle[] styles = painter.getStyles(); - - for(;;) - { - byte id = tokens.id; - if(id == Token.END) - { - return x; - } - - if(id == Token.NULL) - fm = painter.getFontMetrics(); - else - fm = styles[id].getFontMetrics(defaultFont, this); - - int length = tokens.length; - - if(offset + segmentOffset < lineSegment.offset + length) - { - lineSegment.count = offset - (lineSegment.offset - segmentOffset); - return x + Utilities.getTabbedTextWidth( - lineSegment,fm,x,painter,0); - } - else - { - lineSegment.count = length; - x += Utilities.getTabbedTextWidth( - lineSegment,fm,x,painter,0); - lineSegment.offset += length; - } - tokens = tokens.next; - } - } - } - - /** - * Converts an x co-ordinate to an offset within a line. - * @param line The line - * @param x The x co-ordinate - */ - public int xToOffset(int line, int x) - { - TokenMarker tokenMarker = getTokenMarker(); - - /* Use painter's cached info for speed */ - FontMetrics fm = painter.getFontMetrics(); - - getLineText(line,lineSegment); - - char[] segmentArray = lineSegment.array; - int segmentOffset = lineSegment.offset; - int segmentCount = lineSegment.count; - - int width = horizontalOffset; - - if(tokenMarker == null) - { - for(int i = 0; i < segmentCount; i++) - { - char c = segmentArray[i + segmentOffset]; - int charWidth; - if(c == '\t') - charWidth = (int)painter.nextTabStop(width,i) - - width; - else - charWidth = fm.charWidth(c); - - if(painter.isBlockCaretEnabled()) - { - if(x - charWidth <= width) - return i; - } - else - { - if(x - charWidth / 2 <= width) - return i; - } - - width += charWidth; - } - - return segmentCount; - } - else - { - Token tokens; - if(painter.currentLineIndex == line && painter - .currentLineTokens != null) - tokens = painter.currentLineTokens; - else - { - painter.currentLineIndex = line; - tokens = painter.currentLineTokens - = tokenMarker.markTokens(lineSegment,line); - } - - int offset = 0; - //Toolkit toolkit = painter.getToolkit(); - Font defaultFont = painter.getFont(); - SyntaxStyle[] styles = painter.getStyles(); - - for(;;) - { - byte id = tokens.id; - if(id == Token.END) - return offset; - - if(id == Token.NULL) - fm = painter.getFontMetrics(); - else - fm = styles[id].getFontMetrics(defaultFont, this); - - int length = tokens.length; - - for(int i = 0; i < length; i++) - { - char c = segmentArray[segmentOffset + offset + i]; - int charWidth; - if(c == '\t') - charWidth = (int)painter.nextTabStop(width,offset + i) - - width; - else - charWidth = fm.charWidth(c); - - if(painter.isBlockCaretEnabled()) - { - if(x - charWidth <= width) - return offset + i; - } - else - { - if(x - charWidth / 2 <= width) - return offset + i; - } - - width += charWidth; - } - - offset += length; - tokens = tokens.next; - } - } - } - - /** - * Converts a point to an offset, from the start of the text. - * @param x The x co-ordinate of the point - * @param y The y co-ordinate of the point - */ - public int xyToOffset(int x, int y) - { - int line = yToLine(y); - int start = getLineStartOffset(line); - return start + xToOffset(line,x); - } - - /** - * Returns the document this text area is editing. - */ - public final SyntaxDocument getDocument() - { - return document; - } - - /** - * Sets the document this text area is editing. - * @param document The document - */ - public void setDocument(SyntaxDocument document) { - if (this.document == document) - return; - if (this.document != null) - this.document.removeDocumentListener(documentHandler); - this.document = document; - - document.addDocumentListener(documentHandler); - - select(0, 0); - updateScrollBars(); - repaintEditor(); - } - - - /** - * Set document with a twist, includes the old caret - * and scroll positions, added for p5. [fry] - */ - public void setDocument(SyntaxDocument document, - int start, int stop, int scroll) { - if (this.document == document) - return; - if (this.document != null) - this.document.removeDocumentListener(documentHandler); - this.document = document; - - document.addDocumentListener(documentHandler); - - select(start, stop); - updateScrollBars(); - setScrollPosition(scroll); - repaintEditor(); - } - - - /** - * Returns the document's token marker. Equivalent to calling - * getDocument().getTokenMarker(). - */ - public final TokenMarker getTokenMarker() - { - return document.getTokenMarker(); - } - - /** - * Sets the document's token marker. Equivalent to caling - * getDocument().setTokenMarker(). - * @param tokenMarker The token marker - */ - public final void setTokenMarker(TokenMarker tokenMarker) - { - document.setTokenMarker(tokenMarker); - } - - /** - * Returns the length of the document. Equivalent to calling - * getDocument().getLength(). - */ - public final int getDocumentLength() - { - return document.getLength(); - } - - /** - * Returns the number of lines in the document. - */ - public final int getLineCount() - { - if (document != null) { - return document.getDefaultRootElement().getElementCount(); - } else { - return 0; - } - } - - /** - * Returns the line containing the specified offset. - * @param offset The offset - */ - public final int getLineOfOffset(int offset) - { - return document.getDefaultRootElement().getElementIndex(offset); - } - - /** - * Returns the start offset of the specified line. - * @param line The line - * @return The start offset of the specified line, or -1 if the line is - * invalid - */ - public int getLineStartOffset(int line) - { - Element lineElement = document.getDefaultRootElement() - .getElement(line); - if(lineElement == null) - return -1; - else - return lineElement.getStartOffset(); - } - - /** - * Returns the end offset of the specified line. - * @param line The line - * @return The end offset of the specified line, or -1 if the line is - * invalid. - */ - public int getLineStopOffset(int line) - { - Element lineElement = document.getDefaultRootElement() - .getElement(line); - if(lineElement == null) - return -1; - else - return lineElement.getEndOffset(); - } - - /** - * Returns the end offset of the specified line, but not past the end of the text - * @param line The line - * @return The end offset of the specified line, safe to use for a selection, or -1 if the line is - * invalid. - */ - public int getSafeLineStopOffset(int line) - { - return Math.min(getLineStopOffset(line),getDocumentLength()); - } - - /** - * Returns the length of the specified line. - * @param line The line - */ - public int getLineLength(int line) - { - Element lineElement = document.getDefaultRootElement() - .getElement(line); - if(lineElement == null) - return -1; - else - return lineElement.getEndOffset() - - lineElement.getStartOffset() - 1; - } - - /** - * Returns the entire text of this text area. - */ - public String getText() - { - try - { - return document.getText(0,document.getLength()); - } - catch(BadLocationException bl) - { - bl.printStackTrace(); - return null; - } - } - - - /** - * Sets the entire text of this text area. - */ - public void setText(String text) - { - try { - document.beginCompoundEdit(); - document.remove(0,document.getLength()); - document.insertString(0,text,null); - - } catch (BadLocationException bl) { - bl.printStackTrace(); - - } finally { - document.endCompoundEdit(); - } - } - - - /** - * Returns the specified substring of the document. - * @param start The start offset - * @param len The length of the substring - * @return The substring, or null if the offsets are invalid - */ - public final String getText(int start, int len) - { - try - { - return document.getText(start,len); - } - catch(BadLocationException bl) - { - bl.printStackTrace(); - return null; - } - } - - /** - * Copies the specified substring of the document into a segment. - * If the offsets are invalid, the segment will contain a null string. - * @param start The start offset - * @param len The length of the substring - * @param segment The segment - */ - public final void getText(int start, int len, Segment segment) - { - try - { - document.getText(start,len,segment); - } - catch(BadLocationException bl) - { - bl.printStackTrace(); - segment.offset = segment.count = 0; - } - } - - /** - * Returns the text on the specified line. - * @param lineIndex The line - * @return The text, or null if the line is invalid - */ - public final String getLineText(int lineIndex) - { - int start = getLineStartOffset(lineIndex); - return getText(start,getLineStopOffset(lineIndex) - start - 1); - } - - /** - * Copies the text on the specified line into a segment. If the line - * is invalid, the segment will contain a null string. - * @param lineIndex The line - */ - public final void getLineText(int lineIndex, Segment segment) - { - int start = getLineStartOffset(lineIndex); - getText(start,getLineStopOffset(lineIndex) - start - 1,segment); - } - - /** - * Returns the selection start offset. - */ - public final int getSelectionStart() - { - return selectionStart; - } - - /** - * Returns the offset where the selection starts on the specified - * line. - */ - public int getSelectionStart(int line) - { - if(line == selectionStartLine) - return selectionStart; - else if(rectSelect) - { - Element map = document.getDefaultRootElement(); - int start = selectionStart - map.getElement(selectionStartLine) - .getStartOffset(); - - Element lineElement = map.getElement(line); - int lineStart = lineElement.getStartOffset(); - int lineEnd = lineElement.getEndOffset() - 1; - return Math.min(lineEnd,lineStart + start); - } - else - return getLineStartOffset(line); - } - - /** - * Returns the selection start line. - */ - public final int getSelectionStartLine() - { - return selectionStartLine; - } - - /** - * Sets the selection start. The new selection will be the new - * selection start and the old selection end. - * @param selectionStart The selection start - * @see #select(int,int) - */ - public final void setSelectionStart(int selectionStart) - { - select(selectionStart,selectionEnd); - } - - /** - * Returns the selection end offset. - */ - public final int getSelectionStop() - { - return selectionEnd; - } - - /** - * Returns the offset where the selection ends on the specified - * line. - */ - public int getSelectionStop(int line) - { - if(line == selectionEndLine) - return selectionEnd; - else if(rectSelect) - { - Element map = document.getDefaultRootElement(); - int end = selectionEnd - map.getElement(selectionEndLine) - .getStartOffset(); - - Element lineElement = map.getElement(line); - int lineStart = lineElement.getStartOffset(); - int lineEnd = lineElement.getEndOffset() - 1; - return Math.min(lineEnd,lineStart + end); - } - else - return getLineStopOffset(line) - 1; - } - - /** - * Returns the selection end line. - */ - public final int getSelectionStopLine() - { - return selectionEndLine; - } - - /** - * Sets the selection end. The new selection will be the old - * selection start and the bew selection end. - * @param selectionEnd The selection end - * @see #select(int,int) - */ - public final void setSelectionEnd(int selectionEnd) - { - select(selectionStart,selectionEnd); - } - - - public final boolean isSelectionActive() - { - return(selectionStart != selectionEnd); - } - - /** - * Returns the caret position. This will either be the selection - * start or the selection end, depending on which direction the - * selection was made in. - */ - public final int getCaretPosition() - { - return (biasLeft ? selectionStart : selectionEnd); - } - - /** - * Returns the caret line. - */ - public final int getCaretLine() - { - return (biasLeft ? selectionStartLine : selectionEndLine); - } - - /** - * Returns the mark position. This will be the opposite selection - * bound to the caret position. - * @see #getCaretPosition() - */ - public final int getMarkPosition() - { - return (biasLeft ? selectionEnd : selectionStart); - } - - /** - * Returns the mark line. - */ - public final int getMarkLine() - { - return (biasLeft ? selectionEndLine : selectionStartLine); - } - - /** - * Sets the caret position. The new selection will consist of the - * caret position only (hence no text will be selected) - * @param caret The caret position - * @see #select(int,int) - */ - public final void setCaretPosition(int caret) - { - select(caret,caret); - } - - /** - * Selects all text in the document. - */ - public final void selectAll() - { - select(0,getDocumentLength()); - } - - /** - * Moves the mark to the caret position. - */ - public final void selectNone() - { - select(getCaretPosition(),getCaretPosition()); - } - - /** - * Selects from the start offset to the end offset. This is the - * general selection method used by all other selecting methods. - * The caret position will be start if start < end, and end - * if end > start. - * @param start The start offset - * @param end The end offset - */ - public void select(int start, int end) - { - int newStart, newEnd; - boolean newBias; - if(start <= end) - { - newStart = start; - newEnd = end; - newBias = false; - } - else - { - newStart = end; - newEnd = start; - newBias = true; - } - - if (newEnd > getDocumentLength()) { - newEnd = getDocumentLength(); - } - - if(newStart < 0) - { - throw new IllegalArgumentException("Bounds out of" - + " range: " + newStart + "," + - newEnd + " [" + getDocumentLength() + "]"); - } - - // If the new position is the same as the old, we don't - // do all this crap, however we still do the stuff at - // the end (clearing magic position, scrolling) - if(newStart != selectionStart || newEnd != selectionEnd - || newBias != biasLeft) - { - int newStartLine = getLineOfOffset(newStart); - int newEndLine = getLineOfOffset(newEnd); - - if(painter.isBracketHighlightEnabled()) - { - if(bracketLine != -1) - painter.invalidateLine(bracketLine); - updateBracketHighlight(end); - if(bracketLine != -1) - painter.invalidateLine(bracketLine); - } - - painter.invalidateLineRange(selectionStartLine,selectionEndLine); - painter.invalidateLineRange(newStartLine,newEndLine); - - document.addUndoableEdit(new CaretUndo(selectionStart,selectionEnd)); - - selectionStart = newStart; - selectionEnd = newEnd; - selectionStartLine = newStartLine; - selectionEndLine = newEndLine; - biasLeft = newBias; - - if (newStart != newEnd) { - Clipboard unixclipboard = getToolkit().getSystemSelection(); - if (unixclipboard != null) { - String selection = getSelectedText(); - if (selection != null) { - unixclipboard.setContents(new StringSelection(selection), null); - } - } - } - - fireCaretEvent(); - } - - // When the user is typing, etc, we don't want the caret - // to blink - blink = true; - caretTimer.restart(); - - // Disable rectangle select if selection start = selection end - if(selectionStart == selectionEnd) - rectSelect = false; - - // Clear the `magic' caret position used by up/down - magicCaret = -1; - - scrollToCaret(); - - // notify the line number feller - if (editorLineStatus != null) { - editorLineStatus.set(selectionStartLine, selectionEndLine); - //System.out.println("why " + selectionStartLine + " " + selectionEndLine); - //System.out.println(getLineOfOffset(start) + " " + - // getLineOfOffset(end)); - } - } - - private boolean isWordCharacter( char ch, String noWordSep ) - { - return Character.isLetterOrDigit(ch) || ch=='_' || noWordSep.indexOf(ch) != -1; - } - - protected void setNewSelectionWord( int line, int offset ) - { - if (getLineLength(line) == 0) { - newSelectionStart = getLineStartOffset(line); - newSelectionEnd = newSelectionStart; - return; - } - - String noWordSep = (String)document.getProperty("noWordSep"); - if(noWordSep == null) - noWordSep = ""; - - String lineText = getLineText(line); - - int wordStart = 0; - int wordEnd = lineText.length(); - - char ch = lineText.charAt(Math.max(0,offset - 1)); - - // special case for whitespace (fry 0122, bug #348) - // this is really nasty.. turns out that double-clicking any non-letter - // or digit char gets lumped together.. sooo, this quickly gets messy, - // because really it needs to check whether the chars are of the same - // type.. so a double space or double - might be grouped together, - // but what about a +=1? do + and - get grouped but not the 1? blech, - // coming back to this later. it's not a difficult fix, just a - // time-consuming one to track down all the proper cases. - /* - if (ch == ' ') { - //System.out.println("yeehaa"); - - for(int i = offset - 1; i >= 0; i--) { - if (lineText.charAt(i) == ' ') { - wordStart = i; - } else { - break; - } - } - for(int i = offset; i < lineText.length(); i++) { - if (lineText.charAt(i) == ' ') { - wordEnd = i + 1; - } else { - break; - } - } - - } else { - */ - - // If the user clicked on a non-letter char, - // we select the surrounding non-letters - boolean selectNoLetter = !isWordCharacter(ch,noWordSep); - - for(int i = offset - 1; i >= 0; i--) { - ch = lineText.charAt(i); - if (selectNoLetter ^ !isWordCharacter(ch,noWordSep)) { - wordStart = i + 1; - break; - } - } - - for(int i = offset; i < lineText.length(); i++) { - ch = lineText.charAt(i); - if(selectNoLetter ^ !isWordCharacter(ch,noWordSep)) { - wordEnd = i; - break; - } - } - //} - int lineStart = getLineStartOffset(line); - - newSelectionStart = lineStart + wordStart; - newSelectionEnd = lineStart + wordEnd; - } - - - /** - * Returns the selected text, or null if no selection is active. - */ - public final String getSelectedText() - { - if(selectionStart == selectionEnd) - return null; - - if(rectSelect) - { - // Return each row of the selection on a new line - - Element map = document.getDefaultRootElement(); - - int start = selectionStart - map.getElement(selectionStartLine) - .getStartOffset(); - int end = selectionEnd - map.getElement(selectionEndLine) - .getStartOffset(); - - // Certain rectangles satisfy this condition... - if(end < start) - { - int tmp = end; - end = start; - start = tmp; - } - - StringBuffer buf = new StringBuffer(); - Segment seg = new Segment(); - - for(int i = selectionStartLine; i <= selectionEndLine; i++) - { - Element lineElement = map.getElement(i); - int lineStart = lineElement.getStartOffset(); - int lineEnd = lineElement.getEndOffset() - 1; - int lineLen = lineEnd - lineStart; - - lineStart = Math.min(lineStart + start,lineEnd); - lineLen = Math.min(end - start,lineEnd - lineStart); - - getText(lineStart,lineLen,seg); - buf.append(seg.array,seg.offset,seg.count); - - if(i != selectionEndLine) - buf.append('\n'); - } - - return buf.toString(); - } - else - { - return getText(selectionStart, - selectionEnd - selectionStart); - } - } - - /** - * Replaces the selection with the specified text. - * @param selectedText The replacement text for the selection - */ - public void setSelectedText(String selectedText) - { - if(!editable) - { - throw new InternalError("Text component" - + " read only"); - } - - document.beginCompoundEdit(); - - try - { - if(rectSelect) - { - Element map = document.getDefaultRootElement(); - - int start = selectionStart - map.getElement(selectionStartLine) - .getStartOffset(); - int end = selectionEnd - map.getElement(selectionEndLine) - .getStartOffset(); - - // Certain rectangles satisfy this condition... - if(end < start) - { - int tmp = end; - end = start; - start = tmp; - } - - int lastNewline = 0; - int currNewline = 0; - - for(int i = selectionStartLine; i <= selectionEndLine; i++) - { - Element lineElement = map.getElement(i); - int lineStart = lineElement.getStartOffset(); - int lineEnd = lineElement.getEndOffset() - 1; - int rectStart = Math.min(lineEnd,lineStart + start); - - document.remove(rectStart,Math.min(lineEnd - rectStart, - end - start)); - - if(selectedText == null) - continue; - - currNewline = selectedText.indexOf('\n',lastNewline); - if(currNewline == -1) - currNewline = selectedText.length(); - - document.insertString(rectStart,selectedText - .substring(lastNewline,currNewline),null); - - lastNewline = Math.min(selectedText.length(), - currNewline + 1); - } - - if(selectedText != null && - currNewline != selectedText.length()) - { - int offset = map.getElement(selectionEndLine) - .getEndOffset() - 1; - document.insertString(offset,"\n",null); - document.insertString(offset + 1,selectedText - .substring(currNewline + 1),null); - } - } - else - { - document.remove(selectionStart, - selectionEnd - selectionStart); - if(selectedText != null) - { - document.insertString(selectionStart, - selectedText,null); - } - } - } - catch(BadLocationException bl) - { - bl.printStackTrace(); - throw new InternalError("Cannot replace" - + " selection"); - } - // No matter what happends... stops us from leaving document - // in a bad state - finally - { - document.endCompoundEdit(); - } - - setCaretPosition(selectionEnd); - } - - /** - * Returns true if this text area is editable, false otherwise. - */ - public final boolean isEditable() - { - return editable; - } - - /** - * Sets if this component is editable. - * @param editable True if this text area should be editable, - * false otherwise - */ - public final void setEditable(boolean editable) - { - this.editable = editable; - } - - /** - * Returns the right click popup menu. - */ - public final JPopupMenu getRightClickPopup() - { - return popup; - } - - /** - * Sets the right click popup menu. - * @param popup The popup - */ - //public final void setRightClickPopup(EditPopupMenu popup) - public final void setRightClickPopup(JPopupMenu popup) - { - this.popup = popup; - } - - - /** - * Returns the `magic' caret position. This can be used to preserve - * the column position when moving up and down lines. - */ - public final int getMagicCaretPosition() - { - return magicCaret; - } - - /** - * Sets the `magic' caret position. This can be used to preserve - * the column position when moving up and down lines. - * @param magicCaret The magic caret position - */ - public final void setMagicCaretPosition(int magicCaret) - { - this.magicCaret = magicCaret; - } - - /** - * Similar to setSelectedText(), but overstrikes the - * appropriate number of characters if overwrite mode is enabled. - * @param str The string - * @see #setSelectedText(String) - * @see #isOverwriteEnabled() - */ - public void overwriteSetSelectedText(String str) - { - // Don't overstrike if there is a selection - if(!overwrite || selectionStart != selectionEnd) - { - setSelectedText(str); - return; - } - - // Don't overstrike if we're on the end of - // the line - int caret = getCaretPosition(); - int caretLineEnd = getLineStopOffset(getCaretLine()); - if(caretLineEnd - caret <= str.length()) - { - setSelectedText(str); - return; - } - - document.beginCompoundEdit(); - - try - { - document.remove(caret,str.length()); - document.insertString(caret,str,null); - } - catch(BadLocationException bl) - { - bl.printStackTrace(); - } - finally - { - document.endCompoundEdit(); - } - } - - /** - * Returns true if overwrite mode is enabled, false otherwise. - */ - public final boolean isOverwriteEnabled() - { - return overwrite; - } - - /** - * Sets if overwrite mode should be enabled. - * @param overwrite True if overwrite mode should be enabled, - * false otherwise. - */ - public final void setOverwriteEnabled(boolean overwrite) - { - this.overwrite = overwrite; - painter.invalidateSelectedLines(); - } - - /** - * Returns true if the selection is rectangular, false otherwise. - */ - public final boolean isSelectionRectangular() - { - return rectSelect; - } - - /** - * Sets if the selection should be rectangular. - * @param rectSelect True if the selection should be rectangular, - * false otherwise. - */ - public final void setSelectionRectangular(boolean rectSelect) - { - this.rectSelect = rectSelect; - painter.invalidateSelectedLines(); - } - - /** - * Returns the position of the highlighted bracket (the bracket - * matching the one before the caret) - */ - public final int getBracketPosition() - { - return bracketPosition; - } - - /** - * Returns the line of the highlighted bracket (the bracket - * matching the one before the caret) - */ - public final int getBracketLine() - { - return bracketLine; - } - - /** - * Adds a caret change listener to this text area. - * @param listener The listener - */ - public final void addCaretListener(CaretListener listener) - { - eventListenerList.add(CaretListener.class,listener); - } - - /** - * Removes a caret change listener from this text area. - * @param listener The listener - */ - public final void removeCaretListener(CaretListener listener) - { - eventListenerList.remove(CaretListener.class,listener); - } - - /** - * Deletes the selected text from the text area and places it - * into the clipboard. - */ - public void cut() - { - if(editable) - { - copy(); - setSelectedText(""); - } - } - - /** - * Places the selected text into the clipboard. - */ - public void copy() - { - if(selectionStart != selectionEnd) - { - Clipboard clipboard = getToolkit().getSystemClipboard(); - - String selection = getSelectedText(); - - int repeatCount = inputHandler.getRepeatCount(); - StringBuffer buf = new StringBuffer(); - for(int i = 0; i < repeatCount; i++) - buf.append(selection); - - Transferable t = new StringSelection(buf.toString()); - clipboard.setContents(t, null); - - Clipboard unixclipboard = getToolkit().getSystemSelection(); - if (unixclipboard != null) unixclipboard.setContents(t, null); - } - } - - /** - * Inserts the clipboard contents into the text. - */ - public void paste() { - if (editable) { - Clipboard clipboard = getToolkit().getSystemClipboard(); - try { - // The MacOS MRJ doesn't convert \r to \n, so do it here - String selection = ((String)clipboard.getContents(this).getTransferData(DataFlavor.stringFlavor)).replace('\r','\n'); - - // particularly on macosx when pasting from safari, - // replace unicode x00A0 (non-breaking space) - // with just a plain space. [fry 030929] - selection = selection.replace('\u00A0', ' '); - - int repeatCount = inputHandler.getRepeatCount(); - StringBuffer buf = new StringBuffer(); - for (int i = 0; i < repeatCount; i++) - buf.append(selection); - selection = buf.toString(); - setSelectedText(selection); - - } catch(Exception e) { - getToolkit().beep(); - System.err.println("Clipboard does not contain a string"); - } - } - } - - /** - * Called by the AWT when this component is removed from it's parent. - * This stops clears the currently focused component. - */ - public void removeNotify() - { - super.removeNotify(); - if(focusedComponent == this) - focusedComponent = null; - } - - /** - * Forwards key events directly to the input handler. - * This is slightly faster than using a KeyListener - * because some Swing overhead is avoided. - */ - public EditorListener editorListener; - - /** - * The component that tracks the current line number. - */ - public EditorLineStatus editorLineStatus; - - - public void processKeyEvent(KeyEvent evt) { - // this had to be added in Processing 007X, because the menu key - // events weren't making it up to the frame. - super.processKeyEvent(evt); - - //System.out.println("jedittextarea: " + evt); - //System.out.println(); - if (inputHandler == null) return; - - switch(evt.getID()) { - case KeyEvent.KEY_TYPED: - if ((editorListener == null) || !editorListener.keyTyped(evt)) { - inputHandler.keyTyped(evt); - } - break; - case KeyEvent.KEY_PRESSED: - if ((editorListener == null) || !editorListener.keyPressed(evt)) { - inputHandler.keyPressed(evt); - } - break; - case KeyEvent.KEY_RELEASED: - inputHandler.keyReleased(evt); - break; - } - } - - // protected members - protected static String LEFT = "left"; - protected static String CENTER = "center"; - protected static String RIGHT = "right"; - protected static String BOTTOM = "bottom"; - - protected static JEditTextArea focusedComponent; - protected static Timer caretTimer; - - protected TextAreaPainter painter; - protected TextAreaLineNumbers editorLineNumbers; - - //protected EditPopupMenu popup; - protected JPopupMenu popup; - - protected EventListenerList eventListenerList; - protected MutableCaretEvent caretEvent; - - protected boolean caretBlinks; - protected boolean caretVisible; - protected boolean blink; - - protected boolean editable; - - protected int firstLine; - protected int visibleLines; - protected int electricScroll; - - protected int horizontalOffset; - - protected JScrollBar vertical; - protected JScrollBar horizontal; - protected boolean scrollBarsInitialized; - - protected InputHandler inputHandler; - protected SyntaxDocument document; - protected DocumentHandler documentHandler; - - protected Segment lineSegment; - - protected int selectionStart; - protected int selectionStartLine; - protected int selectionEnd; - protected int selectionEndLine; - protected boolean biasLeft; - - protected int newSelectionStart; // hack to get around lack of multiple returns in Java - protected int newSelectionEnd; - - protected boolean selectWord; - protected boolean selectLine; - protected int selectionAncorStart; - protected int selectionAncorEnd; - - protected int bracketPosition; - protected int bracketLine; - - protected int magicCaret; - protected boolean overwrite; - protected boolean rectSelect; - - - protected void fireCaretEvent() - { - Object[] listeners = eventListenerList.getListenerList(); - for(int i = listeners.length - 2; i >= 0; i--) - { - if(listeners[i] == CaretListener.class) - { - ((CaretListener)listeners[i+1]).caretUpdate(caretEvent); - } - } - } - - protected void updateBracketHighlight(int newCaretPosition) - { - if(newCaretPosition == 0) - { - bracketPosition = bracketLine = -1; - return; - } - - try - { - int offset = TextUtilities.findMatchingBracket( - document,newCaretPosition - 1); - if(offset != -1) - { - bracketLine = getLineOfOffset(offset); - bracketPosition = offset - getLineStartOffset(bracketLine); - return; - } - } - catch(BadLocationException bl) - { - bl.printStackTrace(); - } - - bracketLine = bracketPosition = -1; - } - - protected void documentChanged(DocumentEvent evt) - { - DocumentEvent.ElementChange ch = - evt.getChange(document.getDefaultRootElement()); - - int count; - if(ch == null) - count = 0; - else - count = ch.getChildrenAdded().length - - ch.getChildrenRemoved().length; - - int line = getLineOfOffset(evt.getOffset()); - if(count == 0) - { - painter.invalidateLine(line); - } - // do magic stuff - else if(line < firstLine) - { - setFirstLine(firstLine + count); - } - // end of magic stuff - else - { - painter.invalidateLineRange(line,firstLine + visibleLines); - updateScrollBars(); - } - } - - class ScrollLayout implements LayoutManager - { - //final int LEFT_EXTRA = 5; - - public void addLayoutComponent(String name, Component comp) - { - if(name.equals(LEFT)) - left = comp; - else if(name.equals(CENTER)) - center = comp; - else if(name.equals(RIGHT)) - right = comp; - else if(name.equals(BOTTOM)) - bottom = comp; - else if(name.equals(LEFT_OF_SCROLLBAR)) - leftOfScrollBar.addElement(comp); - } - - public void removeLayoutComponent(Component comp) - { - if(left == comp) - left = null; - if(center == comp) - center = null; - if(right == comp) - right = null; - if(bottom == comp) - bottom = null; - else - leftOfScrollBar.removeElement(comp); - } - - public Dimension preferredLayoutSize(Container parent) - { - Dimension dim = new Dimension(); - Insets insets = getInsets(); - dim.width = insets.left + insets.right; - dim.height = insets.top + insets.bottom; - - Dimension centerPref = center.getPreferredSize(); - dim.width += centerPref.width; - dim.height += centerPref.height; - Dimension leftPref = left.getPreferredSize(); - dim.width += leftPref.width; - Dimension rightPref = right.getPreferredSize(); - dim.width += rightPref.width; - Dimension bottomPref = bottom.getPreferredSize(); - dim.height += bottomPref.height; - - return dim; - } - - public Dimension minimumLayoutSize(Container parent) - { - Dimension dim = new Dimension(); - Insets insets = getInsets(); - dim.width = insets.left + insets.right; - dim.height = insets.top + insets.bottom; - - Dimension centerPref = center.getMinimumSize(); - dim.width += centerPref.width; - dim.height += centerPref.height; - Dimension leftPref = left.getMinimumSize(); - dim.width += leftPref.width; - Dimension rightPref = right.getMinimumSize(); - dim.width += rightPref.width; - Dimension bottomPref = bottom.getMinimumSize(); - dim.height += bottomPref.height; - - dim.height += 5; - - return dim; - } - - public void layoutContainer(Container parent) - { - Dimension size = parent.getSize(); - Insets insets = parent.getInsets(); - int itop = insets.top; - int ileft = insets.left; - int ibottom = insets.bottom; - int iright = insets.right; - - int leftWidth = left.getSize().width; - int rightWidth = right.getPreferredSize().width; - int bottomHeight = bottom.getPreferredSize().height; - int centerWidth = size.width - leftWidth - rightWidth - ileft - iright; - int centerHeight = size.height - bottomHeight - itop - ibottom; - - left.setBounds(ileft, - itop, - leftWidth, - centerHeight); - - ileft += leftWidth; - - center.setBounds(ileft, // + LEFT_EXTRA, - itop, - centerWidth, // - LEFT_EXTRA, - centerHeight); - - right.setBounds(ileft + centerWidth, - itop, - rightWidth, - centerHeight); - - // Lay out all status components, in order - Enumeration status = leftOfScrollBar.elements(); - while (status.hasMoreElements()) { - Component comp = (Component)status.nextElement(); - Dimension dim = comp.getPreferredSize(); - comp.setBounds(ileft, - itop + centerHeight, - dim.width, - bottomHeight); - ileft += dim.width; - } - - bottom.setBounds(ileft, - itop + centerHeight, - size.width - rightWidth - ileft - iright, - bottomHeight); - } - - // private members - private Component left; - private Component center; - private Component right; - private Component bottom; - private Vector leftOfScrollBar = new Vector(); - } - - static class CaretBlinker implements ActionListener - { - public void actionPerformed(ActionEvent evt) - { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - if(focusedComponent != null - && focusedComponent.hasFocus()) - focusedComponent.blinkCaret(); - } - }); - } - } - - class MutableCaretEvent extends CaretEvent - { - MutableCaretEvent() - { - super(JEditTextArea.this); - } - - public int getDot() - { - return getCaretPosition(); - } - - public int getMark() - { - return getMarkPosition(); - } - } - -/* -#ifdef JDK14 - class WheelHandler implements MouseWheelListener { - - public void mouseWheelMoved(MouseWheelEvent e) { - if (!scrollBarsInitialized) return; - - int amt = e.getWheelRotation(); - //System.out.println(amt); - vertical.setValue(vertical.getValue() + amt * wheelMultiplier); - } - } -#endif -*/ - - class AdjustHandler implements AdjustmentListener - { - public void adjustmentValueChanged(final AdjustmentEvent evt) - { - if(!scrollBarsInitialized) - return; - - // If this is not done, mousePressed events accumilate - // and the result is that scrolling doesn't stop after - // the mouse is released - SwingUtilities.invokeLater(new Runnable() { - public void run() - { - if(evt.getAdjustable() == vertical) - setFirstLine(vertical.getValue()); - else - setHorizontalOffset(-horizontal.getValue()); - } - }); - } - } - - class ComponentHandler extends ComponentAdapter - { - public void componentResized(ComponentEvent evt) - { - recalculateVisibleLines(); - scrollBarsInitialized = true; - } - } - - class DocumentHandler implements DocumentListener - { - public void insertUpdate(DocumentEvent evt) - { - documentChanged(evt); - - int offset = evt.getOffset(); - int length = evt.getLength(); - - int newStart; - int newEnd; - - if (selectionStart > offset || - (selectionStart == selectionEnd && selectionStart == offset)) - newStart = selectionStart + length; - else - newStart = selectionStart; - - if(selectionEnd >= offset) - newEnd = selectionEnd + length; - else - newEnd = selectionEnd; - - select(newStart,newEnd); - } - - public void removeUpdate(DocumentEvent evt) - { - documentChanged(evt); - - int offset = evt.getOffset(); - int length = evt.getLength(); - - int newStart; - int newEnd; - - if(selectionStart > offset) - { - if(selectionStart > offset + length) - newStart = selectionStart - length; - else - newStart = offset; - } - else - newStart = selectionStart; - - if(selectionEnd > offset) - { - if(selectionEnd > offset + length) - newEnd = selectionEnd - length; - else - newEnd = offset; - } - else - newEnd = selectionEnd; - - select(newStart,newEnd); - } - - public void changedUpdate(DocumentEvent evt) - { - } - } - - class DragHandler implements MouseMotionListener - { - public void mouseDragged(MouseEvent evt) - { - if (popup != null && popup.isVisible()) return; - - if ( !selectWord && !selectLine ) { - setSelectionRectangular((evt.getModifiers() - & InputEvent.CTRL_MASK) != 0); - select(getMarkPosition(),xyToOffset(evt.getX(),evt.getY())); - } else { - int line = yToLine(evt.getY()); - if ( selectWord ) { - setNewSelectionWord( line, xToOffset(line,evt.getX()) ); - } else { - newSelectionStart = getLineStartOffset(line); - newSelectionEnd = getSafeLineStopOffset(line); - } - if ( newSelectionStart < selectionAncorStart ) { - select(newSelectionStart,selectionAncorEnd); - } else if ( newSelectionEnd > selectionAncorEnd ) { - select(selectionAncorStart,newSelectionEnd); - } else { - select(newSelectionStart,newSelectionEnd); - } - } - } - - final Cursor normalCursor = new Cursor(Cursor.DEFAULT_CURSOR); - final Cursor handCursor = new Cursor(Cursor.HAND_CURSOR); - - public void mouseMoved(MouseEvent evt) { - int line = yToLine(evt.getY()); - int offset = xToOffset(line, evt.getX()); - boolean wantHandCursor = checkClickedURL(getLineText(line), offset) != null; - JComponent src = (JComponent) evt.getSource(); - if (wantHandCursor) - src.setCursor(handCursor); - else - src.setCursor(normalCursor); - } - } - - class FocusHandler implements FocusListener - { - public void focusGained(FocusEvent evt) - { - //System.out.println("JEditTextArea: focusGained"); - setCaretVisible(true); - focusedComponent = JEditTextArea.this; - } - - public void focusLost(FocusEvent evt) - { - //System.out.println("JEditTextArea: focusLost"); - setCaretVisible(false); - focusedComponent = null; - } - } - - public String checkClickedURL(String line, int offset) { - String[] parse = SyntaxUtilities.parseCommentUrls(line); - if (parse==null) - return null; - int start = parse[0].length(); - int stop = start + parse[1].length(); - if (offsetstop) - return null; - return parse[1]; - } - - class MouseHandler extends MouseAdapter - { - public void mousePressed(MouseEvent evt) - { - requestFocus(); - - // Focus events not fired sometimes? - setCaretVisible(true); - focusedComponent = JEditTextArea.this; - - // isPopupTrigger wasn't working for danh on windows - boolean trigger = (evt.getModifiers() & InputEvent.BUTTON3_MASK) != 0; - // but it's required for macosx, since control-click does - // the same thing as a right-mouse click - if (!trigger && evt.isPopupTrigger()) trigger = true; - - if (trigger && (popup != null)) { - popup.show(painter,evt.getX(),evt.getY()); - return; - } - - // on Linux, middle button pastes selected text - if ((evt.getModifiers() & InputEvent.BUTTON2_MASK) != 0) { - Clipboard unixclipboard = getToolkit().getSystemSelection(); - if (unixclipboard != null) { - Transferable t = unixclipboard.getContents(null); - if (t != null && t.isDataFlavorSupported(DataFlavor.stringFlavor)) { - try { - String s = (String)t.getTransferData(DataFlavor.stringFlavor); - s = s.replace('\u00A0', ' '); - if (editable) setSelectedText(s); - } catch (Exception e) { - System.err.println(e); - e.printStackTrace(); - } - } - return; - } - } - - int line = yToLine(evt.getY()); - int offset = xToOffset(line,evt.getX()); - int dot = getLineStartOffset(line) + offset; - - selectLine = false; - selectWord = false; - - switch(evt.getClickCount()) { - - case 1: - doSingleClick(evt,line,offset,dot); - break; - - case 2: - // It uses the bracket matching stuff, so - // it can throw a BLE - try { - doDoubleClick(evt,line,offset,dot); - } catch(BadLocationException bl) { - bl.printStackTrace(); - } - break; - - case 3: - doTripleClick(evt,line,offset,dot); - break; - } - } - - - private void doSingleClick(MouseEvent evt, int line, - int offset, int dot) { - // Check for click on urls - String clickedURL = checkClickedURL(getLineText(line), offset); - if (clickedURL != null) { - Base.openURL(clickedURL); - return; - } - - if ((evt.getModifiers() & InputEvent.SHIFT_MASK) != 0) { - rectSelect = (evt.getModifiers() & InputEvent.CTRL_MASK) != 0; - select(getMarkPosition(),dot); - } else { - setCaretPosition(dot); - } - } - - - private void doDoubleClick(MouseEvent evt, int line, - int offset, int dot) throws BadLocationException - { - // Ignore empty lines - if (getLineLength(line) == 0) - return; - - try { - int bracket = TextUtilities.findMatchingBracket(document, - Math.max(0,dot - 1)); - if (bracket != -1) { - int mark = getMarkPosition(); - // Hack - if (bracket > mark) { - bracket++; - mark--; - } - select(mark,bracket); - return; - } - } catch(BadLocationException bl) { - bl.printStackTrace(); - } - - setNewSelectionWord( line, offset ); - select(newSelectionStart,newSelectionEnd); - selectWord = true; - selectionAncorStart = selectionStart; - selectionAncorEnd = selectionEnd; - - /* - String lineText = getLineText(line); - String noWordSep = (String)document.getProperty("noWordSep"); - int wordStart = TextUtilities.findWordStart(lineText,offset,noWordSep); - int wordEnd = TextUtilities.findWordEnd(lineText,offset,noWordSep); - - int lineStart = getLineStartOffset(line); - select(lineStart + wordStart,lineStart + wordEnd); - */ - } - - private void doTripleClick(MouseEvent evt, int line, - int offset, int dot) - { - selectLine = true; - select(getLineStartOffset(line),getSafeLineStopOffset(line)); - selectionAncorStart = selectionStart; - selectionAncorEnd = selectionEnd; - } - } - - class CaretUndo extends AbstractUndoableEdit - { - private int start; - private int end; - - CaretUndo(int start, int end) - { - this.start = start; - this.end = end; - } - - public boolean isSignificant() - { - return false; - } - - public String getPresentationName() - { - return "caret move"; - } - - public void undo() throws CannotUndoException - { - super.undo(); - - select(start,end); - } - - public void redo() throws CannotRedoException - { - super.redo(); - - select(start,end); - } - - public boolean addEdit(UndoableEdit edit) - { - if(edit instanceof CaretUndo) - { - CaretUndo cedit = (CaretUndo)edit; - start = cedit.start; - end = cedit.end; - cedit.die(); - - return true; - } - else - return false; - } - } - - static - { - caretTimer = new Timer(500,new CaretBlinker()); - caretTimer.setInitialDelay(500); - caretTimer.start(); - } - - public void setDisplayLineNumbers(boolean displayLineNumbers) { - editorLineNumbers.setDisplayLineNumbers(displayLineNumbers); - } -} diff --git a/app/src/processing/app/syntax/KeywordMap.java b/app/src/processing/app/syntax/KeywordMap.java deleted file mode 100644 index 27d225f8c..000000000 --- a/app/src/processing/app/syntax/KeywordMap.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * KeywordMap.java - Fast keyword->id map - * Copyright (C) 1998, 1999 Slava Pestov - * Copyright (C) 1999 Mike Dillon - * - * You may use and modify this package for any purpose. Redistribution is - * permitted, in both source and binary form, provided that this notice - * remains intact in all source distributions of this package. - */ - -package processing.app.syntax; - -import javax.swing.text.Segment; - -/** - * A KeywordMap is similar to a hashtable in that it maps keys - * to values. However, the `keys' are Swing segments. This allows lookups of - * text substrings without the overhead of creating a new string object. - *

- * This class is used by CTokenMarker to map keywords to ids. - * - * @author Slava Pestov, Mike Dillon - */ -public class KeywordMap -{ - /** - * Creates a new KeywordMap. - * @param ignoreCase True if keys are case insensitive - */ - public KeywordMap(boolean ignoreCase) - { - this(ignoreCase, 52); - this.ignoreCase = ignoreCase; - } - - /** - * Creates a new KeywordMap. - * @param ignoreCase True if the keys are case insensitive - * @param mapLength The number of `buckets' to create. - * A value of 52 will give good performance for most maps. - */ - public KeywordMap(boolean ignoreCase, int mapLength) - { - this.mapLength = mapLength; - this.ignoreCase = ignoreCase; - map = new Keyword[mapLength]; - } - - /** - * Looks up a key. - * @param text The text segment - * @param offset The offset of the substring within the text segment - * @param length The length of the substring - */ - public byte lookup(Segment text, int offset, int length) - { - if(length == 0) - return Token.NULL; - Keyword k = map[getSegmentMapKey(text, offset, length)]; - while(k != null) - { - if(length != k.keyword.length) - { - k = k.next; - continue; - } - if(SyntaxUtilities.regionMatches(ignoreCase,text,offset, - k.keyword)) - return k.id; - k = k.next; - } - return Token.NULL; - } - - /** - * Adds a key-value mapping. - * @param keyword The key - * @param id The value - */ - public void add(String keyword, byte id) - { - int key = getStringMapKey(keyword); - map[key] = new Keyword(keyword.toCharArray(),id,map[key]); - } - - /** - * Returns true if the keyword map is set to be case insensitive, - * false otherwise. - */ - public boolean getIgnoreCase() - { - return ignoreCase; - } - - /** - * Sets if the keyword map should be case insensitive. - * @param ignoreCase True if the keyword map should be case - * insensitive, false otherwise - */ - public void setIgnoreCase(boolean ignoreCase) - { - this.ignoreCase = ignoreCase; - } - - // protected members - protected int mapLength; - - protected int getStringMapKey(String s) - { - return (Character.toUpperCase(s.charAt(0)) + - Character.toUpperCase(s.charAt(s.length()-1))) - % mapLength; - } - - protected int getSegmentMapKey(Segment s, int off, int len) - { - return (Character.toUpperCase(s.array[off]) + - Character.toUpperCase(s.array[off + len - 1])) - % mapLength; - } - - // private members - class Keyword - { - public Keyword(char[] keyword, byte id, Keyword next) - { - this.keyword = keyword; - this.id = id; - this.next = next; - } - - public char[] keyword; - public byte id; - public Keyword next; - } - - private Keyword[] map; - private boolean ignoreCase; -} diff --git a/app/src/processing/app/syntax/PdeTextAreaDefaults.java b/app/src/processing/app/syntax/PdeTextAreaDefaults.java deleted file mode 100644 index 391416f5c..000000000 --- a/app/src/processing/app/syntax/PdeTextAreaDefaults.java +++ /dev/null @@ -1,211 +0,0 @@ -/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ - -/* - PdeTextAreaDefaults - grabs font/color settings for the editor - Part of the Processing project - http://processing.org - - Copyright (c) 2004-06 Ben Fry and Casey Reas - Copyright (c) 2001-03 Massachusetts Institute of Technology - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -package processing.app.syntax; - -import processing.app.*; -import processing.app.helpers.OSUtils; - - -public class PdeTextAreaDefaults extends TextAreaDefaults { - - public PdeTextAreaDefaults() { - - inputHandler = new DefaultInputHandler(); - //inputHandler.addDefaultKeyBindings(); // 0122 - - // use option on mac for text edit controls that are ctrl on windows/linux - String mod = OSUtils.isMacOS() ? "A" : "C"; - - // right now, ctrl-up/down is select up/down, but mod should be - // used instead, because the mac expects it to be option(alt) - - inputHandler.addKeyBinding("BACK_SPACE", InputHandler.BACKSPACE); - // for 0122, shift-backspace is delete, for 0176, it's now a preference, - // to prevent holy warriors from attacking me for it. - if (PreferencesData.getBoolean("editor.keys.shift_backspace_is_delete")) { - inputHandler.addKeyBinding("S+BACK_SPACE", InputHandler.DELETE); - } else { - inputHandler.addKeyBinding("S+BACK_SPACE", InputHandler.BACKSPACE); - } - - inputHandler.addKeyBinding("DELETE", InputHandler.DELETE); - inputHandler.addKeyBinding("S+DELETE", InputHandler.DELETE); - - // the following two were changing for 0122 for better mac/pc compatability - inputHandler.addKeyBinding(mod+"+BACK_SPACE", InputHandler.BACKSPACE_WORD); - inputHandler.addKeyBinding(mod+"+DELETE", InputHandler.DELETE_WORD); - - // handled by listener, don't bother here - //inputHandler.addKeyBinding("ENTER", InputHandler.INSERT_BREAK); - //inputHandler.addKeyBinding("TAB", InputHandler.INSERT_TAB); - - inputHandler.addKeyBinding("INSERT", InputHandler.OVERWRITE); - - // http://dev.processing.org/bugs/show_bug.cgi?id=162 - // added for 0176, though the bindings do not appear relevant for osx - if (PreferencesData.getBoolean("editor.keys.alternative_cut_copy_paste")) { - inputHandler.addKeyBinding("C+INSERT", InputHandler.CLIPBOARD_COPY); - inputHandler.addKeyBinding("S+INSERT", InputHandler.CLIPBOARD_PASTE); - inputHandler.addKeyBinding("S+DELETE", InputHandler.CLIPBOARD_CUT); - } - - // disabling for 0122, not sure what this does - //inputHandler.addKeyBinding("C+\\", InputHandler.TOGGLE_RECT); - - // for 0122, these have been changed for better compatibility - // HOME and END now mean the beginning/end of the document - // for 0176 changed this to a preference so that the Mac OS X people - // can get the "normal" behavior as well if they prefer. - if (PreferencesData.getBoolean("editor.keys.home_and_end_travel_far")) { - inputHandler.addKeyBinding("HOME", InputHandler.DOCUMENT_HOME); - inputHandler.addKeyBinding("END", InputHandler.DOCUMENT_END); - inputHandler.addKeyBinding("S+HOME", InputHandler.SELECT_DOC_HOME); - inputHandler.addKeyBinding("S+END", InputHandler.SELECT_DOC_END); - } else { - // for 0123 added the proper windows defaults - inputHandler.addKeyBinding("HOME", InputHandler.HOME); - inputHandler.addKeyBinding("END", InputHandler.END); - inputHandler.addKeyBinding("S+HOME", InputHandler.SELECT_HOME); - inputHandler.addKeyBinding("S+END", InputHandler.SELECT_END); - inputHandler.addKeyBinding("C+HOME", InputHandler.DOCUMENT_HOME); - inputHandler.addKeyBinding("C+END", InputHandler.DOCUMENT_END); - inputHandler.addKeyBinding("CS+HOME", InputHandler.SELECT_DOC_HOME); - inputHandler.addKeyBinding("CS+END", InputHandler.SELECT_DOC_END); - } - - if (OSUtils.isMacOS()) { - inputHandler.addKeyBinding("M+LEFT", InputHandler.HOME); - inputHandler.addKeyBinding("M+RIGHT", InputHandler.END); - inputHandler.addKeyBinding("MS+LEFT", InputHandler.SELECT_HOME); // 0122 - inputHandler.addKeyBinding("MS+RIGHT", InputHandler.SELECT_END); // 0122 - } else { - inputHandler.addKeyBinding("C+LEFT", InputHandler.HOME); // 0122 - inputHandler.addKeyBinding("C+RIGHT", InputHandler.END); // 0122 - inputHandler.addKeyBinding("CS+HOME", InputHandler.SELECT_HOME); // 0122 - inputHandler.addKeyBinding("CS+END", InputHandler.SELECT_END); // 0122 - } - - inputHandler.addKeyBinding("PAGE_UP", InputHandler.PREV_PAGE); - inputHandler.addKeyBinding("PAGE_DOWN", InputHandler.NEXT_PAGE); - inputHandler.addKeyBinding("S+PAGE_UP", InputHandler.SELECT_PREV_PAGE); - inputHandler.addKeyBinding("S+PAGE_DOWN", InputHandler.SELECT_NEXT_PAGE); - - inputHandler.addKeyBinding("LEFT", InputHandler.PREV_CHAR); - inputHandler.addKeyBinding("S+LEFT", InputHandler.SELECT_PREV_CHAR); - inputHandler.addKeyBinding(mod + "+LEFT", InputHandler.PREV_WORD); - inputHandler.addKeyBinding(mod + "S+LEFT", InputHandler.SELECT_PREV_WORD); - inputHandler.addKeyBinding("RIGHT", InputHandler.NEXT_CHAR); - inputHandler.addKeyBinding("S+RIGHT", InputHandler.SELECT_NEXT_CHAR); - inputHandler.addKeyBinding(mod + "+RIGHT", InputHandler.NEXT_WORD); - inputHandler.addKeyBinding(mod + "S+RIGHT", InputHandler.SELECT_NEXT_WORD); - - inputHandler.addKeyBinding("UP", InputHandler.PREV_LINE); - inputHandler.addKeyBinding(mod + "+UP", InputHandler.PREV_LINE); // p5 - inputHandler.addKeyBinding("S+UP", InputHandler.SELECT_PREV_LINE); - inputHandler.addKeyBinding("DOWN", InputHandler.NEXT_LINE); - inputHandler.addKeyBinding(mod + "+DOWN", InputHandler.NEXT_LINE); // p5 - inputHandler.addKeyBinding("S+DOWN", InputHandler.SELECT_NEXT_LINE); - - inputHandler.addKeyBinding("MS+UP", InputHandler.SELECT_DOC_HOME); - inputHandler.addKeyBinding("CS+UP", InputHandler.SELECT_DOC_HOME); - inputHandler.addKeyBinding("MS+DOWN", InputHandler.SELECT_DOC_END); - inputHandler.addKeyBinding("CS+DOWN", InputHandler.SELECT_DOC_END); - - inputHandler.addKeyBinding(mod + "+ENTER", InputHandler.REPEAT); - - document = new SyntaxDocument(); - editable = true; - electricScroll = 3; - - cols = 80; - rows = 15; - - - // moved from SyntaxUtilities - //DEFAULTS.styles = SyntaxUtilities.getDefaultSyntaxStyles(); - - styles = new SyntaxStyle[Token.ID_COUNT]; - - // comments - styles[Token.COMMENT1] = Theme.getStyle("comment1"); - styles[Token.COMMENT2] = Theme.getStyle("comment2"); - - // abstract, final, private - styles[Token.KEYWORD1] = Theme.getStyle("keyword1"); - - // beginShape, point, line - styles[Token.KEYWORD2] = Theme.getStyle("keyword2"); - - // byte, char, short, color - styles[Token.KEYWORD3] = Theme.getStyle("keyword3"); - - // constants: null, true, this, RGB, TWO_PI - styles[Token.LITERAL1] = Theme.getStyle("literal1"); - - // p5 built in variables: mouseX, width, pixels - styles[Token.LITERAL2] = Theme.getStyle("literal2"); - - // ?? - styles[Token.LABEL] = Theme.getStyle("label"); - - // http://arduino.cc/ - styles[Token.URL] = Theme.getStyle("url"); - - // + - = / - styles[Token.OPERATOR] = Theme.getStyle("operator"); - - // area that's not in use by the text (replaced with tildes) - styles[Token.INVALID] = Theme.getStyle("invalid"); - - - // moved from TextAreaPainter - - font = PreferencesData.getFont("editor.font"); - - fgcolor = Theme.getColor("editor.fgcolor"); - bgcolor = Theme.getColor("editor.bgcolor"); - - caretVisible = true; - caretBlinks = PreferencesData.getBoolean("editor.caret.blink"); - caretColor = Theme.getColor("editor.caret.color"); - - selectionColor = Theme.getColor("editor.selection.color"); - - lineHighlight = - Theme.getBoolean("editor.linehighlight"); - lineHighlightColor = - Theme.getColor("editor.linehighlight.color"); - - bracketHighlight = - Theme.getBoolean("editor.brackethighlight"); - bracketHighlightColor = - Theme.getColor("editor.brackethighlight.color"); - - eolMarkers = Theme.getBoolean("editor.eolmarkers"); - eolMarkerColor = Theme.getColor("editor.eolmarkers.color"); - - paintInvalid = Theme.getBoolean("editor.invalid"); - } -} diff --git a/app/src/processing/app/syntax/SyntaxDocument.java b/app/src/processing/app/syntax/SyntaxDocument.java deleted file mode 100644 index 2a1c3103c..000000000 --- a/app/src/processing/app/syntax/SyntaxDocument.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * SyntaxDocument.java - Document that can be tokenized - * Copyright (C) 1999 Slava Pestov - * - * You may use and modify this package for any purpose. Redistribution is - * permitted, in both source and binary form, provided that this notice - * remains intact in all source distributions of this package. - */ - -package processing.app.syntax; - -import javax.swing.event.*; -import javax.swing.text.*; -import javax.swing.undo.UndoableEdit; - -/** - * A document implementation that can be tokenized by the syntax highlighting - * system. - * - * @author Slava Pestov - */ -public class SyntaxDocument extends PlainDocument -{ - /** - * Returns the token marker that is to be used to split lines - * of this document up into tokens. May return null if this - * document is not to be colorized. - */ - public TokenMarker getTokenMarker() - { - return tokenMarker; - } - - /** - * Sets the token marker that is to be used to split lines of - * this document up into tokens. May throw an exception if - * this is not supported for this type of document. - * @param tm The new token marker - */ - public void setTokenMarker(TokenMarker tm) - { - tokenMarker = tm; - if(tm == null) - return; - tokenMarker.insertLines(0,getDefaultRootElement() - .getElementCount()); - tokenizeLines(); - } - - /** - * Reparses the document, by passing all lines to the token - * marker. This should be called after the document is first - * loaded. - */ - public void tokenizeLines() - { - tokenizeLines(0,getDefaultRootElement().getElementCount()); - } - - /** - * Reparses the document, by passing the specified lines to the - * token marker. This should be called after a large quantity of - * text is first inserted. - * @param start The first line to parse - * @param len The number of lines, after the first one to parse - */ - public void tokenizeLines(int start, int len) - { - if(tokenMarker == null || !tokenMarker.supportsMultilineTokens()) - return; - - Segment lineSegment = new Segment(); - Element map = getDefaultRootElement(); - - len += start; - - try - { - for(int i = start; i < len; i++) - { - Element lineElement = map.getElement(i); - int lineStart = lineElement.getStartOffset(); - getText(lineStart,lineElement.getEndOffset() - - lineStart - 1,lineSegment); - tokenMarker.markTokens(lineSegment,i); - } - } - catch(BadLocationException bl) - { - bl.printStackTrace(); - } - } - - /** - * Starts a compound edit that can be undone in one operation. - * Subclasses that implement undo should override this method; - * this class has no undo functionality so this method is - * empty. - */ - public void beginCompoundEdit() {} - - /** - * Ends a compound edit that can be undone in one operation. - * Subclasses that implement undo should override this method; - * this class has no undo functionality so this method is - * empty. - */ - public void endCompoundEdit() {} - - /** - * Adds an undoable edit to this document's undo list. The edit - * should be ignored if something is currently being undone. - * @param edit The undoable edit - * - * @since jEdit 2.2pre1 - */ - public void addUndoableEdit(UndoableEdit edit) {} - - // protected members - protected TokenMarker tokenMarker; - - /** - * We overwrite this method to update the token marker - * state immediately so that any event listeners get a - * consistent token marker. - */ - protected void fireInsertUpdate(DocumentEvent evt) - { - if(tokenMarker != null) - { - DocumentEvent.ElementChange ch = evt.getChange( - getDefaultRootElement()); - if(ch != null) - { - tokenMarker.insertLines(ch.getIndex() + 1, - ch.getChildrenAdded().length - - ch.getChildrenRemoved().length); - } - } - - super.fireInsertUpdate(evt); - } - - /** - * We overwrite this method to update the token marker - * state immediately so that any event listeners get a - * consistent token marker. - */ - protected void fireRemoveUpdate(DocumentEvent evt) - { - if(tokenMarker != null) - { - DocumentEvent.ElementChange ch = evt.getChange( - getDefaultRootElement()); - if(ch != null) - { - tokenMarker.deleteLines(ch.getIndex() + 1, - ch.getChildrenRemoved().length - - ch.getChildrenAdded().length); - } - } - - super.fireRemoveUpdate(evt); - } -} diff --git a/app/src/processing/app/syntax/SyntaxStyle.java b/app/src/processing/app/syntax/SyntaxStyle.java deleted file mode 100644 index 23a7c71b0..000000000 --- a/app/src/processing/app/syntax/SyntaxStyle.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * SyntaxStyle.java - A simple text style class - * Copyright (C) 1999 Slava Pestov - * - * You may use and modify this package for any purpose. Redistribution is - * permitted, in both source and binary form, provided that this notice - * remains intact in all source distributions of this package. - */ - -package processing.app.syntax; - -import java.awt.*; -import java.awt.font.TextAttribute; -import java.util.Hashtable; -import java.util.Map; - -import javax.swing.JComponent; - - -/** - * A simple text style class. It can specify the color, italic flag, - * and bold flag of a run of text. - * @author Slava Pestov - */ -public class SyntaxStyle -{ - /** - * Creates a new SyntaxStyle. - * @param color The text color - * @param italic True if the text should be italics - * @param bold True if the text should be bold - */ - public SyntaxStyle(Color color, boolean italic, boolean bold, boolean underlined) - { - this.color = color; - this.italic = italic; - this.bold = bold; - this.underlined = underlined; - } - - /** - * Returns the color specified in this style. - */ - public Color getColor() - { - return color; - } - - /** - * Returns true if no font styles are enabled. - */ - public boolean isPlain() - { - return !(bold || italic || underlined); - } - - /** - * Returns true if italics is enabled for this style. - */ - public boolean isItalic() - { - return italic; - } - - /** - * Returns true if boldface is enabled for this style. - */ - public boolean isBold() - { - return bold; - } - - /** - * @return true if underline is enabled for this style. - */ - public boolean isUnderlined() { - return underlined; - } - - /** - * Returns the specified font, but with the style's bold, underline and - * italic flags applied. - */ - public Font getStyledFont(Font font) - { - if(font == null) - throw new NullPointerException("font param must not" - + " be null"); - if(font.equals(lastFont)) - return lastStyledFont; - lastFont = font; - - lastStyledFont = new Font(font.getFamily(), - (bold ? Font.BOLD : 0) - | (italic ? Font.ITALIC : 0), - font.getSize()); - if (underlined) { - Map attr = new Hashtable(); - attr.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON); - lastStyledFont = lastStyledFont.deriveFont(attr); - } - return lastStyledFont; - } - - /** - * Returns the font metrics for the styled font. - */ - public FontMetrics getFontMetrics(Font font, JComponent comp) - { - if(font == null) - throw new NullPointerException("font param must not" - + " be null"); - if(font.equals(lastFont) && fontMetrics != null) - return fontMetrics; - lastFont = font; - lastStyledFont = new Font(font.getFamily(), - (bold ? Font.BOLD : 0) - | (italic ? Font.ITALIC : 0), - font.getSize()); - if (underlined) { - Map attr = new Hashtable(); - attr.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON); - lastStyledFont = lastStyledFont.deriveFont(attr); - } - //fontMetrics = Toolkit.getDefaultToolkit().getFontMetrics(lastStyledFont); - fontMetrics = comp.getFontMetrics(lastStyledFont); - return fontMetrics; - } - - /** - * Sets the foreground color and font of the specified graphics - * context to that specified in this style. - * @param gfx The graphics context - * @param font The font to add the styles to - */ - public void setGraphicsFlags(Graphics gfx, Font font) - { - Font _font = getStyledFont(font); - gfx.setFont(_font); - gfx.setColor(color); - } - - /** - * Returns a string representation of this object. - */ - public String toString() - { - return getClass().getName() + "[color=" + color + - (italic ? ",italic" : "") + - (bold ? ",bold" : "") + - (underlined ? ",underlined" : "") + - "]"; - } - - // private members - private Color color; - private boolean italic; - private boolean bold; - private boolean underlined; - private Font lastFont; - private Font lastStyledFont; - private FontMetrics fontMetrics; -} diff --git a/app/src/processing/app/syntax/SyntaxUtilities.java b/app/src/processing/app/syntax/SyntaxUtilities.java deleted file mode 100644 index 6eef977a0..000000000 --- a/app/src/processing/app/syntax/SyntaxUtilities.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * SyntaxUtilities.java - Utility functions used by syntax colorizing - * Copyright (C) 1999 Slava Pestov - * - * You may use and modify this package for any purpose. Redistribution is - * permitted, in both source and binary form, provided that this notice - * remains intact in all source distributions of this package. - */ - -package processing.app.syntax; - -import javax.swing.text.*; -import java.awt.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - - -/** - * Class with several utility functions used by jEdit's syntax colorizing - * subsystem. - * - * @author Slava Pestov - */ -public class SyntaxUtilities -{ - /** - * Checks if a subregion of a Segment is equal to a - * string. - * @param ignoreCase True if case should be ignored, false otherwise - * @param text The segment - * @param offset The offset into the segment - * @param match The string to match - */ - public static boolean regionMatches(boolean ignoreCase, Segment text, - int offset, String match) - { - int length = offset + match.length(); - char[] textArray = text.array; - if(length > text.offset + text.count) - return false; - for(int i = offset, j = 0; i < length; i++, j++) - { - char c1 = textArray[i]; - char c2 = match.charAt(j); - if(ignoreCase) - { - c1 = Character.toUpperCase(c1); - c2 = Character.toUpperCase(c2); - } - if(c1 != c2) - return false; - } - return true; - } - - - /** - * Checks if a subregion of a Segment is equal to a - * character array. - * @param ignoreCase True if case should be ignored, false otherwise - * @param text The segment - * @param offset The offset into the segment - * @param match The character array to match - */ - public static boolean regionMatches(boolean ignoreCase, Segment text, - int offset, char[] match) - { - int length = offset + match.length; - char[] textArray = text.array; - if(length > text.offset + text.count) - return false; - for(int i = offset, j = 0; i < length; i++, j++) - { - char c1 = textArray[i]; - char c2 = match[j]; - if(ignoreCase) - { - c1 = Character.toUpperCase(c1); - c2 = Character.toUpperCase(c2); - } - if(c1 != c2) - return false; - } - return true; - } - - - /** - * Returns the default style table. This can be passed to the - * setStyles() method of SyntaxDocument - * to use the default syntax styles. - */ - public static SyntaxStyle[] getDefaultSyntaxStyles() - { - SyntaxStyle[] styles = new SyntaxStyle[Token.ID_COUNT]; - - styles[Token.COMMENT1] = new SyntaxStyle(Color.black,true,false,false); - styles[Token.COMMENT2] = new SyntaxStyle(new Color(0x990033),true,false,false); - styles[Token.KEYWORD1] = new SyntaxStyle(Color.black,false,true,false); - styles[Token.KEYWORD2] = new SyntaxStyle(Color.magenta,false,false,false); - styles[Token.KEYWORD3] = new SyntaxStyle(new Color(0x009600),false,false,false); - styles[Token.LITERAL1] = new SyntaxStyle(new Color(0x650099),false,false,false); - styles[Token.LITERAL2] = new SyntaxStyle(new Color(0x650099),false,true,false); - styles[Token.LABEL] = new SyntaxStyle(new Color(0x990033),false,true,false); - styles[Token.OPERATOR] = new SyntaxStyle(Color.black,false,true,false); - styles[Token.URL] = new SyntaxStyle(Color.blue,true,false,false); - styles[Token.INVALID] = new SyntaxStyle(Color.red,false,true,false); - - return styles; - } - - - /** - * Paints the specified line onto the graphics context. Note that this - * method munges the offset and count values of the segment. - * @param line The line segment - * @param tokens The token list for the line - * @param styles The syntax style list - * @param expander The tab expander used to determine tab stops. May - * be null - * @param gfx The graphics context - * @param x The x co-ordinate - * @param y The y co-ordinate - * @return The x co-ordinate, plus the width of the painted string - */ - public static int paintSyntaxLine(Segment line, Token tokens, - SyntaxStyle[] styles, - TabExpander expander, Graphics gfx, - int x, int y) - { - Font defaultFont = gfx.getFont(); - Color defaultColor = gfx.getColor(); - - for(;;) - { - byte id = tokens.id; - if(id == Token.END) - break; - - int length = tokens.length; - if(id == Token.NULL) - { - if(!defaultColor.equals(gfx.getColor())) - gfx.setColor(defaultColor); - if(!defaultFont.equals(gfx.getFont())) - gfx.setFont(defaultFont); - } - else - styles[id].setGraphicsFlags(gfx,defaultFont); - - line.count = length; - if (id == Token.COMMENT1 || id == Token.COMMENT2) - x = drawTabbedCommentsText(line, x, y, gfx, expander, styles, styles[id]); - else - x = Utilities.drawTabbedText(line, x, y, gfx, expander, 0); - line.offset += length; - - tokens = tokens.next; - } - - return x; - } - - /** - * Parse comments and identify "@schematics <something>" pattern. - * - * @param line - * A string to parse - * @return null if the pattern is not found, otherwise an array of - * String is returned: the elements with index 0, 1 and 2 are - * respectively the preamble, the <something> stuff, and - * the remaining part of the string. - */ - public static String[] parseCommentUrls(String line) { - Matcher m = urlPattern.matcher(line.toString()); - if (!m.find()) - return null; - - String res[] = new String[3]; - res[0] = line.substring(0, m.start(1)); - res[1] = line.substring(m.start(1), m.end(1)); - res[2] = line.substring(m.end(1)); - // System.out.println("0 =>"+res[0]+"<\n1 =>"+res[1]+"< \n2 =>"+res[2]+"<"); - return res; - } - - static private Pattern urlPattern = Pattern.compile( - "((?:https?|ftp)://" + // ( Protocol - "(?:(?:[\\w_\\-]+:)?[\\w_\\-]+@)?" + // Username and password - "(?:[\\w_\\-]+\\.)+[\\w_\\-]+" + // Domain name - "(?::[0-9]{1,5})?" + // Port - "(?:/[\\w_\\-./?%&=+]*)?)" + // Path ) - "(?:\\s|$)"); // whitespace or EOL - - public static Segment stringToSegment(String v) { - return new Segment(v.toCharArray(), 0, v.length()); - } - - private static int drawTabbedCommentsText(Segment line, int x, int y, - Graphics gfx, TabExpander expander, SyntaxStyle[] styles, - SyntaxStyle commentStyle) { - - String parse[] = parseCommentUrls(line.toString()); - if (parse == null) - // Revert to plain writing. - return Utilities.drawTabbedText(line, x, y, gfx, expander, 0); - Segment pre = stringToSegment(parse[0]); - Segment tag = stringToSegment(parse[1]); - Segment post = stringToSegment(parse[2]); - - if (pre.count>0) - x = Utilities.drawTabbedText(pre, x, y, gfx, expander, 0); - - Font f = gfx.getFont(); - styles[Token.URL].setGraphicsFlags(gfx, f); - x = Utilities.drawTabbedText(tag, x, y, gfx, expander, 0); - - commentStyle.setGraphicsFlags(gfx, f); - if (post.count>0) - x = Utilities.drawTabbedText(post, x, y, gfx, expander, 0); - return x; - } - - // private members - private SyntaxUtilities() {} -} diff --git a/app/src/processing/app/syntax/TextAreaDefaults.java b/app/src/processing/app/syntax/TextAreaDefaults.java deleted file mode 100644 index c2e878578..000000000 --- a/app/src/processing/app/syntax/TextAreaDefaults.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * TextAreaDefaults.java - Encapsulates default values for various settings - * Copyright (C) 1999 Slava Pestov - * - * You may use and modify this package for any purpose. Redistribution is - * permitted, in both source and binary form, provided that this notice - * remains intact in all source distributions of this package. - */ - -package processing.app.syntax; - -import java.awt.*; -//import javax.swing.JPopupMenu; - -/** - * Encapsulates default settings for a text area. This can be passed - * to the constructor once the necessary fields have been filled out. - * The advantage of doing this over calling lots of set() methods after - * creating the text area is that this method is faster. - */ -public class TextAreaDefaults -{ - private static TextAreaDefaults DEFAULTS; - - public InputHandler inputHandler; - public SyntaxDocument document; - public boolean editable; - - public boolean caretVisible; - public boolean caretBlinks; - public boolean blockCaret; - public int electricScroll; - - public int cols; - public int rows; - public SyntaxStyle[] styles; - public Color caretColor; - public Color selectionColor; - public Color lineHighlightColor; - public boolean lineHighlight; - public Color bracketHighlightColor; - public boolean bracketHighlight; - public Color eolMarkerColor; - public boolean eolMarkers; - public boolean paintInvalid; - - - // moved from TextAreaPainter [fry] - public Font font; - public Color fgcolor; - public Color bgcolor; - - //public JPopupMenu popup; - - - /** - * Returns a new TextAreaDefaults object with the default values filled - * in. - */ - public static TextAreaDefaults getDefaults() - { - if (DEFAULTS == null) { - DEFAULTS = new TextAreaDefaults(); - - DEFAULTS.inputHandler = new DefaultInputHandler(); - DEFAULTS.inputHandler.addDefaultKeyBindings(); - DEFAULTS.document = new SyntaxDocument(); - DEFAULTS.editable = true; - - DEFAULTS.caretVisible = true; - DEFAULTS.caretBlinks = true; - DEFAULTS.electricScroll = 3; - - DEFAULTS.cols = 80; - DEFAULTS.rows = 25; - DEFAULTS.styles = SyntaxUtilities.getDefaultSyntaxStyles(); - DEFAULTS.caretColor = Color.red; - DEFAULTS.selectionColor = new Color(0xccccff); - DEFAULTS.lineHighlightColor = new Color(0xe0e0e0); - DEFAULTS.lineHighlight = true; - DEFAULTS.bracketHighlightColor = Color.black; - DEFAULTS.bracketHighlight = true; - DEFAULTS.eolMarkerColor = new Color(0x009999); - DEFAULTS.eolMarkers = true; - DEFAULTS.paintInvalid = true; - } - - return DEFAULTS; - } -} diff --git a/app/src/processing/app/syntax/TextAreaLineNumbers.java b/app/src/processing/app/syntax/TextAreaLineNumbers.java deleted file mode 100644 index 39f7438f2..000000000 --- a/app/src/processing/app/syntax/TextAreaLineNumbers.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * TextAreaLineNumbers.java - Show line numbers for the open file in the editor - * Copyright (C) 2013 Cayci Gorlitsky - * - * You may use and modify this package for any purpose. Redistribution is - * permitted, in both source and binary form, provided that this notice - * remains intact in all source distributions of this package. - */ - -package processing.app.syntax; - -import java.awt.Color; -import java.awt.Graphics; -import java.awt.Rectangle; - -import javax.swing.border.MatteBorder; - -public class TextAreaLineNumbers extends TextAreaPainter { - - private final int LEFT_INDENT = 6; - private final int RIGHT_INDENT = 6; - private final int RIGHT_BORDER_WIDTH = 1; - private final int PADDING_WIDTH = LEFT_INDENT + RIGHT_INDENT + RIGHT_BORDER_WIDTH; - - private final int MIN_WIDTH; - private final int DIGIT_WIDTH; - private final int MIN_NUM_DIGITS = 2; - - private int currStartNum = 0; - private int currEndNum = 0; - private int currNumDigits = MIN_NUM_DIGITS; - - - - public TextAreaLineNumbers(JEditTextArea textArea, TextAreaDefaults defaults) { - super(textArea, defaults); - DIGIT_WIDTH = getFontMetrics(getFont()).stringWidth("0"); - MIN_WIDTH = DIGIT_WIDTH * MIN_NUM_DIGITS + PADDING_WIDTH; - setEnabled(false); - setBorder(new MatteBorder(0, 0, 0, RIGHT_BORDER_WIDTH, new Color(240, 240, 240))); - } - - public void updateLineNumbers(int startNum, int endNum) { - if (currStartNum == startNum && currEndNum == endNum) { - return; - } - currStartNum = startNum; - currEndNum = endNum; - - invalidate(); - repaint(); - } - - @Override - public void paint(Graphics gfx) { - super.paint(gfx); - getBorder().paintBorder(this, gfx, 0, 0, getSize().width, getSize().height); - } - - @Override - protected void paintLine(Graphics gfx, TokenMarker tokenMarker, - int line, int x) - { - currentLineIndex = line; - gfx.setFont(getFont()); - gfx.setColor(Color.GRAY); - int y = textArea.lineToY(line); - int startX = getBounds().x + getBounds().width; - if (line >= 0 && line < textArea.getLineCount()) { - String lineNumberString = String.valueOf(line+1); - int lineStartX = startX - RIGHT_BORDER_WIDTH - RIGHT_INDENT - fm.stringWidth(lineNumberString); - gfx.drawString(lineNumberString,lineStartX,y + fm.getHeight()); - } - } - - public void updateWidthForNumDigits(int numDigits) { - if (currNumDigits == numDigits) { - return; - } - currNumDigits = numDigits; - - if (isVisible()) { - updateBounds(); - invalidate(); - repaint(); - } - } - - public void setDisplayLineNumbers(boolean displayLineNumbers) { - setVisible(displayLineNumbers); - if (displayLineNumbers) { - updateBounds(); - } else { - setBounds(new Rectangle(0, getHeight())); - } - invalidate(); - repaint(); - } - - private void updateBounds() { - if (isVisible()) { - setBounds(new Rectangle(Math.max(MIN_WIDTH, DIGIT_WIDTH * currNumDigits + PADDING_WIDTH), getHeight())); - textArea.validate(); - } - } -} diff --git a/app/src/processing/app/syntax/TextAreaPainter.java b/app/src/processing/app/syntax/TextAreaPainter.java deleted file mode 100644 index 3607c46fa..000000000 --- a/app/src/processing/app/syntax/TextAreaPainter.java +++ /dev/null @@ -1,787 +0,0 @@ -/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ - -/* - * TextAreaPainter.java - Paints the text area - * Copyright (C) 1999 Slava Pestov - * - * You may use and modify this package for any purpose. Redistribution is - * permitted, in both source and binary form, provided that this notice - * remains intact in all source distributions of this package. - */ - -package processing.app.syntax; - -import processing.app.*; -import processing.app.syntax.im.CompositionTextPainter; - -import javax.swing.ToolTipManager; -import javax.swing.text.*; -import javax.swing.JComponent; -import java.awt.event.MouseEvent; -import java.awt.*; -import java.awt.print.*; - -/** - * The text area repaint manager. It performs double buffering and paints - * lines of text. - * @author Slava Pestov - */ -public class TextAreaPainter extends JComponent -implements TabExpander, Printable -{ - /** True if inside printing, will handle disabling the highlight */ - boolean printing; - /** Current setting for editor.antialias preference */ - boolean antialias; - - /** A specific painter composed by the InputMethod.*/ - protected CompositionTextPainter compositionTextPainter; - - /** - * Creates a new repaint manager. This should be not be called - * directly. - */ - public TextAreaPainter(JEditTextArea textArea, TextAreaDefaults defaults) - { - this.textArea = textArea; - - setAutoscrolls(true); - setDoubleBuffered(true); - setOpaque(true); - - ToolTipManager.sharedInstance().registerComponent(this); - - currentLine = new Segment(); - currentLineIndex = -1; - - setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); - - setFont(defaults.font); - setForeground(defaults.fgcolor); - setBackground(defaults.bgcolor); - - antialias = PreferencesData.getBoolean("editor.antialias"); - - blockCaret = defaults.blockCaret; - styles = defaults.styles; - cols = defaults.cols; - rows = defaults.rows; - caretColor = defaults.caretColor; - selectionColor = defaults.selectionColor; - lineHighlightColor = defaults.lineHighlightColor; - lineHighlight = defaults.lineHighlight; - bracketHighlightColor = defaults.bracketHighlightColor; - bracketHighlight = defaults.bracketHighlight; - paintInvalid = defaults.paintInvalid; - eolMarkerColor = defaults.eolMarkerColor; - eolMarkers = defaults.eolMarkers; - } - - /** - * Get CompositionTextPainter. if CompositionTextPainter is not created, create it. - */ - public CompositionTextPainter getCompositionTextpainter(){ - if(compositionTextPainter == null){ - compositionTextPainter = new CompositionTextPainter(textArea); - } - return compositionTextPainter; - } - - /** - * Returns if this component can be traversed by pressing the - * Tab key. This returns false. - */ -// public final boolean isManagingFocus() -// { -// return false; -// } - - /** - * Returns the syntax styles used to paint colorized text. Entry n - * will be used to paint tokens with id = n. - * @see processing.app.syntax.Token - */ - public final SyntaxStyle[] getStyles() - { - return styles; - } - - /** - * Sets the syntax styles used to paint colorized text. Entry n - * will be used to paint tokens with id = n. - * @param styles The syntax styles - * @see processing.app.syntax.Token - */ - public final void setStyles(SyntaxStyle[] styles) - { - this.styles = styles; - repaint(); - } - - /** - * Returns the caret color. - */ - public final Color getCaretColor() - { - return caretColor; - } - - /** - * Sets the caret color. - * @param caretColor The caret color - */ - public final void setCaretColor(Color caretColor) - { - this.caretColor = caretColor; - invalidateSelectedLines(); - } - - /** - * Returns the selection color. - */ - public final Color getSelectionColor() - { - return selectionColor; - } - - /** - * Sets the selection color. - * @param selectionColor The selection color - */ - public final void setSelectionColor(Color selectionColor) - { - this.selectionColor = selectionColor; - invalidateSelectedLines(); - } - - /** - * Returns the line highlight color. - */ - public final Color getLineHighlightColor() - { - return lineHighlightColor; - } - - /** - * Sets the line highlight color. - * @param lineHighlightColor The line highlight color - */ - public final void setLineHighlightColor(Color lineHighlightColor) - { - this.lineHighlightColor = lineHighlightColor; - invalidateSelectedLines(); - } - - /** - * Returns true if line highlight is enabled, false otherwise. - */ - public final boolean isLineHighlightEnabled() - { - return lineHighlight; - } - - /** - * Enables or disables current line highlighting. - * @param lineHighlight True if current line highlight - * should be enabled, false otherwise - */ - public final void setLineHighlightEnabled(boolean lineHighlight) - { - this.lineHighlight = lineHighlight; - invalidateSelectedLines(); - } - - /** - * Returns the bracket highlight color. - */ - public final Color getBracketHighlightColor() - { - return bracketHighlightColor; - } - - /** - * Sets the bracket highlight color. - * @param bracketHighlightColor The bracket highlight color - */ - public final void setBracketHighlightColor(Color bracketHighlightColor) - { - this.bracketHighlightColor = bracketHighlightColor; - invalidateLine(textArea.getBracketLine()); - } - - /** - * Returns true if bracket highlighting is enabled, false otherwise. - * When bracket highlighting is enabled, the bracket matching the - * one before the caret (if any) is highlighted. - */ - public final boolean isBracketHighlightEnabled() - { - return bracketHighlight; - } - - /** - * Enables or disables bracket highlighting. - * When bracket highlighting is enabled, the bracket matching the - * one before the caret (if any) is highlighted. - * @param bracketHighlight True if bracket highlighting should be - * enabled, false otherwise - */ - public final void setBracketHighlightEnabled(boolean bracketHighlight) - { - this.bracketHighlight = bracketHighlight; - invalidateLine(textArea.getBracketLine()); - } - - /** - * Returns true if the caret should be drawn as a block, false otherwise. - */ - public final boolean isBlockCaretEnabled() - { - return blockCaret; - } - - /** - * Sets if the caret should be drawn as a block, false otherwise. - * @param blockCaret True if the caret should be drawn as a block, - * false otherwise. - */ - public final void setBlockCaretEnabled(boolean blockCaret) - { - this.blockCaret = blockCaret; - invalidateSelectedLines(); - } - - /** - * Returns the EOL marker color. - */ - public final Color getEOLMarkerColor() - { - return eolMarkerColor; - } - - /** - * Sets the EOL marker color. - * @param eolMarkerColor The EOL marker color - */ - public final void setEOLMarkerColor(Color eolMarkerColor) - { - this.eolMarkerColor = eolMarkerColor; - repaint(); - } - - /** - * Returns true if EOL markers are drawn, false otherwise. - */ - public final boolean getEOLMarkersPainted() - { - return eolMarkers; - } - - /** - * Sets if EOL markers are to be drawn. - * @param eolMarkers True if EOL markers should be drawn, false otherwise - */ - public final void setEOLMarkersPainted(boolean eolMarkers) - { - this.eolMarkers = eolMarkers; - repaint(); - } - - /** - * Returns true if invalid lines are painted as red tildes (~), - * false otherwise. - */ - public boolean getInvalidLinesPainted() - { - return paintInvalid; - } - - /** - * Sets if invalid lines are to be painted as red tildes. - * @param paintInvalid True if invalid lines should be drawn, false otherwise - */ - public void setInvalidLinesPainted(boolean paintInvalid) - { - this.paintInvalid = paintInvalid; - } - - /** - * Adds a custom highlight painter. - * @param highlight The highlight - */ - public void addCustomHighlight(Highlight highlight) - { - highlight.init(textArea,highlights); - highlights = highlight; - } - - /** - * Highlight interface. - */ - public interface Highlight - { - /** - * Called after the highlight painter has been added. - * @param textArea The text area - * @param next The painter this one should delegate to - */ - void init(JEditTextArea textArea, Highlight next); - - /** - * This should paint the highlight and delgate to the - * next highlight painter. - * @param gfx The graphics context - * @param line The line number - * @param y The y co-ordinate of the line - */ - void paintHighlight(Graphics gfx, int line, int y); - - /** - * Returns the tool tip to display at the specified - * location. If this highlighter doesn't know what to - * display, it should delegate to the next highlight - * painter. - * @param evt The mouse event - */ - String getToolTipText(MouseEvent evt); - } - - /** - * Returns the tool tip to display at the specified location. - * @param evt The mouse event - */ - public String getToolTipText(MouseEvent evt) - { - if(highlights != null) - return highlights.getToolTipText(evt); - else - return null; - } - - /** - * Returns the font metrics used by this component. - */ - public FontMetrics getFontMetrics() - { - return fm; - } - - /** - * Sets the font for this component. This is overridden to update the - * cached font metrics and to recalculate which lines are visible. - * @param font The font - */ - public void setFont(Font font) - { - super.setFont(font); - fm = super.getFontMetrics(font); - textArea.recalculateVisibleLines(); - } - - /** - * Repaints the text. - * @param gfx The graphics context - */ - public void paint(Graphics gfx) - { - Graphics2D g2 = (Graphics2D) gfx; - g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, - antialias ? - RenderingHints.VALUE_TEXT_ANTIALIAS_ON : - RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); - - tabSize = fm.charWidth(' ') * ((Integer)textArea.getDocument().getProperty(PlainDocument.tabSizeAttribute)).intValue(); - - Rectangle clipRect = gfx.getClipBounds(); - - gfx.setColor(getBackground()); - gfx.fillRect(clipRect.x,clipRect.y,clipRect.width,clipRect.height); - - // We don't use yToLine() here because that method doesn't - // return lines past the end of the document - int height = fm.getHeight(); - int firstLine = textArea.getFirstLine(); - int firstInvalid = firstLine + clipRect.y / height; - // Because the clipRect's height is usually an even multiple - // of the font height, we subtract 1 from it, otherwise one - // too many lines will always be painted. - int lastInvalid = firstLine + (clipRect.y + clipRect.height - 1) / height; - - try { - TokenMarker tokenMarker = textArea.getDocument().getTokenMarker(); - int x = textArea.getHorizontalOffset(); - - for (int line = firstInvalid; line <= lastInvalid; line++) { - paintLine(gfx,tokenMarker,line,x); - } - - if (tokenMarker != null && tokenMarker.isNextLineRequested()) { - int h = clipRect.y + clipRect.height; - repaint(0,h,getWidth(),getHeight() - h); - } - } catch (Exception e) { - System.err.println("Error repainting line" - + " range {" + firstInvalid + "," - + lastInvalid + "}:"); - e.printStackTrace(); - } - } - - - public int print(Graphics g, PageFormat pageFormat, int pageIndex) { - int lineHeight = fm.getHeight(); - int linesPerPage = (int) (pageFormat.getImageableHeight() / lineHeight); - int lineCount = textArea.getLineCount(); - int lastPage = lineCount / linesPerPage; - - if (pageIndex > lastPage) { - return NO_SUCH_PAGE; - - } else { - Graphics2D g2d = (Graphics2D)g; - TokenMarker tokenMarker = textArea.getDocument().getTokenMarker(); - int firstLine = pageIndex*linesPerPage; - g2d.translate(Math.max(54, pageFormat.getImageableX()), - pageFormat.getImageableY() - firstLine*lineHeight); - printing = true; - for (int line = firstLine; line < firstLine + linesPerPage; line++) { - paintLine(g2d, tokenMarker, line, 0); - } - printing = false; - return PAGE_EXISTS; - } - } - - - /** - * Marks a line as needing a repaint. - * @param line The line to invalidate - */ - public final void invalidateLine(int line) - { - repaint(0,textArea.lineToY(line) + fm.getMaxDescent() + fm.getLeading(), - getWidth(),fm.getHeight()); - } - - /** - * Marks a range of lines as needing a repaint. - * @param firstLine The first line to invalidate - * @param lastLine The last line to invalidate - */ - public final void invalidateLineRange(int firstLine, int lastLine) - { - repaint(0,textArea.lineToY(firstLine) + - fm.getMaxDescent() + fm.getLeading(), - getWidth(),(lastLine - firstLine + 1) * fm.getHeight()); - } - - /** - * Repaints the lines containing the selection. - */ - public final void invalidateSelectedLines() - { - invalidateLineRange(textArea.getSelectionStartLine(), - textArea.getSelectionStopLine()); - } - - /** - * Implementation of TabExpander interface. Returns next tab stop after - * a specified point. - * @param x The x co-ordinate - * @param tabOffset Ignored - * @return The next tab stop after x - */ - public float nextTabStop(float x, int tabOffset) - { - int offset = textArea.getHorizontalOffset(); - int ntabs = ((int)x - offset) / tabSize; - return (ntabs + 1) * tabSize + offset; - } - - /** - * Returns the painter's preferred size. - */ - public Dimension getPreferredSize() - { - Dimension dim = new Dimension(); - dim.width = fm.charWidth('w') * cols; - dim.height = fm.getHeight() * rows; - return dim; - } - - - /** - * Returns the painter's minimum size. - */ - public Dimension getMinimumSize() - { - Dimension dim = new Dimension(); - dim.width = fm.charWidth('w') * 10; - dim.height = fm.getHeight() * 4; - return dim; - } - - // package-private members - int currentLineIndex; - Token currentLineTokens; - Segment currentLine; - - /** - * Accessor used by tools that want to hook in and grab the formatting. - */ - public int getCurrentLineIndex() { - return currentLineIndex; - } - - /** - * Accessor used by tools that want to hook in and grab the formatting. - */ - public void setCurrentLineIndex(int what) { - currentLineIndex = what; - } - - /** - * Accessor used by tools that want to hook in and grab the formatting. - */ - public Token getCurrentLineTokens() { - return currentLineTokens; - } - - /** - * Accessor used by tools that want to hook in and grab the formatting. - */ - public void setCurrentLineTokens(Token tokens) { - currentLineTokens = tokens; - } - - /** - * Accessor used by tools that want to hook in and grab the formatting. - */ - public Segment getCurrentLine() { - return currentLine; - } - - - // protected members - protected JEditTextArea textArea; - - protected SyntaxStyle[] styles; - protected Color caretColor; - protected Color selectionColor; - protected Color lineHighlightColor; - protected Color bracketHighlightColor; - protected Color eolMarkerColor; - - protected boolean blockCaret; - protected boolean lineHighlight; - protected boolean bracketHighlight; - protected boolean paintInvalid; - protected boolean eolMarkers; - protected int cols; - protected int rows; - - protected int tabSize; - protected FontMetrics fm; - - protected Highlight highlights; - - protected void paintLine(Graphics gfx, TokenMarker tokenMarker, - int line, int x) - { - Font defaultFont = getFont(); - Color defaultColor = getForeground(); - - currentLineIndex = line; - int y = textArea.lineToY(line); - - if (line < 0 || line >= textArea.getLineCount()) { - if (paintInvalid) { - paintHighlight(gfx,line,y); - styles[Token.INVALID].setGraphicsFlags(gfx,defaultFont); - gfx.drawString("~",0,y + fm.getHeight()); - } - } else if(tokenMarker == null) { - paintPlainLine(gfx,line,defaultFont,defaultColor,x,y); - } else { - paintSyntaxLine(gfx,tokenMarker,line,defaultFont, - defaultColor,x,y); - } - } - - protected void paintPlainLine(Graphics gfx, int line, Font defaultFont, - Color defaultColor, int x, int y) - { - paintHighlight(gfx,line,y); - textArea.getLineText(line,currentLine); - - gfx.setFont(defaultFont); - gfx.setColor(defaultColor); - - y += fm.getHeight(); - x = Utilities.drawTabbedText(currentLine,x,y,gfx,this,0); - /* - * Draw characters via input method. - */ - if (compositionTextPainter != null && compositionTextPainter.hasComposedTextLayout()) { - compositionTextPainter.draw(gfx, lineHighlightColor); - } - if (eolMarkers) { - gfx.setColor(eolMarkerColor); - gfx.drawString(".",x,y); - } - } - - protected void paintSyntaxLine(Graphics gfx, TokenMarker tokenMarker, - int line, Font defaultFont, - Color defaultColor, int x, int y) - { - textArea.getLineText(currentLineIndex,currentLine); - currentLineTokens = tokenMarker.markTokens(currentLine, - currentLineIndex); - - paintHighlight(gfx,line,y); - - gfx.setFont(defaultFont); - gfx.setColor(defaultColor); - y += fm.getHeight(); - x = SyntaxUtilities.paintSyntaxLine(currentLine, - currentLineTokens, - styles, this, gfx, x, y); - /* - * Draw characters via input method. - */ - if (compositionTextPainter != null && compositionTextPainter.hasComposedTextLayout()) { - compositionTextPainter.draw(gfx, lineHighlightColor); - } - if (eolMarkers) { - gfx.setColor(eolMarkerColor); - gfx.drawString(".",x,y); - } - } - - protected void paintHighlight(Graphics gfx, int line, int y) - { - if (!printing) { - if (line >= textArea.getSelectionStartLine() - && line <= textArea.getSelectionStopLine()) - paintLineHighlight(gfx,line,y); - - if (highlights != null) - highlights.paintHighlight(gfx,line,y); - - if (bracketHighlight && line == textArea.getBracketLine()) - paintBracketHighlight(gfx,line,y); - - if (line == textArea.getCaretLine()) - paintCaret(gfx,line,y); - } - } - - protected void paintLineHighlight(Graphics gfx, int line, int y) - { - int height = fm.getHeight(); - y += fm.getLeading() + fm.getMaxDescent(); - - int selectionStart = textArea.getSelectionStart(); - int selectionEnd = textArea.getSelectionStop(); - - if (selectionStart == selectionEnd) { - if (lineHighlight) { - gfx.setColor(lineHighlightColor); - gfx.fillRect(0,y,getWidth(),height); - } - } else { - gfx.setColor(selectionColor); - - int selectionStartLine = textArea.getSelectionStartLine(); - int selectionEndLine = textArea.getSelectionStopLine(); - int lineStart = textArea.getLineStartOffset(line); - - int x1, x2; - if (textArea.isSelectionRectangular()) { - int lineLen = textArea.getLineLength(line); - x1 = textArea._offsetToX(line,Math.min(lineLen, selectionStart - textArea.getLineStartOffset(selectionStartLine))); - x2 = textArea._offsetToX(line,Math.min(lineLen, selectionEnd - textArea.getLineStartOffset(selectionEndLine))); - if (x1 == x2) - x2++; - } else if(selectionStartLine == selectionEndLine) { - x1 = textArea._offsetToX(line, selectionStart - lineStart); - x2 = textArea._offsetToX(line, selectionEnd - lineStart); - } else if(line == selectionStartLine) { - x1 = textArea._offsetToX(line, selectionStart - lineStart); - x2 = getWidth(); - } else if(line == selectionEndLine) { - //x1 = 0; - // hack from stendahl to avoid doing weird side selection thing - x1 = textArea._offsetToX(line, 0); - // attempt at getting the gutter too, but doesn't seem to work - //x1 = textArea._offsetToX(line, -textArea.getHorizontalOffset()); - x2 = textArea._offsetToX(line, selectionEnd - lineStart); - } else { - //x1 = 0; - // hack from stendahl to avoid doing weird side selection thing - x1 = textArea._offsetToX(line, 0); - // attempt at getting the gutter too, but doesn't seem to work - //x1 = textArea._offsetToX(line, -textArea.getHorizontalOffset()); - x2 = getWidth(); - } - - // "inlined" min/max() - gfx.fillRect(x1 > x2 ? x2 : x1,y,x1 > x2 ? - (x1 - x2) : (x2 - x1),height); - } - - } - - protected void paintBracketHighlight(Graphics gfx, int line, int y) - { - int position = textArea.getBracketPosition(); - if(position == -1) - return; - y += fm.getLeading() + fm.getMaxDescent(); - int x = textArea._offsetToX(line,position); - gfx.setColor(bracketHighlightColor); - // Hack!!! Since there is no fast way to get the character - // from the bracket matching routine, we use ( since all - // brackets probably have the same width anyway - gfx.drawRect(x,y,fm.charWidth('(') - 1, - fm.getHeight() - 1); - } - - protected void paintCaret(Graphics gfx, int line, int y) - { - //System.out.println("painting caret " + line + " " + y); - if (textArea.isCaretVisible()) { - //System.out.println("caret is visible"); - int offset = - textArea.getCaretPosition() - textArea.getLineStartOffset(line); - int caretX = textArea._offsetToX(line, offset); - int caretWidth = ((blockCaret || - textArea.isOverwriteEnabled()) ? - fm.charWidth('w') : 1); - y += fm.getLeading() + fm.getMaxDescent(); - int height = fm.getHeight(); - - //System.out.println("caretX, width = " + caretX + " " + caretWidth); - - gfx.setColor(caretColor); - - if (textArea.isOverwriteEnabled()) { - gfx.fillRect(caretX,y + height - 1, caretWidth,1); - - } else { - // some machines don't like the drawRect for the single - // pixel caret.. this caused a lot of hell because on that - // minority of machines, the caret wouldn't show up past - // the first column. the fix is to use drawLine() in - // those cases, as a workaround. - if (caretWidth == 1) { - gfx.drawLine(caretX, y, caretX, y + height - 1); - } else { - gfx.drawRect(caretX, y, caretWidth - 1, height - 1); - } - //gfx.drawRect(caretX, y, caretWidth, height - 1); - } - } - } -} diff --git a/app/src/processing/app/syntax/TextUtilities.java b/app/src/processing/app/syntax/TextUtilities.java deleted file mode 100644 index f009cd051..000000000 --- a/app/src/processing/app/syntax/TextUtilities.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * TextUtilities.java - Utility functions used by the text area classes - * Copyright (C) 1999 Slava Pestov - * - * You may use and modify this package for any purpose. Redistribution is - * permitted, in both source and binary form, provided that this notice - * remains intact in all source distributions of this package. - */ - -package processing.app.syntax; - -import javax.swing.text.*; - -/** - * Class with several utility functions used by the text area component. - * @author Slava Pestov - */ -public class TextUtilities -{ - /** - * Returns the offset of the bracket matching the one at the - * specified offset of the document, or -1 if the bracket is - * unmatched (or if the character is not a bracket). - * @param doc The document - * @param offset The offset - * @exception BadLocationException If an out-of-bounds access - * was attempted on the document text - */ - public static int findMatchingBracket(Document doc, int offset) - throws BadLocationException - { - if(doc.getLength() == 0) - return -1; - char c = doc.getText(offset,1).charAt(0); - char cprime; // c` - corresponding character - boolean direction; // true = back, false = forward - - switch(c) - { - case '(': cprime = ')'; direction = false; break; - case ')': cprime = '('; direction = true; break; - case '[': cprime = ']'; direction = false; break; - case ']': cprime = '['; direction = true; break; - case '{': cprime = '}'; direction = false; break; - case '}': cprime = '{'; direction = true; break; - default: return -1; - } - - int count; - - // How to merge these two cases is left as an exercise - // for the reader. - - // Go back or forward - if(direction) - { - // Count is 1 initially because we have already - // `found' one closing bracket - count = 1; - - // Get text[0,offset-1]; - String text = doc.getText(0,offset); - - // Scan backwards - for(int i = offset - 1; i >= 0; i--) - { - // If text[i] == c, we have found another - // closing bracket, therefore we will need - // two opening brackets to complete the - // match. - char x = text.charAt(i); - if(x == c) - count++; - - // If text[i] == cprime, we have found a - // opening bracket, so we return i if - // --count == 0 - else if(x == cprime) - { - if(--count == 0) - return i; - } - } - } - else - { - // Count is 1 initially because we have already - // `found' one opening bracket - count = 1; - - // So we don't have to + 1 in every loop - offset++; - - // Number of characters to check - int len = doc.getLength() - offset; - - // Get text[offset+1,len]; - String text = doc.getText(offset,len); - - // Scan forwards - for(int i = 0; i < len; i++) - { - // If text[i] == c, we have found another - // opening bracket, therefore we will need - // two closing brackets to complete the - // match. - char x = text.charAt(i); - - if(x == c) - count++; - - // If text[i] == cprime, we have found an - // closing bracket, so we return i if - // --count == 0 - else if(x == cprime) - { - if(--count == 0) - return i + offset; - } - } - } - - // Nothing found - return -1; - } - - /** - * Locates the start of the word at the specified position. - * @param line The text - * @param pos The position - */ - public static int findWordStart(String line, int pos, String noWordSep) - { - char ch = line.charAt(pos - 1); - - if(noWordSep == null) - noWordSep = ""; - boolean selectNoLetter = (!Character.isLetterOrDigit(ch) - && noWordSep.indexOf(ch) == -1); - - int wordStart = 0; - for(int i = pos - 1; i >= 0; i--) - { - ch = line.charAt(i); - if(selectNoLetter ^ (!Character.isLetterOrDigit(ch) && - noWordSep.indexOf(ch) == -1)) - { - wordStart = i + 1; - break; - } - } - - return wordStart; - } - - /** - * Locates the end of the word at the specified position. - * @param line The text - * @param pos The position - */ - public static int findWordEnd(String line, int pos, String noWordSep) - { - char ch = line.charAt(pos); - - if(noWordSep == null) - noWordSep = ""; - boolean selectNoLetter = (!Character.isLetterOrDigit(ch) - && noWordSep.indexOf(ch) == -1); - - int wordEnd = line.length(); - for(int i = pos; i < line.length(); i++) - { - ch = line.charAt(i); - if(selectNoLetter ^ (!Character.isLetterOrDigit(ch) && - noWordSep.indexOf(ch) == -1)) - { - wordEnd = i; - break; - } - } - return wordEnd; - } -} diff --git a/app/src/processing/app/syntax/TokenMarker.java b/app/src/processing/app/syntax/TokenMarker.java deleted file mode 100644 index 9244556d3..000000000 --- a/app/src/processing/app/syntax/TokenMarker.java +++ /dev/null @@ -1,341 +0,0 @@ -/* - * TokenMarker.java - Generic token marker - * Copyright (C) 1998, 1999 Slava Pestov - * - * You may use and modify this package for any purpose. Redistribution is - * permitted, in both source and binary form, provided that this notice - * remains intact in all source distributions of this package. - */ - -package processing.app.syntax; - -import javax.swing.text.Segment; - -/** - * A token marker that splits lines of text into tokens. Each token carries - * a length field and an indentification tag that can be mapped to a color - * for painting that token.

- * - * For performance reasons, the linked list of tokens is reused after each - * line is tokenized. Therefore, the return value of markTokens - * should only be used for immediate painting. Notably, it cannot be - * cached. - * - * @author Slava Pestov - */ -public abstract class TokenMarker -{ - /** - * A wrapper for the lower-level markTokensImpl method - * that is called to split a line up into tokens. - * @param line The line - * @param lineIndex The line number - */ - public Token markTokens(Segment line, int lineIndex) - { - if(lineIndex >= length) - { - throw new IllegalArgumentException("Tokenizing invalid line: " - + lineIndex); - } - - lastToken = null; - - LineInfo info = lineInfo[lineIndex]; - LineInfo prev; - if(lineIndex == 0) - prev = null; - else - prev = lineInfo[lineIndex - 1]; - - byte oldToken = info.token; - byte token = markTokensImpl(prev == null ? - Token.NULL : prev.token,line,lineIndex); - - info.token = token; - - /* - * This is a foul hack. It stops nextLineRequested - * from being cleared if the same line is marked twice. - * - * Why is this necessary? It's all JEditTextArea's fault. - * When something is inserted into the text, firing a - * document event, the insertUpdate() method shifts the - * caret (if necessary) by the amount inserted. - * - * All caret movement is handled by the select() method, - * which eventually pipes the new position to scrollTo() - * and calls repaint(). - * - * Note that at this point in time, the new line hasn't - * yet been painted; the caret is moved first. - * - * scrollTo() calls offsetToX(), which tokenizes the line - * unless it is being called on the last line painted - * (in which case it uses the text area's painter cached - * token list). What scrollTo() does next is irrelevant. - * - * After scrollTo() has done it's job, repaint() is - * called, and eventually we end up in paintLine(), whose - * job is to paint the changed line. It, too, calls - * markTokens(). - * - * The problem was that if the line started a multiline - * token, the first markTokens() (done in offsetToX()) - * would set nextLineRequested (because the line end - * token had changed) but the second would clear it - * (because the line was the same that time) and therefore - * paintLine() would never know that it needed to repaint - * subsequent lines. - * - * This bug took me ages to track down, that's why I wrote - * all the relevant info down so that others wouldn't - * duplicate it. - */ - if(!(lastLine == lineIndex && nextLineRequested)) - nextLineRequested = (oldToken != token); - - lastLine = lineIndex; - - addToken(0,Token.END); - - return firstToken; - } - - /** - * An abstract method that splits a line up into tokens. It - * should parse the line, and call addToken() to - * add syntax tokens to the token list. Then, it should return - * the initial token type for the next line.

- * - * For example if the current line contains the start of a - * multiline comment that doesn't end on that line, this method - * should return the comment token type so that it continues on - * the next line. - * - * @param token The initial token type for this line - * @param line The line to be tokenized - * @param lineIndex The index of the line in the document, - * starting at 0 - * @return The initial token type for the next line - */ - protected abstract byte markTokensImpl(byte token, Segment line, - int lineIndex); - - /** - * Returns if the token marker supports tokens that span multiple - * lines. If this is true, the object using this token marker is - * required to pass all lines in the document to the - * markTokens() method (in turn).

- * - * The default implementation returns true; it should be overridden - * to return false on simpler token markers for increased speed. - */ - public boolean supportsMultilineTokens() - { - return true; - } - - /** - * Informs the token marker that lines have been inserted into - * the document. This inserts a gap in the lineInfo - * array. - * @param index The first line number - * @param lines The number of lines - */ - public void insertLines(int index, int lines) - { - if(lines <= 0) - return; - length += lines; - ensureCapacity(length); - int len = index + lines; - System.arraycopy(lineInfo,index,lineInfo,len, - lineInfo.length - len); - - for(int i = index + lines - 1; i >= index; i--) - { - lineInfo[i] = new LineInfo(); - } - } - - /** - * Informs the token marker that line have been deleted from - * the document. This removes the lines in question from the - * lineInfo array. - * @param index The first line number - * @param lines The number of lines - */ - public void deleteLines(int index, int lines) - { - if (lines <= 0) - return; - int len = index + lines; - length -= lines; - System.arraycopy(lineInfo,len,lineInfo, - index,lineInfo.length - len); - } - - /** - * Returns the number of lines in this token marker. - */ - public int getLineCount() - { - return length; - } - - /** - * Returns true if the next line should be repainted. This - * will return true after a line has been tokenized that starts - * a multiline token that continues onto the next line. - */ - public boolean isNextLineRequested() - { - return nextLineRequested; - } - - // protected members - - /** - * The first token in the list. This should be used as the return - * value from markTokens(). - */ - protected Token firstToken; - - /** - * The last token in the list. New tokens are added here. - * This should be set to null before a new line is to be tokenized. - */ - protected Token lastToken; - - /** - * An array for storing information about lines. It is enlarged and - * shrunk automatically by the insertLines() and - * deleteLines() methods. - */ - protected LineInfo[] lineInfo; - - /** - * The number of lines in the model being tokenized. This can be - * less than the length of the lineInfo array. - */ - protected int length; - - /** - * The last tokenized line. - */ - protected int lastLine; - - /** - * True if the next line should be painted. - */ - protected boolean nextLineRequested; - - /** - * Creates a new TokenMarker. This DOES NOT create - * a lineInfo array; an initial call to insertLines() - * does that. - */ - protected TokenMarker() - { - lastLine = -1; - } - - /** - * Ensures that the lineInfo array can contain the - * specified index. This enlarges it if necessary. No action is - * taken if the array is large enough already.

- * - * It should be unnecessary to call this under normal - * circumstances; insertLine() should take care of - * enlarging the line info array automatically. - * - * @param index The array index - */ - protected void ensureCapacity(int index) - { - if(lineInfo == null) - lineInfo = new LineInfo[index + 1]; - else if(lineInfo.length <= index) - { - LineInfo[] lineInfoN = new LineInfo[(index + 1) * 2]; - System.arraycopy(lineInfo,0,lineInfoN,0, - lineInfo.length); - lineInfo = lineInfoN; - } - } - - /** - * Adds a token to the token list. - * @param length The length of the token - * @param id The id of the token - */ - protected void addToken(int length, byte id) - { - if(id >= Token.INTERNAL_FIRST && id <= Token.INTERNAL_LAST) - throw new InternalError("Invalid id: " + id); - - if(length == 0 && id != Token.END) - return; - - if(firstToken == null) - { - firstToken = new Token(length,id); - lastToken = firstToken; - } - else if(lastToken == null) - { - lastToken = firstToken; - firstToken.length = length; - firstToken.id = id; - } - else if(lastToken.next == null) - { - lastToken.next = new Token(length,id); - lastToken = lastToken.next; - } - else - { - lastToken = lastToken.next; - lastToken.length = length; - lastToken.id = id; - } - } - - /** - * Inner class for storing information about tokenized lines. - */ - public class LineInfo - { - /** - * Creates a new LineInfo object with token = Token.NULL - * and obj = null. - */ - public LineInfo() - { - } - - /** - * Creates a new LineInfo object with the specified - * parameters. - */ - public LineInfo(byte token, Object obj) - { - this.token = token; - this.obj = obj; - } - - /** - * The id of the last token of the line. - */ - public byte token; - - /** - * This is for use by the token marker implementations - * themselves. It can be used to store anything that - * is an object and that needs to exist on a per-line - * basis. - */ - public Object obj; - } -} diff --git a/app/src/processing/app/syntax/im/CompositionTextManager.java b/app/src/processing/app/syntax/im/CompositionTextManager.java deleted file mode 100644 index ba9ee155f..000000000 --- a/app/src/processing/app/syntax/im/CompositionTextManager.java +++ /dev/null @@ -1,198 +0,0 @@ -package processing.app.syntax.im; - -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.Graphics2D; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.font.FontRenderContext; -import java.awt.font.TextAttribute; -import java.awt.font.TextLayout; -import java.text.AttributedCharacterIterator; -import java.text.AttributedString; - -import javax.swing.text.BadLocationException; - -import processing.app.syntax.JEditTextArea; -import processing.app.syntax.TextAreaPainter; - -/** - * This class Manage texts from input method - * by begin-process-end steps. - * - * First, if a user start inputing via input method, - * beginCompositionText is called from InputMethodSupport. - * Second, the user continues from input method, processCompositionText is called - * and reflect user inputs to text area. - * Finally the user try to commit text, endCompositionText is called. - * - * @author Takashi Maekawa (takachin@generative.info) - */ - -public class CompositionTextManager { - private JEditTextArea textArea; - private String prevComposeString; - private int prevCommittedCount; - private boolean isInputProcess; - private int initialCaretPosition; - public static final int COMPOSING_UNDERBAR_HEIGHT = 5; - - /** - * Create text manager class with a textarea. - * @param textArea texarea component for PDE. - */ - public CompositionTextManager(JEditTextArea textArea) { - this.textArea = textArea; - prevComposeString = ""; - isInputProcess = false; - prevCommittedCount = 0; - } - - /** - * Get this text manager is whether in input process or not. - */ - public boolean getIsInputProcess() { - return isInputProcess; - } - /** - * Insert full width space - */ - public void insertFullWidthSpace() { - initialCaretPosition = textArea.getCaretPosition(); - int layoutCaretPosition = initialCaretPosition; - try { - textArea.getDocument().insertString(layoutCaretPosition, "\u3000", null); - } catch (BadLocationException e) { - e.printStackTrace(); - } - } - - /** - * Called when a user begins input from input method. - * This method initializes text manager. - * - * @param text Text from InputMethodEvent. - * @param commited_count Numbers of committed characters in text. - */ - public void beginCompositionText(AttributedCharacterIterator text, int committed_count) { - isInputProcess = true; - prevComposeString = ""; - initialCaretPosition = textArea.getCaretPosition(); - processCompositionText(text, committed_count); - } - - /** - * Called when a user processing input characters and - * select candidates from input method. - * - * @param text Text from InputMethodEvent. - * @param commited_count Numbers of committed characters in text. - */ - public void processCompositionText(AttributedCharacterIterator text, int committed_count) { - int layoutCaretPosition = initialCaretPosition + committed_count; - CompositionTextPainter compositionPainter = textArea.getPainter().getCompositionTextpainter(); - compositionPainter.setComposedTextLayout(getTextLayout(text, committed_count), layoutCaretPosition); - int textLength = text.getEndIndex() - text.getBeginIndex() - committed_count; - StringBuffer unCommitedStringBuf = new StringBuffer(textLength); - char c; - for (c = text.setIndex(committed_count); c != AttributedCharacterIterator.DONE - && textLength > 0; c = text.next(), --textLength) { - unCommitedStringBuf.append(c); - } - String unCommittedString = unCommitedStringBuf.toString(); - try { - if(canRemovePreviousInput(committed_count)){ - textArea.getDocument().remove(layoutCaretPosition, prevComposeString.length()); - } - textArea.getDocument().insertString(layoutCaretPosition, unCommittedString, null); - if(committed_count > 0){ - initialCaretPosition = initialCaretPosition + committed_count; - } - prevComposeString = unCommittedString; - prevCommittedCount = committed_count; - } catch (BadLocationException e) { - e.printStackTrace(); - } - } - - private boolean canRemovePreviousInput(int committed_count){ - return (prevCommittedCount == committed_count || prevCommittedCount > committed_count); - } - - /** - * Called when a user fixed text from input method or delete all - * composition text. This method resets CompositionTextPainter. - * - * @param text Text from InputMethodEvent. - * @param commited_count Numbers of committed characters in text. - */ - public void endCompositionText(AttributedCharacterIterator text, int committed_count) { - /* - * If there are no committed characters, remove it all from textarea. - * This case will happen if a user delete all composing characters by backspace or delete key. - * If it does, these previous characters are needed to be deleted. - */ - if(committed_count == 0){ - removeNotCommittedText(text); - } - CompositionTextPainter compositionPainter = textArea.getPainter().getCompositionTextpainter(); - compositionPainter.invalidateComposedTextLayout(initialCaretPosition + committed_count); - prevComposeString = ""; - isInputProcess = false; - } - - private void removeNotCommittedText(AttributedCharacterIterator text){ - if (prevComposeString.length() == 0) { - return; - } - try { - textArea.getDocument().remove(initialCaretPosition, prevComposeString.length()); - } catch (BadLocationException e) { - e.printStackTrace(); - } - } - - private TextLayout getTextLayout(AttributedCharacterIterator text, int committed_count) { - AttributedString composed = new AttributedString(text, committed_count, text.getEndIndex()); - Font font = textArea.getPainter().getFont(); - FontRenderContext context = ((Graphics2D) (textArea.getPainter().getGraphics())).getFontRenderContext(); - composed.addAttribute(TextAttribute.FONT, font); - TextLayout layout = new TextLayout(composed.getIterator(), context); - return layout; - } - - private Point getCaretLocation() { - Point loc = new Point(); - TextAreaPainter painter = textArea.getPainter(); - FontMetrics fm = painter.getFontMetrics(); - int offsetY = fm.getHeight() - COMPOSING_UNDERBAR_HEIGHT; - int lineIndex = textArea.getCaretLine(); - loc.y = lineIndex * fm.getHeight() + offsetY; - int offsetX = textArea.getCaretPosition() - - textArea.getLineStartOffset(lineIndex); - loc.x = textArea.offsetToX(lineIndex, offsetX); - return loc; - } - - public Rectangle getTextLocation() { - Point caret = getCaretLocation(); - return getCaretRectangle(caret.x, caret.y); - } - - private Rectangle getCaretRectangle(int x, int y) { - TextAreaPainter painter = textArea.getPainter(); - Point origin = painter.getLocationOnScreen(); - int height = painter.getFontMetrics().getHeight(); - return new Rectangle(origin.x + x, origin.y + y, 0, height); - } - - public AttributedCharacterIterator getCommittedText(int beginIndex, int endIndex) { - int length = endIndex - beginIndex; - String textAreaString = textArea.getText(beginIndex, length); - return new AttributedString(textAreaString).getIterator(); - } - - public int getInsertPositionOffset() { - return textArea.getCaretPosition() * -1; - } -} diff --git a/app/src/processing/app/syntax/im/CompositionTextPainter.java b/app/src/processing/app/syntax/im/CompositionTextPainter.java deleted file mode 100644 index 0084f491f..000000000 --- a/app/src/processing/app/syntax/im/CompositionTextPainter.java +++ /dev/null @@ -1,124 +0,0 @@ -package processing.app.syntax.im; - -import java.awt.Color; -import java.awt.FontMetrics; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.Point; -import java.awt.font.TextLayout; - -import processing.app.syntax.JEditTextArea; -import processing.app.syntax.TextAreaPainter; - -/** - * Paint texts from input method. Text via input method are transmitted by - * AttributedCaharacterIterator. This class helps the PDE's TextAreaPainter - * to handle AttributedCaharacterIterator. - * - * For practical purposes, paint to textarea is done by TextLayout class. - * Because TextLayout class is easy to draw composing texts. (For example, - * draw underline composing texts, focus when select from candidates text.) - * - * @author Takashi Maekawa (takachin@generative.info) - */ -public class CompositionTextPainter { - private TextLayout composedTextLayout; - private int composedBeginCaretPosition = 0; - private JEditTextArea textArea; - - /** - * Constructor for painter. - * @param textarea textarea used by PDE. - */ - public CompositionTextPainter(JEditTextArea textArea) { - this.textArea = textArea; - composedTextLayout = null; - } - - /** - * Check the painter has TextLayout. - * If a user input via InputMethod, this result will return true. - * @param textarea textarea used by PDE. - */ - public boolean hasComposedTextLayout() { - return (composedTextLayout != null); - } - - /** - * Set TextLayout to the painter. - * TextLayout will be created and set by CompositionTextManager. - * - * @see CompositionTextManager - * @param textarea textarea used by PDE. - */ - public void setComposedTextLayout(TextLayout composedTextLayout, int composedStartCaretPosition) { - this.composedTextLayout = composedTextLayout; - this.composedBeginCaretPosition = composedStartCaretPosition; - } - - /** - * Invalidate this TextLayout to set null. - * If a user end input via InputMethod, this method will called from CompositionTextManager.endCompositionText - */ - public void invalidateComposedTextLayout(int composedEndCaretPosition) { - this.composedTextLayout = null; - this.composedBeginCaretPosition = composedEndCaretPosition; - //this.composedBeginCaretPosition = textArea.getCaretPosition(); - } - - /** - * Draw text via input method with composed text information. - * This method can draw texts with some underlines to illustrate converting characters. - * - * This method is workaround for TextAreaPainter. - * Because, TextAreaPainter can't treat AttributedCharacterIterator directly. - * AttributedCharacterIterator has very important information when composing text. - * It has a map where are converted characters and committed characters. - * Ideally, changing TextAreaPainter method can treat AttributedCharacterIterator is better. But it's very tough!! - * So I choose to write some code as a workaround. - * - * This draw method is proceeded with the following steps. - * 1. Original TextAreaPainter draws characters. - * 2. This refillComposedArea method erase previous paint characters by textarea's background color. - * The refill area is only square that width and height defined by characters with input method. - * 3. CompositionTextPainter.draw method paints composed text. It was actually drawn by TextLayout. - * - * @param gfx set TextAreaPainter's Graphics object. - * @param fillBackGroundColor set textarea's background. - */ - public void draw(Graphics gfx, Color fillBackGroundColor) { - assert(composedTextLayout != null); - Point composedLoc = getCaretLocation(); - refillComposedArea(fillBackGroundColor, composedLoc.x, composedLoc.y); - composedTextLayout.draw((Graphics2D) gfx, composedLoc.x, composedLoc.y); - } - - /** - * Fill color to erase characters drawn by original TextAreaPainter. - * - * @param fillColor fill color to erase characters drawn by original TextAreaPainter method. - * @param x x-coordinate where to fill. - * @param y y-coordinate where to fill. - */ - private void refillComposedArea(Color fillColor, int x, int y) { - Graphics gfx = textArea.getPainter().getGraphics(); - gfx.setColor(fillColor); - FontMetrics fm = textArea.getPainter().getFontMetrics(); - int newY = y - (fm.getHeight() - CompositionTextManager.COMPOSING_UNDERBAR_HEIGHT); - int paintHeight = fm.getHeight(); - int paintWidth = (int) composedTextLayout.getBounds().getWidth(); - gfx.fillRect(x, newY, paintWidth, paintHeight); - } - - private Point getCaretLocation() { - Point loc = new Point(); - TextAreaPainter painter = textArea.getPainter(); - FontMetrics fm = painter.getFontMetrics(); - int offsetY = fm.getHeight() - CompositionTextManager.COMPOSING_UNDERBAR_HEIGHT; - int lineIndex = textArea.getCaretLine(); - loc.y = lineIndex * fm.getHeight() + offsetY; - int offsetX = composedBeginCaretPosition - textArea.getLineStartOffset(lineIndex); - loc.x = textArea.offsetToX(lineIndex, offsetX); - return loc; - } -} diff --git a/app/src/processing/app/syntax/im/InputMethodSupport.java b/app/src/processing/app/syntax/im/InputMethodSupport.java deleted file mode 100644 index 461be3d16..000000000 --- a/app/src/processing/app/syntax/im/InputMethodSupport.java +++ /dev/null @@ -1,120 +0,0 @@ -package processing.app.syntax.im; - -import java.awt.Rectangle; -import java.awt.event.InputMethodEvent; -import java.awt.event.InputMethodListener; -import java.awt.font.TextHitInfo; -import java.awt.im.InputMethodRequests; -import java.text.AttributedCharacterIterator; - -import processing.app.syntax.JEditTextArea; - -/** - * Support in-line Japanese input for PDE. (Maybe Chinese, Korean and more) - * This class is implemented by Java Input Method Framework and handles - * If you would like to know more about Java Input Method Framework, - * Please see http://java.sun.com/j2se/1.5.0/docs/guide/imf/ - * - * This class is implemented to fix Bug #854. - * http://dev.processing.org/bugs/show_bug.cgi?id=854 - * - * @author Takashi Maekawa (takachin@generative.info) - */ -public class InputMethodSupport implements InputMethodRequests, - InputMethodListener { - - private int committed_count = 0; - private CompositionTextManager textManager; - - public InputMethodSupport(JEditTextArea textArea) { - textManager = new CompositionTextManager(textArea); - textArea.enableInputMethods(true); - textArea.addInputMethodListener(this); - } - - public Rectangle getTextLocation(TextHitInfo offset) { - return textManager.getTextLocation(); - } - - public TextHitInfo getLocationOffset(int x, int y) { - return null; - } - - public int getInsertPositionOffset() { - return textManager.getInsertPositionOffset(); - } - - public AttributedCharacterIterator getCommittedText(int beginIndex, - int endIndex, AttributedCharacterIterator.Attribute[] attributes) { - return textManager.getCommittedText(beginIndex, endIndex); - } - - public int getCommittedTextLength() { - return committed_count; - } - - public AttributedCharacterIterator cancelLatestCommittedText( - AttributedCharacterIterator.Attribute[] attributes) { - return null; - } - - public AttributedCharacterIterator getSelectedText( - AttributedCharacterIterator.Attribute[] attributes) { - return null; - } - - /** - * Handles events from InputMethod. - * This method judges whether beginning of input or - * progress of input or end and call related method. - * - * @param event event from Input Method. - */ - public void inputMethodTextChanged(InputMethodEvent event) { - AttributedCharacterIterator text = event.getText(); - committed_count = event.getCommittedCharacterCount(); - if(isFullWidthSpaceInput(text)){ - textManager.insertFullWidthSpace(); - caretPositionChanged(event); - return; - } - if(isBeginInputProcess(text, textManager)){ - textManager.beginCompositionText(text, committed_count); - caretPositionChanged(event); - return; - } - if (isInputProcess(text)){ - textManager.processCompositionText(text, committed_count); - caretPositionChanged(event); - return; - } - textManager.endCompositionText(text, committed_count); - caretPositionChanged(event); - } - - private boolean isFullWidthSpaceInput(AttributedCharacterIterator text){ - if(text == null) - return false; - if(textManager.getIsInputProcess()) - return false; - return (String.valueOf(text.first()).equals("\u3000")); - } - - private boolean isBeginInputProcess(AttributedCharacterIterator text, CompositionTextManager textManager){ - if(text == null) - return false; - if(textManager.getIsInputProcess()) - return false; - return (isInputProcess(text)); - } - - private boolean isInputProcess(AttributedCharacterIterator text){ - if(text == null) - return false; - return (text.getEndIndex() - (text.getBeginIndex() + committed_count) > 0); - } - - public void caretPositionChanged(InputMethodEvent event) { - event.consume(); - } -} diff --git a/app/src/processing/app/syntax/readme.txt b/app/src/processing/app/syntax/readme.txt deleted file mode 100644 index 07a825cd7..000000000 --- a/app/src/processing/app/syntax/readme.txt +++ /dev/null @@ -1,46 +0,0 @@ -OLDSYNTAX PACKAGE README - -I am placing the jEdit 2.2.1 syntax highlighting package in the public -domain. This means it can be integrated into commercial programs, etc. - -This package requires at least Java 1.1 and Swing 1.1. Syntax -highlighting for the following file types is supported: - -- C++, C -- CORBA IDL -- Eiffel -- HTML -- Java -- Java properties -- JavaScript -- MS-DOS INI -- MS-DOS batch files -- Makefile -- PHP -- Perl -- Python -- TeX -- Transact-SQL -- Unix patch/diff -- Unix shell script -- XML - -This package is undocumented; read the source (start by taking a look at -JEditTextArea.java) to find out how to use it; it's really simple. Feel -free to e-mail questions, queries, etc. to me, but keep in mind that -this code is very old and I no longer maintain it. So if you find a bug, -don't bother me about it; fix it yourself. - -* Copyright - -The jEdit 2.2.1 syntax highlighting package contains code that is -Copyright 1998-1999 Slava Pestov, Artur Biesiadowski, Clancy Malcolm, -Jonathan Revusky, Juha Lindfors and Mike Dillon. - -You may use and modify this package for any purpose. Redistribution is -permitted, in both source and binary form, provided that this notice -remains intact in all source distributions of this package. - --- Slava Pestov -25 September 2000 - diff --git a/app/test/processing/app/helpers/JEditTextAreaComponentDriver.java b/app/test/processing/app/helpers/JEditTextAreaComponentDriver.java deleted file mode 100644 index 22ef7848c..000000000 --- a/app/test/processing/app/helpers/JEditTextAreaComponentDriver.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * This file is part of Arduino. - * - * Copyright 2015 Arduino LLC (http://www.arduino.cc/) - * - * Arduino is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * As a special exception, you may use this file as part of a free software - * library without restriction. Specifically, if other files instantiate - * templates or use macros or inline functions from this file, or you compile - * this file and link it with other files to produce an executable, this - * file does not by itself cause the resulting executable to be covered by - * the GNU General Public License. This exception does not however - * invalidate any other reasons why the executable file might be covered by - * the GNU General Public License. - */ - -package processing.app.helpers; - -import org.fest.swing.core.Robot; -import org.fest.swing.driver.JComponentDriver; -import org.fest.swing.edt.GuiActionRunner; -import org.fest.swing.edt.GuiQuery; -import processing.app.syntax.JEditTextArea; - -public class JEditTextAreaComponentDriver extends JComponentDriver { - - public JEditTextAreaComponentDriver(Robot robot) { - super(robot); - } - - public void enterText(JEditTextArea target, String text) { - focusAndWaitForFocusGain(target); - robot.enterText(text); - } - - public void setText(final JEditTextArea target, final String text) { - focusAndWaitForFocusGain(target); - GuiActionRunner.execute(new GuiQuery() { - - protected JEditTextArea executeInEDT() { - target.setText(text); - return target; - } - - }); - robot.waitForIdle(); - } - - public String getText(final JEditTextArea target) { - focusAndWaitForFocusGain(target); - return GuiActionRunner.execute(new GuiQuery() { - - protected String executeInEDT() { - return target.getText(); - } - - }); - } - - public JEditTextArea selectAll(final JEditTextArea target) { - return GuiActionRunner.execute(new GuiQuery() { - - protected JEditTextArea executeInEDT() { - target.selectAll(); - return target; - } - - }); - } - - public Integer getCaretPosition(final JEditTextArea target) { - focusAndWaitForFocusGain(target); - return GuiActionRunner.execute(new GuiQuery() { - - protected Integer executeInEDT() { - return target.getCaretPosition(); - } - - }); - } - - public void setCaretPosition(final JEditTextArea target, final int caretPosition) { - focusAndWaitForFocusGain(target); - GuiActionRunner.execute(new GuiQuery() { - - protected JEditTextArea executeInEDT() { - target.setCaretPosition(caretPosition); - return target; - } - - }); - robot.waitForIdle(); - } - -} diff --git a/app/test/processing/app/helpers/JEditTextAreaComponentMatcher.java b/app/test/processing/app/helpers/JEditTextAreaComponentMatcher.java deleted file mode 100644 index ad6f0ce77..000000000 --- a/app/test/processing/app/helpers/JEditTextAreaComponentMatcher.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of Arduino. - * - * Copyright 2015 Arduino LLC (http://www.arduino.cc/) - * - * Arduino is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * As a special exception, you may use this file as part of a free software - * library without restriction. Specifically, if other files instantiate - * templates or use macros or inline functions from this file, or you compile - * this file and link it with other files to produce an executable, this - * file does not by itself cause the resulting executable to be covered by - * the GNU General Public License. This exception does not however - * invalidate any other reasons why the executable file might be covered by - * the GNU General Public License. - */ - -package processing.app.helpers; - -import org.fest.swing.core.ComponentMatcher; -import processing.app.syntax.JEditTextArea; - -import java.awt.*; - -public class JEditTextAreaComponentMatcher implements ComponentMatcher { - - private final String name; - - public JEditTextAreaComponentMatcher(String name) { - this.name = name; - } - - @Override - public boolean matches(Component component) { - return component instanceof JEditTextArea && name.equals(component.getName()); - } -} diff --git a/app/test/processing/app/helpers/JEditTextAreaFixture.java b/app/test/processing/app/helpers/JEditTextAreaFixture.java deleted file mode 100644 index 291910abe..000000000 --- a/app/test/processing/app/helpers/JEditTextAreaFixture.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * This file is part of Arduino. - * - * Copyright 2015 Arduino LLC (http://www.arduino.cc/) - * - * Arduino is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * As a special exception, you may use this file as part of a free software - * library without restriction. Specifically, if other files instantiate - * templates or use macros or inline functions from this file, or you compile - * this file and link it with other files to produce an executable, this - * file does not by itself cause the resulting executable to be covered by - * the GNU General Public License. This exception does not however - * invalidate any other reasons why the executable file might be covered by - * the GNU General Public License. - */ - -package processing.app.helpers; - -import org.fest.swing.core.Robot; -import org.fest.swing.fixture.ComponentFixture; -import processing.app.syntax.JEditTextArea; - -public class JEditTextAreaFixture extends ComponentFixture { - - private final JEditTextAreaComponentDriver driver; - - public JEditTextAreaFixture(Robot robot, Class type) { - super(robot, type); - this.driver = new JEditTextAreaComponentDriver(robot); - } - - public JEditTextAreaFixture(Robot robot, String name, Class type) { - super(robot, name, type); - this.driver = new JEditTextAreaComponentDriver(robot); - } - - public JEditTextAreaFixture(Robot robot, JEditTextArea target) { - super(robot, target); - this.driver = new JEditTextAreaComponentDriver(robot); - } - - public JEditTextAreaFixture enterText(String text) { - driver.enterText((JEditTextArea) target, text); - return this; - } - - public JEditTextAreaFixture setText(String text) { - driver.setText((JEditTextArea) target, text); - return this; - } - - public String getText() { - return driver.getText((JEditTextArea) target); - } - - public JEditTextAreaFixture selectAll() { - driver.selectAll((JEditTextArea) target); - return this; - } - - public int getCaretPosition() { - return driver.getCaretPosition((JEditTextArea) target); - } - - public void setCaretPosition(int caretPosition) { - driver.setCaretPosition((JEditTextArea) target, caretPosition); - } -}