From c30c2a3109a5c2342d8091da57e7492db0c0ddc7 Mon Sep 17 00:00:00 2001 From: sspanak Date: Wed, 25 Jun 2025 11:22:51 +0300 Subject: [PATCH] fixed the text case cycle order when the current 'word' is a special character --- .../sspanak/tt9/ime/CommandHandler.java | 2 +- .../sspanak/tt9/ime/modes/InputMode.java | 2 +- .../sspanak/tt9/ime/modes/ModeIdeograms.java | 2 +- .../sspanak/tt9/ime/modes/ModeWords.java | 25 +++++++++++++------ .../github/sspanak/tt9/ui/tray/StatusBar.java | 6 +++++ 5 files changed, 27 insertions(+), 10 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 5f46f05d..a318cc25 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 @@ -211,7 +211,7 @@ abstract public class CommandHandler extends TextEditingHandler { protected boolean nextTextCase() { final String currentWord = suggestionOps.isEmpty() || mInputMode.getSequence().isEmpty() ? "" : suggestionOps.getCurrent(); - if (!mInputMode.nextTextCase(currentWord)) { + if (!mInputMode.nextTextCase(currentWord, statusBar.getText())) { return false; } 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 de7d22d0..dddb306f 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 @@ -206,7 +206,7 @@ abstract public class InputMode { * If "analyzeSurroundingText" is true, and when the mode supports text analyzing, it may apply * additional logic to determine the next valid text case. */ - public boolean nextTextCase(@Nullable String currentWord) { + public boolean nextTextCase(@Nullable String currentWord, @Nullable String statusBarText) { if (!language.hasUpperCase()) { return false; } diff --git a/app/src/main/java/io/github/sspanak/tt9/ime/modes/ModeIdeograms.java b/app/src/main/java/io/github/sspanak/tt9/ime/modes/ModeIdeograms.java index b7e187c9..5df344ed 100644 --- a/app/src/main/java/io/github/sspanak/tt9/ime/modes/ModeIdeograms.java +++ b/app/src/main/java/io/github/sspanak/tt9/ime/modes/ModeIdeograms.java @@ -30,7 +30,7 @@ public class ModeIdeograms extends ModeWords { @Override protected String adjustSuggestionTextCase(String word, int newTextCase) { return word; } @Override public void determineNextWordTextCase(int nextDigit) {} - @Override public boolean nextTextCase(@Nullable String currentWord) { return false; } + @Override public boolean nextTextCase(@Nullable String currentWord, @Nullable String statusBarText) { return false; } @Override 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 6774d9da..06f45fe9 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 @@ -383,20 +383,31 @@ class ModeWords extends ModeCheonjiin { } @Override - public boolean nextTextCase(@Nullable String currentWord) { - if (currentWord == null || currentWord.isEmpty() || (currentWord.length() == 1 && !Character.isAlphabetic(currentWord.charAt(0)))) { + public boolean nextTextCase(@Nullable String currentWord, @Nullable String statusBarText) { + if (!language.hasUpperCase()) { + return false; + } + + // if the user is typing, assume the text case of the current word + if (currentWord == null || currentWord.isEmpty()) { textCase = getTextCase(); - } else { + } + // if not typing, assume the displayed text case + else if (statusBarText != null && !statusBarText.isEmpty() && currentWord.length() == 1 && !Character.isAlphabetic(currentWord.charAt(0))) { + textCase = new Text(language, statusBarText).getTextCase(); + } + // ... or fallback to the mode text case + else { textCase = new Text(language, currentWord).getTextCase(); } - // Skip capitalized text for words like: 've, 's, 'll, etc... only allow upper and lower cases. - boolean changed = super.nextTextCase(currentWord); + // do not capitalize words like: 've, 's, 'll, etc, only allow upper and lower cases. + boolean changed = super.nextTextCase(currentWord, statusBarText); if (textCase != CASE_LOWER && textCase != CASE_UPPER && currentWord != null && currentWord.length() > 1 && !Character.isAlphabetic(currentWord.charAt(0))) { - changed = super.nextTextCase(currentWord); + changed = super.nextTextCase(currentWord, statusBarText); } - // since it's a user's choice, the default matters no more + // since the user made an explicit choice, the app default matters no more textFieldTextCase = changed ? CASE_UNDEFINED : textFieldTextCase; return changed; diff --git a/app/src/main/java/io/github/sspanak/tt9/ui/tray/StatusBar.java b/app/src/main/java/io/github/sspanak/tt9/ui/tray/StatusBar.java index ab5c0827..a492624b 100644 --- a/app/src/main/java/io/github/sspanak/tt9/ui/tray/StatusBar.java +++ b/app/src/main/java/io/github/sspanak/tt9/ui/tray/StatusBar.java @@ -35,6 +35,12 @@ public class StatusBar { } + @Nullable + public String getText() { + return statusText; + } + + public boolean isErrorShown() { return statusText != null && statusText.startsWith("❌"); }