Loading java/src/com/android/inputmethod/latin/ContactsDictionary.java +2 −1 Original line number Diff line number Diff line Loading @@ -149,7 +149,8 @@ public class ContactsDictionary extends ExpandableDictionary { // capitalization of i. final int wordLen = word.length(); if (wordLen < maxWordLength && wordLen > 1) { super.addWord(word, FREQUENCY_FOR_CONTACTS); super.addWord(word, null /* shortcut */, FREQUENCY_FOR_CONTACTS); if (!TextUtils.isEmpty(prevWord)) { super.setBigram(prevWord, word, FREQUENCY_FOR_CONTACTS_BIGRAM); Loading java/src/com/android/inputmethod/latin/Dictionary.java +0 −5 Original line number Diff line number Diff line Loading @@ -23,11 +23,6 @@ import com.android.inputmethod.keyboard.ProximityInfo; * strokes. */ public abstract class Dictionary { /** * Whether or not to replicate the typed word in the suggested list, even if it's valid. */ protected static final boolean INCLUDE_TYPED_WORD_IF_VALID = false; /** * The weight to give to a word if it's length is the same as the number of typed characters. */ Loading java/src/com/android/inputmethod/latin/ExpandableDictionary.java +68 −20 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import com.android.inputmethod.keyboard.KeyDetector; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.ProximityInfo; import java.util.ArrayList; import java.util.LinkedList; /** Loading Loading @@ -53,6 +54,8 @@ public class ExpandableDictionary extends Dictionary { boolean mTerminal; Node mParent; NodeArray mChildren; ArrayList<char[]> mShortcutTargets; boolean mShortcutOnly; LinkedList<NextWord> mNGrams; // Supports ngram } Loading Loading @@ -150,15 +153,15 @@ public class ExpandableDictionary extends Dictionary { return BinaryDictionary.MAX_WORD_LENGTH; } public void addWord(String word, int frequency) { public void addWord(final String word, final String shortcutTarget, final int frequency) { if (word.length() >= BinaryDictionary.MAX_WORD_LENGTH) { return; } addWordRec(mRoots, word, 0, frequency, null); addWordRec(mRoots, word, 0, shortcutTarget, frequency, null); } private void addWordRec(NodeArray children, final String word, final int depth, final int frequency, Node parentNode) { final String shortcutTarget, final int frequency, Node parentNode) { final int wordLength = word.length(); if (wordLength <= depth) return; final char c = word.charAt(depth); Loading @@ -172,15 +175,25 @@ public class ExpandableDictionary extends Dictionary { break; } } final boolean isShortcutOnly = (null != shortcutTarget); if (childNode == null) { childNode = new Node(); childNode.mCode = c; childNode.mParent = parentNode; childNode.mShortcutOnly = isShortcutOnly; children.add(childNode); } if (wordLength == depth + 1) { // Terminate this word childNode.mTerminal = true; if (isShortcutOnly) { if (null == childNode.mShortcutTargets) { childNode.mShortcutTargets = new ArrayList<char[]>(); } childNode.mShortcutTargets.add(shortcutTarget.toCharArray()); } else { childNode.mShortcutOnly = false; } childNode.mFrequency = Math.max(frequency, childNode.mFrequency); if (childNode.mFrequency > 255) childNode.mFrequency = 255; return; Loading @@ -188,7 +201,7 @@ public class ExpandableDictionary extends Dictionary { if (childNode.mChildren == null) { childNode.mChildren = new NodeArray(); } addWordRec(childNode.mChildren, word, depth + 1, frequency, childNode); addWordRec(childNode.mChildren, word, depth + 1, shortcutTarget, frequency, childNode); } @Override Loading Loading @@ -239,7 +252,13 @@ public class ExpandableDictionary extends Dictionary { if (mRequiresReload) startDictionaryLoadingTaskLocked(); if (mUpdatingDictionary) return false; } return getWordFrequency(word) > -1; final Node node = searchNode(mRoots, word, 0, word.length()); // If node is null, we didn't find the word, so it's not valid. // If node.mShortcutOnly is true, then it exists as a shortcut but not as a word, // so that means it's not a valid word. // If node.mShortcutOnly is false, then it exists as a word (it may also exist as // a shortcut, but this does not matter), so it's a valid word. return (node == null) ? false : !node.mShortcutOnly; } /** Loading @@ -247,7 +266,7 @@ public class ExpandableDictionary extends Dictionary { */ protected int getWordFrequency(CharSequence word) { // Case-sensitive search Node node = searchNode(mRoots, word, 0, word.length()); final Node node = searchNode(mRoots, word, 0, word.length()); return (node == null) ? -1 : node.mFrequency; } Loading @@ -261,6 +280,35 @@ public class ExpandableDictionary extends Dictionary { } } /** * Helper method to add a word and its shortcuts. * * @param node the terminal node * @param word the word to insert, as an array of code points * @param depth the depth of the node in the tree * @param finalFreq the frequency for this word * @return whether there is still space for more words. {@see Dictionary.WordCallback#addWord}. */ private boolean addWordAndShortcutsFromNode(final Node node, final char[] word, final int depth, final int finalFreq, final WordCallback callback) { if (finalFreq > 0 && !node.mShortcutOnly) { if (!callback.addWord(word, 0, depth + 1, finalFreq, mDicTypeId, Dictionary.UNIGRAM)) { return false; } } if (null != node.mShortcutTargets) { final int length = node.mShortcutTargets.size(); for (int shortcutIndex = 0; shortcutIndex < length; ++shortcutIndex) { final char[] shortcut = node.mShortcutTargets.get(shortcutIndex); if (!callback.addWord(shortcut, 0, shortcut.length, finalFreq, mDicTypeId, Dictionary.UNIGRAM)) { return false; } } } return true; } /** * Recursively traverse the tree for words that match the input. Input consists of * a list of arrays. Each item in the list is one input character position. An input Loading Loading @@ -313,8 +361,8 @@ public class ExpandableDictionary extends Dictionary { } else { finalFreq = computeSkippedWordFinalFreq(freq, snr, mInputLength); } if (!callback.addWord(word, 0, depth + 1, finalFreq, mDicTypeId, Dictionary.UNIGRAM)) { if (!addWordAndShortcutsFromNode(node, word, depth, finalFreq, callback)) { // No space left in the queue, bail out return; } } Loading Loading @@ -344,8 +392,6 @@ public class ExpandableDictionary extends Dictionary { if (codeSize == inputIndex + 1) { if (terminal) { if (INCLUDE_TYPED_WORD_IF_VALID || !same(word, depth + 1, codes.getTypedWord())) { final int finalFreq; if (skipPos < 0) { finalFreq = freq * snr * addedAttenuation Loading @@ -354,8 +400,10 @@ public class ExpandableDictionary extends Dictionary { finalFreq = computeSkippedWordFinalFreq(freq, snr * addedAttenuation, mInputLength); } callback.addWord(word, 0, depth + 1, finalFreq, mDicTypeId, Dictionary.UNIGRAM); if (!addWordAndShortcutsFromNode(node, word, depth, finalFreq, callback)) { // No space left in the queue, bail out return; } } if (children != null) { Loading java/src/com/android/inputmethod/latin/LatinIME.java +1 −1 Original line number Diff line number Diff line Loading @@ -1121,7 +1121,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen @Override public boolean addWordToDictionary(String word) { mUserDictionary.addWord(word, 128); mUserDictionary.addWordToUserDictionary(word, 128); // Suggestion strip should be updated after the operation of adding word to the // user dictionary mHandler.postUpdateSuggestions(); Loading java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserDictionary.java +1 −1 Original line number Diff line number Diff line Loading @@ -42,6 +42,6 @@ public class SynchronouslyLoadedUserDictionary extends UserDictionary { @Override public synchronized boolean isValidWord(CharSequence word) { blockingReloadDictionaryIfRequired(); return getWordFrequency(word) > -1; return super.isValidWord(word); } } Loading
java/src/com/android/inputmethod/latin/ContactsDictionary.java +2 −1 Original line number Diff line number Diff line Loading @@ -149,7 +149,8 @@ public class ContactsDictionary extends ExpandableDictionary { // capitalization of i. final int wordLen = word.length(); if (wordLen < maxWordLength && wordLen > 1) { super.addWord(word, FREQUENCY_FOR_CONTACTS); super.addWord(word, null /* shortcut */, FREQUENCY_FOR_CONTACTS); if (!TextUtils.isEmpty(prevWord)) { super.setBigram(prevWord, word, FREQUENCY_FOR_CONTACTS_BIGRAM); Loading
java/src/com/android/inputmethod/latin/Dictionary.java +0 −5 Original line number Diff line number Diff line Loading @@ -23,11 +23,6 @@ import com.android.inputmethod.keyboard.ProximityInfo; * strokes. */ public abstract class Dictionary { /** * Whether or not to replicate the typed word in the suggested list, even if it's valid. */ protected static final boolean INCLUDE_TYPED_WORD_IF_VALID = false; /** * The weight to give to a word if it's length is the same as the number of typed characters. */ Loading
java/src/com/android/inputmethod/latin/ExpandableDictionary.java +68 −20 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import com.android.inputmethod.keyboard.KeyDetector; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.ProximityInfo; import java.util.ArrayList; import java.util.LinkedList; /** Loading Loading @@ -53,6 +54,8 @@ public class ExpandableDictionary extends Dictionary { boolean mTerminal; Node mParent; NodeArray mChildren; ArrayList<char[]> mShortcutTargets; boolean mShortcutOnly; LinkedList<NextWord> mNGrams; // Supports ngram } Loading Loading @@ -150,15 +153,15 @@ public class ExpandableDictionary extends Dictionary { return BinaryDictionary.MAX_WORD_LENGTH; } public void addWord(String word, int frequency) { public void addWord(final String word, final String shortcutTarget, final int frequency) { if (word.length() >= BinaryDictionary.MAX_WORD_LENGTH) { return; } addWordRec(mRoots, word, 0, frequency, null); addWordRec(mRoots, word, 0, shortcutTarget, frequency, null); } private void addWordRec(NodeArray children, final String word, final int depth, final int frequency, Node parentNode) { final String shortcutTarget, final int frequency, Node parentNode) { final int wordLength = word.length(); if (wordLength <= depth) return; final char c = word.charAt(depth); Loading @@ -172,15 +175,25 @@ public class ExpandableDictionary extends Dictionary { break; } } final boolean isShortcutOnly = (null != shortcutTarget); if (childNode == null) { childNode = new Node(); childNode.mCode = c; childNode.mParent = parentNode; childNode.mShortcutOnly = isShortcutOnly; children.add(childNode); } if (wordLength == depth + 1) { // Terminate this word childNode.mTerminal = true; if (isShortcutOnly) { if (null == childNode.mShortcutTargets) { childNode.mShortcutTargets = new ArrayList<char[]>(); } childNode.mShortcutTargets.add(shortcutTarget.toCharArray()); } else { childNode.mShortcutOnly = false; } childNode.mFrequency = Math.max(frequency, childNode.mFrequency); if (childNode.mFrequency > 255) childNode.mFrequency = 255; return; Loading @@ -188,7 +201,7 @@ public class ExpandableDictionary extends Dictionary { if (childNode.mChildren == null) { childNode.mChildren = new NodeArray(); } addWordRec(childNode.mChildren, word, depth + 1, frequency, childNode); addWordRec(childNode.mChildren, word, depth + 1, shortcutTarget, frequency, childNode); } @Override Loading Loading @@ -239,7 +252,13 @@ public class ExpandableDictionary extends Dictionary { if (mRequiresReload) startDictionaryLoadingTaskLocked(); if (mUpdatingDictionary) return false; } return getWordFrequency(word) > -1; final Node node = searchNode(mRoots, word, 0, word.length()); // If node is null, we didn't find the word, so it's not valid. // If node.mShortcutOnly is true, then it exists as a shortcut but not as a word, // so that means it's not a valid word. // If node.mShortcutOnly is false, then it exists as a word (it may also exist as // a shortcut, but this does not matter), so it's a valid word. return (node == null) ? false : !node.mShortcutOnly; } /** Loading @@ -247,7 +266,7 @@ public class ExpandableDictionary extends Dictionary { */ protected int getWordFrequency(CharSequence word) { // Case-sensitive search Node node = searchNode(mRoots, word, 0, word.length()); final Node node = searchNode(mRoots, word, 0, word.length()); return (node == null) ? -1 : node.mFrequency; } Loading @@ -261,6 +280,35 @@ public class ExpandableDictionary extends Dictionary { } } /** * Helper method to add a word and its shortcuts. * * @param node the terminal node * @param word the word to insert, as an array of code points * @param depth the depth of the node in the tree * @param finalFreq the frequency for this word * @return whether there is still space for more words. {@see Dictionary.WordCallback#addWord}. */ private boolean addWordAndShortcutsFromNode(final Node node, final char[] word, final int depth, final int finalFreq, final WordCallback callback) { if (finalFreq > 0 && !node.mShortcutOnly) { if (!callback.addWord(word, 0, depth + 1, finalFreq, mDicTypeId, Dictionary.UNIGRAM)) { return false; } } if (null != node.mShortcutTargets) { final int length = node.mShortcutTargets.size(); for (int shortcutIndex = 0; shortcutIndex < length; ++shortcutIndex) { final char[] shortcut = node.mShortcutTargets.get(shortcutIndex); if (!callback.addWord(shortcut, 0, shortcut.length, finalFreq, mDicTypeId, Dictionary.UNIGRAM)) { return false; } } } return true; } /** * Recursively traverse the tree for words that match the input. Input consists of * a list of arrays. Each item in the list is one input character position. An input Loading Loading @@ -313,8 +361,8 @@ public class ExpandableDictionary extends Dictionary { } else { finalFreq = computeSkippedWordFinalFreq(freq, snr, mInputLength); } if (!callback.addWord(word, 0, depth + 1, finalFreq, mDicTypeId, Dictionary.UNIGRAM)) { if (!addWordAndShortcutsFromNode(node, word, depth, finalFreq, callback)) { // No space left in the queue, bail out return; } } Loading Loading @@ -344,8 +392,6 @@ public class ExpandableDictionary extends Dictionary { if (codeSize == inputIndex + 1) { if (terminal) { if (INCLUDE_TYPED_WORD_IF_VALID || !same(word, depth + 1, codes.getTypedWord())) { final int finalFreq; if (skipPos < 0) { finalFreq = freq * snr * addedAttenuation Loading @@ -354,8 +400,10 @@ public class ExpandableDictionary extends Dictionary { finalFreq = computeSkippedWordFinalFreq(freq, snr * addedAttenuation, mInputLength); } callback.addWord(word, 0, depth + 1, finalFreq, mDicTypeId, Dictionary.UNIGRAM); if (!addWordAndShortcutsFromNode(node, word, depth, finalFreq, callback)) { // No space left in the queue, bail out return; } } if (children != null) { Loading
java/src/com/android/inputmethod/latin/LatinIME.java +1 −1 Original line number Diff line number Diff line Loading @@ -1121,7 +1121,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen @Override public boolean addWordToDictionary(String word) { mUserDictionary.addWord(word, 128); mUserDictionary.addWordToUserDictionary(word, 128); // Suggestion strip should be updated after the operation of adding word to the // user dictionary mHandler.postUpdateSuggestions(); Loading
java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserDictionary.java +1 −1 Original line number Diff line number Diff line Loading @@ -42,6 +42,6 @@ public class SynchronouslyLoadedUserDictionary extends UserDictionary { @Override public synchronized boolean isValidWord(CharSequence word) { blockingReloadDictionaryIfRequired(); return getWordFrequency(word) > -1; return super.isValidWord(word); } }