PageRenderTime 36ms CodeModel.GetById 28ms app.highlight 6ms RepoModel.GetById 1ms app.codeStats 0ms

/ime/latinime/src/com/googlecode/eyesfree/inputmethod/latin/UserDictionary.java

http://eyes-free.googlecode.com/
Java | 143 lines | 91 code | 21 blank | 31 comment | 9 complexity | 2afbc20b16dd6bc4c5745007c4d4b612 MD5 | raw file
  1/*
  2 * Copyright (C) 2008 The Android Open Source Project
  3 *
  4 * Licensed under the Apache License, Version 2.0 (the "License");
  5 * you may not use this file except in compliance with the License.
  6 * You may obtain a copy of the License at
  7 *
  8 *      http://www.apache.org/licenses/LICENSE-2.0
  9 *
 10 * Unless required by applicable law or agreed to in writing, software
 11 * distributed under the License is distributed on an "AS IS" BASIS,
 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13 * See the License for the specific language governing permissions and
 14 * limitations under the License.
 15 */
 16
 17package com.googlecode.eyesfree.inputmethod.latin;
 18
 19import android.content.ContentResolver;
 20import android.content.ContentValues;
 21import android.content.Context;
 22import android.database.ContentObserver;
 23import android.database.Cursor;
 24import android.provider.UserDictionary.Words;
 25
 26public class UserDictionary extends ExpandableDictionary {
 27
 28    private static final String[] PROJECTION = {
 29        Words._ID,
 30        Words.WORD,
 31        Words.FREQUENCY
 32    };
 33
 34    private static final int INDEX_WORD = 1;
 35    private static final int INDEX_FREQUENCY = 2;
 36
 37    private ContentObserver mObserver;
 38    private String mLocale;
 39
 40    public UserDictionary(Context context, String locale) {
 41        super(context, Suggest.DIC_USER);
 42        mLocale = locale;
 43        // Perform a managed query. The Activity will handle closing and requerying the cursor
 44        // when needed.
 45        ContentResolver cres = context.getContentResolver();
 46
 47        cres.registerContentObserver(Words.CONTENT_URI, true, mObserver = new ContentObserver(null) {
 48            @Override
 49            public void onChange(boolean self) {
 50                setRequiresReload(true);
 51            }
 52        });
 53
 54        loadDictionary();
 55    }
 56
 57    @Override
 58    public synchronized void close() {
 59        if (mObserver != null) {
 60            getContext().getContentResolver().unregisterContentObserver(mObserver);
 61            mObserver = null;
 62        }
 63        super.close();
 64    }
 65
 66    @Override
 67    public void loadDictionaryAsync() {
 68        Cursor cursor = getContext().getContentResolver()
 69                .query(Words.CONTENT_URI, PROJECTION, "(locale IS NULL) or (locale=?)",
 70                        new String[] { mLocale }, null);
 71        addWords(cursor);
 72    }
 73
 74    /**
 75     * Adds a word to the dictionary and makes it persistent.
 76     * @param word the word to add. If the word is capitalized, then the dictionary will
 77     * recognize it as a capitalized word when searched.
 78     * @param frequency the frequency of occurrence of the word. A frequency of 255 is considered
 79     * the highest.
 80     * @TODO use a higher or float range for frequency
 81     */
 82    @Override
 83    public synchronized void addWord(String word, int frequency) {
 84        // Force load the dictionary here synchronously
 85        if (getRequiresReload()) loadDictionaryAsync();
 86        // Safeguard against adding long words. Can cause stack overflow.
 87        if (word.length() >= getMaxWordLength()) return;
 88
 89        super.addWord(word, frequency);
 90
 91        // Update the user dictionary provider
 92        final ContentValues values = new ContentValues(5);
 93        values.put(Words.WORD, word);
 94        values.put(Words.FREQUENCY, frequency);
 95        values.put(Words.LOCALE, mLocale);
 96        values.put(Words.APP_ID, 0);
 97
 98        final ContentResolver contentResolver = getContext().getContentResolver();
 99        new Thread("addWord") {
100            @Override
101            public void run() {
102                contentResolver.insert(Words.CONTENT_URI, values);
103            }
104        }.start();
105
106        // In case the above does a synchronous callback of the change observer
107        setRequiresReload(false);
108    }
109
110    @Override
111    public synchronized void getWords(final WordComposer codes, final WordCallback callback,
112            int[] nextLettersFrequencies) {
113        super.getWords(codes, callback, nextLettersFrequencies);
114    }
115
116    @Override
117    public synchronized boolean isValidWord(CharSequence word) {
118        return super.isValidWord(word);
119    }
120
121    private void addWords(Cursor cursor) {
122        if (cursor == null) {
123            return;
124        }
125
126        clearDictionary();
127
128        final int maxWordLength = getMaxWordLength();
129        if (cursor.moveToFirst()) {
130            while (!cursor.isAfterLast()) {
131                String word = cursor.getString(INDEX_WORD);
132                int frequency = cursor.getInt(INDEX_FREQUENCY);
133                // Safeguard against adding really long words. Stack may overflow due
134                // to recursion
135                if (word.length() < maxWordLength) {
136                    super.addWord(word, frequency);
137                }
138                cursor.moveToNext();
139            }
140        }
141        cursor.close();
142    }
143}