From c484050678c3c3e6964897142c6e50fd6c2a24e1 Mon Sep 17 00:00:00 2001 From: sspanak Date: Wed, 7 May 2025 15:03:11 +0300 Subject: [PATCH] Shift is Shift, it no longer serves for hacks to type special characters --- .../sspanak/tt9/ime/CommandHandler.java | 31 +++++++------------ .../sspanak/tt9/ime/modes/InputMode.java | 27 +--------------- .../github/sspanak/tt9/ime/modes/Mode123.java | 19 ------------ .../github/sspanak/tt9/ime/modes/ModeABC.java | 16 ---------- .../sspanak/tt9/ime/modes/ModeCheonjiin.java | 5 --- .../sspanak/tt9/ime/modes/ModeWords.java | 10 +++++- 6 files changed, 21 insertions(+), 87 deletions(-) diff --git a/app/src/main/java/io/github/sspanak/tt9/ime/CommandHandler.java b/app/src/main/java/io/github/sspanak/tt9/ime/CommandHandler.java index ef45c66d..afe8eee9 100644 --- a/app/src/main/java/io/github/sspanak/tt9/ime/CommandHandler.java +++ b/app/src/main/java/io/github/sspanak/tt9/ime/CommandHandler.java @@ -221,26 +221,24 @@ abstract public class CommandHandler extends TextEditingHandler { protected boolean nextTextCase() { - if (suggestionOps.isEmpty() || mInputMode.getSuggestions().isEmpty()) { - // When there are no suggestions, there is no need to execute the code for - // adjusting them below. - if (mInputMode.nextTextCase()) { - settings.saveTextCase(mInputMode.getTextCase()); - return true; - } else { - return false; - } + if (!mInputMode.nextTextCase()) { + return false; + } + + // When there are no suggestions, there is no need to execute the code below for adjusting their text case. + if (mInputMode.getSuggestions().isEmpty()) { + settings.saveTextCase(mInputMode.getTextCase()); + return true; } // When we are in AUTO mode and current dictionary word is in uppercase, // the mode would switch to UPPERCASE, but visually, the word would not change. // This is why we retry, until there is a visual change. - boolean isChanged = false; String before = suggestionOps.get(0); - for (int retries = 0; retries < 2 && mInputMode.nextTextCase(); retries++) { + boolean beforeStartsWithLetter = !before.isEmpty() && Character.isAlphabetic(before.charAt(0)); + for (int retries = 0; beforeStartsWithLetter && retries < 2 && mInputMode.nextTextCase(); retries++) { String after = mInputMode.getSuggestions().get(0); if (!after.equals(before)) { - isChanged = true; break; } } @@ -248,19 +246,12 @@ abstract public class CommandHandler extends TextEditingHandler { int currentSuggestionIndex = suggestionOps.getCurrentIndex(); currentSuggestionIndex = suggestionOps.containsStem() ? currentSuggestionIndex - 1 : currentSuggestionIndex; - // If the suggestions are special characters, changing the text case means selecting the - // next character group. It makes no sense to keep the previous selection for a completely - // different list of characters, that's why we reset it. - if (!Character.isAlphabetic(mInputMode.getSuggestions().get(0).charAt(0))) { - currentSuggestionIndex = 0; - } - suggestionOps.set(mInputMode.getSuggestions(), currentSuggestionIndex, mInputMode.containsGeneratedSuggestions()); textField.setComposingText(suggestionOps.getCurrent()); settings.saveTextCase(mInputMode.getTextCase()); - return isChanged; + return true; } 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 629399f7..0250ca80 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 @@ -9,7 +9,6 @@ import io.github.sspanak.tt9.hacks.InputType; import io.github.sspanak.tt9.ime.helpers.TextField; 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.languages.NullLanguage; import io.github.sspanak.tt9.preferences.settings.SettingsStore; import io.github.sspanak.tt9.util.Logger; @@ -175,11 +174,7 @@ abstract public class InputMode { } public boolean nextTextCase() { - if (nextSpecialCharacters()) { - return true; - } - - if (!language.hasUpperCase() || digitSequence.startsWith(NaturalLanguage.PUNCTUATION_KEY) || digitSequence.startsWith(NaturalLanguage.SPECIAL_CHAR_KEY)) { + if (!language.hasUpperCase()) { return false; } @@ -195,26 +190,6 @@ abstract public class InputMode { protected String adjustSuggestionTextCase(String word, int newTextCase) { return word; } - protected boolean shouldSelectNextSpecialCharacters() { - return !digitSequence.isEmpty(); - } - - - /** - * This is used in nextTextCase() for switching to the next set of characters. Obviously, - * special chars do not have a text case, but we use this trick to alternate the char groups. - */ - protected boolean nextSpecialCharacters() { - int previousGroup = specialCharSelectedGroup; - specialCharSelectedGroup++; - - return - shouldSelectNextSpecialCharacters() // check if the operation makes sense at all - && loadSpecialCharacters() // validates specialCharSelectedGroup and advances, if possible - && previousGroup != specialCharSelectedGroup; // verifies validation has passed - } - - protected boolean loadSpecialCharacters() { int key = digitSequence.charAt(0) - '0'; ArrayList chars = settings.getOrderedKeyChars(language, key, specialCharSelectedGroup); 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 765c8fac..d85824f3 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 @@ -7,7 +7,6 @@ import java.util.ArrayList; import io.github.sspanak.tt9.hacks.InputType; import io.github.sspanak.tt9.languages.Language; import io.github.sspanak.tt9.languages.LanguageCollection; -import io.github.sspanak.tt9.languages.NaturalLanguage; import io.github.sspanak.tt9.preferences.settings.SettingsStore; import io.github.sspanak.tt9.util.TextTools; import io.github.sspanak.tt9.util.chars.Characters; @@ -62,24 +61,6 @@ class Mode123 extends ModePassthrough { } - @Override - protected boolean shouldSelectNextSpecialCharacters() { - return !isEmailMode && digitSequence.equals(NaturalLanguage.SPECIAL_CHAR_KEY); - } - - - @Override protected boolean nextSpecialCharacters() { - if (!super.nextSpecialCharacters()) { - return false; - } - - ArrayList ordered = applyNumericFieldCharacterOrder(suggestions); - suggestions.clear(); - suggestions.addAll(ordered); - return true; - } - - protected ArrayList applyNumericFieldCharacterOrder(ArrayList unordered) { ArrayList ordered = new ArrayList<>(); 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 b955d30a..d5a9c205 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 @@ -8,7 +8,6 @@ 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.chars.Characters; @@ -75,21 +74,6 @@ class ModeABC extends InputMode { } } - @Override - protected boolean shouldSelectNextSpecialCharacters() { - return KEY_CHARACTERS.isEmpty() && digitSequence.equals(NaturalLanguage.SPECIAL_CHAR_KEY); - } - - @Override - protected boolean nextSpecialCharacters() { - if (!super.nextSpecialCharacters()) { - return false; - } - - suggestions.add(language.getKeyNumeral(digitSequence.charAt(0) - '0')); - return true; - } - @Override public boolean changeLanguage(@Nullable Language newLanguage) { if (newLanguage != null && !newLanguage.hasABC()) { diff --git a/app/src/main/java/io/github/sspanak/tt9/ime/modes/ModeCheonjiin.java b/app/src/main/java/io/github/sspanak/tt9/ime/modes/ModeCheonjiin.java index f1567453..f1a7e09e 100644 --- a/app/src/main/java/io/github/sspanak/tt9/ime/modes/ModeCheonjiin.java +++ b/app/src/main/java/io/github/sspanak/tt9/ime/modes/ModeCheonjiin.java @@ -395,11 +395,6 @@ class ModeCheonjiin extends InputMode { } - protected boolean shouldSelectNextSpecialCharacters() { - return digitSequence.equals(SPECIAL_CHAR_SEQUENCE); - } - - @Override public boolean shouldAddTrailingSpace(boolean isWordAcceptedManually, int nextKey) { return autoSpace.shouldAddTrailingSpace(textField, inputType, isWordAcceptedManually, nextKey); diff --git a/app/src/main/java/io/github/sspanak/tt9/ime/modes/ModeWords.java b/app/src/main/java/io/github/sspanak/tt9/ime/modes/ModeWords.java index a5003198..60123121 100644 --- a/app/src/main/java/io/github/sspanak/tt9/ime/modes/ModeWords.java +++ b/app/src/main/java/io/github/sspanak/tt9/ime/modes/ModeWords.java @@ -368,17 +368,25 @@ class ModeWords extends ModeCheonjiin { return (textCase == CASE_UPPER || textCase == CASE_LOWER) ? textCase : CASE_CAPITALIZE; } + @Override public boolean nextTextCase() { int before = textCase; boolean changed = super.nextTextCase(); - // When Auto Text Case is on, only upper- and automatic cases are available, so we skip lowercase. + // When we are in AUTO mode and current dictionary word is in uppercase, + // the mode would switch to UPPERCASE, but visually, the word would not change. + // This is why we retry, until there is a visual change. // Yet, we allow adjusting individual words to lowercase, if needed. if (digitSequence.isEmpty() && settings.getAutoTextCase() && language.hasUpperCase() && (before == CASE_LOWER || textCase == CASE_LOWER)) { changed = super.nextTextCase(); } + boolean onlySpecialChars = digitSequence.startsWith(PUNCTUATION_SEQUENCE) || digitSequence.startsWith(SPECIAL_CHAR_SEQUENCE) || digitSequence.startsWith(EMOJI_SEQUENCE); + if (onlySpecialChars && textCase == CASE_CAPITALIZE) { + super.nextTextCase(); + } + // since it's a user's choice, the default matters no more textFieldTextCase = changed ? CASE_UNDEFINED : textFieldTextCase;