mirror of
https://github.com/esp8266/Arduino.git
synced 2025-06-17 22:23:10 +03:00
removing files from the old editor
This commit is contained in:
committed by
Federico Fissore
parent
e70545948c
commit
2e497c6c47
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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
|
|
||||||
* <i>[modifiers+]key</i> 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 <i>modifiers</i>+<i>shortcut</i> where <i>modifiers</i>
|
|
||||||
* is any combination of A for Alt, C for Control, S for Shift
|
|
||||||
* or M for Meta, and <i>shortcut</i> is either a single character,
|
|
||||||
* or a keycode name from the <code>KeyEvent</code> class, without
|
|
||||||
* the <code>VK_</code> 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;
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -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 <code>KeywordMap</code> 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.
|
|
||||||
* <p>
|
|
||||||
* This class is used by <code>CTokenMarker</code> to map keywords to ids.
|
|
||||||
*
|
|
||||||
* @author Slava Pestov, Mike Dillon
|
|
||||||
*/
|
|
||||||
public class KeywordMap
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Creates a new <code>KeywordMap</code>.
|
|
||||||
* @param ignoreCase True if keys are case insensitive
|
|
||||||
*/
|
|
||||||
public KeywordMap(boolean ignoreCase)
|
|
||||||
{
|
|
||||||
this(ignoreCase, 52);
|
|
||||||
this.ignoreCase = ignoreCase;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new <code>KeywordMap</code>.
|
|
||||||
* @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;
|
|
||||||
}
|
|
@ -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");
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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<TextAttribute, Object> attr = new Hashtable<TextAttribute, Object>();
|
|
||||||
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<TextAttribute, Object> attr = new Hashtable<TextAttribute, Object>();
|
|
||||||
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;
|
|
||||||
}
|
|
@ -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 <code>Segment</code> 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 <code>Segment</code> 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
|
|
||||||
* <code>setStyles()</code> method of <code>SyntaxDocument</code>
|
|
||||||
* 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 <b><something></b>" pattern.
|
|
||||||
*
|
|
||||||
* @param line
|
|
||||||
* A string to parse
|
|
||||||
* @return <b>null</b> 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 <b><something></b> 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() {}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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 <i>n</i>
|
|
||||||
* will be used to paint tokens with id = <i>n</i>.
|
|
||||||
* @see processing.app.syntax.Token
|
|
||||||
*/
|
|
||||||
public final SyntaxStyle[] getStyles()
|
|
||||||
{
|
|
||||||
return styles;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the syntax styles used to paint colorized text. Entry <i>n</i>
|
|
||||||
* will be used to paint tokens with id = <i>n</i>.
|
|
||||||
* @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 <i>x</i>
|
|
||||||
*/
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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.<p>
|
|
||||||
*
|
|
||||||
* For performance reasons, the linked list of tokens is reused after each
|
|
||||||
* line is tokenized. Therefore, the return value of <code>markTokens</code>
|
|
||||||
* 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 <code>markTokensImpl</code> 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 <code>addToken()</code> to
|
|
||||||
* add syntax tokens to the token list. Then, it should return
|
|
||||||
* the initial token type for the next line.<p>
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
* <code>markTokens()</code> method (in turn).<p>
|
|
||||||
*
|
|
||||||
* 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 <code>lineInfo</code>
|
|
||||||
* 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
|
|
||||||
* <code>lineInfo</code> 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 <code>markTokens()</code>.
|
|
||||||
*/
|
|
||||||
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 <code>insertLines()</code> and
|
|
||||||
* <code>deleteLines()</code> methods.
|
|
||||||
*/
|
|
||||||
protected LineInfo[] lineInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The number of lines in the model being tokenized. This can be
|
|
||||||
* less than the length of the <code>lineInfo</code> 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 <code>TokenMarker</code>. This DOES NOT create
|
|
||||||
* a lineInfo array; an initial call to <code>insertLines()</code>
|
|
||||||
* does that.
|
|
||||||
*/
|
|
||||||
protected TokenMarker()
|
|
||||||
{
|
|
||||||
lastLine = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ensures that the <code>lineInfo</code> array can contain the
|
|
||||||
* specified index. This enlarges it if necessary. No action is
|
|
||||||
* taken if the array is large enough already.<p>
|
|
||||||
*
|
|
||||||
* It should be unnecessary to call this under normal
|
|
||||||
* circumstances; <code>insertLine()</code> 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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -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
|
|
||||||
<sp@gjt.org>
|
|
@ -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<JEditTextArea>() {
|
|
||||||
|
|
||||||
protected JEditTextArea executeInEDT() {
|
|
||||||
target.setText(text);
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
robot.waitForIdle();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getText(final JEditTextArea target) {
|
|
||||||
focusAndWaitForFocusGain(target);
|
|
||||||
return GuiActionRunner.execute(new GuiQuery<String>() {
|
|
||||||
|
|
||||||
protected String executeInEDT() {
|
|
||||||
return target.getText();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public JEditTextArea selectAll(final JEditTextArea target) {
|
|
||||||
return GuiActionRunner.execute(new GuiQuery<JEditTextArea>() {
|
|
||||||
|
|
||||||
protected JEditTextArea executeInEDT() {
|
|
||||||
target.selectAll();
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getCaretPosition(final JEditTextArea target) {
|
|
||||||
focusAndWaitForFocusGain(target);
|
|
||||||
return GuiActionRunner.execute(new GuiQuery<Integer>() {
|
|
||||||
|
|
||||||
protected Integer executeInEDT() {
|
|
||||||
return target.getCaretPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCaretPosition(final JEditTextArea target, final int caretPosition) {
|
|
||||||
focusAndWaitForFocusGain(target);
|
|
||||||
GuiActionRunner.execute(new GuiQuery<JEditTextArea>() {
|
|
||||||
|
|
||||||
protected JEditTextArea executeInEDT() {
|
|
||||||
target.setCaretPosition(caretPosition);
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
robot.waitForIdle();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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());
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue
Block a user