• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package com.android.inputmethod.compat;
18 
19 import com.android.inputmethod.latin.SuggestedWords;
20 import com.android.inputmethod.latin.SuggestionSpanPickedNotificationReceiver;
21 
22 import android.content.Context;
23 import android.text.Spannable;
24 import android.text.SpannableString;
25 import android.text.Spanned;
26 import android.text.TextUtils;
27 import android.util.Log;
28 
29 import java.lang.reflect.Constructor;
30 import java.util.ArrayList;
31 import java.util.Locale;
32 
33 public class SuggestionSpanUtils {
34     private static final String TAG = SuggestionSpanUtils.class.getSimpleName();
35     // TODO: Use reflection to get field values
36     public static final String ACTION_SUGGESTION_PICKED =
37             "android.text.style.SUGGESTION_PICKED";
38     public static final String SUGGESTION_SPAN_PICKED_AFTER = "after";
39     public static final String SUGGESTION_SPAN_PICKED_BEFORE = "before";
40     public static final String SUGGESTION_SPAN_PICKED_HASHCODE = "hashcode";
41     // TODO: Use the API constant after it gets public.
42     public static final int FLAG_AUTO_CORRECTION = 0x0004;
43     public static final int SUGGESTION_MAX_SIZE = 5;
44     public static final boolean SUGGESTION_SPAN_IS_SUPPORTED;
45 
46     private static final Class<?> CLASS_SuggestionSpan = CompatUtils
47             .getClass("android.text.style.SuggestionSpan");
48     private static final Class<?>[] INPUT_TYPE_SuggestionSpan = new Class<?>[] {
49             Context.class, Locale.class, String[].class, int.class, Class.class };
50     private static final Constructor<?> CONSTRUCTOR_SuggestionSpan = CompatUtils
51             .getConstructor(CLASS_SuggestionSpan, INPUT_TYPE_SuggestionSpan);
52     static {
53         SUGGESTION_SPAN_IS_SUPPORTED =
54                 CLASS_SuggestionSpan != null && CONSTRUCTOR_SuggestionSpan != null;
55     }
56 
getTextWithAutoCorrectionIndicatorUnderline( Context context, CharSequence text)57     public static CharSequence getTextWithAutoCorrectionIndicatorUnderline(
58             Context context, CharSequence text) {
59         if (TextUtils.isEmpty(text) || CONSTRUCTOR_SuggestionSpan == null) {
60             return text;
61         }
62         final Spannable spannable = text instanceof Spannable
63                 ? (Spannable) text : new SpannableString(text);
64         final Object[] args =
65                 { context, null, new String[] {}, FLAG_AUTO_CORRECTION,
66                         (Class<?>) SuggestionSpanPickedNotificationReceiver.class };
67         final Object ss = CompatUtils.newInstance(CONSTRUCTOR_SuggestionSpan, args);
68         if (ss == null) {
69             Log.w(TAG, "Suggestion span was not created.");
70             return text;
71         }
72         spannable.setSpan(ss, 0, text.length(),
73                 Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_COMPOSING);
74         return spannable;
75     }
76 
getTextWithSuggestionSpan(Context context, CharSequence pickedWord, SuggestedWords suggestedWords)77     public static CharSequence getTextWithSuggestionSpan(Context context,
78             CharSequence pickedWord, SuggestedWords suggestedWords) {
79         if (TextUtils.isEmpty(pickedWord) || CONSTRUCTOR_SuggestionSpan == null
80                 || suggestedWords == null || suggestedWords.size() == 0
81                 || suggestedWords.getInfo(0).isObsoleteSuggestedWord()) {
82             return pickedWord;
83         }
84 
85         final Spannable spannable;
86         if (pickedWord instanceof Spannable) {
87             spannable = (Spannable) pickedWord;
88         } else {
89             spannable = new SpannableString(pickedWord);
90         }
91         final ArrayList<String> suggestionsList = new ArrayList<String>();
92         for (int i = 0; i < suggestedWords.size(); ++i) {
93             if (suggestionsList.size() >= SUGGESTION_MAX_SIZE) {
94                 break;
95             }
96             final CharSequence word = suggestedWords.getWord(i);
97             if (!TextUtils.equals(pickedWord, word)) {
98                 suggestionsList.add(word.toString());
99             }
100         }
101 
102         final Object[] args =
103                 { context, null, suggestionsList.toArray(new String[suggestionsList.size()]), 0,
104                         (Class<?>) SuggestionSpanPickedNotificationReceiver.class };
105         final Object ss = CompatUtils.newInstance(CONSTRUCTOR_SuggestionSpan, args);
106         if (ss == null) {
107             return pickedWord;
108         }
109         spannable.setSpan(ss, 0, pickedWord.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
110         return spannable;
111     }
112 }
113