fixed more problems regarding Shift and automatic text case
This commit is contained in:
parent
62e8a08576
commit
548041be28
7 changed files with 30 additions and 46 deletions
|
|
@ -209,10 +209,12 @@ abstract public class CommandHandler extends TextEditingHandler {
|
||||||
|
|
||||||
|
|
||||||
protected boolean nextTextCase() {
|
protected boolean nextTextCase() {
|
||||||
if (!mInputMode.nextTextCase(true)) {
|
if (!mInputMode.nextTextCase()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mInputMode.skipNextTextCaseDetection();
|
||||||
|
|
||||||
// if there are no suggestions or they are special chars, we don't need to adjust their text case
|
// if there are no suggestions or they are special chars, we don't need to adjust their text case
|
||||||
final String currentWord = suggestionOps.isEmpty() || mInputMode.getSequence().isEmpty() ? "" : suggestionOps.getCurrent();
|
final String currentWord = suggestionOps.isEmpty() || mInputMode.getSequence().isEmpty() ? "" : suggestionOps.getCurrent();
|
||||||
if (currentWord.isEmpty() || !Character.isAlphabetic(currentWord.charAt(0))) {
|
if (currentWord.isEmpty() || !Character.isAlphabetic(currentWord.charAt(0))) {
|
||||||
|
|
@ -227,7 +229,7 @@ abstract public class CommandHandler extends TextEditingHandler {
|
||||||
currentSuggestionIndex = suggestionOps.containsStem() ? currentSuggestionIndex - 1 : currentSuggestionIndex;
|
currentSuggestionIndex = suggestionOps.containsStem() ? currentSuggestionIndex - 1 : currentSuggestionIndex;
|
||||||
|
|
||||||
for (int retries = 0; retries <= 2; retries++) {
|
for (int retries = 0; retries <= 2; retries++) {
|
||||||
if (!currentWord.equals(mInputMode.getSuggestions().get(currentSuggestionIndex)) || !mInputMode.nextTextCase(false)) {
|
if (!currentWord.equals(mInputMode.getSuggestions().get(currentSuggestionIndex)) || !mInputMode.nextTextCase()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -146,15 +146,10 @@ public abstract class TypingHandler extends KeyPadHandler {
|
||||||
if (settings.getBackspaceRecomposing() && repeat == 0 && noTextSelection && suggestionOps.isEmpty() && !DictionaryLoader.getInstance(this).isRunning()) {
|
if (settings.getBackspaceRecomposing() && repeat == 0 && noTextSelection && suggestionOps.isEmpty() && !DictionaryLoader.getInstance(this).isRunning()) {
|
||||||
final String previousWord = mInputMode.recompose();
|
final String previousWord = mInputMode.recompose();
|
||||||
if (textField.recompose(previousWord)) {
|
if (textField.recompose(previousWord)) {
|
||||||
mInputMode.setOnEndRecomposing(this::updateShiftState);
|
|
||||||
getSuggestions(previousWord);
|
getSuggestions(previousWord);
|
||||||
} else {
|
} else {
|
||||||
mInputMode.reset();
|
mInputMode.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mainView.isTextEditingPaletteShown() && !mainView.isCommandPaletteShown()) {
|
|
||||||
statusBar.setText(mInputMode);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -432,7 +427,7 @@ public abstract class TypingHandler extends KeyPadHandler {
|
||||||
String trimmedWord = suggestionOps.getCurrent(mLanguage, mInputMode.getSequenceLength());
|
String trimmedWord = suggestionOps.getCurrent(mLanguage, mInputMode.getSequenceLength());
|
||||||
appHacks.setComposingTextWithHighlightedStem(trimmedWord, mInputMode);
|
appHacks.setComposingTextWithHighlightedStem(trimmedWord, mInputMode);
|
||||||
|
|
||||||
updateShiftState(false, true);
|
updateShiftState(mInputMode.getSuggestions().isEmpty(), true);
|
||||||
forceShowWindow();
|
forceShowWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -445,8 +440,8 @@ public abstract class TypingHandler extends KeyPadHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void updateShiftState(boolean determineTextCase, boolean onlyWhenWords) {
|
protected void updateShiftState(boolean determineTextCase, boolean onlyWhenLetters) {
|
||||||
if (onlyWhenWords && (suggestionOps.isEmpty() || !new Text(suggestionOps.getCurrent()).isAlphabetic())) {
|
if (onlyWhenLetters && !new Text(suggestionOps.getCurrent()).isAlphabetic()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -460,9 +455,4 @@ public abstract class TypingHandler extends KeyPadHandler {
|
||||||
statusBar.setText(mInputMode);
|
statusBar.setText(mInputMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void updateShiftState() {
|
|
||||||
updateShiftState(false, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ abstract class UiHandler extends AbstractHandler {
|
||||||
return modeTextCase;
|
return modeTextCase;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wordTextCase = currentWord.getTextCase();
|
final int wordTextCase = currentWord.getTextCase();
|
||||||
return wordTextCase == InputMode.CASE_UPPER ? InputMode.CASE_CAPITALIZE : wordTextCase;
|
return wordTextCase == InputMode.CASE_UPPER ? InputMode.CASE_CAPITALIZE : wordTextCase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,6 @@ abstract public class InputMode {
|
||||||
@NonNull protected String digitSequence = "";
|
@NonNull protected String digitSequence = "";
|
||||||
protected final boolean isEmailMode;
|
protected final boolean isEmailMode;
|
||||||
@NonNull protected Language language = new NullLanguage();
|
@NonNull protected Language language = new NullLanguage();
|
||||||
@NonNull protected Runnable onEndRecomposing = () -> {};
|
|
||||||
protected final SettingsStore settings;
|
protected final SettingsStore settings;
|
||||||
@NonNull protected final ArrayList<String> suggestions = new ArrayList<>();
|
@NonNull protected final ArrayList<String> suggestions = new ArrayList<>();
|
||||||
@NonNull protected Runnable onSuggestionsUpdated = () -> {};
|
@NonNull protected Runnable onSuggestionsUpdated = () -> {};
|
||||||
|
|
@ -179,7 +178,6 @@ abstract public class InputMode {
|
||||||
|
|
||||||
public void beforeDeleteText() {}
|
public void beforeDeleteText() {}
|
||||||
public String recompose() { return null; }
|
public String recompose() { return null; }
|
||||||
public void setOnEndRecomposing(Runnable r) { onEndRecomposing = r != null ? r : () -> {}; }
|
|
||||||
public void replaceLastLetter() {}
|
public void replaceLastLetter() {}
|
||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
|
|
@ -208,7 +206,7 @@ abstract public class InputMode {
|
||||||
* If "analyzeSurroundingText" is true, and when the mode supports text analyzing, it may apply
|
* If "analyzeSurroundingText" is true, and when the mode supports text analyzing, it may apply
|
||||||
* additional logic to determine the next valid text case.
|
* additional logic to determine the next valid text case.
|
||||||
*/
|
*/
|
||||||
public boolean nextTextCase(boolean analyzeSurroundingText) {
|
public boolean nextTextCase() {
|
||||||
if (!language.hasUpperCase()) {
|
if (!language.hasUpperCase()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -220,6 +218,7 @@ abstract public class InputMode {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void determineNextWordTextCase(int nextDigit) {}
|
public void determineNextWordTextCase(int nextDigit) {}
|
||||||
|
public void skipNextTextCaseDetection() {}
|
||||||
|
|
||||||
// Based on the internal logic of the mode (punctuation or grammar rules), re-adjust the text case for when getSuggestions() is called.
|
// Based on the internal logic of the mode (punctuation or grammar rules), re-adjust the text case for when getSuggestions() is called.
|
||||||
protected String adjustSuggestionTextCase(String word, int newTextCase) { return word; }
|
protected String adjustSuggestionTextCase(String word, int newTextCase) { return word; }
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ public class ModeIdeograms extends ModeWords {
|
||||||
|
|
||||||
@Override protected String adjustSuggestionTextCase(String word, int newTextCase) { return word; }
|
@Override protected String adjustSuggestionTextCase(String word, int newTextCase) { return word; }
|
||||||
@Override public void determineNextWordTextCase(int nextDigit) {}
|
@Override public void determineNextWordTextCase(int nextDigit) {}
|
||||||
@Override public boolean nextTextCase(boolean analyzeSurroundingText) { return false; }
|
@Override public boolean nextTextCase() { return false; }
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -160,10 +160,10 @@ class ModeWords extends ModeCheonjiin {
|
||||||
if (isRecomposing) {
|
if (isRecomposing) {
|
||||||
isRecomposing = false;
|
isRecomposing = false;
|
||||||
textCase = settings.getTextCase();
|
textCase = settings.getTextCase();
|
||||||
onEndRecomposing.run();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reset() {
|
public void reset() {
|
||||||
basicReset();
|
basicReset();
|
||||||
|
|
@ -382,14 +382,12 @@ class ModeWords extends ModeCheonjiin {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean nextTextCase(boolean analyzeSurroundingText) {
|
public boolean nextTextCase() {
|
||||||
boolean changed = super.nextTextCase(analyzeSurroundingText);
|
// convert any internally used text cases to user-friendly, because this is what the user
|
||||||
|
// is allowed to choose from.
|
||||||
|
textCase = getTextCase();
|
||||||
|
|
||||||
// "analyzeSurroundingText" is true only when Shift is pressed to avoid expensive
|
boolean changed = super.nextTextCase();
|
||||||
// calls to getStringBeforeCursor().
|
|
||||||
if (analyzeSurroundingText && textCase == CASE_LOWER && autoTextCase.isLowerCaseForbidden(language, textField.getStringBeforeCursor())) {
|
|
||||||
changed = super.nextTextCase(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// since it's a user's choice, the default matters no more
|
// since it's a user's choice, the default matters no more
|
||||||
textFieldTextCase = changed ? CASE_UNDEFINED : textFieldTextCase;
|
textFieldTextCase = changed ? CASE_UNDEFINED : textFieldTextCase;
|
||||||
|
|
@ -397,6 +395,10 @@ class ModeWords extends ModeCheonjiin {
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void skipNextTextCaseDetection() {
|
||||||
|
autoTextCase.skipNext();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldReplaceLastLetter(int n, boolean h) {
|
public boolean shouldReplaceLastLetter(int n, boolean h) {
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,14 @@ public class AutoTextCase {
|
||||||
@NonNull private final Sequences sequences;
|
@NonNull private final Sequences sequences;
|
||||||
@NonNull private final SettingsStore settings;
|
@NonNull private final SettingsStore settings;
|
||||||
private final boolean isUs;
|
private final boolean isUs;
|
||||||
|
private boolean skipNext;
|
||||||
|
|
||||||
|
|
||||||
public AutoTextCase(@NonNull SettingsStore settingsStore, @NonNull Sequences sequences, @Nullable InputType inputType) {
|
public AutoTextCase(@NonNull SettingsStore settingsStore, @NonNull Sequences sequences, @Nullable InputType inputType) {
|
||||||
this.sequences = sequences;
|
this.sequences = sequences;
|
||||||
settings = settingsStore;
|
settings = settingsStore;
|
||||||
isUs = inputType != null && inputType.isUs();
|
isUs = inputType != null && inputType.isUs();
|
||||||
|
skipNext = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -59,6 +61,11 @@ public class AutoTextCase {
|
||||||
return currentTextCase;
|
return currentTextCase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (skipNext) {
|
||||||
|
skipNext = false;
|
||||||
|
return textFieldTextCase != InputMode.CASE_UNDEFINED ? textFieldTextCase : currentTextCase;
|
||||||
|
}
|
||||||
|
|
||||||
// lowercase also takes priority but not as strict as uppercase
|
// lowercase also takes priority but not as strict as uppercase
|
||||||
if (textFieldTextCase != InputMode.CASE_UNDEFINED && currentTextCase != InputMode.CASE_LOWER) {
|
if (textFieldTextCase != InputMode.CASE_UNDEFINED && currentTextCase != InputMode.CASE_LOWER) {
|
||||||
return textFieldTextCase;
|
return textFieldTextCase;
|
||||||
|
|
@ -90,23 +97,7 @@ public class AutoTextCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
public void skipNext() {
|
||||||
* Prevent lowercase at the beginning of a line when the respective setting is enabled,
|
skipNext = true;
|
||||||
* or at the beginning of a sentence, when auto capitalization is enabled.
|
|
||||||
*/
|
|
||||||
public boolean isLowerCaseForbidden(@NonNull Language language, @NonNull String beforeCursor) {
|
|
||||||
if (!language.hasUpperCase()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings.getAutoTextCase() && (beforeCursor.isEmpty() || Text.isStartOfSentence(beforeCursor))) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings.getAutoCapitalsAfterNewline() && beforeCursor.endsWith("\n")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue