1 /* 2 * Copyright (C) 2010 The Android Open Source Project 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.deprecated.languageswitcher; 18 19 import com.android.inputmethod.compat.SharedPreferencesCompat; 20 import com.android.inputmethod.latin.LatinIME; 21 import com.android.inputmethod.latin.LatinImeLogger; 22 import com.android.inputmethod.latin.LocaleUtils; 23 import com.android.inputmethod.latin.Settings; 24 25 import android.content.SharedPreferences; 26 import android.content.SharedPreferences.Editor; 27 import android.content.res.Configuration; 28 import android.text.TextUtils; 29 import android.util.Log; 30 31 import java.util.ArrayList; 32 import java.util.Locale; 33 34 /** 35 * Keeps track of list of selected input languages and the current 36 * input language that the user has selected. 37 */ 38 public class LanguageSwitcher { 39 private static final String TAG = LanguageSwitcher.class.getSimpleName(); 40 41 @SuppressWarnings("unused") 42 private static final String KEYBOARD_MODE = "keyboard"; 43 private static final String[] EMPTY_STIRNG_ARRAY = new String[0]; 44 45 private final ArrayList<Locale> mLocales = new ArrayList<Locale>(); 46 private final LatinIME mIme; 47 private String[] mSelectedLanguageArray = EMPTY_STIRNG_ARRAY; 48 private String mSelectedLanguages; 49 private int mCurrentIndex = 0; 50 private String mDefaultInputLanguage; 51 private Locale mDefaultInputLocale; 52 private Locale mSystemLocale; 53 54 public LanguageSwitcher(LatinIME ime) { 55 mIme = ime; 56 } 57 58 public int getLocaleCount() { 59 return mLocales.size(); 60 } 61 62 public void onConfigurationChanged(Configuration conf, SharedPreferences prefs) { 63 final Locale newLocale = conf.locale; 64 if (!getSystemLocale().toString().equals(newLocale.toString())) { 65 loadLocales(prefs, newLocale); 66 } 67 } 68 69 /** 70 * Loads the currently selected input languages from shared preferences. 71 * @param sp shared preference for getting the current input language and enabled languages 72 * @param systemLocale the current system locale, stored for changing the current input language 73 * based on the system current system locale. 74 * @return whether there was any change 75 */ 76 public boolean loadLocales(SharedPreferences sp, Locale systemLocale) { 77 if (LatinImeLogger.sDBG) { 78 Log.d(TAG, "load locales"); 79 } 80 if (systemLocale != null) { 81 setSystemLocale(systemLocale); 82 } 83 String selectedLanguages = sp.getString(Settings.PREF_SELECTED_LANGUAGES, null); 84 String currentLanguage = sp.getString(Settings.PREF_INPUT_LANGUAGE, null); 85 if (TextUtils.isEmpty(selectedLanguages)) { 86 mSelectedLanguageArray = EMPTY_STIRNG_ARRAY; 87 mSelectedLanguages = null; 88 loadDefaults(); 89 if (mLocales.size() == 0) { 90 return false; 91 } 92 mLocales.clear(); 93 return true; 94 } 95 if (selectedLanguages.equals(mSelectedLanguages)) { 96 return false; 97 } 98 mSelectedLanguageArray = selectedLanguages.split(","); 99 mSelectedLanguages = selectedLanguages; // Cache it for comparison later 100 constructLocales(); 101 mCurrentIndex = 0; 102 if (currentLanguage != null) { 103 // Find the index 104 mCurrentIndex = 0; 105 for (int i = 0; i < mLocales.size(); i++) { 106 if (mSelectedLanguageArray[i].equals(currentLanguage)) { 107 mCurrentIndex = i; 108 break; 109 } 110 } 111 // If we didn't find the index, use the first one 112 } 113 return true; 114 } 115 116 private void loadDefaults() { 117 if (LatinImeLogger.sDBG) { 118 Log.d(TAG, "load default locales:"); 119 } 120 mDefaultInputLocale = mIme.getResources().getConfiguration().locale; 121 String country = mDefaultInputLocale.getCountry(); 122 mDefaultInputLanguage = mDefaultInputLocale.getLanguage() + 123 (TextUtils.isEmpty(country) ? "" : "_" + country); 124 } 125 126 private void constructLocales() { 127 mLocales.clear(); 128 for (final String lang : mSelectedLanguageArray) { 129 final Locale locale = LocaleUtils.constructLocaleFromString(lang); 130 mLocales.add(locale); 131 } 132 } 133 134 /** 135 * Returns the currently selected input language code, or the display language code if 136 * no specific locale was selected for input. 137 */ 138 public String getInputLanguage() { 139 if (getLocaleCount() == 0) return mDefaultInputLanguage; 140 141 return mSelectedLanguageArray[mCurrentIndex]; 142 } 143 144 /** 145 * Returns the list of enabled language codes. 146 */ 147 public String[] getEnabledLanguages(boolean allowImplicitlySelectedLanguages) { 148 if (mSelectedLanguageArray.length == 0 && allowImplicitlySelectedLanguages) { 149 return new String[] { mDefaultInputLanguage }; 150 } 151 return mSelectedLanguageArray; 152 } 153 154 /** 155 * Returns the currently selected input locale, or the display locale if no specific 156 * locale was selected for input. 157 */ 158 public Locale getInputLocale() { 159 if (getLocaleCount() == 0) return mDefaultInputLocale; 160 161 return mLocales.get(mCurrentIndex); 162 } 163 164 private int nextLocaleIndex() { 165 final int size = mLocales.size(); 166 return (mCurrentIndex + 1) % size; 167 } 168 169 private int prevLocaleIndex() { 170 final int size = mLocales.size(); 171 return (mCurrentIndex - 1 + size) % size; 172 } 173 174 /** 175 * Returns the next input locale in the list. Wraps around to the beginning of the 176 * list if we're at the end of the list. 177 */ 178 public Locale getNextInputLocale() { 179 if (getLocaleCount() == 0) return mDefaultInputLocale; 180 return mLocales.get(nextLocaleIndex()); 181 } 182 183 /** 184 * Sets the system locale (display UI) used for comparing with the input language. 185 * @param locale the locale of the system 186 */ 187 private void setSystemLocale(Locale locale) { 188 mSystemLocale = locale; 189 } 190 191 /** 192 * Returns the system locale. 193 * @return the system locale 194 */ 195 private Locale getSystemLocale() { 196 return mSystemLocale; 197 } 198 199 /** 200 * Returns the previous input locale in the list. Wraps around to the end of the 201 * list if we're at the beginning of the list. 202 */ 203 public Locale getPrevInputLocale() { 204 if (getLocaleCount() == 0) return mDefaultInputLocale; 205 return mLocales.get(prevLocaleIndex()); 206 } 207 208 public void reset() { 209 mCurrentIndex = 0; 210 } 211 212 public void next() { 213 mCurrentIndex = nextLocaleIndex(); 214 } 215 216 public void prev() { 217 mCurrentIndex = prevLocaleIndex(); 218 } 219 220 public void setLocale(String localeStr) { 221 final int N = mLocales.size(); 222 for (int i = 0; i < N; ++i) { 223 if (mLocales.get(i).toString().equals(localeStr)) { 224 mCurrentIndex = i; 225 } 226 } 227 } 228 229 public void persist(SharedPreferences prefs) { 230 Editor editor = prefs.edit(); 231 editor.putString(Settings.PREF_INPUT_LANGUAGE, getInputLanguage()); 232 SharedPreferencesCompat.apply(editor); 233 } 234 } 235