aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/keyboard/Keyboard.java21
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java11
-rw-r--r--java/src/com/android/inputmethod/latin/SubtypeSwitcher.java4
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java157
4 files changed, 148 insertions, 45 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index 2b1cc43cd..07b9c1e8c 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -31,6 +31,7 @@ import com.android.inputmethod.keyboard.internal.KeyStyles;
import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.Utils;
import com.android.inputmethod.latin.XmlParseUtils;
import org.xmlpull.v1.XmlPullParser;
@@ -715,22 +716,30 @@ public class Keyboard {
R.styleable.Keyboard_Key);
try {
final int displayHeight = mDisplayMetrics.heightPixels;
- final int keyboardHeight = (int)keyboardAttr.getDimension(
- R.styleable.Keyboard_keyboardHeight, displayHeight / 2);
- final int maxKeyboardHeight = (int)getDimensionOrFraction(keyboardAttr,
+ final String keyboardHeightString = Utils.getDeviceOverrideValue(
+ mResources, R.array.keyboard_heights, null);
+ final float keyboardHeight;
+ if (keyboardHeightString != null) {
+ keyboardHeight = Float.parseFloat(keyboardHeightString)
+ * mDisplayMetrics.density;
+ } else {
+ keyboardHeight = keyboardAttr.getDimension(
+ R.styleable.Keyboard_keyboardHeight, displayHeight / 2);
+ }
+ final float maxKeyboardHeight = getDimensionOrFraction(keyboardAttr,
R.styleable.Keyboard_maxKeyboardHeight, displayHeight, displayHeight / 2);
- int minKeyboardHeight = (int)getDimensionOrFraction(keyboardAttr,
+ float minKeyboardHeight = getDimensionOrFraction(keyboardAttr,
R.styleable.Keyboard_minKeyboardHeight, displayHeight, displayHeight / 2);
if (minKeyboardHeight < 0) {
// Specified fraction was negative, so it should be calculated against display
// width.
- minKeyboardHeight = -(int)getDimensionOrFraction(keyboardAttr,
+ minKeyboardHeight = -getDimensionOrFraction(keyboardAttr,
R.styleable.Keyboard_minKeyboardHeight, displayWidth, displayWidth / 2);
}
final Params params = mParams;
// Keyboard height will not exceed maxKeyboardHeight and will not be less than
// minKeyboardHeight.
- params.mOccupiedHeight = Math.max(
+ params.mOccupiedHeight = (int)Math.max(
Math.min(keyboardHeight, maxKeyboardHeight), minKeyboardHeight);
params.mOccupiedWidth = params.mId.mWidth;
params.mTopPadding = (int)getDimensionOrFraction(keyboardAttr,
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 7903820f7..175d953a6 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -503,7 +503,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
private void initSuggest() {
final String localeStr = mSubtypeSwitcher.getInputLocaleStr();
- final Locale keyboardLocale = LocaleUtils.constructLocaleFromString(localeStr);
+ final Locale keyboardLocale = mSubtypeSwitcher.getInputLocale();
final Resources res = mResources;
final Locale savedLocale = LocaleUtils.setSystemLocale(res, keyboardLocale);
@@ -567,8 +567,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
/* package private */ void resetSuggestMainDict() {
- final String localeStr = mSubtypeSwitcher.getInputLocaleStr();
- final Locale keyboardLocale = LocaleUtils.constructLocaleFromString(localeStr);
+ final Locale keyboardLocale = mSubtypeSwitcher.getInputLocale();
int mainDicResId = DictionaryFactory.getMainDictionaryResourceId(mResources);
mSuggest.resetMainDict(this, mainDicResId, keyboardLocale);
}
@@ -1007,10 +1006,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
final int touchHeight = inputView.getHeight() + extraHeight
// Extend touchable region below the keyboard.
+ EXTENDED_TOUCHABLE_REGION_HEIGHT;
- if (DEBUG) {
- Log.d(TAG, "Touchable region: y=" + touchY + " width=" + touchWidth
- + " height=" + touchHeight);
- }
setTouchableRegionCompat(outInsets, 0, touchY, touchWidth, touchHeight);
}
outInsets.contentTopInsets = touchY;
@@ -1995,7 +1990,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
private void addToUserHistoryDictionary(final CharSequence suggestion) {
- if (suggestion == null || suggestion.length() < 1) return;
+ if (TextUtils.isEmpty(suggestion)) return;
// Only auto-add to dictionary if auto-correct is ON. Otherwise we'll be
// adding words in situations where the user or application really didn't
diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
index ffbbf9bb8..3524c72f6 100644
--- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
+++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
@@ -47,13 +47,13 @@ public class SubtypeSwitcher {
private static final String TAG = SubtypeSwitcher.class.getSimpleName();
public static final String KEYBOARD_MODE = "keyboard";
- private static final char LOCALE_SEPARATER = '_';
+ private static final char LOCALE_SEPARATOR = '_';
private static final String VOICE_MODE = "voice";
private static final String SUBTYPE_EXTRAVALUE_REQUIRE_NETWORK_CONNECTIVITY =
"requireNetworkConnectivity";
private final TextUtils.SimpleStringSplitter mLocaleSplitter =
- new TextUtils.SimpleStringSplitter(LOCALE_SEPARATER);
+ new TextUtils.SimpleStringSplitter(LOCALE_SEPARATOR);
private static final SubtypeSwitcher sInstance = new SubtypeSwitcher();
private /* final */ LatinIME mService;
diff --git a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
index 70530c338..64fcd7f1a 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
@@ -59,7 +59,7 @@ public class FusionDictionary implements Iterable<Word> {
*/
public static class WeightedString {
final String mWord;
- final int mFrequency;
+ int mFrequency;
public WeightedString(String word, int frequency) {
mWord = word;
mFrequency = frequency;
@@ -94,10 +94,10 @@ public class FusionDictionary implements Iterable<Word> {
public static class CharGroup {
public static final int NOT_A_TERMINAL = -1;
final int mChars[];
- final ArrayList<WeightedString> mShortcutTargets;
- final ArrayList<WeightedString> mBigrams;
- final int mFrequency; // NOT_A_TERMINAL == mFrequency indicates this is not a terminal.
- final boolean mIsShortcutOnly; // Only valid if this is a terminal.
+ ArrayList<WeightedString> mShortcutTargets;
+ ArrayList<WeightedString> mBigrams;
+ int mFrequency; // NOT_A_TERMINAL == mFrequency indicates this is not a terminal.
+ boolean mIsShortcutOnly; // Only valid if this is a terminal.
Node mChildren;
// The two following members to help with binary generation
int mCachedSize;
@@ -146,6 +146,102 @@ public class FusionDictionary implements Iterable<Word> {
assert(mChars.length > 0);
return 1 < mChars.length;
}
+
+ /**
+ * Adds a word to the bigram list. Updates the frequency if the word already
+ * exists.
+ */
+ public void addBigram(final String word, final int frequency) {
+ if (mBigrams == null) {
+ mBigrams = new ArrayList<WeightedString>();
+ }
+ WeightedString bigram = getBigram(word);
+ if (bigram != null) {
+ bigram.mFrequency = frequency;
+ } else {
+ bigram = new WeightedString(word, frequency);
+ mBigrams.add(bigram);
+ }
+ }
+
+ /**
+ * Gets the shortcut target for the given word. Returns null if the word is not in the
+ * shortcut list.
+ */
+ public WeightedString getShortcut(final String word) {
+ if (mShortcutTargets != null) {
+ final int size = mShortcutTargets.size();
+ for (int i = 0; i < size; ++i) {
+ WeightedString shortcut = mShortcutTargets.get(i);
+ if (shortcut.mWord.equals(word)) {
+ return shortcut;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Gets the bigram for the given word.
+ * Returns null if the word is not in the bigrams list.
+ */
+ public WeightedString getBigram(final String word) {
+ if (mBigrams != null) {
+ final int size = mBigrams.size();
+ for (int i = 0; i < size; ++i) {
+ WeightedString bigram = mBigrams.get(i);
+ if (bigram.mWord.equals(word)) {
+ return bigram;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Updates the CharGroup with the given properties. Adds the shortcut and bigram lists to
+ * the existing ones if any. Note: unigram, bigram, and shortcut frequencies are only
+ * updated if they are higher than the existing ones.
+ */
+ public void update(int frequency, ArrayList<WeightedString> shortcutTargets,
+ ArrayList<WeightedString> bigrams, boolean isShortcutOnly) {
+ if (frequency > mFrequency) {
+ mFrequency = frequency;
+ }
+ if (shortcutTargets != null) {
+ if (mShortcutTargets == null) {
+ mShortcutTargets = shortcutTargets;
+ } else {
+ final int size = shortcutTargets.size();
+ for (int i = 0; i < size; ++i) {
+ final WeightedString shortcut = shortcutTargets.get(i);
+ final WeightedString existingShortcut = getShortcut(shortcut.mWord);
+ if (existingShortcut == null) {
+ mShortcutTargets.add(shortcut);
+ } else if (existingShortcut.mFrequency < shortcut.mFrequency) {
+ existingShortcut.mFrequency = shortcut.mFrequency;
+ }
+ }
+ }
+ }
+ if (bigrams != null) {
+ if (mBigrams == null) {
+ mBigrams = bigrams;
+ } else {
+ final int size = bigrams.size();
+ for (int i = 0; i < size; ++i) {
+ final WeightedString bigram = bigrams.get(i);
+ final WeightedString existingBigram = getBigram(bigram.mWord);
+ if (existingBigram == null) {
+ mBigrams.add(bigram);
+ } else if (existingBigram.mFrequency < bigram.mFrequency) {
+ existingBigram.mFrequency = bigram.mFrequency;
+ }
+ }
+ }
+ }
+ mIsShortcutOnly = isShortcutOnly;
+ }
}
/**
@@ -259,6 +355,27 @@ public class FusionDictionary implements Iterable<Word> {
}
/**
+ * Helper method to add a new bigram to the dictionary.
+ *
+ * @param word1 the previous word of the context
+ * @param word2 the next word of the context
+ * @param frequency the bigram frequency
+ */
+ public void setBigram(final String word1, final String word2, final int frequency) {
+ CharGroup charGroup = findWordInTree(mRoot, word1);
+ if (charGroup != null) {
+ final CharGroup charGroup2 = findWordInTree(mRoot, word2);
+ if (charGroup2 == null) {
+ // TODO: refactor with the identical code in addNeutralWords
+ add(getCodePoints(word2), 0, null, null, false /* isShortcutOnly */);
+ }
+ charGroup.addBigram(word2, frequency);
+ } else {
+ throw new RuntimeException("First word of bigram not found");
+ }
+ }
+
+ /**
* Add a word to this dictionary.
*
* The shortcuts and bigrams, if any, have to be in the dictionary already. If they aren't,
@@ -306,17 +423,9 @@ public class FusionDictionary implements Iterable<Word> {
if (differentCharIndex == currentGroup.mChars.length) {
if (charIndex + differentCharIndex >= word.length) {
// The new word is a prefix of an existing word, but the node on which it
- // should end already exists as is.
- if (currentGroup.mFrequency > 0) {
- throw new RuntimeException("Such a word already exists in the dictionary : "
- + new String(word, 0, word.length));
- } else {
- final CharGroup newNode = new CharGroup(currentGroup.mChars,
- shortcutTargets, bigrams, frequency, currentGroup.mChildren,
- isShortcutOnly);
- currentNode.mData.set(nodeIndex, newNode);
- checkStack(currentNode);
- }
+ // should end already exists as is. Since the old CharNode was not a terminal,
+ // make it one by filling in its frequency and other attributes
+ currentGroup.update(frequency, shortcutTargets, bigrams, isShortcutOnly);
} else {
// The new word matches the full old word and extends past it.
// We only have to create a new node and add it to the end of this.
@@ -328,19 +437,9 @@ public class FusionDictionary implements Iterable<Word> {
}
} else {
if (0 == differentCharIndex) {
- // Exact same word. Check the frequency is 0 or NOT_A_TERMINAL, and update.
- if (0 != frequency) {
- if (0 < currentGroup.mFrequency) {
- throw new RuntimeException("This word already exists with frequency "
- + currentGroup.mFrequency + " : "
- + new String(word, 0, word.length));
- }
- final CharGroup newGroup = new CharGroup(word,
- currentGroup.mShortcutTargets, currentGroup.mBigrams,
- frequency, currentGroup.mChildren,
- currentGroup.mIsShortcutOnly && isShortcutOnly);
- currentNode.mData.set(nodeIndex, newGroup);
- }
+ // Exact same word. Update the frequency if higher. This will also add the
+ // new bigrams to the existing bigram list if it already exists.
+ currentGroup.update(frequency, shortcutTargets, bigrams, isShortcutOnly);
} else {
// Partial prefix match only. We have to replace the current node with a node
// containing the current prefix and create two new ones for the tails.