/* * Copyright (C) 2008-2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.android.inputmethod.deprecated.languageswitcher; import com.android.inputmethod.compat.SharedPreferencesCompat; import com.android.inputmethod.keyboard.internal.KeyboardBuilder; import com.sugree.inputmethod.latin.R; import com.sugree.inputmethod.latin.DictionaryFactory; import com.sugree.inputmethod.latin.LocaleUtils; import com.sugree.inputmethod.latin.Settings; import com.sugree.inputmethod.latin.Utils; import org.xmlpull.v1.XmlPullParserException; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.content.res.Resources; import android.os.Bundle; import android.preference.CheckBoxPreference; import android.preference.PreferenceActivity; import android.preference.PreferenceGroup; import android.preference.PreferenceManager; import android.text.TextUtils; import android.util.Pair; import java.io.IOException; import java.text.Collator; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Locale; import java.util.Map.Entry; import java.util.TreeMap; public class InputLanguageSelection extends PreferenceActivity { private SharedPreferences mPrefs; private String mSelectedLanguages; private HashMap<CheckBoxPreference, Locale> mLocaleMap = new HashMap<CheckBoxPreference, Locale>(); private static class LocaleEntry implements Comparable<Object> { private static Collator sCollator = Collator.getInstance(); private String mLabel; public final Locale mLocale; public LocaleEntry(String label, Locale locale) { this.mLabel = label; this.mLocale = locale; } @Override public String toString() { return this.mLabel; } @Override public int compareTo(Object o) { return sCollator.compare(this.mLabel, ((LocaleEntry) o).mLabel); } } @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); addPreferencesFromResource(R.xml.language_prefs); // Get the settings preferences mPrefs = PreferenceManager.getDefaultSharedPreferences(this); mSelectedLanguages = mPrefs.getString(Settings.PREF_SELECTED_LANGUAGES, ""); String[] languageList = mSelectedLanguages.split(","); ArrayList<LocaleEntry> availableLanguages = getUniqueLocales(); PreferenceGroup parent = getPreferenceScreen(); final HashMap<Long, LocaleEntry> dictionaryIdLocaleMap = new HashMap<Long, LocaleEntry>(); final TreeMap<LocaleEntry, Boolean> localeHasDictionaryMap = new TreeMap<LocaleEntry, Boolean>(); for (int i = 0; i < availableLanguages.size(); i++) { LocaleEntry loc = availableLanguages.get(i); Locale locale = loc.mLocale; final Pair<Long, Boolean> hasDictionaryOrLayout = hasDictionaryOrLayout(locale); final Long dictionaryId = hasDictionaryOrLayout.first; final boolean hasLayout = hasDictionaryOrLayout.second; final boolean hasDictionary = dictionaryId != null; // Add this locale to the supported list if: // 1) this locale has a layout/ 2) this locale has a dictionary // If some locales have no layout but have a same dictionary, the shortest locale // will be added to the supported list. if (!hasLayout && !hasDictionary) { continue; } if (hasLayout) { localeHasDictionaryMap.put(loc, hasDictionary); } if (!hasDictionary) { continue; } if (dictionaryIdLocaleMap.containsKey(dictionaryId)) { final String newLocale = locale.toString(); final String oldLocale = dictionaryIdLocaleMap.get(dictionaryId).mLocale.toString(); // Check if this locale is more appropriate to be the candidate of the input locale. if (oldLocale.length() <= newLocale.length() && !hasLayout) { // Don't add this new locale to the map<dictionary id, locale> if: // 1) the new locale's name is longer than the existing one, and // 2) the new locale doesn't have its layout continue; } } dictionaryIdLocaleMap.put(dictionaryId, loc); } for (LocaleEntry localeEntry : dictionaryIdLocaleMap.values()) { if (!localeHasDictionaryMap.containsKey(localeEntry)) { localeHasDictionaryMap.put(localeEntry, true); } } for (Entry<LocaleEntry, Boolean> entry : localeHasDictionaryMap.entrySet()) { final LocaleEntry localeEntry = entry.getKey(); final Locale locale = localeEntry.mLocale; final Boolean hasDictionary = entry.getValue(); CheckBoxPreference pref = new CheckBoxPreference(this); pref.setTitle(localeEntry.mLabel); boolean checked = isLocaleIn(locale, languageList); pref.setChecked(checked); if (hasDictionary) { pref.setSummary(R.string.has_dictionary); } mLocaleMap.put(pref, locale); parent.addPreference(pref); } } private boolean isLocaleIn(Locale locale, String[] list) { String lang = get5Code(locale); for (int i = 0; i < list.length; i++) { if (lang.equalsIgnoreCase(list[i])) return true; } return false; } private Pair<Long, Boolean> hasDictionaryOrLayout(Locale locale) { if (locale == null) return new Pair<Long, Boolean>(null, false); final Resources res = getResources(); final Locale saveLocale = LocaleUtils.setSystemLocale(res, locale); final Long dictionaryId = DictionaryFactory.getDictionaryId(this, locale); boolean hasLayout = false; try { final String localeStr = locale.toString(); final String[] layoutCountryCodes = KeyboardBuilder.parseKeyboardLocale( this, R.xml.kbd_qwerty).split(",", -1); if (!TextUtils.isEmpty(localeStr) && layoutCountryCodes.length > 0) { for (String s : layoutCountryCodes) { if (s.equals(localeStr)) { hasLayout = true; break; } } } } catch (XmlPullParserException e) { } catch (IOException e) { } LocaleUtils.setSystemLocale(res, saveLocale); return new Pair<Long, Boolean>(dictionaryId, hasLayout); } private String get5Code(Locale locale) { String country = locale.getCountry(); return locale.getLanguage() + (TextUtils.isEmpty(country) ? "" : "_" + country); } @Override protected void onResume() { super.onResume(); } @Override protected void onPause() { super.onPause(); // Save the selected languages String checkedLanguages = ""; PreferenceGroup parent = getPreferenceScreen(); int count = parent.getPreferenceCount(); for (int i = 0; i < count; i++) { CheckBoxPreference pref = (CheckBoxPreference) parent.getPreference(i); if (pref.isChecked()) { checkedLanguages += get5Code(mLocaleMap.get(pref)) + ","; } } if (checkedLanguages.length() < 1) checkedLanguages = null; // Save null Editor editor = mPrefs.edit(); editor.putString(Settings.PREF_SELECTED_LANGUAGES, checkedLanguages); SharedPreferencesCompat.apply(editor); } public ArrayList<LocaleEntry> getUniqueLocales() { String[] locales = getAssets().getLocales(); Arrays.sort(locales); ArrayList<LocaleEntry> uniqueLocales = new ArrayList<LocaleEntry>(); final int origSize = locales.length; LocaleEntry[] preprocess = new LocaleEntry[origSize]; int finalSize = 0; for (int i = 0 ; i < origSize; i++ ) { String s = locales[i]; int len = s.length(); String language = ""; String country = ""; if (len == 5) { language = s.substring(0, 2); country = s.substring(3, 5); } else if (len < 5) { language = s; } Locale l = new Locale(language, country); // Exclude languages that are not relevant to LatinIME if (TextUtils.isEmpty(language)) { continue; } if (finalSize == 0) { preprocess[finalSize++] = new LocaleEntry(Utils.getFullDisplayName(l, false), l); } else { if (s.equals("zz_ZZ")) { // ignore this locale } else { final String displayName = Utils.getFullDisplayName(l, false); preprocess[finalSize++] = new LocaleEntry(displayName, l); } } } for (int i = 0; i < finalSize ; i++) { uniqueLocales.add(preprocess[i]); } return uniqueLocales; } }