always show typed word when autocorrect can happen

fixes #458
This commit is contained in:
Helium314 2024-01-28 20:01:34 +01:00
parent c761f6f357
commit 2beb949aed
2 changed files with 48 additions and 45 deletions

View file

@ -149,8 +149,7 @@ public final class Suggest {
final int inputStyleIfNotPrediction, final boolean isCorrectionEnabled, final int inputStyleIfNotPrediction, final boolean isCorrectionEnabled,
final int sequenceNumber, final OnGetSuggestedWordsCallback callback) { final int sequenceNumber, final OnGetSuggestedWordsCallback callback) {
final String typedWordString = wordComposer.getTypedWord(); final String typedWordString = wordComposer.getTypedWord();
final int trailingSingleQuotesCount = final int trailingSingleQuotesCount = StringUtils.getTrailingSingleQuotesCount(typedWordString);
StringUtils.getTrailingSingleQuotesCount(typedWordString);
final SuggestionResults suggestionResults = typedWordString.isEmpty() final SuggestionResults suggestionResults = typedWordString.isEmpty()
? getNextWordSuggestions(ngramContext, keyboard, inputStyleIfNotPrediction, settingsValuesForSuggestion) ? getNextWordSuggestions(ngramContext, keyboard, inputStyleIfNotPrediction, settingsValuesForSuggestion)
@ -162,7 +161,6 @@ public final class Suggest {
getTransformedSuggestedWordInfoList(wordComposer, suggestionResults, getTransformedSuggestedWordInfoList(wordComposer, suggestionResults,
trailingSingleQuotesCount, locale); trailingSingleQuotesCount, locale);
boolean foundInDictionary = false;
Dictionary sourceDictionaryOfRemovedWord = null; Dictionary sourceDictionaryOfRemovedWord = null;
// store the original SuggestedWordInfo for typed word, as it will be removed // store the original SuggestedWordInfo for typed word, as it will be removed
// we may want to re-add it in case auto-correction happens, so that the original word can at least be selected // we may want to re-add it in case auto-correction happens, so that the original word can at least be selected
@ -170,10 +168,9 @@ public final class Suggest {
for (final SuggestedWordInfo info : suggestionsContainer) { for (final SuggestedWordInfo info : suggestionsContainer) {
// Search for the best dictionary, defined as the first one with the highest match // Search for the best dictionary, defined as the first one with the highest match
// quality we can find. // quality we can find.
if (!foundInDictionary && typedWordString.equals(info.mWord)) { if (typedWordString.equals(info.mWord)) {
// Use this source if the old match had lower quality than this match // Use this source if the old match had lower quality than this match
sourceDictionaryOfRemovedWord = info.mSourceDict; sourceDictionaryOfRemovedWord = info.mSourceDict;
foundInDictionary = true;
typedWordFirstOccurrenceWordInfo = info; typedWordFirstOccurrenceWordInfo = info;
break; break;
} }
@ -238,23 +235,20 @@ public final class Suggest {
final boolean isTypedWordValid = firstOccurrenceOfTypedWordInSuggestions > -1 final boolean isTypedWordValid = firstOccurrenceOfTypedWordInSuggestions > -1
|| (!resultsArePredictions && !allowsToBeAutoCorrected); || (!resultsArePredictions && !allowsToBeAutoCorrected);
if (hasAutoCorrection && typedWordFirstOccurrenceWordInfo != null) { if (hasAutoCorrection) {
// typed word is valid (in suggestions), but will not be shown if hasAutoCorrection // make sure typed word is shown, so user is able to override incoming autocorrection
// -> add it after the auto-correct suggestion if (typedWordFirstOccurrenceWordInfo != null) {
// todo: it would be better to adjust this in SuggestedWords (getWordCountToShow, maybe more) if (SuggestionStripView.DEBUG_SUGGESTIONS)
// and SuggestionStripView (shouldOmitTypedWord, getStyledSuggestedWord) addDebugInfo(typedWordFirstOccurrenceWordInfo, typedWordString);
// but this could become more complicated than simply adding a duplicate word in a case suggestionsList.add(2, typedWordFirstOccurrenceWordInfo);
// where the first occurrence of that word is ignored } else {
if (SuggestionStripView.DEBUG_SUGGESTIONS) suggestionsList.add(2, new SuggestedWordInfo(typedWordString, "", 0, SuggestedWordInfo.KIND_TYPED,
addDebugInfo(typedWordFirstOccurrenceWordInfo, typedWordString); Dictionary.DICTIONARY_USER_TYPED, SuggestedWordInfo.NOT_AN_INDEX, SuggestedWordInfo.NOT_A_CONFIDENCE));
suggestionsList.add(2, typedWordFirstOccurrenceWordInfo); }
} }
callback.onGetSuggestedWords(new SuggestedWords(suggestionsList, callback.onGetSuggestedWords(new SuggestedWords(suggestionsList, suggestionResults.mRawSuggestions,
suggestionResults.mRawSuggestions, typedWordInfo, typedWordInfo, isTypedWordValid, hasAutoCorrection, false, inputStyle, sequenceNumber));
isTypedWordValid,
hasAutoCorrection /* willAutoCorrect */,
false /* isObsoleteSuggestions */, inputStyle, sequenceNumber));
} }
// annoyingly complicated thing to avoid getting emptyWordSuggestions more than once // annoyingly complicated thing to avoid getting emptyWordSuggestions more than once

View file

@ -46,6 +46,7 @@ import org.dslul.openboard.inputmethod.keyboard.Keyboard;
import org.dslul.openboard.inputmethod.keyboard.MainKeyboardView; import org.dslul.openboard.inputmethod.keyboard.MainKeyboardView;
import org.dslul.openboard.inputmethod.keyboard.MoreKeysPanel; import org.dslul.openboard.inputmethod.keyboard.MoreKeysPanel;
import org.dslul.openboard.inputmethod.latin.AudioAndHapticFeedbackManager; import org.dslul.openboard.inputmethod.latin.AudioAndHapticFeedbackManager;
import org.dslul.openboard.inputmethod.latin.Dictionary;
import org.dslul.openboard.inputmethod.latin.R; import org.dslul.openboard.inputmethod.latin.R;
import org.dslul.openboard.inputmethod.latin.SuggestedWords; import org.dslul.openboard.inputmethod.latin.SuggestedWords;
import org.dslul.openboard.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import org.dslul.openboard.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
@ -404,32 +405,40 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
@SuppressLint("ClickableViewAccessibility") // no need for View#performClick, we return false mostly anyway @SuppressLint("ClickableViewAccessibility") // no need for View#performClick, we return false mostly anyway
private boolean onLongClickSuggestion(final TextView wordView) { private boolean onLongClickSuggestion(final TextView wordView) {
final Drawable icon = mBinIcon; boolean showIcon = true;
Settings.getInstance().getCurrent().mColors.setColor(icon, ColorType.REMOVE_SUGGESTION_ICON); if (wordView.getTag() instanceof Integer) {
int w = icon.getIntrinsicWidth(); final int index = (int) wordView.getTag();
int h = icon.getIntrinsicWidth(); if (index < mSuggestedWords.size() && mSuggestedWords.getInfo(index).mSourceDict == Dictionary.DICTIONARY_USER_TYPED)
wordView.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null); showIcon = false;
wordView.setEllipsize(TextUtils.TruncateAt.END); }
AtomicBoolean downOk = new AtomicBoolean(false); if (showIcon) {
wordView.setOnTouchListener((view1, motionEvent) -> { final Drawable icon = mBinIcon;
if (motionEvent.getAction() == MotionEvent.ACTION_UP) { Settings.getInstance().getCurrent().mColors.setColor(icon, ColorType.REMOVE_SUGGESTION_ICON);
final float x = motionEvent.getX(); int w = icon.getIntrinsicWidth();
final float y = motionEvent.getY(); int h = icon.getIntrinsicWidth();
if (0 < x && x < w && 0 < y && y < h) { wordView.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
removeSuggestion(wordView); wordView.setEllipsize(TextUtils.TruncateAt.END);
wordView.cancelLongPress(); AtomicBoolean downOk = new AtomicBoolean(false);
wordView.setPressed(false); wordView.setOnTouchListener((view1, motionEvent) -> {
return true; if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
final float x = motionEvent.getX();
final float y = motionEvent.getY();
if (0 < x && x < w && 0 < y && y < h) {
removeSuggestion(wordView);
wordView.cancelLongPress();
wordView.setPressed(false);
return true;
}
} else if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
final float x = motionEvent.getX();
final float y = motionEvent.getY();
if (0 < x && x < w && 0 < y && y < h) {
downOk.set(true);
}
} }
} else if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { return false;
final float x = motionEvent.getX(); });
final float y = motionEvent.getY(); }
if (0 < x && x < w && 0 < y && y < h) {
downOk.set(true);
}
}
return false;
});
if (DebugFlags.DEBUG_ENABLED && (isShowingMoreSuggestionPanel() || !showMoreSuggestions())) { if (DebugFlags.DEBUG_ENABLED && (isShowingMoreSuggestionPanel() || !showMoreSuggestions())) {
showSourceDict(wordView); showSourceDict(wordView);
return true; return true;