UserDictionaryList.java revision a2bfd46adf6aca5864be3d6ef2204bc18008e9c9
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>();
61dcef94165b256c2bc8d3a05e2fe0caf0795c7155Satoshi Kataoka        boolean addedAllLocale = false;
62a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        if (null == cursor) {
63a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka            // The user dictionary service is not present or disabled. Return null.
64a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka            return null;
65a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        } else if (cursor.moveToFirst()) {
66a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka            final int columnIndex = cursor.getColumnIndex(UserDictionary.Words.LOCALE);
67a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka            do {
68dcef94165b256c2bc8d3a05e2fe0caf0795c7155Satoshi Kataoka                final String locale = cursor.getString(columnIndex);
69dcef94165b256c2bc8d3a05e2fe0caf0795c7155Satoshi Kataoka                final boolean allLocale = TextUtils.isEmpty(locale);
70a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka                localeSet.add(allLocale ? "" : locale);
71dcef94165b256c2bc8d3a05e2fe0caf0795c7155Satoshi Kataoka                if (allLocale) {
72dcef94165b256c2bc8d3a05e2fe0caf0795c7155Satoshi Kataoka                    addedAllLocale = true;
73dcef94165b256c2bc8d3a05e2fe0caf0795c7155Satoshi Kataoka                }
74a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka            } while (cursor.moveToNext());
75a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        }
76dcef94165b256c2bc8d3a05e2fe0caf0795c7155Satoshi Kataoka        if (!UserDictionarySettings.IS_SHORTCUT_API_SUPPORTED && !addedAllLocale) {
77dcef94165b256c2bc8d3a05e2fe0caf0795c7155Satoshi Kataoka            // For ICS, we need to show "For all languages" in case that the keyboard locale
78dcef94165b256c2bc8d3a05e2fe0caf0795c7155Satoshi Kataoka            // is different from the system locale
79a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka            localeSet.add("");
80dcef94165b256c2bc8d3a05e2fe0caf0795c7155Satoshi Kataoka        }
81a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka
82a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka        final InputMethodManager imm =
83a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka                (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE);
84a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka        final List<InputMethodInfo> imis = imm.getEnabledInputMethodList();
85a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka        for (final InputMethodInfo imi : imis) {
86a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka            final List<InputMethodSubtype> subtypes =
87a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka                    imm.getEnabledInputMethodSubtypeList(
88a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka                            imi, true /* allowsImplicitlySelectedSubtypes */);
89a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka            for (InputMethodSubtype subtype : subtypes) {
90a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka                final String locale = subtype.getLocale();
91a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka                if (!TextUtils.isEmpty(locale)) {
92a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka                    localeSet.add(locale);
93a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka                }
94a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka            }
95a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka        }
96a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka
97a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka        // We come here after we have collected locales from existing user dictionary entries and
98a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka        // enabled subtypes. If we already have the locale-without-country version of the system
99a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka        // locale, we don't add the system locale to avoid confusion even though it's technically
100a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka        // correct to add it.
101a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka        if (!localeSet.contains(Locale.getDefault().getLanguage().toString())) {
102a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka            localeSet.add(Locale.getDefault().toString());
103a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka        }
104a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka
105a2bfd46adf6aca5864be3d6ef2204bc18008e9c9Satoshi Kataoka        return localeSet;
106a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka    }
107a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka
108a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka    /**
109a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka     * Creates the entries that allow the user to go into the user dictionary for each locale.
110a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka     * @param userDictGroup The group to put the settings in.
111a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka     */
112a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka    protected void createUserDictSettings(PreferenceGroup userDictGroup) {
113a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        final Activity activity = getActivity();
114a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        userDictGroup.removeAll();
115a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        final TreeSet<String> localeList =
116a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka                UserDictionaryList.getUserDictionaryLocalesSet(activity);
117a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka
118a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        if (localeList.isEmpty()) {
119a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka            userDictGroup.addPreference(createUserDictionaryPreference(null, activity));
120a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        } else {
121a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka            for (String locale : localeList) {
122a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka                userDictGroup.addPreference(createUserDictionaryPreference(locale, activity));
123a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka            }
124a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        }
125a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka    }
126a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka
127a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka    /**
128a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka     * Create a single User Dictionary Preference object, with its parameters set.
129a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka     * @param locale The locale for which this user dictionary is for.
130a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka     * @return The corresponding preference.
131a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka     */
132a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka    protected Preference createUserDictionaryPreference(String locale, Activity activity) {
133a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        final Preference newPref = new Preference(getActivity());
134a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        final Intent intent = new Intent(USER_DICTIONARY_SETTINGS_INTENT_ACTION);
135a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        if (null == locale) {
136a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka            newPref.setTitle(Locale.getDefault().getDisplayName());
137a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        } else {
138a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka            if ("".equals(locale))
139a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka                newPref.setTitle(getString(R.string.user_dict_settings_all_languages));
140a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka            else
141a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka                newPref.setTitle(LocaleUtils.constructLocaleFromString(locale).getDisplayName());
142a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka            intent.putExtra("locale", locale);
143a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka            newPref.getExtras().putString("locale", locale);
144a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        }
145a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        newPref.setIntent(intent);
146a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        newPref.setFragment(UserDictionarySettings.class.getName());
147a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        return newPref;
148a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka    }
149a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka
150a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka    @Override
151a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka    public void onResume() {
152a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        super.onResume();
153a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka        createUserDictSettings(getPreferenceScreen());
154a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka    }
155a79ba8a3d6dbdee777f156449c436fd3a4a57febSatoshi Kataoka}
156