diff --git a/app/src/main/java/io/github/sspanak/tt9/ime/TraditionalT9.java b/app/src/main/java/io/github/sspanak/tt9/ime/TraditionalT9.java index 0a5ee2a3..59ac704e 100644 --- a/app/src/main/java/io/github/sspanak/tt9/ime/TraditionalT9.java +++ b/app/src/main/java/io/github/sspanak/tt9/ime/TraditionalT9.java @@ -30,6 +30,7 @@ import io.github.sspanak.tt9.ime.modes.ModePassthrough; import io.github.sspanak.tt9.ime.modes.ModePredictive; import io.github.sspanak.tt9.languages.Language; import io.github.sspanak.tt9.languages.LanguageCollection; +import io.github.sspanak.tt9.languages.Text; import io.github.sspanak.tt9.preferences.SettingsStore; import io.github.sspanak.tt9.preferences.helpers.Hotkeys; import io.github.sspanak.tt9.ui.PopupDialogActivity; @@ -486,15 +487,17 @@ public class TraditionalT9 extends KeyPadHandler { } cancelAutoAccept(); - commitCurrentSuggestion(false); - resetKeyRepeat(); nextLang(); mInputMode.changeLanguage(mLanguage); - mInputMode.reset(); + mInputMode.clearWordStem(); + getSuggestions(); statusBar.setText(mInputMode.toString()); mainView.render(); forceShowWindowIfHidden(); + if (!suggestionBar.isEmpty()) { + UI.toastLanguage(this, mLanguage); + } if (mInputMode instanceof ModePredictive) { DictionaryLoader.autoLoad(this, mLanguage); @@ -658,6 +661,15 @@ public class TraditionalT9 extends KeyPadHandler { // display the word suggestions setSuggestions(mInputMode.getSuggestions()); + // In case we are here, because the language was changed, and there were words for the old language, + // but there are no words for the new language, we'll get only generated suggestions, consisting + // of the last word of the previous language + endings from the new language. These words are invalid, + // so we discard them. + if (mInputMode instanceof ModePredictive && !mLanguage.isValidWord(suggestionBar.getCurrentSuggestion()) && !Text.isGraphic(suggestionBar.getCurrentSuggestion())) { + mInputMode.reset(); + setSuggestions(null); + } + // flush the first suggestion, if the InputMode has requested it if (scheduleAutoAccept(mInputMode.getAutoAcceptTimeout())) { return; 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 e33c3cd2..df290244 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 @@ -29,8 +29,8 @@ public class ModeABC extends InputMode { reset(); autoAcceptTimeout = 0; digitSequence = String.valueOf(number); - suggestions.add(language.getKeyNumber(number)); shouldSelectNextLetter = false; + suggestions.add(language.getKeyNumber(number)); } else if (repeat > 0) { autoAcceptTimeout = settings.getAbcAutoAcceptTimeout(); shouldSelectNextLetter = true; @@ -38,9 +38,9 @@ public class ModeABC extends InputMode { reset(); autoAcceptTimeout = settings.getAbcAutoAcceptTimeout(); digitSequence = String.valueOf(number); + shouldSelectNextLetter = false; suggestions.addAll(language.getKeyCharacters(number)); suggestions.add(language.getKeyNumber(number)); - shouldSelectNextLetter = false; } return true; @@ -51,6 +51,14 @@ public class ModeABC extends InputMode { return newTextCase == CASE_UPPER ? word.toUpperCase(language.getLocale()) : word.toLowerCase(language.getLocale()); } + private void refreshSuggestions() { + if (digitSequence.isEmpty()) { + suggestions.clear(); + } else { + onNumber(digitSequence.charAt(0) - '0', false, 0); + } + } + @Override protected boolean nextSpecialCharacters() { if (digitSequence.equals(Language.SPECIAL_CHARS_KEY) && super.nextSpecialCharacters()) { @@ -70,6 +78,9 @@ public class ModeABC extends InputMode { if (language.hasUpperCase()) { allowedTextCases.add(CASE_UPPER); } + + refreshSuggestions(); + shouldSelectNextLetter = true; // do not accept any previous suggestions after loading the new ones } @Override public int getSequenceLength() { return 1; } diff --git a/app/src/main/java/io/github/sspanak/tt9/languages/Language.java b/app/src/main/java/io/github/sspanak/tt9/languages/Language.java index def4fa69..46153adc 100644 --- a/app/src/main/java/io/github/sspanak/tt9/languages/Language.java +++ b/app/src/main/java/io/github/sspanak/tt9/languages/Language.java @@ -266,6 +266,29 @@ public class Language implements Comparable { } + /** + * Checks whether the given word contains characters outside of the language alphabet. + */ + public boolean isValidWord(String word) { + if (word == null || word.isEmpty() || (word.length() == 1 && Character.isDigit(word.charAt(0)))) { + return true; + } + + String lowerCaseWord = word.toLowerCase(locale); + if (characterKeyMap.isEmpty()) { + generateCharacterKeyMap(); + } + + for (int i = 0; i < lowerCaseWord.length(); i++) { + if (!characterKeyMap.containsKey(lowerCaseWord.charAt(i))) { + return false; + } + } + + return true; + } + + @NonNull @Override public String toString() { diff --git a/app/src/main/java/io/github/sspanak/tt9/ui/UI.java b/app/src/main/java/io/github/sspanak/tt9/ui/UI.java index 952e2679..7836f6e1 100644 --- a/app/src/main/java/io/github/sspanak/tt9/ui/UI.java +++ b/app/src/main/java/io/github/sspanak/tt9/ui/UI.java @@ -7,10 +7,15 @@ import android.os.Looper; import android.view.inputmethod.InputMethodManager; import android.widget.Toast; +import androidx.annotation.NonNull; + import io.github.sspanak.tt9.ime.TraditionalT9; +import io.github.sspanak.tt9.languages.Language; import io.github.sspanak.tt9.preferences.PreferencesActivity; public class UI { + private static Toast toastLang = null; + public static void showAddWordDialog(TraditionalT9 tt9, int language, String currentWord) { Intent intent = new Intent(tt9, PopupDialogActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); @@ -93,4 +98,15 @@ public class UI { public static void toastLong(Context context, CharSequence msg) { Toast.makeText(context, msg, Toast.LENGTH_LONG).show(); } + + public static void toastLanguage(@NonNull Context context, @NonNull Language language) { + if (toastLang != null) { + toastLang.cancel(); + } + + // we recreate the toast, because if set new text, when it is fading out, + // the new text is discarded + toastLang = Toast.makeText(context, language.getName(), Toast.LENGTH_SHORT); + toastLang.show(); + } }