• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.inputmethod.latin;
18 
19 import android.text.TextUtils;
20 import android.util.Log;
21 
22 import java.util.ArrayList;
23 import java.util.Map;
24 
25 public class AutoCorrection {
26     private static final boolean DBG = LatinImeLogger.sDBG;
27     private static final String TAG = AutoCorrection.class.getSimpleName();
28     private boolean mHasAutoCorrection;
29     private CharSequence mAutoCorrectionWord;
30     private double mNormalizedScore;
31 
init()32     public void init() {
33         mHasAutoCorrection = false;
34         mAutoCorrectionWord = null;
35         mNormalizedScore = Integer.MIN_VALUE;
36     }
37 
hasAutoCorrection()38     public boolean hasAutoCorrection() {
39         return mHasAutoCorrection;
40     }
41 
getAutoCorrectionWord()42     public CharSequence getAutoCorrectionWord() {
43         return mAutoCorrectionWord;
44     }
45 
getNormalizedScore()46     public double getNormalizedScore() {
47         return mNormalizedScore;
48     }
49 
updateAutoCorrectionStatus(Map<String, Dictionary> dictionaries, WordComposer wordComposer, ArrayList<CharSequence> suggestions, int[] sortedScores, CharSequence typedWord, double autoCorrectionThreshold, int correctionMode, CharSequence whitelistedWord)50     public void updateAutoCorrectionStatus(Map<String, Dictionary> dictionaries,
51             WordComposer wordComposer, ArrayList<CharSequence> suggestions, int[] sortedScores,
52             CharSequence typedWord, double autoCorrectionThreshold, int correctionMode,
53             CharSequence whitelistedWord) {
54         if (hasAutoCorrectionForWhitelistedWord(whitelistedWord)) {
55             mHasAutoCorrection = true;
56             mAutoCorrectionWord = whitelistedWord;
57         } else if (hasAutoCorrectionForTypedWord(
58                 dictionaries, wordComposer, suggestions, typedWord, correctionMode)) {
59             mHasAutoCorrection = true;
60             mAutoCorrectionWord = typedWord;
61         } else if (hasAutoCorrectionForBinaryDictionary(wordComposer, suggestions, correctionMode,
62                 sortedScores, typedWord, autoCorrectionThreshold)) {
63             mHasAutoCorrection = true;
64             mAutoCorrectionWord = suggestions.get(0);
65         }
66     }
67 
isValidWord( Map<String, Dictionary> dictionaries, CharSequence word, boolean ignoreCase)68     public static boolean isValidWord(
69             Map<String, Dictionary> dictionaries, CharSequence word, boolean ignoreCase) {
70         if (TextUtils.isEmpty(word)) {
71             return false;
72         }
73         final CharSequence lowerCasedWord = word.toString().toLowerCase();
74         for (final String key : dictionaries.keySet()) {
75             if (key.equals(Suggest.DICT_KEY_WHITELIST)) continue;
76             final Dictionary dictionary = dictionaries.get(key);
77             if (dictionary.isValidWord(word)
78                     || (ignoreCase && dictionary.isValidWord(lowerCasedWord))) {
79                 return true;
80             }
81         }
82         return false;
83     }
84 
allowsToBeAutoCorrected( Map<String, Dictionary> dictionaries, CharSequence word, boolean ignoreCase)85     public static boolean allowsToBeAutoCorrected(
86             Map<String, Dictionary> dictionaries, CharSequence word, boolean ignoreCase) {
87         final WhitelistDictionary whitelistDictionary =
88                 (WhitelistDictionary)dictionaries.get(Suggest.DICT_KEY_WHITELIST);
89         // If "word" is in the whitelist dictionary, it should not be auto corrected.
90         if (whitelistDictionary != null
91                 && whitelistDictionary.shouldForciblyAutoCorrectFrom(word)) {
92             return true;
93         }
94         return !isValidWord(dictionaries, word, ignoreCase);
95     }
96 
hasAutoCorrectionForWhitelistedWord(CharSequence whiteListedWord)97     private static boolean hasAutoCorrectionForWhitelistedWord(CharSequence whiteListedWord) {
98         return whiteListedWord != null;
99     }
100 
hasAutoCorrectionForTypedWord(Map<String, Dictionary> dictionaries, WordComposer wordComposer, ArrayList<CharSequence> suggestions, CharSequence typedWord, int correctionMode)101     private boolean hasAutoCorrectionForTypedWord(Map<String, Dictionary> dictionaries,
102             WordComposer wordComposer, ArrayList<CharSequence> suggestions, CharSequence typedWord,
103             int correctionMode) {
104         if (TextUtils.isEmpty(typedWord)) return false;
105         boolean allowsAutoCorrect = allowsToBeAutoCorrected(dictionaries, typedWord, false);
106         return wordComposer.size() > 1 && suggestions.size() > 0 && !allowsAutoCorrect
107                 && (correctionMode == Suggest.CORRECTION_FULL
108                 || correctionMode == Suggest.CORRECTION_FULL_BIGRAM);
109     }
110 
hasAutoCorrectionForBinaryDictionary(WordComposer wordComposer, ArrayList<CharSequence> suggestions, int correctionMode, int[] sortedScores, CharSequence typedWord, double autoCorrectionThreshold)111     private boolean hasAutoCorrectionForBinaryDictionary(WordComposer wordComposer,
112             ArrayList<CharSequence> suggestions, int correctionMode, int[] sortedScores,
113             CharSequence typedWord, double autoCorrectionThreshold) {
114         if (wordComposer.size() > 1 && (correctionMode == Suggest.CORRECTION_FULL
115                 || correctionMode == Suggest.CORRECTION_FULL_BIGRAM)
116                 && typedWord != null && suggestions.size() > 0 && sortedScores.length > 0) {
117             final CharSequence autoCorrectionSuggestion = suggestions.get(0);
118             final int autoCorrectionSuggestionScore = sortedScores[0];
119             // TODO: when the normalized score of the first suggestion is nearly equals to
120             //       the normalized score of the second suggestion, behave less aggressive.
121             mNormalizedScore = Utils.calcNormalizedScore(
122                     typedWord,autoCorrectionSuggestion, autoCorrectionSuggestionScore);
123             if (DBG) {
124                 Log.d(TAG, "Normalized " + typedWord + "," + autoCorrectionSuggestion + ","
125                         + autoCorrectionSuggestionScore + ", " + mNormalizedScore
126                         + "(" + autoCorrectionThreshold + ")");
127             }
128             if (mNormalizedScore >= autoCorrectionThreshold) {
129                 if (DBG) {
130                     Log.d(TAG, "Auto corrected by S-threshold.");
131                 }
132                 return true;
133             }
134         }
135         return false;
136     }
137 
138 }
139