FileDocCategorySizeDatePackage
Suggest.javaAPI DocAndroid 1.5 API10514Wed May 06 22:42:48 BST 2009com.android.inputmethod.latin

Suggest

public class Suggest extends Object implements Dictionary.WordCallback
This class loads a dictionary and provides a list of suggestions for a given sequence of characters. This includes corrections and completions.
hide
pending API Council Approval

Fields Summary
public static final int
CORRECTION_NONE
public static final int
CORRECTION_BASIC
public static final int
CORRECTION_FULL
private Dictionary
mMainDict
private Dictionary
mUserDictionary
private int
mPrefMaxSuggestions
private int[]
mPriorities
private List
mSuggestions
private boolean
mIncludeTypedWordIfValid
private List
mStringPool
private android.content.Context
mContext
private boolean
mHaveCorrection
private CharSequence
mOriginalWord
private String
mLowerOriginalWord
private int
mCorrectionMode
Constructors Summary
public Suggest(android.content.Context context, int dictionaryResId)



         
        mContext = context;
        mMainDict = new BinaryDictionary(context, dictionaryResId);
        for (int i = 0; i < mPrefMaxSuggestions; i++) {
            StringBuilder sb = new StringBuilder(32);
            mStringPool.add(sb);
        }
    
Methods Summary
public booleanaddWord(char[] word, int offset, int length, int freq)

        int pos = 0;
        final int[] priorities = mPriorities;
        final int prefMaxSuggestions = mPrefMaxSuggestions;
        // Check if it's the same word, only caps are different
        if (compareCaseInsensitive(mLowerOriginalWord, word, offset, length)) {
            pos = 0;
        } else {
            // Check the last one's priority and bail
            if (priorities[prefMaxSuggestions - 1] >= freq) return true;
            while (pos < prefMaxSuggestions) {
                if (priorities[pos] < freq
                        || (priorities[pos] == freq && length < mSuggestions
                                .get(pos).length())) {
                    break;
                }
                pos++;
            }
        }
        
        if (pos >= prefMaxSuggestions) {
            return true;
        }
        System.arraycopy(priorities, pos, priorities, pos + 1,
                prefMaxSuggestions - pos - 1);
        priorities[pos] = freq;
        int poolSize = mStringPool.size();
        StringBuilder sb = poolSize > 0 ? (StringBuilder) mStringPool.remove(poolSize - 1) 
                : new StringBuilder(32);
        sb.setLength(0);
        sb.append(word, offset, length);
        mSuggestions.add(pos, sb);
        if (mSuggestions.size() > prefMaxSuggestions) {
            CharSequence garbage = mSuggestions.remove(prefMaxSuggestions);
            if (garbage instanceof StringBuilder) {
                mStringPool.add(garbage);
            }
        }
        return true;
    
private voidcollectGarbage()

        int poolSize = mStringPool.size();
        int garbageSize = mSuggestions.size();
        while (poolSize < mPrefMaxSuggestions && garbageSize > 0) {
            CharSequence garbage = mSuggestions.get(garbageSize - 1);
            if (garbage != null && garbage instanceof StringBuilder) {
                mStringPool.add(garbage);
                poolSize++;
            }
            garbageSize--;
        }
        if (poolSize == mPrefMaxSuggestions + 1) {
            Log.w("Suggest", "String pool got too big: " + poolSize);
        }
        mSuggestions.clear();
    
private booleancompareCaseInsensitive(java.lang.String mLowerOriginalWord, char[] word, int offset, int length)

        final int originalLength = mLowerOriginalWord.length();
        if (originalLength == length && Character.isUpperCase(word[offset])) {
            for (int i = 0; i < originalLength; i++) {
                if (mLowerOriginalWord.charAt(i) != Character.toLowerCase(word[offset+i])) {
                    return false;
                }
            }
            return true;
        }
        return false;
    
public intgetCorrectionMode()

        return mCorrectionMode;
    
public java.util.ListgetSuggestions(android.view.View view, WordComposer wordComposer, boolean includeTypedWordIfValid)
Returns a list of words that match the list of character codes passed in. This list will be overwritten the next time this function is called.

param
a view for retrieving the context for AutoText
param
codes the list of codes. Each list item contains an array of character codes in order of probability where the character at index 0 in the array has the highest probability.
return
list of suggestions.

        mHaveCorrection = false;
        collectGarbage();
        Arrays.fill(mPriorities, 0);
        mIncludeTypedWordIfValid = includeTypedWordIfValid;
        
        // Save a lowercase version of the original word
        mOriginalWord = wordComposer.getTypedWord();
        if (mOriginalWord != null) {
            mOriginalWord = mOriginalWord.toString();
            mLowerOriginalWord = mOriginalWord.toString().toLowerCase();
        } else {
            mLowerOriginalWord = "";
        }
        // Search the dictionary only if there are at least 2 characters
        if (wordComposer.size() > 1) {
            if (mUserDictionary != null) {
                mUserDictionary.getWords(wordComposer, this);
                if (mSuggestions.size() > 0 && isValidWord(mOriginalWord)) {
                    mHaveCorrection = true;
                }
            }
            mMainDict.getWords(wordComposer, this);
            if (mCorrectionMode == CORRECTION_FULL && mSuggestions.size() > 0) {
                mHaveCorrection = true;
            }
        }
        if (mOriginalWord != null) {
            mSuggestions.add(0, mOriginalWord.toString());
        }
        
        // Check if the first suggestion has a minimum number of characters in common
        if (mCorrectionMode == CORRECTION_FULL && mSuggestions.size() > 1) {
            if (!haveSufficientCommonality(mLowerOriginalWord, mSuggestions.get(1))) {
                mHaveCorrection = false;
            }
        }
        
        int i = 0;
        int max = 6;
        // Don't autotext the suggestions from the dictionaries
        if (mCorrectionMode == CORRECTION_BASIC) max = 1;
        while (i < mSuggestions.size() && i < max) {
            String suggestedWord = mSuggestions.get(i).toString().toLowerCase();
            CharSequence autoText =
                    AutoText.get(suggestedWord, 0, suggestedWord.length(), view);
            // Is there an AutoText correction?
            boolean canAdd = autoText != null;
            // Is that correction already the current prediction (or original word)?
            canAdd &= !TextUtils.equals(autoText, mSuggestions.get(i));
            // Is that correction already the next predicted word?
            if (canAdd && i + 1 < mSuggestions.size() && mCorrectionMode != CORRECTION_BASIC) {
                canAdd &= !TextUtils.equals(autoText, mSuggestions.get(i + 1));
            }
            if (canAdd) {
                mHaveCorrection = true;
                mSuggestions.add(i + 1, autoText);
                i++;
            }
            i++;
        }
        
        return mSuggestions;
    
public booleanhasMinimalCorrection()

        return mHaveCorrection;
    
private booleanhaveSufficientCommonality(java.lang.String original, java.lang.CharSequence suggestion)

        final int len = Math.min(original.length(), suggestion.length());
        if (len <= 2) return true;
        int matching = 0;
        for (int i = 0; i < len; i++) {
            if (UserDictionary.toLowerCase(original.charAt(i)) 
                    == UserDictionary.toLowerCase(suggestion.charAt(i))) {
                matching++;
            }
        }
        if (len <= 4) {
            return matching >= 2;
        } else {
            return matching > len / 2;
        }
    
public booleanisValidWord(java.lang.CharSequence word)

        if (word == null || word.length() == 0) {
            return false;
        }
        return (mCorrectionMode == CORRECTION_FULL && mMainDict.isValidWord(word)) 
                || (mCorrectionMode > CORRECTION_NONE && 
                    (mUserDictionary != null && mUserDictionary.isValidWord(word)));
    
public voidsetCorrectionMode(int mode)

        mCorrectionMode = mode;
    
public voidsetMaxSuggestions(int maxSuggestions)
Number of suggestions to generate from the input key sequence. This has to be a number between 1 and 100 (inclusive).

param
maxSuggestions
throws
IllegalArgumentException if the number is out of range

        if (maxSuggestions < 1 || maxSuggestions > 100) {
            throw new IllegalArgumentException("maxSuggestions must be between 1 and 100");
        }
        mPrefMaxSuggestions = maxSuggestions;
        mPriorities = new int[mPrefMaxSuggestions];
        collectGarbage();
        while (mStringPool.size() < mPrefMaxSuggestions) {
            StringBuilder sb = new StringBuilder(32);
            mStringPool.add(sb);
        }
    
public voidsetUserDictionary(Dictionary userDictionary)
Sets an optional user dictionary resource to be loaded. The user dictionary is consulted before the main dictionary, if set.

        mUserDictionary = userDictionary;