blob: c000ae3f6b2a0708e8251ee39ac994056ffea08e [file] [log] [blame]
satokadb43582011-03-09 10:08:47 +09001/*
2 * Copyright (C) 2011 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 android.text.style;
18
Qingqing Dengef20b232019-01-09 12:22:02 -080019import android.annotation.ColorInt;
Yohei Yukawa60fbc8e2016-01-14 12:16:06 -080020import android.annotation.NonNull;
21import android.annotation.Nullable;
Mathew Inwoodefeab842018-08-14 15:21:30 +010022import android.annotation.UnsupportedAppUsage;
satokadb43582011-03-09 10:08:47 +090023import android.content.Context;
Luca Zanolin7d1c55f2011-08-16 14:59:26 +010024import android.content.res.TypedArray;
25import android.graphics.Color;
satokadb43582011-03-09 10:08:47 +090026import android.os.Parcel;
27import android.os.Parcelable;
satokf9f01002011-05-19 21:31:50 +090028import android.os.SystemClock;
satokadb43582011-03-09 10:08:47 +090029import android.text.ParcelableSpan;
Luca Zanolin7d1c55f2011-08-16 14:59:26 +010030import android.text.TextPaint;
satokadb43582011-03-09 10:08:47 +090031import android.text.TextUtils;
Gilles Debunne6e0b22b2012-01-25 14:57:40 -080032import android.util.Log;
Gilles Debunne4dacef22011-07-08 11:45:39 -070033import android.widget.TextView;
satokadb43582011-03-09 10:08:47 +090034
satoke3797a12011-03-22 06:34:48 +090035import java.util.Arrays;
satokadb43582011-03-09 10:08:47 +090036import java.util.Locale;
37
satoke3797a12011-03-22 06:34:48 +090038/**
Gilles Debunne4dacef22011-07-08 11:45:39 -070039 * Holds suggestion candidates for the text enclosed in this span.
40 *
41 * When such a span is edited in an EditText, double tapping on the text enclosed in this span will
42 * display a popup dialog listing suggestion replacement for that text. The user can then replace
43 * the original text by one of the suggestions.
44 *
Luca Zanolin7d1c55f2011-08-16 14:59:26 +010045 * These spans should typically be created by the input method to provide correction and alternates
Gilles Debunne4dacef22011-07-08 11:45:39 -070046 * for the text.
47 *
Gilles Debunne6435a562011-08-04 21:22:30 -070048 * @see TextView#isSuggestionsEnabled()
satoke3797a12011-03-22 06:34:48 +090049 */
Luca Zanolin7d1c55f2011-08-16 14:59:26 +010050public class SuggestionSpan extends CharacterStyle implements ParcelableSpan {
51
Luca Zanolin0c96b81f2012-08-29 11:33:12 +010052 private static final String TAG = "SuggestionSpan";
53
satokadb43582011-03-09 10:08:47 +090054 /**
Luca Zanolin7d1c55f2011-08-16 14:59:26 +010055 * Sets this flag if the suggestions should be easily accessible with few interactions.
56 * This flag should be set for every suggestions that the user is likely to use.
satokadb43582011-03-09 10:08:47 +090057 */
Luca Zanolin7d1c55f2011-08-16 14:59:26 +010058 public static final int FLAG_EASY_CORRECT = 0x0001;
59
60 /**
61 * Sets this flag if the suggestions apply to a misspelled word/text. This type of suggestion is
62 * rendered differently to highlight the error.
63 */
64 public static final int FLAG_MISSPELLED = 0x0002;
satokadb43582011-03-09 10:08:47 +090065
satok9ca4b432011-10-07 15:08:19 +090066 /**
67 * Sets this flag if the auto correction is about to be applied to a word/text
68 * that the user is typing/composing. This type of suggestion is rendered differently
69 * to indicate the auto correction is happening.
satok9ca4b432011-10-07 15:08:19 +090070 */
71 public static final int FLAG_AUTO_CORRECTION = 0x0004;
72
Yohei Yukawa17ace292019-01-21 09:24:26 -080073 /**
74 * This action is deprecated in {@link android.os.Build.VERSION_CODES#Q}.
75 *
76 * @deprecated For IMEs to receive this kind of user interaction signals, implement IMEs' own
77 * suggestion picker UI instead of relying on {@link SuggestionSpan}. To retrieve
78 * bounding boxes for each character of the composing text, use
79 * {@link android.view.inputmethod.CursorAnchorInfo}.
80 */
81 @Deprecated
satokf9f01002011-05-19 21:31:50 +090082 public static final String ACTION_SUGGESTION_PICKED = "android.text.style.SUGGESTION_PICKED";
Yohei Yukawa17ace292019-01-21 09:24:26 -080083
84 /**
85 * This is deprecated in {@link android.os.Build.VERSION_CODES#Q}.
86 *
87 * @deprecated See {@link #ACTION_SUGGESTION_PICKED}.
88 */
89 @Deprecated
satokf9f01002011-05-19 21:31:50 +090090 public static final String SUGGESTION_SPAN_PICKED_AFTER = "after";
Yohei Yukawa17ace292019-01-21 09:24:26 -080091 /**
92 * This is deprecated in {@link android.os.Build.VERSION_CODES#Q}.
93 *
94 * @deprecated See {@link #ACTION_SUGGESTION_PICKED}.
95 */
96 @Deprecated
satokf9f01002011-05-19 21:31:50 +090097 public static final String SUGGESTION_SPAN_PICKED_BEFORE = "before";
Yohei Yukawa17ace292019-01-21 09:24:26 -080098 /**
99 * This is deprecated in {@link android.os.Build.VERSION_CODES#Q}.
100 *
101 * @deprecated See {@link #ACTION_SUGGESTION_PICKED}.
102 */
103 @Deprecated
satokf9f01002011-05-19 21:31:50 +0900104 public static final String SUGGESTION_SPAN_PICKED_HASHCODE = "hashcode";
105
106 public static final int SUGGESTIONS_MAX_SIZE = 5;
satokadb43582011-03-09 10:08:47 +0900107
108 /*
109 * TODO: Needs to check the validity and add a feature that TextView will change
satokb3fc1a52011-04-06 18:28:55 +0900110 * the current IME to the other IME which is specified in SuggestionSpan.
111 * An IME needs to set the span by specifying the target IME and Subtype of SuggestionSpan.
satokadb43582011-03-09 10:08:47 +0900112 * And the current IME might want to specify any IME as the target IME including other IMEs.
113 */
114
Gilles Debunne6435a562011-08-04 21:22:30 -0700115 private int mFlags;
satoke3797a12011-03-22 06:34:48 +0900116 private final String[] mSuggestions;
Yohei Yukawa60fbc8e2016-01-14 12:16:06 -0800117 /**
118 * Kept for compatibility for apps that rely on invalid locale strings e.g.
119 * {@code new Locale(" an ", " i n v a l i d ", "data")}, which cannot be handled by
120 * {@link #mLanguageTag}.
121 */
122 @NonNull
123 private final String mLocaleStringForCompatibility;
124 @NonNull
125 private final String mLanguageTag;
satokf9f01002011-05-19 21:31:50 +0900126 private final int mHashCode;
127
Mathew Inwoodefeab842018-08-14 15:21:30 +0100128 @UnsupportedAppUsage
Luca Zanolinfe5e9832011-09-02 19:41:42 +0100129 private float mEasyCorrectUnderlineThickness;
Mathew Inwoodefeab842018-08-14 15:21:30 +0100130 @UnsupportedAppUsage
Luca Zanolinfe5e9832011-09-02 19:41:42 +0100131 private int mEasyCorrectUnderlineColor;
132
133 private float mMisspelledUnderlineThickness;
134 private int mMisspelledUnderlineColor;
Luca Zanolin7d1c55f2011-08-16 14:59:26 +0100135
satok9ca4b432011-10-07 15:08:19 +0900136 private float mAutoCorrectionUnderlineThickness;
137 private int mAutoCorrectionUnderlineColor;
138
satokadb43582011-03-09 10:08:47 +0900139 /**
140 * @param context Context for the application
satoke3797a12011-03-22 06:34:48 +0900141 * @param suggestions Suggestions for the string under the span
satokadb43582011-03-09 10:08:47 +0900142 * @param flags Additional flags indicating how this span is handled in TextView
143 */
satokb3fc1a52011-04-06 18:28:55 +0900144 public SuggestionSpan(Context context, String[] suggestions, int flags) {
satoke3797a12011-03-22 06:34:48 +0900145 this(context, null, suggestions, flags, null);
satokadb43582011-03-09 10:08:47 +0900146 }
147
148 /**
149 * @param locale Locale of the suggestions
satoke3797a12011-03-22 06:34:48 +0900150 * @param suggestions Suggestions for the string under the span
satokadb43582011-03-09 10:08:47 +0900151 * @param flags Additional flags indicating how this span is handled in TextView
152 */
satokb3fc1a52011-04-06 18:28:55 +0900153 public SuggestionSpan(Locale locale, String[] suggestions, int flags) {
satoke3797a12011-03-22 06:34:48 +0900154 this(null, locale, suggestions, flags, null);
satokadb43582011-03-09 10:08:47 +0900155 }
156
157 /**
158 * @param context Context for the application
159 * @param locale locale Locale of the suggestions
Gilles Debunnec9fd9782011-09-09 09:20:12 -0700160 * @param suggestions Suggestions for the string under the span. Only the first up to
Gilles Debunne6e0b22b2012-01-25 14:57:40 -0800161 * {@link SuggestionSpan#SUGGESTIONS_MAX_SIZE} will be considered. Null values not permitted.
satokadb43582011-03-09 10:08:47 +0900162 * @param flags Additional flags indicating how this span is handled in TextView
satokf9f01002011-05-19 21:31:50 +0900163 * @param notificationTargetClass if not null, this class will get notified when the user
Yohei Yukawa17ace292019-01-21 09:24:26 -0800164 * selects one of the suggestions. On Android
165 * {@link android.os.Build.VERSION_CODES#Q} and later this
166 * parameter is always ignored.
satokadb43582011-03-09 10:08:47 +0900167 */
satokb3fc1a52011-04-06 18:28:55 +0900168 public SuggestionSpan(Context context, Locale locale, String[] suggestions, int flags,
satokf9f01002011-05-19 21:31:50 +0900169 Class<?> notificationTargetClass) {
satoke3797a12011-03-22 06:34:48 +0900170 final int N = Math.min(SUGGESTIONS_MAX_SIZE, suggestions.length);
171 mSuggestions = Arrays.copyOf(suggestions, N);
satokadb43582011-03-09 10:08:47 +0900172 mFlags = flags;
Yohei Yukawa60fbc8e2016-01-14 12:16:06 -0800173 final Locale sourceLocale;
Gilles Debunne6e0b22b2012-01-25 14:57:40 -0800174 if (locale != null) {
Yohei Yukawa60fbc8e2016-01-14 12:16:06 -0800175 sourceLocale = locale;
Gilles Debunne6e0b22b2012-01-25 14:57:40 -0800176 } else if (context != null) {
Yohei Yukawa60fbc8e2016-01-14 12:16:06 -0800177 // TODO: Consider to context.getResources().getResolvedLocale() instead.
178 sourceLocale = context.getResources().getConfiguration().locale;
satokadb43582011-03-09 10:08:47 +0900179 } else {
Gilles Debunne6e0b22b2012-01-25 14:57:40 -0800180 Log.e("SuggestionSpan", "No locale or context specified in SuggestionSpan constructor");
Yohei Yukawa60fbc8e2016-01-14 12:16:06 -0800181 sourceLocale = null;
satokadb43582011-03-09 10:08:47 +0900182 }
Yohei Yukawa60fbc8e2016-01-14 12:16:06 -0800183 mLocaleStringForCompatibility = sourceLocale == null ? "" : sourceLocale.toString();
184 mLanguageTag = sourceLocale == null ? "" : sourceLocale.toLanguageTag();
Yohei Yukawa17ace292019-01-21 09:24:26 -0800185 mHashCode = hashCodeInternal(mSuggestions, mLanguageTag, mLocaleStringForCompatibility);
Luca Zanolin7d1c55f2011-08-16 14:59:26 +0100186
187 initStyle(context);
188 }
189
190 private void initStyle(Context context) {
Gilles Debunnec5436f22011-12-06 10:27:00 -0800191 if (context == null) {
192 mMisspelledUnderlineThickness = 0;
193 mEasyCorrectUnderlineThickness = 0;
194 mAutoCorrectionUnderlineThickness = 0;
195 mMisspelledUnderlineColor = Color.BLACK;
196 mEasyCorrectUnderlineColor = Color.BLACK;
197 mAutoCorrectionUnderlineColor = Color.BLACK;
198 return;
199 }
200
Alan Viverette617feb92013-09-09 18:09:13 -0700201 int defStyleAttr = com.android.internal.R.attr.textAppearanceMisspelledSuggestion;
Luca Zanolinfe5e9832011-09-02 19:41:42 +0100202 TypedArray typedArray = context.obtainStyledAttributes(
Alan Viverette617feb92013-09-09 18:09:13 -0700203 null, com.android.internal.R.styleable.SuggestionSpan, defStyleAttr, 0);
Luca Zanolinfe5e9832011-09-02 19:41:42 +0100204 mMisspelledUnderlineThickness = typedArray.getDimension(
Luca Zanoline6d36822011-08-30 18:04:34 +0100205 com.android.internal.R.styleable.SuggestionSpan_textUnderlineThickness, 0);
Luca Zanolinfe5e9832011-09-02 19:41:42 +0100206 mMisspelledUnderlineColor = typedArray.getColor(
207 com.android.internal.R.styleable.SuggestionSpan_textUnderlineColor, Color.BLACK);
208
Alan Viverette617feb92013-09-09 18:09:13 -0700209 defStyleAttr = com.android.internal.R.attr.textAppearanceEasyCorrectSuggestion;
Luca Zanolinfe5e9832011-09-02 19:41:42 +0100210 typedArray = context.obtainStyledAttributes(
Alan Viverette617feb92013-09-09 18:09:13 -0700211 null, com.android.internal.R.styleable.SuggestionSpan, defStyleAttr, 0);
Luca Zanolinfe5e9832011-09-02 19:41:42 +0100212 mEasyCorrectUnderlineThickness = typedArray.getDimension(
213 com.android.internal.R.styleable.SuggestionSpan_textUnderlineThickness, 0);
214 mEasyCorrectUnderlineColor = typedArray.getColor(
Luca Zanolin7d1c55f2011-08-16 14:59:26 +0100215 com.android.internal.R.styleable.SuggestionSpan_textUnderlineColor, Color.BLACK);
satok9ca4b432011-10-07 15:08:19 +0900216
Alan Viverette617feb92013-09-09 18:09:13 -0700217 defStyleAttr = com.android.internal.R.attr.textAppearanceAutoCorrectionSuggestion;
satok9ca4b432011-10-07 15:08:19 +0900218 typedArray = context.obtainStyledAttributes(
Alan Viverette617feb92013-09-09 18:09:13 -0700219 null, com.android.internal.R.styleable.SuggestionSpan, defStyleAttr, 0);
satok9ca4b432011-10-07 15:08:19 +0900220 mAutoCorrectionUnderlineThickness = typedArray.getDimension(
221 com.android.internal.R.styleable.SuggestionSpan_textUnderlineThickness, 0);
222 mAutoCorrectionUnderlineColor = typedArray.getColor(
223 com.android.internal.R.styleable.SuggestionSpan_textUnderlineColor, Color.BLACK);
satokadb43582011-03-09 10:08:47 +0900224 }
225
satokb3fc1a52011-04-06 18:28:55 +0900226 public SuggestionSpan(Parcel src) {
satoke3797a12011-03-22 06:34:48 +0900227 mSuggestions = src.readStringArray();
satokadb43582011-03-09 10:08:47 +0900228 mFlags = src.readInt();
Yohei Yukawa60fbc8e2016-01-14 12:16:06 -0800229 mLocaleStringForCompatibility = src.readString();
230 mLanguageTag = src.readString();
satokf9f01002011-05-19 21:31:50 +0900231 mHashCode = src.readInt();
Luca Zanolinfe5e9832011-09-02 19:41:42 +0100232 mEasyCorrectUnderlineColor = src.readInt();
233 mEasyCorrectUnderlineThickness = src.readFloat();
234 mMisspelledUnderlineColor = src.readInt();
235 mMisspelledUnderlineThickness = src.readFloat();
satok9ca4b432011-10-07 15:08:19 +0900236 mAutoCorrectionUnderlineColor = src.readInt();
237 mAutoCorrectionUnderlineThickness = src.readFloat();
satokadb43582011-03-09 10:08:47 +0900238 }
239
240 /**
Gilles Debunne4dacef22011-07-08 11:45:39 -0700241 * @return an array of suggestion texts for this span
satokadb43582011-03-09 10:08:47 +0900242 */
satoke3797a12011-03-22 06:34:48 +0900243 public String[] getSuggestions() {
Gilles Debunneee511cc2011-05-05 14:57:50 -0700244 return mSuggestions;
satokadb43582011-03-09 10:08:47 +0900245 }
246
247 /**
Yohei Yukawa60fbc8e2016-01-14 12:16:06 -0800248 * @deprecated use {@link #getLocaleObject()} instead.
249 * @return the locale of the suggestions. An empty string is returned if no locale is specified.
satokadb43582011-03-09 10:08:47 +0900250 */
Yohei Yukawa60fbc8e2016-01-14 12:16:06 -0800251 @NonNull
252 @Deprecated
satokadb43582011-03-09 10:08:47 +0900253 public String getLocale() {
Yohei Yukawa60fbc8e2016-01-14 12:16:06 -0800254 return mLocaleStringForCompatibility;
255 }
256
257 /**
258 * Returns a well-formed BCP 47 language tag representation of the suggestions, as a
259 * {@link Locale} object.
260 *
261 * <p><b>Caveat</b>: The returned object is guaranteed to be a a well-formed BCP 47 language tag
262 * representation. For example, this method can return an empty locale rather than returning a
263 * malformed data when this object is initialized with an malformed {@link Locale} object, e.g.
264 * {@code new Locale(" a ", " b c d ", " "}.</p>
265 *
266 * @return the locale of the suggestions. {@code null} is returned if no locale is specified.
267 */
268 @Nullable
269 public Locale getLocaleObject() {
270 return mLanguageTag.isEmpty() ? null : Locale.forLanguageTag(mLanguageTag);
satokadb43582011-03-09 10:08:47 +0900271 }
272
273 /**
Yohei Yukawa17ace292019-01-21 09:24:26 -0800274 * @return {@code null}.
satok42c5a162011-05-26 16:46:14 +0900275 *
276 * @hide
Yohei Yukawa17ace292019-01-21 09:24:26 -0800277 * @deprecated Do not use. Always returns {@code null}.
satokadb43582011-03-09 10:08:47 +0900278 */
Yohei Yukawa17ace292019-01-21 09:24:26 -0800279 @Deprecated
Mathew Inwoodefeab842018-08-14 15:21:30 +0100280 @UnsupportedAppUsage
satok42c5a162011-05-26 16:46:14 +0900281 public String getNotificationTargetClassName() {
Yohei Yukawa17ace292019-01-21 09:24:26 -0800282 return null;
satokadb43582011-03-09 10:08:47 +0900283 }
284
285 public int getFlags() {
286 return mFlags;
287 }
288
Gilles Debunne6435a562011-08-04 21:22:30 -0700289 public void setFlags(int flags) {
290 mFlags = flags;
291 }
292
satokadb43582011-03-09 10:08:47 +0900293 @Override
294 public int describeContents() {
295 return 0;
296 }
297
298 @Override
299 public void writeToParcel(Parcel dest, int flags) {
Alan Viverettea70d4a92015-06-02 16:11:00 -0700300 writeToParcelInternal(dest, flags);
301 }
302
303 /** @hide */
304 public void writeToParcelInternal(Parcel dest, int flags) {
satoke3797a12011-03-22 06:34:48 +0900305 dest.writeStringArray(mSuggestions);
satokadb43582011-03-09 10:08:47 +0900306 dest.writeInt(mFlags);
Yohei Yukawa60fbc8e2016-01-14 12:16:06 -0800307 dest.writeString(mLocaleStringForCompatibility);
308 dest.writeString(mLanguageTag);
satokf9f01002011-05-19 21:31:50 +0900309 dest.writeInt(mHashCode);
Luca Zanolinfe5e9832011-09-02 19:41:42 +0100310 dest.writeInt(mEasyCorrectUnderlineColor);
311 dest.writeFloat(mEasyCorrectUnderlineThickness);
312 dest.writeInt(mMisspelledUnderlineColor);
313 dest.writeFloat(mMisspelledUnderlineThickness);
satok9ca4b432011-10-07 15:08:19 +0900314 dest.writeInt(mAutoCorrectionUnderlineColor);
315 dest.writeFloat(mAutoCorrectionUnderlineThickness);
satokadb43582011-03-09 10:08:47 +0900316 }
317
318 @Override
319 public int getSpanTypeId() {
Alan Viverettea70d4a92015-06-02 16:11:00 -0700320 return getSpanTypeIdInternal();
321 }
322
323 /** @hide */
324 public int getSpanTypeIdInternal() {
Gilles Debunnea00972a2011-04-13 16:07:31 -0700325 return TextUtils.SUGGESTION_SPAN;
satokadb43582011-03-09 10:08:47 +0900326 }
327
satokf9f01002011-05-19 21:31:50 +0900328 @Override
satok42c5a162011-05-26 16:46:14 +0900329 public boolean equals(Object o) {
330 if (o instanceof SuggestionSpan) {
331 return ((SuggestionSpan)o).hashCode() == mHashCode;
332 }
333 return false;
334 }
335
336 @Override
satokf9f01002011-05-19 21:31:50 +0900337 public int hashCode() {
338 return mHashCode;
339 }
340
Yohei Yukawa60fbc8e2016-01-14 12:16:06 -0800341 private static int hashCodeInternal(String[] suggestions, @NonNull String languageTag,
Yohei Yukawa17ace292019-01-21 09:24:26 -0800342 @NonNull String localeStringForCompatibility) {
Gilles Debunne6435a562011-08-04 21:22:30 -0700343 return Arrays.hashCode(new Object[] {Long.valueOf(SystemClock.uptimeMillis()), suggestions,
Yohei Yukawa17ace292019-01-21 09:24:26 -0800344 languageTag, localeStringForCompatibility});
satokf9f01002011-05-19 21:31:50 +0900345 }
346
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700347 public static final @android.annotation.NonNull Parcelable.Creator<SuggestionSpan> CREATOR =
satokb3fc1a52011-04-06 18:28:55 +0900348 new Parcelable.Creator<SuggestionSpan>() {
satokadb43582011-03-09 10:08:47 +0900349 @Override
satokb3fc1a52011-04-06 18:28:55 +0900350 public SuggestionSpan createFromParcel(Parcel source) {
351 return new SuggestionSpan(source);
satokadb43582011-03-09 10:08:47 +0900352 }
353
354 @Override
satokb3fc1a52011-04-06 18:28:55 +0900355 public SuggestionSpan[] newArray(int size) {
356 return new SuggestionSpan[size];
satokadb43582011-03-09 10:08:47 +0900357 }
358 };
Luca Zanolin7d1c55f2011-08-16 14:59:26 +0100359
360 @Override
361 public void updateDrawState(TextPaint tp) {
Gilles Debunnec9fd9782011-09-09 09:20:12 -0700362 final boolean misspelled = (mFlags & FLAG_MISSPELLED) != 0;
363 final boolean easy = (mFlags & FLAG_EASY_CORRECT) != 0;
satok9ca4b432011-10-07 15:08:19 +0900364 final boolean autoCorrection = (mFlags & FLAG_AUTO_CORRECTION) != 0;
Gilles Debunnec9fd9782011-09-09 09:20:12 -0700365 if (easy) {
366 if (!misspelled) {
367 tp.setUnderlineText(mEasyCorrectUnderlineColor, mEasyCorrectUnderlineThickness);
368 } else if (tp.underlineColor == 0) {
369 // Spans are rendered in an arbitrary order. Since misspelled is less prioritary
370 // than just easy, do not apply misspelled if an easy (or a mispelled) has been set
371 tp.setUnderlineText(mMisspelledUnderlineColor, mMisspelledUnderlineThickness);
372 }
satok9ca4b432011-10-07 15:08:19 +0900373 } else if (autoCorrection) {
374 tp.setUnderlineText(mAutoCorrectionUnderlineColor, mAutoCorrectionUnderlineThickness);
Luca Zanolinfe5e9832011-09-02 19:41:42 +0100375 }
Luca Zanolin7d1c55f2011-08-16 14:59:26 +0100376 }
Gilles Debunnefa4e2d92011-09-08 18:34:22 -0700377
378 /**
379 * @return The color of the underline for that span, or 0 if there is no underline
380 */
Qingqing Dengef20b232019-01-09 12:22:02 -0800381 @ColorInt
Gilles Debunnefa4e2d92011-09-08 18:34:22 -0700382 public int getUnderlineColor() {
383 // The order here should match what is used in updateDrawState
Gilles Debunnec9fd9782011-09-09 09:20:12 -0700384 final boolean misspelled = (mFlags & FLAG_MISSPELLED) != 0;
385 final boolean easy = (mFlags & FLAG_EASY_CORRECT) != 0;
satok9ca4b432011-10-07 15:08:19 +0900386 final boolean autoCorrection = (mFlags & FLAG_AUTO_CORRECTION) != 0;
Gilles Debunnec9fd9782011-09-09 09:20:12 -0700387 if (easy) {
388 if (!misspelled) {
389 return mEasyCorrectUnderlineColor;
390 } else {
391 return mMisspelledUnderlineColor;
392 }
satok9ca4b432011-10-07 15:08:19 +0900393 } else if (autoCorrection) {
394 return mAutoCorrectionUnderlineColor;
Gilles Debunnec9fd9782011-09-09 09:20:12 -0700395 }
Gilles Debunnefa4e2d92011-09-08 18:34:22 -0700396 return 0;
397 }
Luca Zanolin0c96b81f2012-08-29 11:33:12 +0100398
399 /**
Yohei Yukawa17ace292019-01-21 09:24:26 -0800400 * Does nothing.
Luca Zanolin0c96b81f2012-08-29 11:33:12 +0100401 *
Yohei Yukawa17ace292019-01-21 09:24:26 -0800402 * @deprecated this is deprecated in {@link android.os.Build.VERSION_CODES#Q}.
Luca Zanolin0c96b81f2012-08-29 11:33:12 +0100403 * @hide
404 */
Mathew Inwoodefeab842018-08-14 15:21:30 +0100405 @UnsupportedAppUsage
Yohei Yukawa17ace292019-01-21 09:24:26 -0800406 @Deprecated
Luca Zanolin0c96b81f2012-08-29 11:33:12 +0100407 public void notifySelection(Context context, String original, int index) {
Yohei Yukawa17ace292019-01-21 09:24:26 -0800408 Log.w(TAG, "notifySelection() is deprecated. Does nothing.");
Luca Zanolin0c96b81f2012-08-29 11:33:12 +0100409 }
satokadb43582011-03-09 10:08:47 +0900410}