Home | History | Annotate | Download | only in latin
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
      5  * use this file except in compliance with the License. You may obtain a copy of
      6  * 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, WITHOUT
     12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
     13  * License for the specific language governing permissions and limitations under
     14  * the License.
     15  */
     16 
     17 package com.android.inputmethod.latin;
     18 
     19 import android.content.Context;
     20 import android.text.TextUtils;
     21 
     22 import com.android.inputmethod.keyboard.Key;
     23 import com.android.inputmethod.keyboard.KeyDetector;
     24 import com.android.inputmethod.keyboard.KeyboardId;
     25 import com.android.inputmethod.keyboard.LatinKeyboard;
     26 
     27 import java.io.File;
     28 import java.util.Locale;
     29 
     30 public class SuggestHelper {
     31     protected final Suggest mSuggest;
     32     protected final LatinKeyboard mKeyboard;
     33     private final KeyDetector mKeyDetector;
     34 
     35     public SuggestHelper(Context context, int dictionaryId, KeyboardId keyboardId) {
     36         // Use null as the locale for Suggest so as to force it to use the internal dictionary
     37         // (and not try to find a dictionary provider for a specified locale)
     38         mSuggest = new Suggest(context, dictionaryId, null);
     39         mKeyboard = new LatinKeyboard.Builder(context).load(keyboardId).build();
     40         mKeyDetector = new KeyDetector(0);
     41         init();
     42     }
     43 
     44     protected SuggestHelper(final Context context, final File dictionaryPath,
     45             final long startOffset, final long length, final KeyboardId keyboardId,
     46             final Locale locale) {
     47         mSuggest = new Suggest(context, dictionaryPath, startOffset, length, null, locale);
     48         mKeyboard = new LatinKeyboard.Builder(context).load(keyboardId).build();
     49         mKeyDetector = new KeyDetector(0);
     50         init();
     51     }
     52 
     53     private void init() {
     54         mSuggest.setCorrectionMode(Suggest.CORRECTION_FULL);
     55         mKeyDetector.setKeyboard(mKeyboard, 0, 0);
     56         mKeyDetector.setProximityCorrectionEnabled(true);
     57         mKeyDetector.setProximityThreshold(mKeyboard.mMostCommonKeyWidth);
     58     }
     59 
     60     public void setCorrectionMode(int correctionMode) {
     61         mSuggest.setCorrectionMode(correctionMode);
     62     }
     63 
     64     public boolean hasMainDictionary() {
     65         return mSuggest.hasMainDictionary();
     66     }
     67 
     68     private void addKeyInfo(WordComposer word, char c) {
     69         for (final Key key : mKeyboard.mKeys) {
     70             if (key.mCode == c) {
     71                 final int x = key.mX + key.mWidth / 2;
     72                 final int y = key.mY + key.mHeight / 2;
     73                 final int[] codes = mKeyDetector.newCodeArray();
     74                 mKeyDetector.getKeyIndexAndNearbyCodes(x, y, codes);
     75                 word.add(c, codes, x, y);
     76                 return;
     77             }
     78         }
     79         word.add(c, new int[] { c }, WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE);
     80     }
     81 
     82     protected WordComposer createWordComposer(CharSequence s) {
     83         WordComposer word = new WordComposer();
     84         for (int i = 0; i < s.length(); i++) {
     85             final char c = s.charAt(i);
     86             addKeyInfo(word, c);
     87         }
     88         return word;
     89     }
     90 
     91     public boolean isValidWord(CharSequence typed) {
     92         return AutoCorrection.isValidWord(mSuggest.getUnigramDictionaries(),
     93                 typed, false);
     94     }
     95 
     96     // TODO: This may be slow, but is OK for test so far.
     97     public SuggestedWords getSuggestions(CharSequence typed) {
     98         return mSuggest.getSuggestions(createWordComposer(typed), null,
     99                 mKeyboard.getProximityInfo());
    100     }
    101 
    102     public CharSequence getFirstSuggestion(CharSequence typed) {
    103         WordComposer word = createWordComposer(typed);
    104         SuggestedWords suggestions = mSuggest.getSuggestions(word, null,
    105                 mKeyboard.getProximityInfo());
    106         // Note that suggestions.getWord(0) is the word user typed.
    107         return suggestions.size() > 1 ? suggestions.getWord(1) : null;
    108     }
    109 
    110     public CharSequence getAutoCorrection(CharSequence typed) {
    111         WordComposer word = createWordComposer(typed);
    112         SuggestedWords suggestions = mSuggest.getSuggestions(word, null,
    113                 mKeyboard.getProximityInfo());
    114         // Note that suggestions.getWord(0) is the word user typed.
    115         return (suggestions.size() > 1 && mSuggest.hasAutoCorrection())
    116                 ? suggestions.getWord(1) : null;
    117     }
    118 
    119     public int getSuggestIndex(CharSequence typed, CharSequence expected) {
    120         WordComposer word = createWordComposer(typed);
    121         SuggestedWords suggestions = mSuggest.getSuggestions(word, null,
    122                 mKeyboard.getProximityInfo());
    123         // Note that suggestions.getWord(0) is the word user typed.
    124         for (int i = 1; i < suggestions.size(); i++) {
    125             if (TextUtils.equals(suggestions.getWord(i), expected))
    126                 return i;
    127         }
    128         return -1;
    129     }
    130 
    131     private void getBigramSuggestions(CharSequence previous, CharSequence typed) {
    132         if (!TextUtils.isEmpty(previous) && (typed.length() > 1)) {
    133             WordComposer firstChar = createWordComposer(Character.toString(typed.charAt(0)));
    134             mSuggest.getSuggestions(firstChar, previous, mKeyboard.getProximityInfo());
    135         }
    136     }
    137 
    138     public CharSequence getBigramFirstSuggestion(CharSequence previous, CharSequence typed) {
    139         WordComposer word = createWordComposer(typed);
    140         getBigramSuggestions(previous, typed);
    141         SuggestedWords suggestions = mSuggest.getSuggestions(word, previous,
    142                 mKeyboard.getProximityInfo());
    143         return suggestions.size() > 1 ? suggestions.getWord(1) : null;
    144     }
    145 
    146     public CharSequence getBigramAutoCorrection(CharSequence previous, CharSequence typed) {
    147         WordComposer word = createWordComposer(typed);
    148         getBigramSuggestions(previous, typed);
    149         SuggestedWords suggestions = mSuggest.getSuggestions(word, previous,
    150                 mKeyboard.getProximityInfo());
    151         return (suggestions.size() > 1 && mSuggest.hasAutoCorrection())
    152                 ? suggestions.getWord(1) : null;
    153     }
    154 
    155     public int searchBigramSuggestion(CharSequence previous, CharSequence typed,
    156             CharSequence expected) {
    157         WordComposer word = createWordComposer(typed);
    158         getBigramSuggestions(previous, typed);
    159         SuggestedWords suggestions = mSuggest.getSuggestions(word, previous,
    160                 mKeyboard.getProximityInfo());
    161         for (int i = 1; i < suggestions.size(); i++) {
    162             if (TextUtils.equals(suggestions.getWord(i), expected))
    163                 return i;
    164         }
    165         return -1;
    166     }
    167 }
    168