Beispiel #1
0
  /**
   * 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 view a view for retrieving the context for AutoText
   * @param wordComposer contains what is currently being typed
   * @param prevWordForBigram previous word (used only for bigram)
   * @return list of suggestions.
   */
  public List<CharSequence> getSuggestions(
      View view,
      WordComposer wordComposer,
      boolean includeTypedWordIfValid,
      CharSequence prevWordForBigram) {
    LatinImeLogger.onStartSuggestion(prevWordForBigram);
    mHaveCorrection = false;
    mIsFirstCharCapitalized = wordComposer.isFirstCharCapitalized();
    mIsAllUpperCase = wordComposer.isAllUpperCase();
    collectGarbage(mSuggestions, mPrefMaxSuggestions);
    Arrays.fill(mPriorities, 0);
    Arrays.fill(mNextLettersFrequencies, 0);

    // Save a lowercase version of the original word
    mOriginalWord = wordComposer.getTypedWord();
    if (mOriginalWord != null) {
      final String mOriginalWordString = mOriginalWord.toString();
      mOriginalWord = mOriginalWordString;
      mLowerOriginalWord = mOriginalWordString.toLowerCase();
      // Treating USER_TYPED as UNIGRAM suggestion for logging now.
      LatinImeLogger.onAddSuggestedWord(
          mOriginalWordString, Suggest.DIC_USER_TYPED, Dictionary.DataType.UNIGRAM);
    } else {
      mLowerOriginalWord = "";
    }

    if (wordComposer.size() == 1
        && (mCorrectionMode == CORRECTION_FULL_BIGRAM || mCorrectionMode == CORRECTION_BASIC)) {
      // At first character typed, search only the bigrams
      Arrays.fill(mBigramPriorities, 0);
      collectGarbage(mBigramSuggestions, PREF_MAX_BIGRAMS);

      if (!TextUtils.isEmpty(prevWordForBigram)) {
        CharSequence lowerPrevWord = prevWordForBigram.toString().toLowerCase();
        if (mMainDict.isValidWord(lowerPrevWord)) {
          prevWordForBigram = lowerPrevWord;
        }
        if (mUserBigramDictionary != null) {
          mUserBigramDictionary.getBigrams(
              wordComposer, prevWordForBigram, this, mNextLettersFrequencies);
        }
        if (mContactsDictionary != null) {
          mContactsDictionary.getBigrams(
              wordComposer, prevWordForBigram, this, mNextLettersFrequencies);
        }
        if (mMainDict != null) {
          mMainDict.getBigrams(wordComposer, prevWordForBigram, this, mNextLettersFrequencies);
        }
        char currentChar = wordComposer.getTypedWord().charAt(0);
        char currentCharUpper = Character.toUpperCase(currentChar);
        int count = 0;
        int bigramSuggestionSize = mBigramSuggestions.size();
        for (int i = 0; i < bigramSuggestionSize; i++) {
          if (mBigramSuggestions.get(i).charAt(0) == currentChar
              || mBigramSuggestions.get(i).charAt(0) == currentCharUpper) {
            int poolSize = mStringPool.size();
            StringBuilder sb =
                poolSize > 0
                    ? (StringBuilder) mStringPool.remove(poolSize - 1)
                    : new StringBuilder(getApproxMaxWordLength());
            sb.setLength(0);
            sb.append(mBigramSuggestions.get(i));
            mSuggestions.add(count++, sb);
            if (count > mPrefMaxSuggestions) break;
          }
        }
      }

    } else if (wordComposer.size() > 1) {
      // At second character typed, search the unigrams (scores being affected by bigrams)
      if (mUserDictionary != null || mContactsDictionary != null) {
        if (mUserDictionary != null) {
          mUserDictionary.getWords(wordComposer, this, mNextLettersFrequencies);
        }
        if (mContactsDictionary != null) {
          mContactsDictionary.getWords(wordComposer, this, mNextLettersFrequencies);
        }

        if (mSuggestions.size() > 0
            && isValidWord(mOriginalWord)
            && (mCorrectionMode == CORRECTION_FULL || mCorrectionMode == CORRECTION_FULL_BIGRAM)) {
          mHaveCorrection = true;
        }
      }
      mMainDict.getWords(wordComposer, this, mNextLettersFrequencies);
      if ((mCorrectionMode == CORRECTION_FULL || mCorrectionMode == CORRECTION_FULL_BIGRAM)
          && 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 (wordComposer.size() > 1
        && mSuggestions.size() > 1
        && (mCorrectionMode == CORRECTION_FULL || mCorrectionMode == CORRECTION_FULL_BIGRAM)) {
      if (!haveSufficientCommonality(mLowerOriginalWord, mSuggestions.get(1))) {
        mHaveCorrection = false;
      }
    }
    if (mAutoTextEnabled) {
      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++;
      }
    }
    removeDupes();
    return mSuggestions;
  }