1 /* 2 * Copyright (C) 2008-2009 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * 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, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17 package com.android.inputmethod.latin; 18 19 import android.content.SharedPreferences; 20 import android.content.SharedPreferences.Editor; 21 import android.content.res.Configuration; 22 import android.content.res.Resources; 23 import android.os.Bundle; 24 import android.preference.CheckBoxPreference; 25 import android.preference.PreferenceActivity; 26 import android.preference.PreferenceGroup; 27 import android.preference.PreferenceManager; 28 import android.text.TextUtils; 29 30 import java.text.Collator; 31 import java.util.ArrayList; 32 import java.util.Arrays; 33 import java.util.Locale; 34 35 public class InputLanguageSelection extends PreferenceActivity { 36 37 private String mSelectedLanguages; 38 private ArrayList<Loc> mAvailableLanguages = new ArrayList<Loc>(); 39 40 private static final String[] WHITELIST_LANGUAGES = { 41 "cs", "da", "de", "en_GB", "en_US", "es", "es_US", "fr", "it", "nb", "nl", "pl", "pt", 42 "ru", "tr", 43 }; 44 isWhitelisted(String lang)45 private static boolean isWhitelisted(String lang) { 46 for (String s : WHITELIST_LANGUAGES) { 47 if (s.equalsIgnoreCase(lang)) { 48 return true; 49 } 50 } 51 return false; 52 } 53 54 private static class Loc implements Comparable<Object> { 55 static Collator sCollator = Collator.getInstance(); 56 57 String label; 58 Locale locale; 59 Loc(String label, Locale locale)60 public Loc(String label, Locale locale) { 61 this.label = label; 62 this.locale = locale; 63 } 64 65 @Override toString()66 public String toString() { 67 return this.label; 68 } 69 compareTo(Object o)70 public int compareTo(Object o) { 71 return sCollator.compare(this.label, ((Loc) o).label); 72 } 73 } 74 75 @Override onCreate(Bundle icicle)76 protected void onCreate(Bundle icicle) { 77 super.onCreate(icicle); 78 addPreferencesFromResource(R.xml.language_prefs); 79 // Get the settings preferences 80 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); 81 mSelectedLanguages = sp.getString(LatinIME.PREF_SELECTED_LANGUAGES, ""); 82 String[] languageList = mSelectedLanguages.split(","); 83 mAvailableLanguages = getUniqueLocales(); 84 PreferenceGroup parent = getPreferenceScreen(); 85 for (int i = 0; i < mAvailableLanguages.size(); i++) { 86 CheckBoxPreference pref = new CheckBoxPreference(this); 87 Locale locale = mAvailableLanguages.get(i).locale; 88 pref.setTitle(LanguageSwitcher.toTitleCase(locale.getDisplayName(locale), locale)); 89 boolean checked = isLocaleIn(locale, languageList); 90 pref.setChecked(checked); 91 if (hasDictionary(locale)) { 92 pref.setSummary(R.string.has_dictionary); 93 } 94 parent.addPreference(pref); 95 } 96 } 97 isLocaleIn(Locale locale, String[] list)98 private boolean isLocaleIn(Locale locale, String[] list) { 99 String lang = get5Code(locale); 100 for (int i = 0; i < list.length; i++) { 101 if (lang.equalsIgnoreCase(list[i])) return true; 102 } 103 return false; 104 } 105 hasDictionary(Locale locale)106 private boolean hasDictionary(Locale locale) { 107 Resources res = getResources(); 108 Configuration conf = res.getConfiguration(); 109 Locale saveLocale = conf.locale; 110 boolean haveDictionary = false; 111 conf.locale = locale; 112 res.updateConfiguration(conf, res.getDisplayMetrics()); 113 114 int[] dictionaries = LatinIME.getDictionary(res); 115 BinaryDictionary bd = new BinaryDictionary(this, dictionaries, Suggest.DIC_MAIN); 116 117 // Is the dictionary larger than a placeholder? Arbitrarily chose a lower limit of 118 // 4000-5000 words, whereas the LARGE_DICTIONARY is about 20000+ words. 119 if (bd.getSize() > Suggest.LARGE_DICTIONARY_THRESHOLD / 4) { 120 haveDictionary = true; 121 } 122 bd.close(); 123 conf.locale = saveLocale; 124 res.updateConfiguration(conf, res.getDisplayMetrics()); 125 return haveDictionary; 126 } 127 get5Code(Locale locale)128 private String get5Code(Locale locale) { 129 String country = locale.getCountry(); 130 return locale.getLanguage() 131 + (TextUtils.isEmpty(country) ? "" : "_" + country); 132 } 133 134 @Override onResume()135 protected void onResume() { 136 super.onResume(); 137 } 138 139 @Override onPause()140 protected void onPause() { 141 super.onPause(); 142 // Save the selected languages 143 String checkedLanguages = ""; 144 PreferenceGroup parent = getPreferenceScreen(); 145 int count = parent.getPreferenceCount(); 146 for (int i = 0; i < count; i++) { 147 CheckBoxPreference pref = (CheckBoxPreference) parent.getPreference(i); 148 if (pref.isChecked()) { 149 Locale locale = mAvailableLanguages.get(i).locale; 150 checkedLanguages += get5Code(locale) + ","; 151 } 152 } 153 if (checkedLanguages.length() < 1) checkedLanguages = null; // Save null 154 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); 155 Editor editor = sp.edit(); 156 editor.putString(LatinIME.PREF_SELECTED_LANGUAGES, checkedLanguages); 157 SharedPreferencesCompat.apply(editor); 158 } 159 getUniqueLocales()160 ArrayList<Loc> getUniqueLocales() { 161 String[] locales = getAssets().getLocales(); 162 Arrays.sort(locales); 163 ArrayList<Loc> uniqueLocales = new ArrayList<Loc>(); 164 165 final int origSize = locales.length; 166 Loc[] preprocess = new Loc[origSize]; 167 int finalSize = 0; 168 for (int i = 0 ; i < origSize; i++ ) { 169 String s = locales[i]; 170 int len = s.length(); 171 final Locale l; 172 final String language; 173 if (len == 5) { 174 language = s.substring(0, 2); 175 String country = s.substring(3, 5); 176 l = new Locale(language, country); 177 } else if (len == 2) { 178 language = s; 179 l = new Locale(language); 180 } else { 181 continue; 182 } 183 // Exclude languages that are not relevant to LatinIME 184 if (!isWhitelisted(s)) continue; 185 186 if (finalSize == 0) { 187 preprocess[finalSize++] = 188 new Loc(LanguageSwitcher.toTitleCase(l.getDisplayName(l), l), l); 189 } else { 190 // check previous entry: 191 // same lang and a country -> upgrade to full name and 192 // insert ours with full name 193 // diff lang -> insert ours with lang-only name 194 if (preprocess[finalSize-1].locale.getLanguage().equals( 195 language)) { 196 preprocess[finalSize-1].label = LanguageSwitcher.toTitleCase( 197 preprocess[finalSize-1].locale.getDisplayName(), 198 preprocess[finalSize-1].locale); 199 preprocess[finalSize++] = 200 new Loc(LanguageSwitcher.toTitleCase(l.getDisplayName(), l), l); 201 } else { 202 String displayName; 203 if (s.equals("zz_ZZ")) { 204 } else { 205 displayName = LanguageSwitcher.toTitleCase(l.getDisplayName(l), l); 206 preprocess[finalSize++] = new Loc(displayName, l); 207 } 208 } 209 } 210 } 211 for (int i = 0; i < finalSize ; i++) { 212 uniqueLocales.add(preprocess[i]); 213 } 214 return uniqueLocales; 215 } 216 } 217