aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardParser.java68
-rw-r--r--java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java8
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/SpellChecker.java114
3 files changed, 173 insertions, 17 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardParser.java b/java/src/com/android/inputmethod/keyboard/KeyboardParser.java
index 4ae011347..c2db62a1c 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardParser.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardParser.java
@@ -467,8 +467,8 @@ public class KeyboardParser {
final TypedArray viewAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser),
R.styleable.KeyboardView);
try {
- final boolean modeMatched = matchInteger(a,
- R.styleable.Keyboard_Case_mode, id.mMode);
+ final boolean modeMatched = matchTypedValue(a,
+ R.styleable.Keyboard_Case_mode, id.mMode, KeyboardId.modeName(id.mMode));
final boolean webInputMatched = matchBoolean(a,
R.styleable.Keyboard_Case_webInput, id.mWebInput);
final boolean passwordInputMatched = matchBoolean(a,
@@ -487,21 +487,22 @@ public class KeyboardParser {
// this attribute with id.mImeOptions as integer value is enough for our purpose.
final boolean imeActionMatched = matchInteger(a,
R.styleable.Keyboard_Case_imeAction, id.mImeAction);
+ final boolean localeCodeMatched = matchString(a,
+ R.styleable.Keyboard_Case_localeCode, id.mLocale.toString());
final boolean languageCodeMatched = matchString(a,
R.styleable.Keyboard_Case_languageCode, id.mLocale.getLanguage());
final boolean countryCodeMatched = matchString(a,
R.styleable.Keyboard_Case_countryCode, id.mLocale.getCountry());
final boolean selected = modeMatched && webInputMatched && passwordInputMatched
&& settingsKeyMatched && voiceEnabledMatched && voiceKeyMatched
- && colorSchemeMatched && imeActionMatched && languageCodeMatched
- && countryCodeMatched;
+ && colorSchemeMatched && imeActionMatched && localeCodeMatched
+ && languageCodeMatched && countryCodeMatched;
- if (DEBUG) Log.d(TAG, String.format("<%s%s%s%s%s%s%s%s%s%s%s> %s", TAG_CASE,
- textAttr(KeyboardId.modeName(
- a.getInt(R.styleable.Keyboard_Case_mode, -1)), "mode"),
+ if (DEBUG) Log.d(TAG, String.format("<%s%s%s%s%s%s%s%s%s%s%s%s> %s", TAG_CASE,
+ textAttr(a.getString(R.styleable.Keyboard_Case_mode), "mode"),
textAttr(KeyboardId.colorSchemeName(
viewAttr.getInt(
- R.styleable.KeyboardView_colorScheme, -1)), "colorSchemeName"),
+ R.styleable.KeyboardView_colorScheme, -1)), "colorScheme"),
booleanAttr(a, R.styleable.Keyboard_Case_webInput, "webInput"),
booleanAttr(a, R.styleable.Keyboard_Case_passwordInput, "passwordInput"),
booleanAttr(a, R.styleable.Keyboard_Case_hasSettingsKey, "hasSettingsKey"),
@@ -509,6 +510,7 @@ public class KeyboardParser {
booleanAttr(a, R.styleable.Keyboard_Case_hasVoiceKey, "hasVoiceKey"),
textAttr(EditorInfoCompatUtils.imeOptionsName(
a.getInt(R.styleable.Keyboard_Case_imeAction, -1)), "imeAction"),
+ textAttr(a.getString(R.styleable.Keyboard_Case_localeCode), "localeCode"),
textAttr(a.getString(R.styleable.Keyboard_Case_languageCode), "languageCode"),
textAttr(a.getString(R.styleable.Keyboard_Case_countryCode), "countryCode"),
Boolean.toString(selected)));
@@ -535,7 +537,30 @@ public class KeyboardParser {
private static boolean matchString(TypedArray a, int index, String value) {
// If <case> does not have "index" attribute, that means this <case> is wild-card for the
// attribute.
- return !a.hasValue(index) || a.getString(index).equals(value);
+ return !a.hasValue(index) || stringArrayContains(a.getString(index).split("\\|"), value);
+ }
+
+ private static boolean matchTypedValue(TypedArray a, int index, int intValue, String strValue) {
+ // If <case> does not have "index" attribute, that means this <case> is wild-card for the
+ // attribute.
+ final TypedValue v = a.peekValue(index);
+ if (v == null)
+ return true;
+
+ if (isIntegerValue(v)) {
+ return intValue == a.getInt(index, 0);
+ } else if (isStringValue(v)) {
+ return stringArrayContains(a.getString(index).split("\\|"), strValue);
+ }
+ return false;
+ }
+
+ private static boolean stringArrayContains(String[] array, String value) {
+ for (final String elem : array) {
+ if (elem.equals(value))
+ return true;
+ }
+ return false;
}
private boolean parseDefault(XmlResourceParser parser, Row row, List<Key> keys)
@@ -594,7 +619,7 @@ public class KeyboardParser {
}
private void endKey(Key key) {
- mCurrentX = key.mX + key.mGap + key.mWidth;
+ mCurrentX = key.mX - key.mGap / 2 + key.mWidth + key.mGap;
}
private void endKeyboard(int defaultVerticalGap) {
@@ -610,19 +635,34 @@ public class KeyboardParser {
final TypedValue value = a.peekValue(index);
if (value == null)
return defValue;
- if (value.type == TypedValue.TYPE_FRACTION) {
+ if (isFractionValue(value)) {
// Round it to avoid values like 47.9999 from getting truncated
return Math.round(a.getFraction(index, base, base, defValue));
- } else if (value.type == TypedValue.TYPE_DIMENSION) {
+ } else if (isDimensionValue(value)) {
return a.getDimensionPixelOffset(index, defValue);
- } else if (value.type >= TypedValue.TYPE_FIRST_INT
- && value.type <= TypedValue.TYPE_LAST_INT) {
+ } else if (isIntegerValue(value)) {
// For enum value.
return a.getInt(index, defValue);
}
return defValue;
}
+ private static boolean isFractionValue(TypedValue v) {
+ return v.type == TypedValue.TYPE_FRACTION;
+ }
+
+ private static boolean isDimensionValue(TypedValue v) {
+ return v.type == TypedValue.TYPE_DIMENSION;
+ }
+
+ private static boolean isIntegerValue(TypedValue v) {
+ return v.type >= TypedValue.TYPE_FIRST_INT && v.type <= TypedValue.TYPE_LAST_INT;
+ }
+
+ private static boolean isStringValue(TypedValue v) {
+ return v.type == TypedValue.TYPE_STRING;
+ }
+
@SuppressWarnings("serial")
public static class ParseException extends InflateException {
public ParseException(String msg, XmlResourceParser parser) {
diff --git a/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java b/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java
index fa2aa874c..60d87f789 100644
--- a/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java
@@ -76,9 +76,11 @@ public class PopupMiniKeyboardView extends KeyboardView implements PopupPanel {
final int pointX = (mConfigShowMiniKeyboardAtTouchedPoint) ? tracker.getLastX()
: parentKey.mX + parentKey.mWidth / 2;
final int pointY = parentKey.mY;
- final int miniKeyboardX = pointX - miniKeyboard.getDefaultCoordX()
- - container.getPaddingLeft()
- + parentKeyboardView.getPaddingLeft() + mCoordinates[0];
+ final int miniKeyboardLeft = pointX - miniKeyboard.getDefaultCoordX()
+ + parentKeyboardView.getPaddingLeft();
+ final int miniKeyboardX = Math.max(0, Math.min(miniKeyboardLeft,
+ parentKeyboardView.getWidth() - miniKeyboard.getMinWidth()))
+ - container.getPaddingLeft() + mCoordinates[0];
final int miniKeyboardY = pointY - parentKeyboard.getVerticalGap()
- (container.getMeasuredHeight() - container.getPaddingBottom())
+ parentKeyboardView.getPaddingTop() + mCoordinates[1];
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/SpellChecker.java b/java/src/com/android/inputmethod/latin/spellcheck/SpellChecker.java
new file mode 100644
index 000000000..e3407a269
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/spellcheck/SpellChecker.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.android.inputmethod.latin.spellcheck;
+
+import android.content.Context;
+import android.content.res.Resources;
+
+import com.android.inputmethod.latin.Dictionary;
+import com.android.inputmethod.latin.Dictionary.DataType;
+import com.android.inputmethod.latin.Dictionary.WordCallback;
+import com.android.inputmethod.latin.DictionaryFactory;
+import com.android.inputmethod.latin.Utils;
+import com.android.inputmethod.latin.WordComposer;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Implements spell checking methods.
+ */
+public class SpellChecker {
+
+ public final Dictionary mDictionary;
+
+ public SpellChecker(final Context context, final Locale locale) {
+ final Resources resources = context.getResources();
+ final int fallbackResourceId = Utils.getMainDictionaryResourceId(resources);
+ mDictionary = DictionaryFactory.createDictionaryFromManager(context, locale,
+ fallbackResourceId);
+ }
+
+ // Note : this must be reentrant
+ /**
+ * Finds out whether a word is in the dictionary or not.
+ *
+ * @param text the sequence containing the word to check for.
+ * @param start the index of the first character of the word in text.
+ * @param end the index of the next-to-last character in text.
+ * @return true if the word is in the dictionary, false otherwise.
+ */
+ public boolean isCorrect(final CharSequence text, final int start, final int end) {
+ return mDictionary.isValidWord(text.subSequence(start, end));
+ }
+
+ private static class SuggestionsGatherer implements WordCallback {
+ private final int DEFAULT_SUGGESTION_LENGTH = 16;
+ private final List<String> mSuggestions = new LinkedList<String>();
+ private int[] mScores = new int[DEFAULT_SUGGESTION_LENGTH];
+ private int mLength = 0;
+
+ synchronized public boolean addWord(char[] word, int wordOffset, int wordLength, int score,
+ int dicTypeId, DataType dataType) {
+ if (mLength >= mScores.length) {
+ final int newLength = mScores.length * 2;
+ mScores = new int[newLength];
+ }
+ final int positionIndex = Arrays.binarySearch(mScores, 0, mLength, score);
+ // binarySearch returns the index if the element exists, and -<insertion index> - 1
+ // if it doesn't. See documentation for binarySearch.
+ final int insertionIndex = positionIndex >= 0 ? positionIndex : -positionIndex - 1;
+ System.arraycopy(mScores, insertionIndex, mScores, insertionIndex + 1,
+ mLength - insertionIndex);
+ mLength += 1;
+ mScores[insertionIndex] = score;
+ mSuggestions.add(insertionIndex, new String(word, wordOffset, wordLength));
+ return true;
+ }
+
+ public List<String> getGatheredSuggestions() {
+ return mSuggestions;
+ }
+ }
+
+ // Note : this must be reentrant
+ /**
+ * Gets a list of suggestions for a specific string.
+ *
+ * This returns a list of possible corrections for the text passed as an
+ * arguments. It may split or group words, and even perform grammatical
+ * analysis.
+ *
+ * @param text the sequence containing the word to check for.
+ * @param start the index of the first character of the word in text.
+ * @param end the index of the next-to-last character in text.
+ * @return a list of possible suggestions to replace the text.
+ */
+ public List<String> getSuggestions(final CharSequence text, final int start, final int end) {
+ final SuggestionsGatherer suggestionsGatherer = new SuggestionsGatherer();
+ final WordComposer composer = new WordComposer();
+ for (int i = start; i < end; ++i) {
+ int character = text.charAt(i);
+ composer.add(character, new int[] { character },
+ WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE);
+ }
+ mDictionary.getWords(composer, suggestionsGatherer);
+ return suggestionsGatherer.getGatheredSuggestions();
+ }
+}