aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/latin/UserDictionary.java38
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java38
2 files changed, 70 insertions, 6 deletions
diff --git a/java/src/com/android/inputmethod/latin/UserDictionary.java b/java/src/com/android/inputmethod/latin/UserDictionary.java
index 6608d8268..d696a6158 100644
--- a/java/src/com/android/inputmethod/latin/UserDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserDictionary.java
@@ -25,16 +25,17 @@ import android.database.Cursor;
import android.net.Uri;
import android.os.RemoteException;
import android.provider.UserDictionary.Words;
+import android.text.TextUtils;
import com.android.inputmethod.keyboard.ProximityInfo;
public class UserDictionary extends ExpandableDictionary {
-
+
private static final String[] PROJECTION_QUERY = {
Words.WORD,
Words.FREQUENCY,
};
-
+
private static final String[] PROJECTION_ADD = {
Words._ID,
Words.FREQUENCY,
@@ -42,10 +43,11 @@ public class UserDictionary extends ExpandableDictionary {
};
private ContentObserver mObserver;
- private String mLocale;
+ final private String mLocale;
public UserDictionary(Context context, String locale) {
super(context, Suggest.DIC_USER);
+ if (null == locale) throw new NullPointerException(); // Catch the error earlier
mLocale = locale;
// Perform a managed query. The Activity will handle closing and re-querying the cursor
// when needed.
@@ -73,9 +75,35 @@ public class UserDictionary extends ExpandableDictionary {
@Override
public void loadDictionaryAsync() {
+ // Split the locale. For example "en" => ["en"], "de_DE" => ["de", "DE"],
+ // "en_US_foo_bar_qux" => ["en", "US", "foo_bar_qux"] because of the limit of 3.
+ // This is correct for locale processing.
+ // For this example, we'll look at the "en_US_POSIX" case.
+ final String[] localeElements =
+ TextUtils.isEmpty(mLocale) ? new String[] {} : mLocale.split("_", 3);
+
+ final StringBuilder request = new StringBuilder("(locale is NULL)");
+ String localeSoFar = "";
+ // At start, localeElements = ["en", "US", "POSIX"] ; localeSoFar = "" ;
+ // and request = "(locale is NULL)"
+ for (int i = 0; i < localeElements.length; ++i) {
+ // i | localeSoFar | localeElements
+ // 0 | "" | ["en", "US", "POSIX"]
+ // 1 | "en_" | ["en", "US", "POSIX"]
+ // 2 | "en_US_" | ["en", "en_US", "POSIX"]
+ localeElements[i] = localeSoFar + localeElements[i];
+ localeSoFar = localeElements[i] + "_";
+ // i | request
+ // 0 | "(locale is NULL)"
+ // 1 | "(locale is NULL) or (locale=?)"
+ // 2 | "(locale is NULL) or (locale=?) or (locale=?)"
+ request.append(" or (locale=?)");
+ }
+ // At the end, localeElements = ["en", "en_US", "en_US_POSIX"]; localeSoFar = en_US_POSIX_"
+ // and request = "(locale is NULL) or (locale=?) or (locale=?) or (locale=?)"
Cursor cursor = getContext().getContentResolver()
- .query(Words.CONTENT_URI, PROJECTION_QUERY, "(locale IS NULL) or (locale=?)",
- new String[] { mLocale }, null);
+ .query(Words.CONTENT_URI, PROJECTION_QUERY, request.toString(),
+ localeElements, null);
addWords(cursor);
}
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
index 3cf8788aa..dfa0abf1b 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
@@ -282,6 +282,42 @@ public class AndroidSpellCheckerService extends SpellCheckerService {
mLocale = LocaleUtils.constructLocaleFromString(localeString);
}
+ /**
+ * Finds out whether a particular string should be filtered out of spell checking.
+ *
+ * This will loosely match URLs, numbers, symbols.
+ *
+ * @param text the string to evaluate.
+ * @return true if we should filter this text out, false otherwise
+ */
+ private boolean shouldFilterOut(final String text) {
+ if (TextUtils.isEmpty(text) || text.length() <= 1) return true;
+
+ // TODO: check if an equivalent processing can't be done more quickly with a
+ // compiled regexp.
+ // Filter by first letter
+ final int firstCodePoint = text.codePointAt(0);
+ // Filter out words that don't start with a letter or an apostrophe
+ if (!Character.isLetter(firstCodePoint)
+ && '\'' != firstCodePoint) return true;
+
+ // Filter contents
+ final int length = text.length();
+ int letterCount = 0;
+ for (int i = 0; i < length; ++i) {
+ final int codePoint = text.codePointAt(i);
+ // Any word containing a '@' is probably an e-mail address
+ // Any word containing a '/' is probably either an ad-hoc combination of two
+ // words or a URI - in either case we don't want to spell check that
+ if ('@' == codePoint
+ || '/' == codePoint) return true;
+ if (Character.isLetter(codePoint)) ++letterCount;
+ }
+ // Guestimate heuristic: perform spell checking if at least 3/4 of the characters
+ // in this word are letters
+ return (letterCount * 4 < length * 3);
+ }
+
// Note : this must be reentrant
/**
* Gets a list of suggestions for a specific string. This returns a list of possible
@@ -293,7 +329,7 @@ public class AndroidSpellCheckerService extends SpellCheckerService {
final int suggestionsLimit) {
final String text = textInfo.getText();
- if (TextUtils.isEmpty(text)) return EMPTY_SUGGESTIONS_INFO;
+ if (shouldFilterOut(text)) return EMPTY_SUGGESTIONS_INFO;
final SuggestionsGatherer suggestionsGatherer =
new SuggestionsGatherer(suggestionsLimit);