aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/latin/UserDictionary.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android/inputmethod/latin/UserDictionary.java')
-rw-r--r--java/src/com/android/inputmethod/latin/UserDictionary.java138
1 files changed, 138 insertions, 0 deletions
diff --git a/java/src/com/android/inputmethod/latin/UserDictionary.java b/java/src/com/android/inputmethod/latin/UserDictionary.java
new file mode 100644
index 000000000..4b98eacce
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/UserDictionary.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2008 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;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.UserDictionary.Words;
+
+public class UserDictionary extends ExpandableDictionary {
+
+ private static final String[] PROJECTION = {
+ Words._ID,
+ Words.WORD,
+ Words.FREQUENCY
+ };
+
+ private static final int INDEX_WORD = 1;
+ private static final int INDEX_FREQUENCY = 2;
+
+ private ContentObserver mObserver;
+
+ private boolean mRequiresReload;
+ private String mLocale;
+
+ public UserDictionary(Context context, String locale) {
+ super(context);
+ mLocale = locale;
+ // Perform a managed query. The Activity will handle closing and requerying the cursor
+ // when needed.
+ ContentResolver cres = context.getContentResolver();
+
+ cres.registerContentObserver(Words.CONTENT_URI, true, mObserver = new ContentObserver(null) {
+ @Override
+ public void onChange(boolean self) {
+ mRequiresReload = true;
+ }
+ });
+
+ loadDictionary();
+ }
+
+ public synchronized void close() {
+ if (mObserver != null) {
+ getContext().getContentResolver().unregisterContentObserver(mObserver);
+ mObserver = null;
+ }
+ }
+
+ private synchronized void loadDictionary() {
+ Cursor cursor = getContext().getContentResolver()
+ .query(Words.CONTENT_URI, PROJECTION, "(locale IS NULL) or (locale=?)",
+ new String[] { mLocale }, null);
+ addWords(cursor);
+ mRequiresReload = false;
+ }
+
+ /**
+ * Adds a word to the dictionary and makes it persistent.
+ * @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(String word, int frequency) {
+ if (mRequiresReload) loadDictionary();
+ // Safeguard against adding long words. Can cause stack overflow.
+ if (word.length() >= getMaxWordLength()) return;
+
+ super.addWord(word, frequency);
+
+ // Update the user dictionary provider
+ ContentValues values = new ContentValues(5);
+ values.put(Words.WORD, word);
+ values.put(Words.FREQUENCY, frequency);
+ values.put(Words.LOCALE, mLocale);
+ values.put(Words.APP_ID, 0);
+
+ getContext().getContentResolver().insert(Words.CONTENT_URI, values);
+ // In case the above does a synchronous callback of the change observer
+ mRequiresReload = false;
+ }
+
+ @Override
+ public synchronized void getWords(final WordComposer codes, final WordCallback callback,
+ int[] nextLettersFrequencies) {
+ if (mRequiresReload) loadDictionary();
+ super.getWords(codes, callback, nextLettersFrequencies);
+ }
+
+ @Override
+ public synchronized boolean isValidWord(CharSequence word) {
+ if (mRequiresReload) loadDictionary();
+ return super.isValidWord(word);
+ }
+
+ private void addWords(Cursor cursor) {
+ clearDictionary();
+
+ final int maxWordLength = getMaxWordLength();
+ if (cursor.moveToFirst()) {
+ while (!cursor.isAfterLast()) {
+ String word = cursor.getString(INDEX_WORD);
+ int frequency = cursor.getInt(INDEX_FREQUENCY);
+ // Safeguard against adding really long words. Stack may overflow due
+ // to recursion
+ if (word.length() < maxWordLength) {
+ super.addWord(word, frequency);
+ }
+ cursor.moveToNext();
+ }
+ }
+ cursor.close();
+ }
+}