Skip to content

Commit c106c8f

Browse files
committed
proper text case adjustment
1 parent 0ee5c74 commit c106c8f

File tree

7 files changed

+59
-13
lines changed

7 files changed

+59
-13
lines changed

app/src/main/java/io/github/sspanak/tt9/db/mindReading/MindReader.java

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,16 @@
88
import java.util.concurrent.ExecutorService;
99
import java.util.concurrent.RejectedExecutionException;
1010

11+
import io.github.sspanak.tt9.hacks.InputType;
12+
import io.github.sspanak.tt9.ime.helpers.TextField;
1113
import io.github.sspanak.tt9.ime.modes.InputMode;
1214
import io.github.sspanak.tt9.ime.modes.InputModeKind;
15+
import io.github.sspanak.tt9.ime.modes.helpers.AutoTextCase;
16+
import io.github.sspanak.tt9.ime.modes.helpers.Sequences;
1317
import io.github.sspanak.tt9.languages.Language;
1418
import io.github.sspanak.tt9.languages.LanguageKind;
1519
import io.github.sspanak.tt9.languages.NaturalLanguage;
20+
import io.github.sspanak.tt9.languages.exceptions.InvalidLanguageCharactersException;
1621
import io.github.sspanak.tt9.preferences.settings.SettingsStore;
1722
import io.github.sspanak.tt9.util.Logger;
1823
import io.github.sspanak.tt9.util.Text;
@@ -23,6 +28,7 @@ public class MindReader {
2328
private static final String LOG_TAG = MindReader.class.getSimpleName();
2429

2530
// @todo: move these constants to SettingsStatic
31+
// @todo: test and maybe set a maximum size for MindReaderNgramList?
2632
private static final int MAX_NGRAM_SIZE = 4;
2733
private static final int MAX_BIGRAM_SUGGESTIONS = 5;
2834
private static final int MAX_TRIGRAM_SUGGESTIONS = 4;
@@ -31,6 +37,7 @@ public class MindReader {
3137
static final int DICTIONARY_WORD_SIZE = 16; // in bytes
3238
private static final int MAX_DICTIONARY_WORDS = (int) Math.pow(2, DICTIONARY_WORD_SIZE);
3339

40+
@Nullable private final AutoTextCase autoTextCase;
3441
@Nullable private final ExecutorService executor;
3542
@Nullable private final SettingsStore settings;
3643

@@ -44,11 +51,12 @@ public class MindReader {
4451

4552

4653
public MindReader() {
47-
this(null, null);
54+
this(null, null, null);
4855
}
4956

5057

51-
public MindReader(@Nullable SettingsStore settings, @Nullable ExecutorService executor) {
58+
public MindReader(@Nullable SettingsStore settings, @Nullable ExecutorService executor, @Nullable InputType inputType) {
59+
this.autoTextCase = settings != null ? new AutoTextCase(settings, new Sequences(), inputType) : null;
5260
this.executor = executor;
5361
this.settings = settings;
5462
}
@@ -63,10 +71,9 @@ public void clearContext() {
6371

6472

6573
@NonNull
66-
public ArrayList<String> getCurrentWords(int textCase) {
67-
// @todo: use AutoTextCase.adjustParagraphTextCase() here. "before" is the context.
74+
public ArrayList<String> getCurrentWords(@Nullable InputMode inputMode, @NonNull TextField textField, @NonNull InputType inputType, int textCase) {
6875
final ArrayList<String> copy = new ArrayList<>(words);
69-
copy.replaceAll(text -> new Text(wordContext.language, text).toTextCase(textCase));
76+
copy.replaceAll(text -> adjustWordTextCase(inputMode, text, inputType.determineTextCase(), textCase, textField));
7077
return copy;
7178
}
7279

@@ -81,6 +88,7 @@ public void guessNext(@NonNull InputMode inputMode, @NonNull Language language,
8188

8289
loadingId = 0;
8390

91+
// @todo: this fails for ABC. Fix it!
8492
if (setContextSync(inputMode, language, surroundingText, lastWord)) {
8593
runInThread(() -> {
8694
processContext(inputMode, language, saveContext);
@@ -181,6 +189,29 @@ public void processContext(@Nullable InputMode inputMode, @NonNull Language lang
181189
}
182190

183191

192+
private String adjustWordTextCase(@Nullable InputMode inputMode, @NonNull String word, int modeTextCase, int textFieldTextCase, @NonNull TextField textField) {
193+
if (autoTextCase == null || wordContext.language == null || settings == null || !settings.isAutoTextCaseOn(inputMode)) {
194+
return word;
195+
}
196+
197+
String digitSequence;
198+
try {
199+
digitSequence = wordContext.language.getDigitSequenceForWord(word);
200+
} catch (InvalidLanguageCharactersException e) {
201+
return word;
202+
}
203+
204+
205+
String context = wordContext.getRaw();
206+
if (!new Text(wordContext.language, context).endsWithLetter()) {
207+
context += " ";
208+
}
209+
210+
final int newTextCase = autoTextCase.determineNextWordTextCase(wordContext.language, modeTextCase, textFieldTextCase, textField, digitSequence, context);
211+
return autoTextCase.adjustSuggestionTextCase(new Text(wordContext.language, word), newTextCase);
212+
}
213+
214+
184215
private void changeLanguage(@NonNull Language language) {
185216
if (!language.equals(wordContext.language)) {
186217
// @todo: save the current dictionary for the previous language

app/src/main/java/io/github/sspanak/tt9/db/mindReading/MindReaderContext.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,12 @@ MindReaderNgram[] getEndingNgrams(@NonNull MindReaderDictionary dictionary) {
9696
}
9797

9898

99+
@NonNull
100+
String getRaw() {
101+
return raw.toString();
102+
}
103+
104+
99105
/**
100106
* Appends the given word to the current context text, separating it with a space if needed.
101107
* The word is trimmed before appending.

app/src/main/java/io/github/sspanak/tt9/ime/SuggestionHandler.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import android.os.Handler;
44
import android.os.Looper;
5+
import android.view.inputmethod.EditorInfo;
56

67
import androidx.annotation.MainThread;
78
import androidx.annotation.NonNull;
@@ -27,9 +28,9 @@ abstract public class SuggestionHandler extends TypingHandler {
2728

2829

2930
@Override
30-
protected void onInit() {
31-
super.onInit();
32-
mindReader = new MindReader(settings, executor);
31+
protected void setInputField(EditorInfo field) {
32+
super.setInputField(field);
33+
mindReader = new MindReader(settings, executor, inputType);
3334
}
3435

3536

@@ -209,7 +210,7 @@ private void onAfterSuggestionsHandled(@Nullable Runnable callback, @Nullable St
209210

210211
@NonNull
211212
protected ArrayList<String> getCurrentGuesses() {
212-
return mindReader.getCurrentWords(mInputMode.getTextCase());
213+
return mindReader.getCurrentWords(mInputMode, textField, inputType, mInputMode.getTextCase());
213214
}
214215

215216

app/src/main/java/io/github/sspanak/tt9/ime/VoiceHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ private void onVoiceInputStarted() {
103103

104104

105105
private String autoCapitalize(String str) {
106-
if (autoTextCase == null) {
106+
if (autoTextCase == null || !settings.isAutoTextCaseOn(mInputMode)) {
107107
return str;
108108
}
109109

app/src/main/java/io/github/sspanak/tt9/ime/modes/ModeWords.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,10 @@ public void determineNextWordTextCase(@Nullable String beforeCursor, int nextDig
415415
return;
416416
}
417417

418+
if (!settings.isAutoTextCaseOn(this)) {
419+
return;
420+
}
421+
418422
final String nextSequence = nextDigit >= 0 ? digitSequence + nextDigit : digitSequence;
419423
textCase = autoTextCase.determineNextWordTextCase(language, textCase, textFieldTextCase, textField, nextSequence, beforeCursor);
420424
}

app/src/main/java/io/github/sspanak/tt9/ime/modes/helpers/AutoTextCase.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,8 @@ public int determineNextLetterTextCase(@NonNull Language language, int textField
118118
*/
119119
public int determineNextWordTextCase(@NonNull Language language, int currentTextCase, int textFieldTextCase, @Nullable TextField textField, @Nullable String digitSequence, @Nullable String beforeCursor) {
120120
if (
121-
// When the setting is off or invalid, don't do any changes.
122-
!settings.getAutoTextCasePredictive()
123121
// If the user has explicitly selected uppercase, we respect that.
124-
|| currentTextCase == InputMode.CASE_UPPER
122+
currentTextCase == InputMode.CASE_UPPER
125123
// save resources if the language has no uppercase letters
126124
|| !language.hasUpperCase()
127125
) {

app/src/main/java/io/github/sspanak/tt9/preferences/settings/SettingsTyping.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ public boolean getAutoTrimTrailingSpace() {
4646
return prefs.getBoolean("auto_trim_trailing_space", true);
4747
}
4848

49+
public boolean isAutoTextCaseOn(@Nullable InputMode mode) {
50+
return
51+
(InputModeKind.isPredictive(mode) && getAutoTextCasePredictive()) ||
52+
(InputModeKind.isABC(mode) && getAutoTextCaseAbc());
53+
}
54+
4955
public boolean isAutoAssistanceOn(@Nullable InputMode mode) {
5056
return
5157
(getAutoMindReading() && (InputModeKind.isPredictive(mode) || InputModeKind.isABC(mode))) ||

0 commit comments

Comments
 (0)