/*
Реализация спецификаций CLDC версии 1.1 (JSR-139), MIDP версии 2.1 (JSR-118)
и других спецификаций для функционирования компактных приложений на языке
Java (мидлетов) в среде программного обеспечения Малик Эмулятор.
Copyright © 2016, 2019 Малик Разработчик
Это свободная программа: вы можете перераспространять ее и/или изменять
ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
общественной лицензии GNU.
Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<https://www.gnu.org/licenses/>.
*/
package javax.microedition.lcdui;
import java.lang.ref.*;
import malik.emulator.io.j2me.input.*;
public final class TextInput extends TextOutputMultilined
implements CharDestination, Input
{
private static final class InputCommandHandler extends WeakReference
implements CommandListener
{
InputCommandHandler(CommandListener thisListener)
{
super(thisListener);
}
public void commandAction(Command command, Displayable screen)
{
CommandListener thisListener;
if((thisListener = (CommandListener) get()) == null)
{
return;
}
thisListener.commandAction(command, screen);
}
}
public static final char DEFAULT_PASSWORD_CHAR = 0x2022;
public static final int DEFAULT_CHAR_ARRAY_LENGTH = 1024;
private static String CLIP_BOARD;
private static final char[][] CHARACTER_SUBSETS_CHARS;
private static final String[] CHARACTER_SUBSETS_NAMES;
private static final Command[] ADDITIONAL_CAPABILITIES_COMMANDS;
static
{
CHARACTER_SUBSETS_CHARS = new char[][] {
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".toCharArray(), (
"АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ" +
"абвгдеёжзийклмнопрстуфхцчшщъыьэюя").toCharArray(), (
"\u0400\u0401\u0402\u0403\u0404\u0405\u0406\u0407" +
"\u0408\u0409\u040a\u040b\u040c\u040d\u040e\u040f" +
"\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417" +
"\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f" +
"\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427" +
"\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f" +
"\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437" +
"\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f" +
"\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447" +
"\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f" +
"\u0450\u0451\u0452\u0453\u0454\u0455\u0456\u0457" +
"\u0458\u0459\u045a\u045b\u045c\u045d\u045e\u045f").toCharArray(), (
"\u0020\u0021\"\u0023\u0024\u0025\u0026\u0027" +
"\u0028\u0029\u002a\u002b\u002c\u002d\u002e\u002f" +
"\u003a\u003b\u003c\u003d\u003e\u003f\u0040\u005b" +
"\\\u005d\u005e\u005f\u0060\u007b\u007c\u007d" +
"\u007e\u00a1\u00a3\u00a4\u00a5\u00a7\u00bf\u20ac").toCharArray()
};
CHARACTER_SUBSETS_NAMES = new String[] {
"Базовая латиница",
"Кириллица (русский язык)",
"Кириллица (вся)",
"Прочие символы"
};
ADDITIONAL_CAPABILITIES_COMMANDS = new Command[] {
new Command("Вставить символ", Command.SCREEN, 0),
new Command("Перенос строки", Command.SCREEN, 0),
new Command("Язык ввода", Command.SCREEN, 0),
new Command("Скопировать", Command.SCREEN, 0),
new Command("Вставить", Command.SCREEN, 0)
};
}
public static boolean isConstraintsValid(int constraints)
{
return (constraints & CONSTRAINT_MASK) <= 5 && (constraints >>> 16) < 0x40;
}
public static boolean isConstraintsMatch(int constraints, String src)
{
boolean f;
int i;
int length;
if(!isConstraintsValid(constraints))
{
throw new IllegalArgumentException("TextInput.isConstraintsMatch: " +
"недопустимое значение параметра constraints.");
}
if(src == null)
{
return true;
}
length = src.length();
switch(constraints & CONSTRAINT_MASK)
{
case ANY:
case EMAILADDR:
case URL:
return true;
case NUMERIC:
for(i = 0; i < length; i++)
{
switch(src.charAt(i))
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
break;
case '-':
if(i > 0)
{
return false;
}
break;
default:
return false;
}
}
return true;
case PHONENUMBER:
for(i = 0; i < length; i++)
{
switch(src.charAt(i))
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '*':
case '#':
break;
case '+':
if(i > 0)
{
return false;
}
break;
default:
return false;
}
}
return true;
case DECIMAL:
f = false;
for(i = 0; i < length; i++)
{
switch(src.charAt(i))
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
break;
case '.':
if(f)
{
return false;
}
f = true;
break;
case '-':
if(i > 0)
{
return false;
}
break;
default:
return false;
}
}
return true;
}
return false;
}
public static boolean isConstraintsMatch(int constraints, char[] src, int offset, int length)
{
boolean f;
int i;
int j;
int lim;
int len;
if(!isConstraintsValid(constraints))
{
throw new IllegalArgumentException("TextInput.isConstraintsMatch: " +
"недопустимое значение параметра constraints.");
}
if(src == null)
{
return true;
}
if((lim = offset + length) > (len = src.length) ||
lim < offset || offset > len || offset < 0)
{
throw new IndexOutOfBoundsException("TextInput.isConstraintsMatch: " +
"индекс выходит из дапазона.");
}
switch(constraints & CONSTRAINT_MASK)
{
case ANY:
case EMAILADDR:
case URL:
return true;
case NUMERIC:
for(j = offset, i = 0; i < length; j++, i++)
{
switch(src[j])
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
break;
case '-':
if(i > 0)
{
return false;
}
break;
default:
return false;
}
}
return true;
case PHONENUMBER:
for(j = offset, i = 0; i < length; j++, i++)
{
switch(src[j])
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '*':
case '#':
break;
case '+':
if(i > 0)
{
return false;
}
break;
default:
return false;
}
}
return true;
case DECIMAL:
f = false;
for(j = offset, i = 0; i < length; j++, i++)
{
switch(src[j])
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
break;
case '.':
if(f)
{
return false;
}
f = true;
break;
case '-':
if(i > 0)
{
return false;
}
break;
default:
return false;
}
}
return true;
}
return false;
}
public static boolean isAdditionalCapabilitiesCommand(Command command)
{
int i;
for(i = ADDITIONAL_CAPABILITIES_COMMANDS.length; i-- > 0; )
{
if(ADDITIONAL_CAPABILITIES_COMMANDS[i] == command)
{
return true;
}
}
return false;
}
public static Command[] getAdditionalCapabilitiesCommands(int constraints,
boolean lineSeparatorAllowed)
{
boolean any;
int len;
Command[] result;
any = (len = constraints & CONSTRAINT_MASK) == ANY || len == EMAILADDR || len == URL;
switch((constraints >> 16) & 0x03)
{
default:
result = new Command[0];
break;
case UNEDITABLE >> 16:
result = new Command[] {
ADDITIONAL_CAPABILITIES_COMMANDS[3]
};
break;
case PASSWORD >> 16:
if(!any)
{
result = new Command[] {
ADDITIONAL_CAPABILITIES_COMMANDS[4]
};
}
else if(lineSeparatorAllowed)
{
result = new Command[] {
ADDITIONAL_CAPABILITIES_COMMANDS[0],
ADDITIONAL_CAPABILITIES_COMMANDS[1],
ADDITIONAL_CAPABILITIES_COMMANDS[2],
ADDITIONAL_CAPABILITIES_COMMANDS[4]
};
}
else
{
result = new Command[] {
ADDITIONAL_CAPABILITIES_COMMANDS[0],
ADDITIONAL_CAPABILITIES_COMMANDS[2],
ADDITIONAL_CAPABILITIES_COMMANDS[4]
};
}
break;
case 0:
if(!any)
{
result = new Command[] {
ADDITIONAL_CAPABILITIES_COMMANDS[3],
ADDITIONAL_CAPABILITIES_COMMANDS[4]
};
}
else if(lineSeparatorAllowed)
{
Array.copy(ADDITIONAL_CAPABILITIES_COMMANDS, 0, result = new Command[len =
ADDITIONAL_CAPABILITIES_COMMANDS.length], 0, len);
}
else
{
result = new Command[] {
ADDITIONAL_CAPABILITIES_COMMANDS[0],
ADDITIONAL_CAPABILITIES_COMMANDS[2],
ADDITIONAL_CAPABILITIES_COMMANDS[3],
ADDITIONAL_CAPABILITIES_COMMANDS[4]
};
}
break;
}
return result;
}
private static void fillPasswordChars(char[] dst)
{
int i;
for(i = dst.length; i-- > 0; dst[i] = DEFAULT_PASSWORD_CHAR);
}
private static boolean isCapsLockPressed()
{
return (((int) MalikSystem.syscall(0L, 0x0051)) & 0x02) != 0;
}
public class AdditionalCapabilities extends Object
implements CommandListener
{
private CharList[] screensWithChars;
private List screenSelectCharset;
private List screenSelectLanguage;
private Displayable sourceScreen;
private CharDestination destination;
private CommandListener listener;
private Command back;
private Command insert;
public AdditionalCapabilities(CharDestination destination)
{
this.screensWithChars = new CharList[CHARACTER_SUBSETS_CHARS.length];
this.destination = destination;
this.listener = new InputCommandHandler(this);
}
public void commandAction(Command command, Displayable screen)
{
List list;
String content;
CharList charList;
Displayable source;
Display display = MIDletProxy.getInstance().getEmulatorScreen();
Command[] additional = ADDITIONAL_CAPABILITIES_COMMANDS;
if(command == additional[0])
{
sourceScreen = screen;
display.setCurrent(getScreenSelectCharset());
return;
}
if(command == additional[1])
{
destination.insert(LINE_SEPARATOR);
return;
}
if(command == additional[2])
{
sourceScreen = screen;
display.setCurrent(getScreenSelectLanguage());
return;
}
if(command == additional[3])
{
if((content = (TextInput.this).getString()).length() > 0)
{
CLIP_BOARD = content;
}
return;
}
if(command == additional[4])
{
destination.insert(CLIP_BOARD);
return;
}
if(screen == (list = screenSelectCharset))
{
if(command == List.SELECT_COMMAND)
{
display.setCurrent(getScreenWithChars(list.getSelectedIndex()));
return;
}
if(command == back)
{
if((source = sourceScreen) != null && source.isSystem())
{
display.setCurrent(source);
} else
{
display.hideSystemScreen();
}
sourceScreen = null;
}
return;
}
if(screen == (list = screenSelectLanguage))
{
if(command == List.SELECT_COMMAND)
{
(TextInput.this).setInputMode(AvailableInputModes.getInputModeAt(
list.getSelectedIndex()));
if((source = sourceScreen) != null && source.isSystem())
{
display.setCurrent(source);
} else
{
display.hideSystemScreen();
}
sourceScreen = null;
return;
}
if(command == back)
{
if((source = sourceScreen) != null && source.isSystem())
{
display.setCurrent(source);
} else
{
display.hideSystemScreen();
}
sourceScreen = null;
}
return;
}
if(screen instanceof CharList)
{
if(command == insert)
{
destination.insert((charList = (CharList) screen).getChar(
charList.getSelectedIndex()));
return;
}
if(command == back)
{
display.setCurrent(getScreenSelectCharset());
}
}
}
private Command getBack()
{
Command result;
if((result = back) == null)
{
result = back = new Command("Назад", Command.BACK, 0);
}
return result;
}
private Command getInsert()
{
Command result;
if((result = insert) == null)
{
result = insert = new Command("Вставить", Command.OK, 0);
}
return result;
}
private List getScreenSelectCharset()
{
Command[] commands;
String title;
List result;
if((result = screenSelectCharset) == null)
{
title = "Выберите набор символов:";
commands = new Command[] {
getBack()
};
result = screenSelectCharset = new List(false, title, null,
commands, List.SELECT_COMMAND, listener,
Choice.IMPLICIT, CHARACTER_SUBSETS_NAMES, null);
}
return result;
}
private List getScreenSelectLanguage()
{
int i;
Command[] commands;
String title;
List result;
if((result = screenSelectLanguage) == null)
{
title = "Язык ввода";
commands = new Command[] {
getBack()
};
result = screenSelectLanguage = new List(false, title, null,
commands, List.SELECT_COMMAND, listener,
Choice.IMPLICIT, new String[0], null);
for(i = 0; i < AvailableInputModes.getCount(); i++)
{
result.append(AvailableInputModes.getInputModeAt(i).getLocalizedName(), null);
}
}
return result;
}
private CharList getScreenWithChars(int index)
{
Command[] commands;
CharList[] screens;
CharList result;
String title;
if((result = (screens = screensWithChars)[index]) == null)
{
title = CHARACTER_SUBSETS_NAMES[index];
commands = new Command[] {
getBack()
};
result = screens[index] = new CharList(false, title, null,
commands, getInsert(), listener,
CHARACTER_SUBSETS_CHARS[index]);
}
return result;
}
}
private boolean shiftPressed;
private boolean changed;
private int caretPosition;
private int maxLength;
private int constraints;
private char[] content;
private InputMode mode;
public TextInput(String text, int maxLength, int constraints)
{
this(text, maxLength, constraints, DEFAULT_CHAR_ARRAY_LENGTH);
}
public TextInput(String text, int maxLength, int constraints, int charArrayLength)
{
int len;
char[] chars;
char[] content;
if(text == null)
{
text = "";
}
if(charArrayLength < DEFAULT_CHAR_ARRAY_LENGTH)
{
charArrayLength = DEFAULT_CHAR_ARRAY_LENGTH;
}
if(maxLength <= 0)
{
throw new IllegalArgumentException("TextInput: " +
"параметр maxLength может быть только положительным.");
}
if(!isConstraintsValid(constraints))
{
throw new IllegalArgumentException("TextInput: " +
"недопустимое значение параметра constraints.");
}
if(!isConstraintsMatch(constraints, text))
{
throw new IllegalArgumentException("TextInput: " +
"заданный текст не соответствует заданным ограничениям.");
}
if((len = text.length()) > maxLength)
{
throw new IllegalArgumentException("TextInput: " +
"длина текста больше заданной максимальной длины.");
}
if(maxLength > charArrayLength)
{
maxLength = charArrayLength;
}
len = Math.min(len, maxLength);
chars = new char[charArrayLength];
content = new char[charArrayLength];
if((constraints & PASSWORD) != 0)
{
fillPasswordChars(chars);
} else
{
text.getChars(0, len, chars, 0);
}
text.getChars(0, len, content, 0);
this.length = len;
this.chars = chars;
this.maxLength = maxLength;
this.constraints = constraints;
this.content = content;
this.mode = AvailableInputModes.getSystemInputMode();
}
public void clear()
{
length = 0;
caretPosition = 0;
}
public void setText(String text)
{
setString(text);
}
public void append(String data)
{
if(data == null)
{
return;
}
insert(data, this.length);
}
public void append(char[] data, int offset, int length)
{
if(data == null)
{
return;
}
insert(data, offset, length, this.length);
}
public void append(int data, int radix, boolean upperCase)
{
boolean negative;
int value;
int digit;
int len;
int i;
char[] c = new char[len = i = 33];
value = (negative = data < 0) ? data : -data;
if(radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
{
radix = 10;
}
do
{
c[--i] = (char) ((digit = -(value % radix)) < 10 ?
digit + '0' : digit + (upperCase ? 'A' - 10 : 'a' - 10));
} while((value /= radix) != 0);
if(negative)
{
c[--i] = '-';
}
insert(c, i, len - i, this.length);
}
public void insert(char src)
{
int apos;
int bpos;
int curLength;
int newLength;
int remLength;
int constraints;
char[] content;
if(((constraints = this.constraints) & UNEDITABLE) != 0 ||
(newLength = (curLength = this.length) + 1) > maxLength)
{
return;
}
content = this.content;
bpos = (apos = caretPosition) + 1;
if((remLength = curLength - apos) > 0)
{
Array.copy(content, apos, content, bpos, remLength);
}
content[apos] = src;
if(!isConstraintsMatch(constraints, content, 0, newLength))
{
if(remLength > 0)
{
Array.copy(content, bpos, content, apos, remLength);
}
return;
}
if((constraints & PASSWORD) == 0 && newLength > 0)
{
Array.copy(content, 0, chars, 0, newLength);
}
this.length = newLength;
this.changed = true;
this.caretPosition = bpos;
}
public void insert(String src)
{
int apos;
int bpos;
int length;
int curLength;
int newLength;
int remLength;
int constraints;
char[] content;
if((length = src == null ? 0 : src.length()) == 0)
{
this.changed = true;
return;
}
if(((constraints = this.constraints) & UNEDITABLE) != 0 ||
(newLength = (curLength = this.length) + length) > maxLength)
{
return;
}
content = this.content;
bpos = (apos = caretPosition) + length;
if((remLength = curLength - apos) > 0)
{
Array.copy(content, apos, content, bpos, remLength);
}
src.getChars(0, length, content, apos);
if(!isConstraintsMatch(constraints, content, 0, newLength))
{
if(remLength > 0)
{
Array.copy(content, bpos, content, apos, remLength);
}
return;
}
if((constraints & PASSWORD) == 0 && newLength > 0)
{
Array.copy(content, 0, chars, 0, newLength);
}
this.length = newLength;
this.changed = true;
this.caretPosition = bpos;
}
public void insert(String src, int position)
{
int apos;
int bpos;
int length;
int curLength;
int newLength;
int remLength;
int constraints;
char[] content;
if(src == null)
{
throw new NullPointerException("TextInput.insert: " +
"параметр src равен нулевой ссылке.");
}
if((newLength = (curLength = this.length) + (length = src.length())) > maxLength)
{
throw new IllegalArgumentException("TextInput.insert: " +
"длина текста больше заданной максимальной длины.");
}
content = this.content;
bpos = (apos = position < 0 ? 0 : (position > curLength ? curLength : position)) + length;
if((remLength = curLength - apos) > 0)
{
Array.copy(content, apos, content, bpos, remLength);
}
if(length > 0)
{
src.getChars(0, length, content, apos);
}
if(!isConstraintsMatch(constraints = this.constraints, content, 0, newLength))
{
if(remLength > 0)
{
Array.copy(content, bpos, content, apos, remLength);
}
throw new IllegalArgumentException("TextInput.insert: " +
"заданный текст не соответствует заданным ограничениям.");
}
if((constraints & PASSWORD) == 0 && newLength > 0)
{
Array.copy(content, 0, chars, 0, newLength);
}
this.length = newLength;
}
public void insert(char[] src, int offset, int length, int position)
{
int lim;
int len;
int apos;
int bpos;
int curLength;
int newLength;
int remLength;
int constraints;
char[] content;
if(src == null)
{
throw new NullPointerException("TextInput.insert: " +
"параметр src равен нулевой ссылке.");
}
if((lim = offset + length) > (len = src.length) ||
lim < offset || offset > len || offset < 0)
{
throw new ArrayIndexOutOfBoundsException("TextInput.insert: " +
"индекс выходит из диапазона.");
}
if((newLength = (curLength = this.length) + length) > maxLength)
{
throw new IllegalArgumentException("TextInput.insert: " +
"длина текста больше заданной максимальной длины.");
}
content = this.content;
bpos = (apos = position < 0 ? 0 : (position > curLength ? curLength : position)) + length;
if((remLength = curLength - apos) > 0)
{
Array.copy(content, apos, content, bpos, remLength);
}
if(length > 0)
{
Array.copy(src, offset, content, apos, length);
}
if(!isConstraintsMatch(constraints = this.constraints, content, 0, newLength))
{
if(remLength > 0)
{
Array.copy(content, bpos, content, apos, remLength);
}
throw new IllegalArgumentException("TextInput.insert: " +
"заданный текст не соответствует заданным ограничениям.");
}
if((constraints & PASSWORD) == 0 && newLength > 0)
{
Array.copy(content, 0, chars, 0, newLength);
}
this.length = newLength;
}
public void delete(int offset, int length)
{
int lim;
int len;
int apos;
int bpos;
int curLength;
int newLength;
int remLength;
char[] content;
if((lim = offset + length) > (len = this.length) ||
lim < offset || offset > len || offset < 0)
{
throw new StringIndexOutOfBoundsException("TextInput.delete: " +
"индекс выходит из диапазона.");
}
curLength = len;
content = this.content;
bpos = (apos = offset) + length;
if((remLength = len - bpos) > 0)
{
Array.copy(content, bpos, content, apos, remLength);
}
if(caretPosition > (newLength = curLength - length))
{
caretPosition = newLength;
}
if((constraints & PASSWORD) == 0 && newLength > 0)
{
Array.copy(content, 0, chars, 0, newLength);
}
this.length = newLength;
}
public void setString(String src)
{
int newLength;
int constraints;
if(src == null)
{
src = "";
}
if((newLength = src.length()) > maxLength)
{
throw new IllegalArgumentException("TextInput.setString: " +
"длина текста больше заданной максимальной длины.");
}
if(!isConstraintsMatch(constraints = this.constraints, src))
{
throw new IllegalArgumentException("TextInput.setString: " +
"заданный текст не соответствует заданным ограничениям.");
}
if(newLength > 0)
{
src.getChars(0, newLength, content, 0);
}
if(caretPosition > newLength)
{
caretPosition = newLength;
}
if((constraints & PASSWORD) == 0 && newLength > 0)
{
src.getChars(0, newLength, chars, 0);
}
this.length = newLength;
}
public void setChars(char[] src, int offset, int length)
{
int lim;
int len;
int newLength;
int constraints;
char[] tmp;
if(src == null)
{
setString(null);
return;
}
if((lim = offset + length) > (len = src.length) ||
lim < offset || offset > len || offset < 0)
{
throw new ArrayIndexOutOfBoundsException("TextInput.setChars: " +
"индекс выходит из диапазона.");
}
Array.copy(src, offset, tmp = new char[length], 0, length);
if((newLength = length) > maxLength)
{
throw new IllegalArgumentException("TextInput.setChars: " +
"длина текста больше заданной максимальной длины.");
}
if(!isConstraintsMatch(constraints = this.constraints, tmp, 0, newLength))
{
throw new IllegalArgumentException("TextInput.setChars: " +
"заданный текст не соответствует заданным ограничениям.");
}
if(newLength > 0)
{
Array.copy(tmp, 0, content, 0, newLength);
}
if(caretPosition > newLength)
{
caretPosition = newLength;
}
if((constraints & PASSWORD) == 0 && newLength > 0)
{
Array.copy(tmp, 0, chars, 0, newLength);
}
this.length = newLength;
}
public void setConstraints(int constraints)
{
int len;
int oldConstraints;
char[] content;
if((oldConstraints = this.constraints) == constraints)
{
return;
}
if(!isConstraintsValid(constraints))
{
throw new IllegalArgumentException("TextInput.setConstraints: " +
"недопустимое значение параметра constraints.");
}
if(!isConstraintsMatch(constraints, content = this.content, 0, len = length))
{
length = len = 0;
caretPosition = 0;
}
if((oldConstraints & PASSWORD) == 0 && (constraints & PASSWORD) != 0)
{
fillPasswordChars(chars);
}
if((oldConstraints & PASSWORD) != 0 && (constraints & PASSWORD) == 0 && len > 0)
{
Array.copy(content, 0, chars, 0, len);
}
this.constraints = constraints;
}
public void setInitialInputMode(String characterSubset)
{
mode = AvailableInputModes.getInputMode(characterSubset);
}
public int setMaxSize(int maxLength)
{
int tmp;
if(maxLength <= 0)
{
throw new IllegalArgumentException("TextInput.setMaxSize: " +
"недопустимое значение параметра maxLength.");
}
if(maxLength > (tmp = content.length))
{
maxLength = tmp;
}
if(caretPosition > maxLength)
{
caretPosition = maxLength;
}
if(length > maxLength)
{
length = maxLength;
}
return this.maxLength = maxLength;
}
public int size()
{
return length;
}
public int getChars(char[] dst)
{
int result;
if(dst == null)
{
throw new NullPointerException("TextInput.getChars: " +
"параметр dst равен нулевой ссылке.");
}
if(dst.length < (result = length))
{
throw new ArrayIndexOutOfBoundsException("TextInput.getChars: " +
"параметр dst имеет маленькую длину, не позволяющую уместить все символы.");
}
Array.copy(content, 0, dst, 0, result);
return result;
}
public int getConstraints()
{
return constraints;
}
public int getCaretPosition()
{
return caretPosition;
}
public int getMaxSize()
{
return maxLength;
}
public String getString()
{
return (new String(content, 0, length)).intern();
}
public void keyPressed(int key, int charCode)
{
boolean shift;
int tmp;
InputMode mode;
changed = false;
switch(key)
{
case MIDletProxy.KEY_TAB:
/* Нет реакции на клавишу Tab. */
return;
case MIDletProxy.KEY_SHIFT:
case MIDletProxy.KEY_LSHIFT:
case MIDletProxy.KEY_RSHIFT:
/* Нажатие любого Shift. */
shiftPressed = true;
return;
case MIDletProxy.KEY_BACKSPACE:
/* Стереть символ перед кареткой (если он есть). */
if((constraints & UNEDITABLE) == 0 && (tmp = caretPosition) > 0)
{
changed = true;
caretPosition = --tmp;
delete(tmp, 1);
}
return;
case MIDletProxy.KEY_ENTER:
/* Вставка символа перевода строки '\n' и сдвиг каретки. */
insert(LINE_SEPARATOR);
return;
}
/* Обработка нажатия алфавитно-цифровых клавиш */
if((constraints & UNEDITABLE) == 0 && charCode > 0 && (mode = this.mode) != null)
{
shift = shiftPressed;
mode.keyPressedHandle(shift, shift ^ isCapsLockPressed(), key, charCode, this);
}
}
public void keyReleased(int key)
{
switch(key)
{
case MIDletProxy.KEY_SHIFT:
case MIDletProxy.KEY_LSHIFT:
case MIDletProxy.KEY_RSHIFT:
shiftPressed = false;
break;
}
}
public void setCaretPosition(int caretPosition)
{
int tmp;
this.caretPosition = caretPosition < 0 ? 0 :
(caretPosition > (tmp = length) ? tmp : caretPosition);
}
public void setInputMode(InputMode mode)
{
this.mode = mode == null ? AvailableInputModes.getSystemInputMode() : mode;
}
public boolean isChanged()
{
return changed;
}
public int getCaretLine()
{
return getLineAt(caretPosition);
}
public InputMode getInputMode()
{
return mode;
}
}