diff --git a/app/src/main/java/io/github/sspanak/tt9/ime/modes/InputMode.java b/app/src/main/java/io/github/sspanak/tt9/ime/modes/InputMode.java index 9f027839..62903891 100644 --- a/app/src/main/java/io/github/sspanak/tt9/ime/modes/InputMode.java +++ b/app/src/main/java/io/github/sspanak/tt9/ime/modes/InputMode.java @@ -39,9 +39,9 @@ abstract public class InputMode { public static InputMode getInstance(SettingsStore settings, Language language, InputType inputType, int mode) { switch (mode) { case MODE_PREDICTIVE: - return new ModePredictive(settings, language); + return new ModePredictive(settings, inputType, language); case MODE_ABC: - return new ModeABC(settings, language); + return new ModeABC(settings, inputType, language); case MODE_PASSTHROUGH: return new ModePassthrough(); default: diff --git a/app/src/main/java/io/github/sspanak/tt9/ime/modes/Mode123.java b/app/src/main/java/io/github/sspanak/tt9/ime/modes/Mode123.java index 8fb953a0..64e2f832 100644 --- a/app/src/main/java/io/github/sspanak/tt9/ime/modes/Mode123.java +++ b/app/src/main/java/io/github/sspanak/tt9/ime/modes/Mode123.java @@ -3,7 +3,6 @@ package io.github.sspanak.tt9.ime.modes; import androidx.annotation.NonNull; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import io.github.sspanak.tt9.hacks.InputType; @@ -21,50 +20,39 @@ public class Mode123 extends ModePassthrough { @Override public boolean shouldAcceptPreviousSuggestion(int nextKey) { return true; } private final ArrayList> KEY_CHARACTERS = new ArrayList<>(); + private final boolean isEmailMode; public Mode123(InputType inputType, Language language) { this.language = language; + isEmailMode = inputType.isEmail(); if (inputType.isPhoneNumber()) { - getPhoneSpecialCharacters(); + setSpecificSpecialCharacters(Characters.Phone); } else if (inputType.isNumeric()) { - getNumberSpecialCharacters(inputType.isDecimal(), inputType.isSignedNumber()); + setSpecificSpecialCharacters(Characters.getNumberSpecialCharacters(inputType.isDecimal(), inputType.isSignedNumber())); + } else if (inputType.isEmail()) { + setSpecificSpecialCharacters(Characters.Email); } else { - getDefaultSpecialCharacters(); + setDefaultSpecialCharacters(); + } + + } + + + private void setSpecificSpecialCharacters(ArrayList> chars) { + for (ArrayList group : chars) { + KEY_CHARACTERS.add(new ArrayList<>(group)); } } /** - * getPhoneSpecialCharacters - * Special characters for phone number fields, including both characters for conveniently typing a phone number: "()-", - * as well as command characters such as "," = "slight pause" and ";" = "wait" used in Japan and some other countries. - */ - private void getPhoneSpecialCharacters() { - KEY_CHARACTERS.add(new ArrayList<>(Arrays.asList("+", " "))); - KEY_CHARACTERS.add(new ArrayList<>(Arrays.asList("-", "(", ")", ".", ";", ","))); - } - - - /** - * getNumberSpecialCharacters - * Special characters for all kinds of numeric fields: integer, decimal with +/- included as necessary. - */ - private void getNumberSpecialCharacters(boolean decimal, boolean signed) { - KEY_CHARACTERS.add(signed ? new ArrayList<>(Arrays.asList("-", "+")) : new ArrayList<>()); - if (decimal) { - KEY_CHARACTERS.add(new ArrayList<>(Arrays.asList(".", ","))); - } - } - - - /** - * getDefaultSpecialCharacters + * setDefaultSpecialCharacters * Special characters for when the user has selected 123 mode in a text field. In this case, we just * use the default list, but reorder it a bit for convenience. */ - private void getDefaultSpecialCharacters() { + private void setDefaultSpecialCharacters() { // 0-key KEY_CHARACTERS.add(new ArrayList<>(Collections.singletonList("+"))); for (String character : Characters.Special) { @@ -82,8 +70,9 @@ public class Mode123 extends ModePassthrough { } } + @Override protected boolean nextSpecialCharacters() { - return digitSequence.equals(NaturalLanguage.SPECIAL_CHARS_KEY) && super.nextSpecialCharacters(); + return !isEmailMode && digitSequence.equals(NaturalLanguage.SPECIAL_CHARS_KEY) && super.nextSpecialCharacters(); } diff --git a/app/src/main/java/io/github/sspanak/tt9/ime/modes/ModeABC.java b/app/src/main/java/io/github/sspanak/tt9/ime/modes/ModeABC.java index 17daba37..acfd6b87 100644 --- a/app/src/main/java/io/github/sspanak/tt9/ime/modes/ModeABC.java +++ b/app/src/main/java/io/github/sspanak/tt9/ime/modes/ModeABC.java @@ -2,20 +2,31 @@ package io.github.sspanak.tt9.ime.modes; import androidx.annotation.NonNull; +import java.util.ArrayList; + +import io.github.sspanak.tt9.hacks.InputType; import io.github.sspanak.tt9.languages.Language; import io.github.sspanak.tt9.languages.LanguageKind; import io.github.sspanak.tt9.languages.NaturalLanguage; import io.github.sspanak.tt9.preferences.settings.SettingsStore; +import io.github.sspanak.tt9.util.Characters; public class ModeABC extends InputMode { + private final ArrayList> KEY_CHARACTERS = new ArrayList<>(); + private final SettingsStore settings; private boolean shouldSelectNextLetter = false; @Override public int getId() { return MODE_ABC; } - ModeABC(SettingsStore settings, Language lang) { + ModeABC(SettingsStore settings, InputType inputType, Language lang) { this.settings = settings; changeLanguage(lang); + + if (inputType.isEmail()) { + KEY_CHARACTERS.add(new ArrayList<>(Characters.Email.get(0))); + KEY_CHARACTERS.add(new ArrayList<>(Characters.Email.get(1))); + } } @Override @@ -44,7 +55,7 @@ public class ModeABC extends InputMode { autoAcceptTimeout = settings.getAbcAutoAcceptTimeout(); digitSequence = String.valueOf(number); shouldSelectNextLetter = false; - suggestions.addAll(language.getKeyCharacters(number)); + suggestions.addAll(KEY_CHARACTERS.size() > number ? KEY_CHARACTERS.get(number) : language.getKeyCharacters(number)); suggestions.add(language.getKeyNumber(number)); } @@ -66,7 +77,7 @@ public class ModeABC extends InputMode { @Override protected boolean nextSpecialCharacters() { - if (digitSequence.equals(NaturalLanguage.SPECIAL_CHARS_KEY) && super.nextSpecialCharacters()) { + if (KEY_CHARACTERS.isEmpty() && digitSequence.equals(NaturalLanguage.SPECIAL_CHARS_KEY) && super.nextSpecialCharacters()) { suggestions.add(language.getKeyNumber(digitSequence.charAt(0) - '0')); return true; } diff --git a/app/src/main/java/io/github/sspanak/tt9/ime/modes/ModePredictive.java b/app/src/main/java/io/github/sspanak/tt9/ime/modes/ModePredictive.java index 91bf6d01..d990ab93 100644 --- a/app/src/main/java/io/github/sspanak/tt9/ime/modes/ModePredictive.java +++ b/app/src/main/java/io/github/sspanak/tt9/ime/modes/ModePredictive.java @@ -15,12 +15,15 @@ import io.github.sspanak.tt9.languages.Language; import io.github.sspanak.tt9.languages.LanguageKind; import io.github.sspanak.tt9.languages.NaturalLanguage; import io.github.sspanak.tt9.preferences.settings.SettingsStore; +import io.github.sspanak.tt9.util.Characters; import io.github.sspanak.tt9.util.Logger; import io.github.sspanak.tt9.util.Text; public class ModePredictive extends InputMode { private final String LOG_TAG = getClass().getSimpleName(); + private final ArrayList> KEY_CHARACTERS = new ArrayList<>(); + private final SettingsStore settings; public int getId() { return MODE_PREDICTIVE; } @@ -42,7 +45,7 @@ public class ModePredictive extends InputMode { private boolean isCursorDirectionForward = false; - ModePredictive(SettingsStore settings, Language lang) { + ModePredictive(SettingsStore settings, InputType inputType, Language lang) { changeLanguage(lang); defaultTextCase(); @@ -53,6 +56,11 @@ public class ModePredictive extends InputMode { this.settings = settings; digitSequence = ""; + + if (inputType.isEmail()) { + KEY_CHARACTERS.add(new ArrayList<>(Characters.Email.get(0))); + KEY_CHARACTERS.add(new ArrayList<>(Characters.Email.get(1))); + } } @@ -250,7 +258,7 @@ public class ModePredictive extends InputMode { */ private boolean loadStaticSuggestions(Runnable onLoad) { if (digitSequence.equals(NaturalLanguage.PUNCTUATION_KEY) || digitSequence.equals(NaturalLanguage.SPECIAL_CHARS_KEY)) { - super.loadSpecialCharacters(language); + loadSpecialCharacters(language); onLoad.run(); return true; } else if (!digitSequence.equals(EmojiLanguage.CUSTOM_EMOJI_SEQUENCE) && digitSequence.startsWith(EmojiLanguage.EMOJI_SEQUENCE)) { @@ -269,6 +277,19 @@ public class ModePredictive extends InputMode { } + @Override + protected boolean loadSpecialCharacters(Language altLanguage) { + int number = digitSequence.charAt(0) - '0'; + if (KEY_CHARACTERS.size() > number) { + suggestions.clear(); + suggestions.addAll(KEY_CHARACTERS.get(number)); + return true; + } else { + return super.loadSpecialCharacters(language); + } + } + + /** * onPredictions * Gets the currently available Predictions and sends them over to the external caller. diff --git a/app/src/main/java/io/github/sspanak/tt9/util/Characters.java b/app/src/main/java/io/github/sspanak/tt9/util/Characters.java index 6d80f49c..99f874f6 100644 --- a/app/src/main/java/io/github/sspanak/tt9/util/Characters.java +++ b/app/src/main/java/io/github/sspanak/tt9/util/Characters.java @@ -39,6 +39,35 @@ public class Characters { " ", "\n", "@", "_", "#", "%", "[", "]", "{", "}", "ยง", "|", "^", "<", ">", "\\", "/", "=", "*", "+" )); + /** + * The English punctuation filtered to contain only valid email characters. + */ + final public static ArrayList> Email = new ArrayList<>(Arrays.asList( + new ArrayList<>(Arrays.asList("@", "_", "#", "%", "{", "}", "|", "^", "/", "=", "*", "+")), + new ArrayList<>(Arrays.asList(".", "-", "&", "~", "`", "'", "!", "?")) + )); + + /** + * Special characters for phone number fields, including both characters for conveniently typing a phone number: "()-", + * as well as command characters such as "," = "slight pause" and ";" = "wait" used in Japan and some other countries. + */ + final public static ArrayList> Phone = new ArrayList<>(Arrays.asList( + new ArrayList<>(Arrays.asList("+", " ")), + new ArrayList<>(Arrays.asList("-", "(", ")", ".", ";", ",")) + )); + + /** + * Special characters for all kinds of numeric fields: integer, decimal with +/- included as necessary. + */ + public static ArrayList> getNumberSpecialCharacters(boolean decimal, boolean signed) { + ArrayList> keyCharacters = new ArrayList<>(); + keyCharacters.add(signed ? new ArrayList<>(Arrays.asList("-", "+")) : new ArrayList<>()); + if (decimal) { + keyCharacters.add(new ArrayList<>(Arrays.asList(".", ","))); + } + return keyCharacters; + } + final private static ArrayList TextEmoticons = new ArrayList<>(Arrays.asList( ":)", ":D", ":P", ";)", "\\m/", ":-O", ":|", ":(" ));