InputLanguageSelection.java revision 1e5374e98b2707aecd774f495350a74be55ec5dc
136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani/* 236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani * Copyright (C) 2008-2009 Google Inc. 336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani * 436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani * Licensed under the Apache License, Version 2.0 (the "License"); you may not 536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani * use this file except in compliance with the License. You may obtain a copy of 636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani * the License at 736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani * 836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani * http://www.apache.org/licenses/LICENSE-2.0 936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani * 1036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani * Unless required by applicable law or agreed to in writing, software 1136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 1236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 1336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani * License for the specific language governing permissions and limitations under 1436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani * the License. 1536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani */ 1636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 1736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasanipackage com.android.inputmethod.latin; 1836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 1936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasaniimport java.text.Collator; 2036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasaniimport java.util.ArrayList; 2136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasaniimport java.util.Arrays; 2236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasaniimport java.util.Locale; 2336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 2436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasaniimport android.content.SharedPreferences; 2536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasaniimport android.content.SharedPreferences.Editor; 261e5374e98b2707aecd774f495350a74be55ec5dcAmith Yamasaniimport android.content.res.Configuration; 271e5374e98b2707aecd774f495350a74be55ec5dcAmith Yamasaniimport android.content.res.Resources; 2836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasaniimport android.os.Bundle; 2936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasaniimport android.preference.CheckBoxPreference; 3036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasaniimport android.preference.PreferenceActivity; 3136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasaniimport android.preference.PreferenceGroup; 3236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasaniimport android.preference.PreferenceManager; 336516d0fdfcbaa4eb809a8a69bd876293043a68a4Amith Yamasaniimport android.text.TextUtils; 3436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 3536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasanipublic class InputLanguageSelection extends PreferenceActivity { 3636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 3736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani private String mSelectedLanguages; 3836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani private ArrayList<Loc> mAvailableLanguages = new ArrayList<Loc>(); 390a2df340e5bb3f7df4b5a1ddb3e611f08d195948Amith Yamasani private static final String[] BLACKLIST_LANGUAGES = { 401e5374e98b2707aecd774f495350a74be55ec5dcAmith Yamasani "ko", "ja", "zh", "el" 410a2df340e5bb3f7df4b5a1ddb3e611f08d195948Amith Yamasani }; 4236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 4336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani private static class Loc implements Comparable { 4436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani static Collator sCollator = Collator.getInstance(); 4536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 4636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani String label; 4736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani Locale locale; 4836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 4936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani public Loc(String label, Locale locale) { 5036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani this.label = label; 5136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani this.locale = locale; 5236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 5336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 5436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani @Override 5536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani public String toString() { 5636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani return this.label; 5736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 5836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 5936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani public int compareTo(Object o) { 6036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani return sCollator.compare(this.label, ((Loc) o).label); 6136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 6236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 6336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 6436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani @Override 6536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani protected void onCreate(Bundle icicle) { 6636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani super.onCreate(icicle); 6736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani addPreferencesFromResource(R.xml.language_prefs); 6836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani // Get the settings preferences 6936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); 7036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani mSelectedLanguages = sp.getString(LatinIME.PREF_SELECTED_LANGUAGES, ""); 7136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani String[] languageList = mSelectedLanguages.split(","); 7236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani mAvailableLanguages = getUniqueLocales(); 7336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani PreferenceGroup parent = getPreferenceScreen(); 7436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani for (int i = 0; i < mAvailableLanguages.size(); i++) { 7536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani CheckBoxPreference pref = new CheckBoxPreference(this); 7636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani Locale locale = mAvailableLanguages.get(i).locale; 77676fb5b665127f43b7062dfa5ebeb36b1e9f9280Amith Yamasani pref.setTitle(LanguageSwitcher.toTitleCase(locale.getDisplayName(locale))); 7836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani boolean checked = isLocaleIn(locale, languageList); 7936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani pref.setChecked(checked); 801e5374e98b2707aecd774f495350a74be55ec5dcAmith Yamasani if (hasDictionary(locale)) { 811e5374e98b2707aecd774f495350a74be55ec5dcAmith Yamasani pref.setSummary(R.string.has_dictionary); 821e5374e98b2707aecd774f495350a74be55ec5dcAmith Yamasani } 8336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani parent.addPreference(pref); 8436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 8536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 8636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 8736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani private boolean isLocaleIn(Locale locale, String[] list) { 8836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani String lang = get5Code(locale); 8936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani for (int i = 0; i < list.length; i++) { 9036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani if (lang.equalsIgnoreCase(list[i])) return true; 9136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 9236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani // If it matches the current locale 9336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani Locale displayLocale = getResources().getConfiguration().locale; 9436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani if (lang.equalsIgnoreCase(get5Code(displayLocale))) { 9536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani return true; 9636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 9736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani return false; 9836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 9936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 1001e5374e98b2707aecd774f495350a74be55ec5dcAmith Yamasani private boolean hasDictionary(Locale locale) { 1011e5374e98b2707aecd774f495350a74be55ec5dcAmith Yamasani Resources res = getResources(); 1021e5374e98b2707aecd774f495350a74be55ec5dcAmith Yamasani Configuration conf = res.getConfiguration(); 1031e5374e98b2707aecd774f495350a74be55ec5dcAmith Yamasani Locale saveLocale = conf.locale; 1041e5374e98b2707aecd774f495350a74be55ec5dcAmith Yamasani boolean haveDictionary = false; 1051e5374e98b2707aecd774f495350a74be55ec5dcAmith Yamasani conf.locale = locale; 1061e5374e98b2707aecd774f495350a74be55ec5dcAmith Yamasani res.updateConfiguration(conf, res.getDisplayMetrics()); 1071e5374e98b2707aecd774f495350a74be55ec5dcAmith Yamasani BinaryDictionary bd = new BinaryDictionary(this, R.raw.main); 1081e5374e98b2707aecd774f495350a74be55ec5dcAmith Yamasani // Is the dictionary larger than a placeholder? Arbitrarily chose a lower limit of 1091e5374e98b2707aecd774f495350a74be55ec5dcAmith Yamasani // 4000-5000 words, whereas the LARGE_DICTIONARY is about 20000+ words. 1101e5374e98b2707aecd774f495350a74be55ec5dcAmith Yamasani if (bd.getSize() > Suggest.LARGE_DICTIONARY_THRESHOLD / 4) { 1111e5374e98b2707aecd774f495350a74be55ec5dcAmith Yamasani haveDictionary = true; 1121e5374e98b2707aecd774f495350a74be55ec5dcAmith Yamasani } 1131e5374e98b2707aecd774f495350a74be55ec5dcAmith Yamasani bd.close(); 1141e5374e98b2707aecd774f495350a74be55ec5dcAmith Yamasani conf.locale = saveLocale; 1151e5374e98b2707aecd774f495350a74be55ec5dcAmith Yamasani res.updateConfiguration(conf, res.getDisplayMetrics()); 1161e5374e98b2707aecd774f495350a74be55ec5dcAmith Yamasani return haveDictionary; 1171e5374e98b2707aecd774f495350a74be55ec5dcAmith Yamasani } 1181e5374e98b2707aecd774f495350a74be55ec5dcAmith Yamasani 11936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani private String get5Code(Locale locale) { 1206516d0fdfcbaa4eb809a8a69bd876293043a68a4Amith Yamasani String country = locale.getCountry(); 1216516d0fdfcbaa4eb809a8a69bd876293043a68a4Amith Yamasani return locale.getLanguage() 1226516d0fdfcbaa4eb809a8a69bd876293043a68a4Amith Yamasani + (TextUtils.isEmpty(country) ? "" : "_" + country); 12336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 12436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 12536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani @Override 12636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani protected void onResume() { 12736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani super.onResume(); 12836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 12936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 13036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani @Override 13136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani protected void onPause() { 13236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani super.onPause(); 13336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani // Save the selected languages 13436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani String checkedLanguages = ""; 13536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani PreferenceGroup parent = getPreferenceScreen(); 13636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani int count = parent.getPreferenceCount(); 13736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani for (int i = 0; i < count; i++) { 13836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani CheckBoxPreference pref = (CheckBoxPreference) parent.getPreference(i); 13936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani if (pref.isChecked()) { 14036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani Locale locale = mAvailableLanguages.get(i).locale; 14136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani checkedLanguages += get5Code(locale) + ","; 14236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 14336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 14436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani if (checkedLanguages.length() < 1) checkedLanguages = null; // Save null 14536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); 14636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani Editor editor = sp.edit(); 14736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani editor.putString(LatinIME.PREF_SELECTED_LANGUAGES, checkedLanguages); 14836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani editor.commit(); 14936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 15036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 15136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani ArrayList<Loc> getUniqueLocales() { 15236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani String[] locales = getAssets().getLocales(); 15336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani Arrays.sort(locales); 15436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani ArrayList<Loc> uniqueLocales = new ArrayList<Loc>(); 15536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 15636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani final int origSize = locales.length; 15736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani Loc[] preprocess = new Loc[origSize]; 15836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani int finalSize = 0; 15936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani for (int i = 0 ; i < origSize; i++ ) { 16036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani String s = locales[i]; 16136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani int len = s.length(); 16236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani if (len == 5) { 16336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani String language = s.substring(0, 2); 16436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani String country = s.substring(3, 5); 16536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani Locale l = new Locale(language, country); 16636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 1670a2df340e5bb3f7df4b5a1ddb3e611f08d195948Amith Yamasani // Exclude languages that are not relevant to LatinIME 1680a2df340e5bb3f7df4b5a1ddb3e611f08d195948Amith Yamasani if (arrayContains(BLACKLIST_LANGUAGES, language)) continue; 1690a2df340e5bb3f7df4b5a1ddb3e611f08d195948Amith Yamasani 17036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani if (finalSize == 0) { 17136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani preprocess[finalSize++] = 172676fb5b665127f43b7062dfa5ebeb36b1e9f9280Amith Yamasani new Loc(LanguageSwitcher.toTitleCase(l.getDisplayName(l)), l); 17336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } else { 17436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani // check previous entry: 17536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani // same lang and a country -> upgrade to full name and 17636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani // insert ours with full name 17736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani // diff lang -> insert ours with lang-only name 17836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani if (preprocess[finalSize-1].locale.getLanguage().equals( 17936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani language)) { 180676fb5b665127f43b7062dfa5ebeb36b1e9f9280Amith Yamasani preprocess[finalSize-1].label = LanguageSwitcher.toTitleCase( 18136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani preprocess[finalSize-1].locale.getDisplayName()); 18236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani preprocess[finalSize++] = 183676fb5b665127f43b7062dfa5ebeb36b1e9f9280Amith Yamasani new Loc(LanguageSwitcher.toTitleCase(l.getDisplayName()), l); 18436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } else { 18536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani String displayName; 18636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani if (s.equals("zz_ZZ")) { 18736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } else { 188676fb5b665127f43b7062dfa5ebeb36b1e9f9280Amith Yamasani displayName = LanguageSwitcher.toTitleCase(l.getDisplayName(l)); 18936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani preprocess[finalSize++] = new Loc(displayName, l); 19036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 19136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 19236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 19336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 19436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 19536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani for (int i = 0; i < finalSize ; i++) { 19636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani uniqueLocales.add(preprocess[i]); 19736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 19836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani return uniqueLocales; 19936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 2000a2df340e5bb3f7df4b5a1ddb3e611f08d195948Amith Yamasani 2010a2df340e5bb3f7df4b5a1ddb3e611f08d195948Amith Yamasani private boolean arrayContains(String[] array, String value) { 2020a2df340e5bb3f7df4b5a1ddb3e611f08d195948Amith Yamasani for (int i = 0; i < array.length; i++) { 2030a2df340e5bb3f7df4b5a1ddb3e611f08d195948Amith Yamasani if (array[i].equalsIgnoreCase(value)) return true; 2040a2df340e5bb3f7df4b5a1ddb3e611f08d195948Amith Yamasani } 2050a2df340e5bb3f7df4b5a1ddb3e611f08d195948Amith Yamasani return false; 2060a2df340e5bb3f7df4b5a1ddb3e611f08d195948Amith Yamasani } 20736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani} 208