diff options
author | 2011-08-17 15:10:56 +0900 | |
---|---|---|
committer | 2011-08-22 14:02:57 +0900 | |
commit | 5d4c5692f11958064ba7c0de5715f30c96175400 (patch) | |
tree | a54da3cbbb9255476a4842793b137e658eaf6bc9 /java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java | |
parent | cee174b8ccb47ccddc8a8a7e88a9c617f9b5e766 (diff) | |
download | latinime-5d4c5692f11958064ba7c0de5715f30c96175400.tar.gz latinime-5d4c5692f11958064ba7c0de5715f30c96175400.tar.xz latinime-5d4c5692f11958064ba7c0de5715f30c96175400.zip |
Fix case sensitivity for the spell checker.
The new behavior is as follows:
- If the word in the dictionary is not fully lower case, then the
exact case is required to match.
- If the word in the dictionary is fully lower case, then any of
the following patterns match:
- fully lower case
- only the first char capitalized
- all caps
Any other capitalization is rejected.
This is probably what people want. If you type a name in all lower
case, it should be marked as a typo, but if you type a word with a
capital for emphasis or just because it's the start of the sentence,
it should match a lower case word in the dictionary. If you have
a spurious capital letter in the middle of a word because of a typo,
it should be marked as such.
Accents are not affected, and should not be. An accented letter
is a different letter and a missing accent should be reported.
We should maybe consider again for some common transpositions
like the "ue" digraph for German, which is now considered a typo,
but will suggest the correct diacritics as the first suggestion.
Bug: 5145751
Change-Id: I651e24f13c90fb94700a1674ad380e95336e7dca
Diffstat (limited to 'java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java')
-rw-r--r-- | java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java index ec82f9e80..21176240f 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java @@ -23,6 +23,7 @@ import android.service.textservice.SpellCheckerService.Session; import android.util.Log; import android.view.textservice.SuggestionsInfo; import android.view.textservice.TextInfo; +import android.text.TextUtils; import com.android.inputmethod.compat.ArraysCompatUtils; import com.android.inputmethod.keyboard.Key; @@ -50,7 +51,8 @@ public class AndroidSpellCheckerService extends SpellCheckerService { private static final boolean DBG = false; private static final int POOL_SIZE = 2; - private final static String[] emptyArray = new String[0]; + private final static SuggestionsInfo EMPTY_SUGGESTIONS_INFO = + new SuggestionsInfo(0, new String[0]); private Map<String, DictionaryPool> mDictionaryPools = Collections.synchronizedMap(new TreeMap<String, DictionaryPool>()); private Map<String, Dictionary> mUserDictionaries = @@ -153,10 +155,14 @@ public class AndroidSpellCheckerService extends SpellCheckerService { private class AndroidSpellCheckerSession extends Session { // Immutable, but need the locale which is not available in the constructor yet DictionaryPool mDictionaryPool; + // Likewise + Locale mLocale; @Override public void onCreate() { - mDictionaryPool = getDictionaryPool(getLocale()); + final String localeString = getLocale(); + mDictionaryPool = getDictionaryPool(localeString); + mLocale = Utils.constructLocaleFromString(localeString); } // Note : this must be reentrant @@ -170,6 +176,8 @@ public class AndroidSpellCheckerService extends SpellCheckerService { final int suggestionsLimit) { final String text = textInfo.getText(); + if (TextUtils.isEmpty(text)) return EMPTY_SUGGESTIONS_INFO; + final SuggestionsGatherer suggestionsGatherer = new SuggestionsGatherer(suggestionsLimit); final WordComposer composer = new WordComposer(); @@ -194,12 +202,32 @@ public class AndroidSpellCheckerService extends SpellCheckerService { dictInfo.mDictionary.getWords(composer, suggestionsGatherer, dictInfo.mProximityInfo); isInDict = dictInfo.mDictionary.isValidWord(text); + if (!isInDict && Character.isUpperCase(text.codePointAt(0))) { + // If the first char is not uppercase, then the word is either all lower case, + // in which case we already tested it, or mixed case, in which case we don't + // want to test a lower-case version of it. Hence the test above. + // Also note that by isEmpty() test at the top of the method codePointAt(0) is + // guaranteed to be there. + final int len = text.codePointCount(0, text.length()); + int capsCount = 1; + for (int i = 1; i < len; ++i) { + if (1 != capsCount && i != capsCount) break; + if (Character.isUpperCase(text.codePointAt(i))) ++capsCount; + } + // We know the first char is upper case. So we want to test if either everything + // else is lower case, or if everything else is upper case. If the string is + // exactly one char long, then we will arrive here with capsCount 0, and this is + // correct, too. + if (1 == capsCount || len == capsCount) { + isInDict = dictInfo.mDictionary.isValidWord(text.toLowerCase(mLocale)); + } + } if (!mDictionaryPool.offer(dictInfo)) { Log.e(TAG, "Can't re-insert a dictionary into its pool"); } } catch (InterruptedException e) { // I don't think this can happen. - return new SuggestionsInfo(0, new String[0]); + return EMPTY_SUGGESTIONS_INFO; } final String[] suggestions = suggestionsGatherer.getGatheredSuggestions(); |