aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/latin
diff options
context:
space:
mode:
authorJean Chalard <jchalard@google.com>2012-05-11 16:33:01 +0900
committerJean Chalard <jchalard@google.com>2012-05-15 12:23:43 +0900
commit19ad9bf1457af47d98d6464392ca2e1c431f9d1f (patch)
tree377cf8e810aca0789796389e6e3a3e440eb326a6 /java/src/com/android/inputmethod/latin
parenta9aeb6f3ccd2964d79c287860bd660d9f19c8917 (diff)
downloadlatinime-19ad9bf1457af47d98d6464392ca2e1c431f9d1f.tar.gz
latinime-19ad9bf1457af47d98d6464392ca2e1c431f9d1f.tar.xz
latinime-19ad9bf1457af47d98d6464392ca2e1c431f9d1f.zip
Read and use user dictionary shortcuts.
Bug: 4646172 Change-Id: I51002c73d5bad1a698110c5cda02253348be8eed
Diffstat (limited to 'java/src/com/android/inputmethod/latin')
-rw-r--r--java/src/com/android/inputmethod/latin/ContactsDictionary.java3
-rw-r--r--java/src/com/android/inputmethod/latin/Dictionary.java5
-rw-r--r--java/src/com/android/inputmethod/latin/ExpandableDictionary.java88
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java2
-rw-r--r--java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserDictionary.java2
-rw-r--r--java/src/com/android/inputmethod/latin/UserDictionary.java19
-rw-r--r--java/src/com/android/inputmethod/latin/UserHistoryDictionary.java4
-rw-r--r--java/src/com/android/inputmethod/latin/WhitelistDictionary.java2
8 files changed, 90 insertions, 35 deletions
diff --git a/java/src/com/android/inputmethod/latin/ContactsDictionary.java b/java/src/com/android/inputmethod/latin/ContactsDictionary.java
index 8a7dfb839..83bc9046b 100644
--- a/java/src/com/android/inputmethod/latin/ContactsDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ContactsDictionary.java
@@ -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);
diff --git a/java/src/com/android/inputmethod/latin/Dictionary.java b/java/src/com/android/inputmethod/latin/Dictionary.java
index a405aa409..1ec678f7f 100644
--- a/java/src/com/android/inputmethod/latin/Dictionary.java
+++ b/java/src/com/android/inputmethod/latin/Dictionary.java
@@ -24,11 +24,6 @@ import com.android.inputmethod.keyboard.ProximityInfo;
*/
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.
*/
protected static final int FULL_WORD_SCORE_MULTIPLIER = 2;
diff --git a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
index fe21ebe87..7a740b3f1 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
@@ -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;
/**
@@ -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
}
@@ -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);
@@ -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;
@@ -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
@@ -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;
}
/**
@@ -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;
}
@@ -262,6 +281,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
* character is actually an array of multiple possible candidates. This function is not
@@ -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;
}
}
@@ -344,18 +392,18 @@ 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
- * FULL_WORD_SCORE_MULTIPLIER;
- } else {
- finalFreq = computeSkippedWordFinalFreq(freq,
- snr * addedAttenuation, mInputLength);
- }
- callback.addWord(word, 0, depth + 1, finalFreq, mDicTypeId,
- Dictionary.UNIGRAM);
+ final int finalFreq;
+ if (skipPos < 0) {
+ finalFreq = freq * snr * addedAttenuation
+ * FULL_WORD_SCORE_MULTIPLIER;
+ } else {
+ finalFreq = computeSkippedWordFinalFreq(freq,
+ snr * addedAttenuation, mInputLength);
+ }
+ if (!addWordAndShortcutsFromNode(node, word, depth, finalFreq,
+ callback)) {
+ // No space left in the queue, bail out
+ return;
}
}
if (children != null) {
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 011b512e8..165df5d17 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1120,7 +1120,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();
diff --git a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserDictionary.java b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserDictionary.java
index 50e8b249e..b78be89b8 100644
--- a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserDictionary.java
+++ b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserDictionary.java
@@ -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);
}
}
diff --git a/java/src/com/android/inputmethod/latin/UserDictionary.java b/java/src/com/android/inputmethod/latin/UserDictionary.java
index 6beeaace9..218bac72a 100644
--- a/java/src/com/android/inputmethod/latin/UserDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserDictionary.java
@@ -31,8 +31,11 @@ import java.util.Arrays;
public class UserDictionary extends ExpandableDictionary {
+ // TODO: use Words.SHORTCUT when it's public in the SDK
+ final static String SHORTCUT = "shortcut";
private static final String[] PROJECTION_QUERY = {
Words.WORD,
+ SHORTCUT,
Words.FREQUENCY,
};
@@ -149,15 +152,18 @@ public class UserDictionary extends ExpandableDictionary {
}
/**
- * Adds a word to the dictionary and makes it persistent.
+ * Adds a word to the user dictionary and makes it persistent.
+ *
+ * This will call upon the system interface to do the actual work through the intent
+ * readied by the system to this effect.
+ *
* @param word the word to add. If the word is capitalized, then the dictionary will
* recognize it as a capitalized word when searched.
* @param frequency the frequency of occurrence of the word. A frequency of 255 is considered
* the highest.
* @TODO use a higher or float range for frequency
*/
- @Override
- public synchronized void addWord(final String word, final int frequency) {
+ public synchronized void addWordToUserDictionary(final String word, final int frequency) {
// Force load the dictionary here synchronously
if (getRequiresReload()) loadDictionaryAsync();
// TODO: do something for the UI. With the following, any sufficiently long word will
@@ -191,14 +197,19 @@ public class UserDictionary extends ExpandableDictionary {
final int maxWordLength = getMaxWordLength();
if (cursor.moveToFirst()) {
final int indexWord = cursor.getColumnIndex(Words.WORD);
+ final int indexShortcut = cursor.getColumnIndex(SHORTCUT);
final int indexFrequency = cursor.getColumnIndex(Words.FREQUENCY);
while (!cursor.isAfterLast()) {
String word = cursor.getString(indexWord);
+ String shortcut = cursor.getString(indexShortcut);
int frequency = cursor.getInt(indexFrequency);
// Safeguard against adding really long words. Stack may overflow due
// to recursion
if (word.length() < maxWordLength) {
- super.addWord(word, frequency);
+ super.addWord(word, null, frequency);
+ }
+ if (null != shortcut && shortcut.length() < maxWordLength) {
+ super.addWord(shortcut, word, frequency);
}
cursor.moveToNext();
}
diff --git a/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java b/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java
index 9191aa953..e13602e50 100644
--- a/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java
@@ -176,7 +176,7 @@ public class UserHistoryDictionary extends ExpandableDictionary {
* The second word may not be null (a NullPointerException would be thrown).
*/
public int addToUserHistory(final String word1, String word2) {
- super.addWord(word2, FREQUENCY_FOR_TYPED);
+ super.addWord(word2, null /* shortcut */, FREQUENCY_FOR_TYPED);
// Do not insert a word as a bigram of itself
if (word2.equals(word1)) {
return 0;
@@ -246,7 +246,7 @@ public class UserHistoryDictionary extends ExpandableDictionary {
// Safeguard against adding really long words. Stack may overflow due
// to recursive lookup
if (null == word1) {
- super.addWord(word2, frequency);
+ super.addWord(word2, null /* shortcut */, frequency);
} else if (word1.length() < BinaryDictionary.MAX_WORD_LENGTH
&& word2.length() < BinaryDictionary.MAX_WORD_LENGTH) {
super.setBigram(word1, word2, frequency);
diff --git a/java/src/com/android/inputmethod/latin/WhitelistDictionary.java b/java/src/com/android/inputmethod/latin/WhitelistDictionary.java
index bb3ba8651..a0de2f970 100644
--- a/java/src/com/android/inputmethod/latin/WhitelistDictionary.java
+++ b/java/src/com/android/inputmethod/latin/WhitelistDictionary.java
@@ -66,7 +66,7 @@ public class WhitelistDictionary extends ExpandableDictionary {
if (before != null && after != null) {
mWhitelistWords.put(
before.toLowerCase(), new Pair<Integer, String>(score, after));
- addWord(after, score);
+ addWord(after, null /* shortcut */, score);
}
}
} catch (NumberFormatException e) {