diff options
Diffstat (limited to 'java/src/com/android/inputmethod/deprecated/languageswitcher')
-rw-r--r-- | java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java | 255 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java | 234 |
2 files changed, 489 insertions, 0 deletions
diff --git a/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java b/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java new file mode 100644 index 000000000..fe70eef96 --- /dev/null +++ b/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java @@ -0,0 +1,255 @@ +/* + * 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.keyboard.KeyboardParser; +import com.android.inputmethod.latin.DictionaryFactory; +import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.Settings; +import com.android.inputmethod.latin.SharedPreferencesCompat; +import com.android.inputmethod.latin.SubtypeSwitcher; +import com.android.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 = Utils.setSystemLocale(res, locale); + final Long dictionaryId = DictionaryFactory.getDictionaryId(this, locale); + boolean hasLayout = false; + + try { + final String localeStr = locale.toString(); + final String[] layoutCountryCodes = KeyboardParser.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) { + } + Utils.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(SubtypeSwitcher.getFullDisplayName(l, false), l); + } else { + if (s.equals("zz_ZZ")) { + // ignore this locale + } else { + final String displayName = SubtypeSwitcher.getFullDisplayName(l, false); + preprocess[finalSize++] = new LocaleEntry(displayName, l); + } + } + } + for (int i = 0; i < finalSize ; i++) { + uniqueLocales.add(preprocess[i]); + } + return uniqueLocales; + } +} diff --git a/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java b/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java new file mode 100644 index 000000000..1eedb5ee1 --- /dev/null +++ b/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2010 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.latin.LatinIME; +import com.android.inputmethod.latin.LatinImeLogger; +import com.android.inputmethod.latin.Settings; +import com.android.inputmethod.latin.SharedPreferencesCompat; +import com.android.inputmethod.latin.Utils; + +import android.content.SharedPreferences; +import android.content.SharedPreferences.Editor; +import android.content.res.Configuration; +import android.text.TextUtils; +import android.util.Log; + +import java.util.ArrayList; +import java.util.Locale; + +/** + * Keeps track of list of selected input languages and the current + * input language that the user has selected. + */ +public class LanguageSwitcher { + private static final String TAG = LanguageSwitcher.class.getSimpleName(); + + @SuppressWarnings("unused") + private static final String KEYBOARD_MODE = "keyboard"; + private static final String[] EMPTY_STIRNG_ARRAY = new String[0]; + + private final ArrayList<Locale> mLocales = new ArrayList<Locale>(); + private final LatinIME mIme; + private String[] mSelectedLanguageArray = EMPTY_STIRNG_ARRAY; + private String mSelectedLanguages; + private int mCurrentIndex = 0; + private String mDefaultInputLanguage; + private Locale mDefaultInputLocale; + private Locale mSystemLocale; + + public LanguageSwitcher(LatinIME ime) { + mIme = ime; + } + + public int getLocaleCount() { + return mLocales.size(); + } + + public void onConfigurationChanged(Configuration conf, SharedPreferences prefs) { + final Locale newLocale = conf.locale; + if (!getSystemLocale().toString().equals(newLocale.toString())) { + loadLocales(prefs, newLocale); + } + } + + /** + * Loads the currently selected input languages from shared preferences. + * @param sp shared preference for getting the current input language and enabled languages + * @param systemLocale the current system locale, stored for changing the current input language + * based on the system current system locale. + * @return whether there was any change + */ + public boolean loadLocales(SharedPreferences sp, Locale systemLocale) { + if (LatinImeLogger.sDBG) { + Log.d(TAG, "load locales"); + } + if (systemLocale != null) { + setSystemLocale(systemLocale); + } + String selectedLanguages = sp.getString(Settings.PREF_SELECTED_LANGUAGES, null); + String currentLanguage = sp.getString(Settings.PREF_INPUT_LANGUAGE, null); + if (TextUtils.isEmpty(selectedLanguages)) { + mSelectedLanguageArray = EMPTY_STIRNG_ARRAY; + mSelectedLanguages = null; + loadDefaults(); + if (mLocales.size() == 0) { + return false; + } + mLocales.clear(); + return true; + } + if (selectedLanguages.equals(mSelectedLanguages)) { + return false; + } + mSelectedLanguageArray = selectedLanguages.split(","); + mSelectedLanguages = selectedLanguages; // Cache it for comparison later + constructLocales(); + mCurrentIndex = 0; + if (currentLanguage != null) { + // Find the index + mCurrentIndex = 0; + for (int i = 0; i < mLocales.size(); i++) { + if (mSelectedLanguageArray[i].equals(currentLanguage)) { + mCurrentIndex = i; + break; + } + } + // If we didn't find the index, use the first one + } + return true; + } + + private void loadDefaults() { + if (LatinImeLogger.sDBG) { + Log.d(TAG, "load default locales:"); + } + mDefaultInputLocale = mIme.getResources().getConfiguration().locale; + String country = mDefaultInputLocale.getCountry(); + mDefaultInputLanguage = mDefaultInputLocale.getLanguage() + + (TextUtils.isEmpty(country) ? "" : "_" + country); + } + + private void constructLocales() { + mLocales.clear(); + for (final String lang : mSelectedLanguageArray) { + final Locale locale = Utils.constructLocaleFromString(lang); + mLocales.add(locale); + } + } + + /** + * Returns the currently selected input language code, or the display language code if + * no specific locale was selected for input. + */ + public String getInputLanguage() { + if (getLocaleCount() == 0) return mDefaultInputLanguage; + + return mSelectedLanguageArray[mCurrentIndex]; + } + + /** + * Returns the list of enabled language codes. + */ + public String[] getEnabledLanguages(boolean allowImplicitlySelectedLanguages) { + if (mSelectedLanguageArray.length == 0 && allowImplicitlySelectedLanguages) { + return new String[] { mDefaultInputLanguage }; + } + return mSelectedLanguageArray; + } + + /** + * Returns the currently selected input locale, or the display locale if no specific + * locale was selected for input. + */ + public Locale getInputLocale() { + if (getLocaleCount() == 0) return mDefaultInputLocale; + + return mLocales.get(mCurrentIndex); + } + + private int nextLocaleIndex() { + final int size = mLocales.size(); + return (mCurrentIndex + 1) % size; + } + + private int prevLocaleIndex() { + final int size = mLocales.size(); + return (mCurrentIndex - 1 + size) % size; + } + + /** + * Returns the next input locale in the list. Wraps around to the beginning of the + * list if we're at the end of the list. + */ + public Locale getNextInputLocale() { + if (getLocaleCount() == 0) return mDefaultInputLocale; + return mLocales.get(nextLocaleIndex()); + } + + /** + * Sets the system locale (display UI) used for comparing with the input language. + * @param locale the locale of the system + */ + private void setSystemLocale(Locale locale) { + mSystemLocale = locale; + } + + /** + * Returns the system locale. + * @return the system locale + */ + private Locale getSystemLocale() { + return mSystemLocale; + } + + /** + * Returns the previous input locale in the list. Wraps around to the end of the + * list if we're at the beginning of the list. + */ + public Locale getPrevInputLocale() { + if (getLocaleCount() == 0) return mDefaultInputLocale; + return mLocales.get(prevLocaleIndex()); + } + + public void reset() { + mCurrentIndex = 0; + } + + public void next() { + mCurrentIndex = nextLocaleIndex(); + } + + public void prev() { + mCurrentIndex = prevLocaleIndex(); + } + + public void setLocale(String localeStr) { + final int N = mLocales.size(); + for (int i = 0; i < N; ++i) { + if (mLocales.get(i).toString().equals(localeStr)) { + mCurrentIndex = i; + } + } + } + + public void persist(SharedPreferences prefs) { + Editor editor = prefs.edit(); + editor.putString(Settings.PREF_INPUT_LANGUAGE, getInputLanguage()); + SharedPreferencesCompat.apply(editor); + } +} |