Home | History | Annotate | Download | only in userdictionary
      1 /*
      2  * Copyright (C) 2013 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.latin.userdictionary;
     18 
     19 import android.app.Activity;
     20 import android.content.Context;
     21 import android.content.Intent;
     22 import android.database.Cursor;
     23 import android.os.Bundle;
     24 import android.preference.Preference;
     25 import android.preference.PreferenceFragment;
     26 import android.preference.PreferenceGroup;
     27 import android.provider.UserDictionary;
     28 import android.text.TextUtils;
     29 import android.view.inputmethod.InputMethodInfo;
     30 import android.view.inputmethod.InputMethodManager;
     31 import android.view.inputmethod.InputMethodSubtype;
     32 
     33 import com.android.inputmethod.latin.R;
     34 import com.android.inputmethod.latin.common.LocaleUtils;
     35 
     36 import java.util.List;
     37 import java.util.Locale;
     38 import java.util.TreeSet;
     39 
     40 import javax.annotation.Nullable;
     41 
     42 // Caveat: This class is basically taken from
     43 // packages/apps/Settings/src/com/android/settings/inputmethod/UserDictionaryList.java
     44 // in order to deal with some devices that have issues with the user dictionary handling
     45 
     46 public class UserDictionaryList extends PreferenceFragment {
     47 
     48     public static final String USER_DICTIONARY_SETTINGS_INTENT_ACTION =
     49             "android.settings.USER_DICTIONARY_SETTINGS";
     50 
     51     @Override
     52     public void onCreate(final Bundle icicle) {
     53         super.onCreate(icicle);
     54         setPreferenceScreen(getPreferenceManager().createPreferenceScreen(getActivity()));
     55     }
     56 
     57     public static TreeSet<String> getUserDictionaryLocalesSet(final Activity activity) {
     58         final Cursor cursor = activity.getContentResolver().query(UserDictionary.Words.CONTENT_URI,
     59                 new String[] { UserDictionary.Words.LOCALE },
     60                 null, null, null);
     61         final TreeSet<String> localeSet = new TreeSet<>();
     62         if (null == cursor) {
     63             // The user dictionary service is not present or disabled. Return null.
     64             return null;
     65         }
     66         try {
     67             if (cursor.moveToFirst()) {
     68                 final int columnIndex = cursor.getColumnIndex(UserDictionary.Words.LOCALE);
     69                 do {
     70                     final String locale = cursor.getString(columnIndex);
     71                     localeSet.add(null != locale ? locale : "");
     72                 } while (cursor.moveToNext());
     73             }
     74         } finally {
     75             cursor.close();
     76         }
     77         if (!UserDictionarySettings.IS_SHORTCUT_API_SUPPORTED) {
     78             // For ICS, we need to show "For all languages" in case that the keyboard locale
     79             // is different from the system locale
     80             localeSet.add("");
     81         }
     82 
     83         final InputMethodManager imm =
     84                 (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE);
     85         final List<InputMethodInfo> imis = imm.getEnabledInputMethodList();
     86         for (final InputMethodInfo imi : imis) {
     87             final List<InputMethodSubtype> subtypes =
     88                     imm.getEnabledInputMethodSubtypeList(
     89                             imi, true /* allowsImplicitlySelectedSubtypes */);
     90             for (InputMethodSubtype subtype : subtypes) {
     91                 final String locale = subtype.getLocale();
     92                 if (!TextUtils.isEmpty(locale)) {
     93                     localeSet.add(locale);
     94                 }
     95             }
     96         }
     97 
     98         // We come here after we have collected locales from existing user dictionary entries and
     99         // enabled subtypes. If we already have the locale-without-country version of the system
    100         // locale, we don't add the system locale to avoid confusion even though it's technically
    101         // correct to add it.
    102         if (!localeSet.contains(Locale.getDefault().getLanguage().toString())) {
    103             localeSet.add(Locale.getDefault().toString());
    104         }
    105 
    106         return localeSet;
    107     }
    108 
    109     /**
    110      * Creates the entries that allow the user to go into the user dictionary for each locale.
    111      * @param userDictGroup The group to put the settings in.
    112      */
    113     protected void createUserDictSettings(final PreferenceGroup userDictGroup) {
    114         final Activity activity = getActivity();
    115         userDictGroup.removeAll();
    116         final TreeSet<String> localeSet =
    117                 UserDictionaryList.getUserDictionaryLocalesSet(activity);
    118 
    119         if (localeSet.size() > 1) {
    120             // Have an "All languages" entry in the languages list if there are two or more active
    121             // languages
    122             localeSet.add("");
    123         }
    124 
    125         if (localeSet.isEmpty()) {
    126             userDictGroup.addPreference(createUserDictionaryPreference(null));
    127         } else {
    128             for (String locale : localeSet) {
    129                 userDictGroup.addPreference(createUserDictionaryPreference(locale));
    130             }
    131         }
    132     }
    133 
    134     /**
    135      * Create a single User Dictionary Preference object, with its parameters set.
    136      * @param localeString The locale for which this user dictionary is for.
    137      * @return The corresponding preference.
    138      */
    139     protected Preference createUserDictionaryPreference(@Nullable final String localeString) {
    140         final Preference newPref = new Preference(getActivity());
    141         final Intent intent = new Intent(USER_DICTIONARY_SETTINGS_INTENT_ACTION);
    142         if (null == localeString) {
    143             newPref.setTitle(Locale.getDefault().getDisplayName());
    144         } else {
    145             if (localeString.isEmpty()) {
    146                 newPref.setTitle(getString(R.string.user_dict_settings_all_languages));
    147             } else {
    148                 newPref.setTitle(
    149                         LocaleUtils.constructLocaleFromString(localeString).getDisplayName());
    150             }
    151             intent.putExtra("locale", localeString);
    152             newPref.getExtras().putString("locale", localeString);
    153         }
    154         newPref.setIntent(intent);
    155         newPref.setFragment(UserDictionarySettings.class.getName());
    156         return newPref;
    157     }
    158 
    159     @Override
    160     public void onResume() {
    161         super.onResume();
    162         createUserDictSettings(getPreferenceScreen());
    163     }
    164 }
    165 
    166