fixed adding words in Ukrainian, Hebrew and Yiddish
This commit is contained in:
parent
3f22d45a3f
commit
2c1ea9c411
5 changed files with 132 additions and 36 deletions
|
|
@ -15,7 +15,6 @@ import io.github.sspanak.tt9.db.sqlite.ReadOps;
|
||||||
import io.github.sspanak.tt9.db.sqlite.SQLiteOpener;
|
import io.github.sspanak.tt9.db.sqlite.SQLiteOpener;
|
||||||
import io.github.sspanak.tt9.db.sqlite.UpdateOps;
|
import io.github.sspanak.tt9.db.sqlite.UpdateOps;
|
||||||
import io.github.sspanak.tt9.ime.TraditionalT9;
|
import io.github.sspanak.tt9.ime.TraditionalT9;
|
||||||
import io.github.sspanak.tt9.languages.Characters;
|
|
||||||
import io.github.sspanak.tt9.languages.EmojiLanguage;
|
import io.github.sspanak.tt9.languages.EmojiLanguage;
|
||||||
import io.github.sspanak.tt9.languages.Language;
|
import io.github.sspanak.tt9.languages.Language;
|
||||||
import io.github.sspanak.tt9.languages.Text;
|
import io.github.sspanak.tt9.languages.Text;
|
||||||
|
|
@ -138,7 +137,7 @@ public class WordStore {
|
||||||
return AddWordDialog.CODE_GENERAL_ERROR;
|
return AddWordDialog.CODE_GENERAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
language = Characters.isGraphic(word) ? new EmojiLanguage() : language;
|
language = Text.isGraphic(word) ? new EmojiLanguage() : language;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (readOps.exists(sqlite.getDb(), language, word)) {
|
if (readOps.exists(sqlite.getDb(), language, word)) {
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,6 @@ import android.view.inputmethod.InputConnection;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import io.github.sspanak.tt9.Logger;
|
import io.github.sspanak.tt9.Logger;
|
||||||
import io.github.sspanak.tt9.ime.modes.InputMode;
|
import io.github.sspanak.tt9.ime.modes.InputMode;
|
||||||
|
|
@ -24,12 +22,6 @@ import io.github.sspanak.tt9.languages.Text;
|
||||||
public class TextField {
|
public class TextField {
|
||||||
public static final int IME_ACTION_ENTER = EditorInfo.IME_MASK_ACTION + 1;
|
public static final int IME_ACTION_ENTER = EditorInfo.IME_MASK_ACTION + 1;
|
||||||
|
|
||||||
private static final Pattern beforeCursorWordRegex = Pattern.compile("([^\\s\\d\\p{P}]+)(?!\n)$");
|
|
||||||
private static final Pattern afterCursorWordRegex = Pattern.compile("^(?<!\n)([^\\s\\d\\p{P}]+)");
|
|
||||||
private static final Pattern beforeCursorUkrainianRegex = Pattern.compile("([(?:^\\s\\d\\p{P}|')]+)(?!\n)$");
|
|
||||||
private static final Pattern afterCursorUkrainianRegex = Pattern.compile("^(?<!\n)([(?:^\\s\\d\\p{P}|')]+)");
|
|
||||||
|
|
||||||
|
|
||||||
public final InputConnection connection;
|
public final InputConnection connection;
|
||||||
public final EditorInfo field;
|
public final EditorInfo field;
|
||||||
|
|
||||||
|
|
@ -175,21 +167,35 @@ public class TextField {
|
||||||
* Returns the word next or around the cursor. Scanning length is up to 50 chars in each direction.
|
* Returns the word next or around the cursor. Scanning length is up to 50 chars in each direction.
|
||||||
*/
|
*/
|
||||||
@NonNull public String getSurroundingWord(Language language) {
|
@NonNull public String getSurroundingWord(Language language) {
|
||||||
Matcher before;
|
Text before = getTextBeforeCursor();
|
||||||
Matcher after;
|
Text after = getTextAfterCursor(50);
|
||||||
|
|
||||||
if (language != null && (language.isHebrew() || language.isUkrainian())) {
|
// emoji
|
||||||
// Hebrew and Ukrainian use apostrophes as letters
|
boolean beforeEndsWithGraphics = before.endsWithGraphic();
|
||||||
before = beforeCursorUkrainianRegex.matcher(getStringBeforeCursor());
|
boolean afterStartsWithGraphics = after.startsWithGraphic();
|
||||||
after = afterCursorUkrainianRegex.matcher(getStringAfterCursor());
|
|
||||||
} else {
|
if (beforeEndsWithGraphics && afterStartsWithGraphics) {
|
||||||
// In other languages, special characters in words will cause automatic word break to fail,
|
return before.leaveEndingGraphics() + after.leaveStartingGraphics();
|
||||||
// resulting in unexpected suggestions. Therefore, they are not allowed.
|
|
||||||
before = beforeCursorWordRegex.matcher(getStringBeforeCursor());
|
|
||||||
after = afterCursorWordRegex.matcher(getStringAfterCursor());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (before.find() ? before.group(1) : "") + (after.find() ? after.group(1) : "");
|
if (afterStartsWithGraphics) {
|
||||||
|
return after.leaveStartingGraphics();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (beforeEndsWithGraphics) {
|
||||||
|
return before.leaveEndingGraphics();
|
||||||
|
}
|
||||||
|
|
||||||
|
// text
|
||||||
|
boolean keepApostrophe = false;
|
||||||
|
boolean keepQuote = false;
|
||||||
|
if (language != null) {
|
||||||
|
// Hebrew and Ukrainian use the respective special characters as letters
|
||||||
|
keepApostrophe = language.isHebrew() || language.isUkrainian();
|
||||||
|
keepQuote = language.isHebrew();
|
||||||
|
}
|
||||||
|
|
||||||
|
return before.subStringEndingWord(keepApostrophe, keepQuote) + after.subStringStartingWord(keepApostrophe, keepQuote);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,20 +58,9 @@ public class Characters {
|
||||||
))
|
))
|
||||||
));
|
));
|
||||||
|
|
||||||
public static boolean isGraphic(String str) {
|
|
||||||
if (str == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0, end = str.length(); i < end; i++) {
|
public static boolean isGraphic(char ch) {
|
||||||
char ch = str.charAt(i);
|
return !(ch < 256 || Character.isLetterOrDigit(ch) || Character.isAlphabetic(ch));
|
||||||
|
|
||||||
if (ch < 256 || Character.isLetterOrDigit(ch) || Character.isAlphabetic(ch)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean noEmojiSupported() {
|
public static boolean noEmojiSupported() {
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ public class EmojiLanguage extends Language {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDigitSequenceForWord(String word) {
|
public String getDigitSequenceForWord(String word) {
|
||||||
return Characters.isGraphic(word) ? CUSTOM_EMOJI_SEQUENCE : null;
|
return Text.isGraphic(word) ? CUSTOM_EMOJI_SEQUENCE : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -45,10 +45,28 @@ public class Text {
|
||||||
return str != null && containsOtherThan1.matcher(str).find();
|
return str != null && containsOtherThan1.matcher(str).find();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean endsWithGraphic() {
|
||||||
|
return text != null && !text.isEmpty() && Characters.isGraphic(text.charAt(text.length() - 1));
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return text == null || text.isEmpty();
|
return text == null || text.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isGraphic(String str) {
|
||||||
|
if (str == null || str.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0, end = str.length(); i < end; i++) {
|
||||||
|
if (!Characters.isGraphic(str.charAt(i))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isMixedCase() {
|
public boolean isMixedCase() {
|
||||||
return
|
return
|
||||||
language != null
|
language != null
|
||||||
|
|
@ -69,6 +87,46 @@ public class Text {
|
||||||
return language != null && text != null && text.toUpperCase(language.getLocale()).equals(text);
|
return language != null && text != null && text.toUpperCase(language.getLocale()).equals(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String leaveEndingGraphics() {
|
||||||
|
if (text == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder(text.length());
|
||||||
|
|
||||||
|
for (int i = text.length() - 1; i >= 0; i--) {
|
||||||
|
char ch = text.charAt(i);
|
||||||
|
|
||||||
|
if (Characters.isGraphic(ch)) {
|
||||||
|
sb.insert(0, ch);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String leaveStartingGraphics() {
|
||||||
|
if (text == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder(text.length());
|
||||||
|
|
||||||
|
for (int i = 0, end = text.length(); i < end; i++) {
|
||||||
|
char ch = text.charAt(i);
|
||||||
|
|
||||||
|
if (Characters.isGraphic(ch)) {
|
||||||
|
sb.append(ch);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
public boolean nextIsPunctuation() {
|
public boolean nextIsPunctuation() {
|
||||||
return text != null && !text.isEmpty() && nextIsPunctuation.matcher(text).find();
|
return text != null && !text.isEmpty() && nextIsPunctuation.matcher(text).find();
|
||||||
}
|
}
|
||||||
|
|
@ -85,6 +143,50 @@ public class Text {
|
||||||
return text != null && !text.isEmpty() && Character.isDigit(text.charAt(0));
|
return text != null && !text.isEmpty() && Character.isDigit(text.charAt(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean startsWithGraphic() {
|
||||||
|
return text != null && !text.isEmpty() && Characters.isGraphic(text.charAt(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String subStringEndingWord(boolean keepApostrophe, boolean keepQuote) {
|
||||||
|
if (text == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder sub = new StringBuilder();
|
||||||
|
|
||||||
|
for (int i = text.length() - 1; i >= 0; i--) {
|
||||||
|
char ch = text.charAt(i);
|
||||||
|
|
||||||
|
if (Character.isAlphabetic(ch) || (keepApostrophe && ch == '\'') || (keepQuote && ch == '"')) {
|
||||||
|
sub.insert(0, ch);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sub.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String subStringStartingWord(boolean keepApostrophe, boolean keepQuote) {
|
||||||
|
if (text == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder sub = new StringBuilder();
|
||||||
|
|
||||||
|
for (int i = 0, end = text.length(); i < end; i++) {
|
||||||
|
char ch = text.charAt(i);
|
||||||
|
|
||||||
|
if (Character.isAlphabetic(ch) || (keepApostrophe && ch == '\'') || (keepQuote && ch == '"')) {
|
||||||
|
sub.append(ch);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sub.toString();
|
||||||
|
}
|
||||||
|
|
||||||
public String toLowerCase() {
|
public String toLowerCase() {
|
||||||
if (text == null) {
|
if (text == null) {
|
||||||
return "";
|
return "";
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue