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.text.TextUtils; 20 import android.view.inputmethod.CompletionInfo; 21 22 import java.util.ArrayList; 23 import java.util.Collections; 24 import java.util.HashSet; 25 import java.util.List; 26 27 public class SuggestedWords { 28 public static final SuggestedWords EMPTY = new SuggestedWords(null, false, false, false, null); 29 30 public final List<CharSequence> mWords; 31 public final boolean mTypedWordValid; 32 public final boolean mHasAutoCorrectionCandidate; 33 public final boolean mIsPunctuationSuggestions; 34 private final List<SuggestedWordInfo> mSuggestedWordInfoList; 35 private boolean mShouldBlockAutoCorrection; 36 37 private SuggestedWords(List<CharSequence> words, boolean typedWordValid, 38 boolean hasAutoCorrectionCandidate, boolean isPunctuationSuggestions, 39 List<SuggestedWordInfo> suggestedWordInfoList) { 40 if (words != null) { 41 mWords = words; 42 } else { 43 mWords = Collections.emptyList(); 44 } 45 mTypedWordValid = typedWordValid; 46 mHasAutoCorrectionCandidate = hasAutoCorrectionCandidate; 47 mIsPunctuationSuggestions = isPunctuationSuggestions; 48 mSuggestedWordInfoList = suggestedWordInfoList; 49 mShouldBlockAutoCorrection = false; 50 } 51 52 public int size() { 53 return mWords.size(); 54 } 55 56 public CharSequence getWord(int pos) { 57 return mWords.get(pos); 58 } 59 60 public SuggestedWordInfo getInfo(int pos) { 61 return mSuggestedWordInfoList != null ? mSuggestedWordInfoList.get(pos) : null; 62 } 63 64 public boolean hasAutoCorrectionWord() { 65 return mHasAutoCorrectionCandidate && size() > 1 && !mTypedWordValid; 66 } 67 68 public boolean hasWordAboveAutoCorrectionScoreThreshold() { 69 return mHasAutoCorrectionCandidate && ((size() > 1 && !mTypedWordValid) || mTypedWordValid); 70 } 71 72 public boolean isPunctuationSuggestions() { 73 return mIsPunctuationSuggestions; 74 } 75 76 public void setShouldBlockAutoCorrection() { 77 mShouldBlockAutoCorrection = true; 78 } 79 80 public boolean shouldBlockAutoCorrection() { 81 return mShouldBlockAutoCorrection; 82 } 83 84 public static class Builder { 85 private List<CharSequence> mWords = new ArrayList<CharSequence>(); 86 private boolean mTypedWordValid; 87 private boolean mHasMinimalSuggestion; 88 private boolean mIsPunctuationSuggestions; 89 private List<SuggestedWordInfo> mSuggestedWordInfoList = 90 new ArrayList<SuggestedWordInfo>(); 91 92 public Builder() { 93 // Nothing to do here. 94 } 95 96 public Builder addWords(List<CharSequence> words, 97 List<SuggestedWordInfo> suggestedWordInfoList) { 98 final int N = words.size(); 99 for (int i = 0; i < N; ++i) { 100 SuggestedWordInfo suggestedWordInfo = null; 101 if (suggestedWordInfoList != null) { 102 suggestedWordInfo = suggestedWordInfoList.get(i); 103 } 104 if (suggestedWordInfo == null) { 105 suggestedWordInfo = new SuggestedWordInfo(); 106 } 107 addWord(words.get(i), suggestedWordInfo); 108 } 109 return this; 110 } 111 112 public Builder addWord(CharSequence word) { 113 return addWord(word, null, false); 114 } 115 116 public Builder addWord(CharSequence word, CharSequence debugString, 117 boolean isPreviousSuggestedWord) { 118 SuggestedWordInfo info = new SuggestedWordInfo(debugString, isPreviousSuggestedWord); 119 return addWord(word, info); 120 } 121 122 private Builder addWord(CharSequence word, SuggestedWordInfo suggestedWordInfo) { 123 if (!TextUtils.isEmpty(word)) { 124 mWords.add(word); 125 // It's okay if suggestedWordInfo is null since it's checked where it's used. 126 mSuggestedWordInfoList.add(suggestedWordInfo); 127 } 128 return this; 129 } 130 131 public Builder setApplicationSpecifiedCompletions(CompletionInfo[] infos) { 132 for (CompletionInfo info : infos) { 133 if (null != info) addWord(info.getText()); 134 } 135 return this; 136 } 137 138 public Builder setTypedWordValid(boolean typedWordValid) { 139 mTypedWordValid = typedWordValid; 140 return this; 141 } 142 143 public Builder setHasMinimalSuggestion(boolean hasMinimalSuggestion) { 144 mHasMinimalSuggestion = hasMinimalSuggestion; 145 return this; 146 } 147 148 public Builder setIsPunctuationSuggestions() { 149 mIsPunctuationSuggestions = true; 150 return this; 151 } 152 153 // Should get rid of the first one (what the user typed previously) from suggestions 154 // and replace it with what the user currently typed. 155 public Builder addTypedWordAndPreviousSuggestions(CharSequence typedWord, 156 SuggestedWords previousSuggestions) { 157 mWords.clear(); 158 mSuggestedWordInfoList.clear(); 159 final HashSet<String> alreadySeen = new HashSet<String>(); 160 addWord(typedWord, null, false); 161 alreadySeen.add(typedWord.toString()); 162 final int previousSize = previousSuggestions.size(); 163 for (int pos = 1; pos < previousSize; pos++) { 164 final String prevWord = previousSuggestions.getWord(pos).toString(); 165 // Filter out duplicate suggestion. 166 if (!alreadySeen.contains(prevWord)) { 167 addWord(prevWord, null, true); 168 alreadySeen.add(prevWord); 169 } 170 } 171 mTypedWordValid = false; 172 mHasMinimalSuggestion = false; 173 return this; 174 } 175 176 public SuggestedWords build() { 177 return new SuggestedWords(mWords, mTypedWordValid, mHasMinimalSuggestion, 178 mIsPunctuationSuggestions, mSuggestedWordInfoList); 179 } 180 181 public int size() { 182 return mWords.size(); 183 } 184 185 public CharSequence getWord(int pos) { 186 return mWords.get(pos); 187 } 188 189 @Override 190 public String toString() { 191 // Pretty-print method to help debug 192 final StringBuilder sb = new StringBuilder("StringBuilder: mTypedWordValid = " 193 + mTypedWordValid + " ; mHasMinimalSuggestion = " + mHasMinimalSuggestion 194 + " ; mIsPunctuationSuggestions = " + mIsPunctuationSuggestions 195 + " --- "); 196 for (CharSequence s : mWords) { 197 sb.append(s); 198 sb.append(" ; "); 199 } 200 return sb.toString(); 201 } 202 } 203 204 public static class SuggestedWordInfo { 205 private final CharSequence mDebugString; 206 private final boolean mPreviousSuggestedWord; 207 208 public SuggestedWordInfo() { 209 mDebugString = ""; 210 mPreviousSuggestedWord = false; 211 } 212 213 public SuggestedWordInfo(CharSequence debugString, boolean previousSuggestedWord) { 214 mDebugString = debugString; 215 mPreviousSuggestedWord = previousSuggestedWord; 216 } 217 218 public String getDebugString() { 219 if (mDebugString == null) { 220 return ""; 221 } else { 222 return mDebugString.toString(); 223 } 224 } 225 226 public boolean isObsoleteSuggestedWord () { 227 return mPreviousSuggestedWord; 228 } 229 } 230 } 231