UserDictionaryList.java revision 5563dc3ad51a350f67ad857991aa97623a0084b8
1a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka/*
2a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka * Copyright (C) 2013 The Android Open Source Project
3a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka *
4a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka * Licensed under the Apache License, Version 2.0 (the "License");
5a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka * you may not use this file except in compliance with the License.
6a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka * You may obtain a copy of the License at
7a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka *
8a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka *      http://www.apache.org/licenses/LICENSE-2.0
9a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka *
10a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka * Unless required by applicable law or agreed to in writing, software
11a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka * distributed under the License is distributed on an "AS IS" BASIS,
12a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka * See the License for the specific language governing permissions and
14a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka * limitations under the License.
15a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka */
16a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka
17a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataokapackage com.android.inputmethod.latin.userdictionary;
18a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka
19a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataokaimport android.app.Activity;
20a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataokaimport android.content.Context;
21a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataokaimport android.content.Intent;
22a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataokaimport android.database.Cursor;
23a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataokaimport android.os.Bundle;
24a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataokaimport android.preference.Preference;
25a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataokaimport android.preference.PreferenceFragment;
26a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataokaimport android.preference.PreferenceGroup;
27a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataokaimport android.provider.UserDictionary;
28dcef94165b256c2bc8d3a05e2fe0caf0795c7155Satoshi Kataokaimport android.text.TextUtils;
29a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataokaimport android.view.inputmethod.InputMethodInfo;
30a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataokaimport android.view.inputmethod.InputMethodManager;
31a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataokaimport android.view.inputmethod.InputMethodSubtype;
32a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka
33e28eba5074664d5716b8e58b8d0a235746b261ebKen Wakasaimport com.android.inputmethod.latin.R;
34e28eba5074664d5716b8e58b8d0a235746b261ebKen Wakasaimport com.android.inputmethod.latin.utils.LocaleUtils;
35e28eba5074664d5716b8e58b8d0a235746b261ebKen Wakasa
36a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataokaimport java.util.List;
37a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataokaimport java.util.Locale;
38a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataokaimport java.util.TreeSet;
39a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka
40a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka// Caveat: This class is basically taken from
41a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka// packages/apps/Settings/src/com/android/settings/inputmethod/UserDictionaryList.java
42a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka// in order to deal with some devices that have issues with the user dictionary handling
43a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka
44a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataokapublic class UserDictionaryList extends PreferenceFragment {
45a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka
46a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka    public static final String USER_DICTIONARY_SETTINGS_INTENT_ACTION =
47a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka            "android.settings.USER_DICTIONARY_SETTINGS";
48a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka
49a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka    @Override
50a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka    public void onCreate(Bundle icicle) {
51a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        super.onCreate(icicle);
52a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        setPreferenceScreen(getPreferenceManager().createPreferenceScreen(getActivity()));
53a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka    }
54a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka
55a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka    public static TreeSet<String> getUserDictionaryLocalesSet(Activity activity) {
56a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        @SuppressWarnings("deprecation")
57a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        final Cursor cursor = activity.managedQuery(UserDictionary.Words.CONTENT_URI,
58a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka                new String[] { UserDictionary.Words.LOCALE },
59a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka                null, null, null);
60a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka        final TreeSet<String> localeSet = new TreeSet<String>();
61a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        if (null == cursor) {
62a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka            // The user dictionary service is not present or disabled. Return null.
63a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka            return null;
64a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        } else if (cursor.moveToFirst()) {
65a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka            final int columnIndex = cursor.getColumnIndex(UserDictionary.Words.LOCALE);
66a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka            do {
67dcef94165b256c2bc8d3a05e2fe0caf0795c7155Satoshi Kataoka                final String locale = cursor.getString(columnIndex);
684ded1af21097652dcd0750d9b3f2f24df2904e25Satoshi Kataoka                localeSet.add(null != locale ? locale : "");
69a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka            } while (cursor.moveToNext());
70a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        }
714ded1af21097652dcd0750d9b3f2f24df2904e25Satoshi Kataoka        if (!UserDictionarySettings.IS_SHORTCUT_API_SUPPORTED) {
72dcef94165b256c2bc8d3a05e2fe0caf0795c7155Satoshi Kataoka            // For ICS, we need to show "For all languages" in case that the keyboard locale
73dcef94165b256c2bc8d3a05e2fe0caf0795c7155Satoshi Kataoka            // is different from the system locale
74a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka            localeSet.add("");
75dcef94165b256c2bc8d3a05e2fe0caf0795c7155Satoshi Kataoka        }
76a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka
77a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka        final InputMethodManager imm =
78a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka                (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE);
79a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka        final List<InputMethodInfo> imis = imm.getEnabledInputMethodList();
80a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka        for (final InputMethodInfo imi : imis) {
81a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka            final List<InputMethodSubtype> subtypes =
82a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka                    imm.getEnabledInputMethodSubtypeList(
83a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka                            imi, true /* allowsImplicitlySelectedSubtypes */);
84a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka            for (InputMethodSubtype subtype : subtypes) {
85a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka                final String locale = subtype.getLocale();
86a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka                if (!TextUtils.isEmpty(locale)) {
87a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka                    localeSet.add(locale);
88a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka                }
89a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka            }
90a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka        }
91a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka
92a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka        // We come here after we have collected locales from existing user dictionary entries and
93a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka        // enabled subtypes. If we already have the locale-without-country version of the system
94a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka        // locale, we don't add the system locale to avoid confusion even though it's technically
95a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka        // correct to add it.
96a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka        if (!localeSet.contains(Locale.getDefault().getLanguage().toString())) {
97a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka            localeSet.add(Locale.getDefault().toString());
98a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka        }
99a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka
100a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka        return localeSet;
101a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka    }
102a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka
103a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka    /**
104a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka     * Creates the entries that allow the user to go into the user dictionary for each locale.
105a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka     * @param userDictGroup The group to put the settings in.
106a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka     */
107a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka    protected void createUserDictSettings(PreferenceGroup userDictGroup) {
108a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        final Activity activity = getActivity();
109a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        userDictGroup.removeAll();
1105563dc3ad51a350f67ad857991aa97623a0084b8Satoshi Kataoka        final TreeSet<String> localeSet =
111a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka                UserDictionaryList.getUserDictionaryLocalesSet(activity);
112a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka
1135563dc3ad51a350f67ad857991aa97623a0084b8Satoshi Kataoka        if (localeSet.size() > 1) {
1145563dc3ad51a350f67ad857991aa97623a0084b8Satoshi Kataoka            // Have an "All languages" entry in the languages list if there are two or more active
1155563dc3ad51a350f67ad857991aa97623a0084b8Satoshi Kataoka            // languages
1165563dc3ad51a350f67ad857991aa97623a0084b8Satoshi Kataoka            localeSet.add("");
1175563dc3ad51a350f67ad857991aa97623a0084b8Satoshi Kataoka        }
1185563dc3ad51a350f67ad857991aa97623a0084b8Satoshi Kataoka
1195563dc3ad51a350f67ad857991aa97623a0084b8Satoshi Kataoka        if (localeSet.isEmpty()) {
120a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka            userDictGroup.addPreference(createUserDictionaryPreference(null, activity));
121a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        } else {
1225563dc3ad51a350f67ad857991aa97623a0084b8Satoshi Kataoka            for (String locale : localeSet) {
123a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka                userDictGroup.addPreference(createUserDictionaryPreference(locale, activity));
124a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka            }
125a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        }
126a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka    }
127a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka
128a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka    /**
129a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka     * Create a single User Dictionary Preference object, with its parameters set.
130a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka     * @param locale The locale for which this user dictionary is for.
131a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka     * @return The corresponding preference.
132a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka     */
133a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka    protected Preference createUserDictionaryPreference(String locale, Activity activity) {
134a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        final Preference newPref = new Preference(getActivity());
135a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        final Intent intent = new Intent(USER_DICTIONARY_SETTINGS_INTENT_ACTION);
136a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        if (null == locale) {
137a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka            newPref.setTitle(Locale.getDefault().getDisplayName());
138a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        } else {
139a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka            if ("".equals(locale))
140a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka                newPref.setTitle(getString(R.string.user_dict_settings_all_languages));
141a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka            else
142a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka                newPref.setTitle(LocaleUtils.constructLocaleFromString(locale).getDisplayName());
143a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka            intent.putExtra("locale", locale);
144a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka            newPref.getExtras().putString("locale", locale);
145a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        }
146a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        newPref.setIntent(intent);
147a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        newPref.setFragment(UserDictionarySettings.class.getName());
148a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        return newPref;
149a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka    }
150a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka
151a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka    @Override
152a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka    public void onResume() {
153a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        super.onResume();
154a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        createUserDictSettings(getPreferenceScreen());
155a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka    }
156a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka}
157