use of com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo in project android_packages_inputmethods_LatinIME by CyanogenMod.
the class Suggest method getSuggestedWordsForNonBatchInput.
// Retrieves suggestions for non-batch input (typing, recorrection, predictions...)
// and calls the callback function with the suggestions.
private void getSuggestedWordsForNonBatchInput(final WordComposer wordComposer, final NgramContext ngramContext, final Keyboard keyboard, final SettingsValuesForSuggestion settingsValuesForSuggestion, final int inputStyleIfNotPrediction, final boolean isCorrectionEnabled, final int sequenceNumber, final OnGetSuggestedWordsCallback callback) {
final String typedWordString = wordComposer.getTypedWord();
final int trailingSingleQuotesCount = StringUtils.getTrailingSingleQuotesCount(typedWordString);
final String consideredWord = trailingSingleQuotesCount > 0 ? typedWordString.substring(0, typedWordString.length() - trailingSingleQuotesCount) : typedWordString;
final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults(wordComposer.getComposedDataSnapshot(), ngramContext, keyboard, settingsValuesForSuggestion, SESSION_ID_TYPING, inputStyleIfNotPrediction);
final Locale locale = mDictionaryFacilitator.getLocale();
final ArrayList<SuggestedWordInfo> suggestionsContainer = getTransformedSuggestedWordInfoList(wordComposer, suggestionResults, trailingSingleQuotesCount, locale);
boolean foundInDictionary = false;
Dictionary sourceDictionaryOfRemovedWord = null;
for (final SuggestedWordInfo info : suggestionsContainer) {
// quality we can find.
if (!foundInDictionary && typedWordString.equals(info.mWord)) {
// Use this source if the old match had lower quality than this match
sourceDictionaryOfRemovedWord = info.mSourceDict;
foundInDictionary = true;
break;
}
}
final int firstOcurrenceOfTypedWordInSuggestions = SuggestedWordInfo.removeDups(typedWordString, suggestionsContainer);
final SuggestedWordInfo whitelistedWordInfo = getWhitelistedWordInfoOrNull(suggestionsContainer);
final String whitelistedWord = whitelistedWordInfo == null ? null : whitelistedWordInfo.mWord;
final boolean resultsArePredictions = !wordComposer.isComposingWord();
// We allow auto-correction if whitelisting is not required or the word is whitelisted,
// or if the word had more than one char and was not suggested.
final boolean allowsToBeAutoCorrected = (SHOULD_AUTO_CORRECT_USING_NON_WHITE_LISTED_SUGGESTION || whitelistedWord != null) || (consideredWord.length() > 1 && (sourceDictionaryOfRemovedWord == null));
final boolean hasAutoCorrection;
// the setting "Auto-correction" is "off": we still suggest, but we don't auto-correct.
if (!isCorrectionEnabled || // If the word does not allow to be auto-corrected, then we don't auto-correct.
!allowsToBeAutoCorrected || // If we are doing prediction, then we never auto-correct of course
resultsArePredictions || // for auto-correction
suggestionResults.isEmpty() || // was type with a lot of care
wordComposer.hasDigits() || // certainly intentional (and careful input)
wordComposer.isMostlyCaps() || // We never auto-correct when suggestions are resumed because it would be unexpected
wordComposer.isResumed() || // TODO: now that we have personalization, we may want to re-evaluate this decision
!mDictionaryFacilitator.hasAtLeastOneInitializedMainDictionary() || // TODO: we may want to have shortcut-only entries auto-correct in the future.
suggestionResults.first().isKindOf(SuggestedWordInfo.KIND_SHORTCUT)) {
hasAutoCorrection = false;
} else {
final SuggestedWordInfo firstSuggestion = suggestionResults.first();
if (suggestionResults.mFirstSuggestionExceedsConfidenceThreshold && firstOcurrenceOfTypedWordInSuggestions != 0) {
hasAutoCorrection = true;
} else if (!AutoCorrectionUtils.suggestionExceedsThreshold(firstSuggestion, consideredWord, mAutoCorrectionThreshold)) {
// Score is too low for autocorrect
hasAutoCorrection = false;
} else {
// We have a high score, so we need to check if this suggestion is in the correct
// form to allow auto-correcting to it in this language. For details of how this
// is determined, see #isAllowedByAutoCorrectionWithSpaceFilter.
// TODO: this should not have its own logic here but be handled by the dictionary.
hasAutoCorrection = isAllowedByAutoCorrectionWithSpaceFilter(firstSuggestion);
}
}
final SuggestedWordInfo typedWordInfo = new SuggestedWordInfo(typedWordString, "", /* prevWordsContext */
SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_TYPED, null == sourceDictionaryOfRemovedWord ? Dictionary.DICTIONARY_USER_TYPED : sourceDictionaryOfRemovedWord, SuggestedWordInfo.NOT_AN_INDEX, /* indexOfTouchPointOfSecondWord */
SuggestedWordInfo.NOT_A_CONFIDENCE);
if (!TextUtils.isEmpty(typedWordString)) {
suggestionsContainer.add(0, typedWordInfo);
}
final ArrayList<SuggestedWordInfo> suggestionsList;
if (DBG && !suggestionsContainer.isEmpty()) {
suggestionsList = getSuggestionsInfoListWithDebugInfo(typedWordString, suggestionsContainer);
} else {
suggestionsList = suggestionsContainer;
}
final int inputStyle;
if (resultsArePredictions) {
inputStyle = suggestionResults.mIsBeginningOfSentence ? SuggestedWords.INPUT_STYLE_BEGINNING_OF_SENTENCE_PREDICTION : SuggestedWords.INPUT_STYLE_PREDICTION;
} else {
inputStyle = inputStyleIfNotPrediction;
}
final boolean isTypedWordValid = firstOcurrenceOfTypedWordInSuggestions > -1 || (!resultsArePredictions && !allowsToBeAutoCorrected);
callback.onGetSuggestedWords(new SuggestedWords(suggestionsList, suggestionResults.mRawSuggestions, typedWordInfo, isTypedWordValid, hasAutoCorrection, /* willAutoCorrect */
false, /* isObsoleteSuggestions */
inputStyle, sequenceNumber));
}
use of com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo in project android_packages_inputmethods_LatinIME by CyanogenMod.
the class InputLogic method commitCurrentAutoCorrection.
/**
* Commit the current auto-correction.
*
* This will commit the best guess of the keyboard regarding what the user meant by typing
* the currently composing word. The IME computes suggestions and assigns a confidence score
* to each of them; when it's confident enough in one suggestion, it replaces the typed string
* by this suggestion at commit time. When it's not confident enough, or when it has no
* suggestions, or when the settings or environment does not allow for auto-correction, then
* this method just commits the typed string.
* Note that if suggestions are currently being computed in the background, this method will
* block until the computation returns. This is necessary for consistency (it would be very
* strange if pressing space would commit a different word depending on how fast you press).
*
* @param settingsValues the current value of the settings.
* @param separator the separator that's causing the commit to happen.
*/
private void commitCurrentAutoCorrection(final SettingsValues settingsValues, final String separator, final LatinIME.UIHandler handler) {
// Complete any pending suggestions query first
if (handler.hasPendingUpdateSuggestions()) {
handler.cancelUpdateSuggestionStrip();
// To know the input style here, we should retrieve the in-flight "update suggestions"
// message and read its arg1 member here. However, the Handler class does not let
// us retrieve this message, so we can't do that. But in fact, we notice that
// we only ever come here when the input style was typing. In the case of batch
// input, we update the suggestions synchronously when the tail batch comes. Likewise
// for application-specified completions. As for recorrections, we never auto-correct,
// so we don't come here either. Hence, the input style is necessarily
// INPUT_STYLE_TYPING.
performUpdateSuggestionStripSync(settingsValues, SuggestedWords.INPUT_STYLE_TYPING);
}
final SuggestedWordInfo autoCorrectionOrNull = mWordComposer.getAutoCorrectionOrNull();
final String typedWord = mWordComposer.getTypedWord();
final String stringToCommit = (autoCorrectionOrNull != null) ? autoCorrectionOrNull.mWord : typedWord;
if (stringToCommit != null) {
if (TextUtils.isEmpty(typedWord)) {
throw new RuntimeException("We have an auto-correction but the typed word " + "is empty? Impossible! I must commit suicide.");
}
final boolean isBatchMode = mWordComposer.isBatchMode();
commitChosenWord(settingsValues, stringToCommit, LastComposedWord.COMMIT_TYPE_DECIDED_WORD, separator);
if (!typedWord.equals(stringToCommit)) {
// This will make the correction flash for a short while as a visual clue
// to the user that auto-correction happened. It has no other effect; in particular
// note that this won't affect the text inside the text field AT ALL: it only makes
// the segment of text starting at the supplied index and running for the length
// of the auto-correction flash. At this moment, the "typedWord" argument is
// ignored by TextView.
mConnection.commitCorrection(new CorrectionInfo(mConnection.getExpectedSelectionEnd() - stringToCommit.length(), typedWord, stringToCommit));
String prevWordsContext = (autoCorrectionOrNull != null) ? autoCorrectionOrNull.mPrevWordsContext : "";
StatsUtils.onAutoCorrection(typedWord, stringToCommit, isBatchMode, mDictionaryFacilitator, prevWordsContext);
StatsUtils.onWordCommitAutoCorrect(stringToCommit, isBatchMode);
} else {
StatsUtils.onWordCommitUserTyped(stringToCommit, isBatchMode);
}
}
}
use of com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo in project android_packages_inputmethods_LatinIME by CyanogenMod.
the class Suggest method getSuggestionsInfoListWithDebugInfo.
private static ArrayList<SuggestedWordInfo> getSuggestionsInfoListWithDebugInfo(final String typedWord, final ArrayList<SuggestedWordInfo> suggestions) {
final SuggestedWordInfo typedWordInfo = suggestions.get(0);
typedWordInfo.setDebugString("+");
final int suggestionsSize = suggestions.size();
final ArrayList<SuggestedWordInfo> suggestionsList = new ArrayList<>(suggestionsSize);
suggestionsList.add(typedWordInfo);
// than i because we added the typed word to mSuggestions without touching mScores.
for (int i = 0; i < suggestionsSize - 1; ++i) {
final SuggestedWordInfo cur = suggestions.get(i + 1);
final float normalizedScore = BinaryDictionaryUtils.calcNormalizedScore(typedWord, cur.toString(), cur.mScore);
final String scoreInfoString;
if (normalizedScore > 0) {
scoreInfoString = String.format(Locale.ROOT, "%d (%4.2f), %s", cur.mScore, normalizedScore, cur.mSourceDict.mDictType);
} else {
scoreInfoString = Integer.toString(cur.mScore);
}
cur.setDebugString(scoreInfoString);
suggestionsList.add(cur);
}
return suggestionsList;
}
Aggregations