diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 697dce28a..d32d94748 100755
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -23,6 +23,13 @@
+
+
+
+
+
+
diff --git a/res/drawable-hdpi/sym_keyboard_globe.png b/res/drawable-hdpi/sym_keyboard_globe.png
new file mode 100644
index 000000000..fa747642d
Binary files /dev/null and b/res/drawable-hdpi/sym_keyboard_globe.png differ
diff --git a/res/values/keycodes.xml b/res/values/keycodes.xml
new file mode 100644
index 000000000..e46e4bc36
--- /dev/null
+++ b/res/values/keycodes.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+ -102
+
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 753d0dc9e..3b3965e09 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -208,4 +208,7 @@
".gov"
".edu"
+
+
+ Select input languages
diff --git a/res/xml-de/kbd_qwerty.xml b/res/xml-de/kbd_qwerty.xml
index 56113e217..2da609ca8 100755
--- a/res/xml-de/kbd_qwerty.xml
+++ b/res/xml-de/kbd_qwerty.xml
@@ -100,7 +100,8 @@
android:popupKeyboard="@xml/kbd_popup_template"
android:popupCharacters="_"
android:keyWidth="20%p" android:keyEdgeFlags="left"/>
-
+
@@ -116,9 +117,7 @@
android:popupKeyboard="@xml/kbd_popup_template"
android:popupCharacters="_"
android:keyWidth="20%p" android:keyEdgeFlags="left"/>
-
-
-
+
@@ -156,7 +153,8 @@
android:popupKeyboard="@xml/kbd_popup_template"
android:popupCharacters="_"
android:keyWidth="20%p" android:keyEdgeFlags="left"/>
-
+
diff --git a/res/xml-fr/kbd_qwerty.xml b/res/xml-fr/kbd_qwerty.xml
index d47042ea7..7c1b24bad 100644
--- a/res/xml-fr/kbd_qwerty.xml
+++ b/res/xml-fr/kbd_qwerty.xml
@@ -102,7 +102,8 @@
android:popupKeyboard="@xml/kbd_popup_template"
android:popupCharacters=""
android:keyWidth="20%p" android:keyEdgeFlags="left"/>
-
+
@@ -118,9 +119,7 @@
android:popupKeyboard="@xml/kbd_popup_template"
android:popupCharacters=""
android:keyWidth="20%p" android:keyEdgeFlags="left"/>
-
-
-
+
@@ -158,7 +155,8 @@
android:popupKeyboard="@xml/kbd_popup_template"
android:popupCharacters=""
android:keyWidth="20%p" android:keyEdgeFlags="left"/>
-
+
diff --git a/res/xml-ru/kbd_qwerty.xml b/res/xml-ru/kbd_qwerty.xml
new file mode 100755
index 000000000..c0afbd7b7
--- /dev/null
+++ b/res/xml-ru/kbd_qwerty.xml
@@ -0,0 +1,150 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/xml/kbd_qwerty.xml b/res/xml/kbd_qwerty.xml
index 0493b9932..d914f46d2 100755
--- a/res/xml/kbd_qwerty.xml
+++ b/res/xml/kbd_qwerty.xml
@@ -114,7 +114,8 @@
android:popupKeyboard="@xml/kbd_popup_template"
android:popupCharacters="_"
android:keyWidth="20%p" android:keyEdgeFlags="left"/>
-
+
@@ -130,10 +131,12 @@
android:popupKeyboard="@xml/kbd_popup_template"
android:popupCharacters="_"
android:keyWidth="20%p" android:keyEdgeFlags="left"/>
-
+
+
-
+ android:keyWidth="15%p"/-->
@@ -170,7 +175,8 @@
android:popupKeyboard="@xml/kbd_popup_template"
android:popupCharacters="_"
android:keyWidth="20%p" android:keyEdgeFlags="left"/>
-
+
@@ -181,4 +187,4 @@
android:keyWidth="20%p" android:keyEdgeFlags="right"/>
-
+
diff --git a/res/xml/kbd_symbols.xml b/res/xml/kbd_symbols.xml
index b1b75c620..5a30c7b8f 100755
--- a/res/xml/kbd_symbols.xml
+++ b/res/xml/kbd_symbols.xml
@@ -120,7 +120,7 @@
android:iconPreview="@drawable/sym_keyboard_feedback_delete"
android:isRepeatable="true"/>
-
+
+
+
+
+
diff --git a/res/xml/prefs.xml b/res/xml/prefs.xml
index 2fc82aadb..d5075c53a 100644
--- a/res/xml/prefs.xml
+++ b/res/xml/prefs.xml
@@ -37,6 +37,14 @@
android:defaultValue="true"
/>
+
+
+
+
diff --git a/src/com/android/inputmethod/latin/BinaryDictionary.java b/src/com/android/inputmethod/latin/BinaryDictionary.java
index 14c543514..36991845c 100644
--- a/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -125,8 +125,10 @@ public class BinaryDictionary extends Dictionary {
return isValidWordNative(mNativeDict, chars, chars.length);
}
+ @Override
public synchronized void close() {
if (mNativeDict != 0) {
+ System.err.println("Closing BinaryDictionary");
closeNative(mNativeDict);
mNativeDict = 0;
}
diff --git a/src/com/android/inputmethod/latin/Dictionary.java b/src/com/android/inputmethod/latin/Dictionary.java
index fdf34264a..6c1c856e7 100644
--- a/src/com/android/inputmethod/latin/Dictionary.java
+++ b/src/com/android/inputmethod/latin/Dictionary.java
@@ -86,4 +86,9 @@ abstract public class Dictionary {
return true;
}
+ /**
+ * Override to clean up any resources.
+ */
+ public void close() {
+ }
}
diff --git a/src/com/android/inputmethod/latin/InputLanguageSelection.java b/src/com/android/inputmethod/latin/InputLanguageSelection.java
new file mode 100644
index 000000000..5bd1391c3
--- /dev/null
+++ b/src/com/android/inputmethod/latin/InputLanguageSelection.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2008-2009 Google Inc.
+ *
+ * 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.latin;
+
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceGroup;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+public class InputLanguageSelection extends PreferenceActivity {
+
+ private String mSelectedLanguages;
+ private ArrayList mAvailableLanguages = new ArrayList();
+
+ private static class Loc implements Comparable {
+ static Collator sCollator = Collator.getInstance();
+
+ String label;
+ Locale locale;
+
+ public Loc(String label, Locale locale) {
+ this.label = label;
+ this.locale = locale;
+ }
+
+ @Override
+ public String toString() {
+ return this.label;
+ }
+
+ public int compareTo(Object o) {
+ return sCollator.compare(this.label, ((Loc) o).label);
+ }
+ }
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ addPreferencesFromResource(R.xml.language_prefs);
+ // Get the settings preferences
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
+ mSelectedLanguages = sp.getString(LatinIME.PREF_SELECTED_LANGUAGES, "");
+ String[] languageList = mSelectedLanguages.split(",");
+ mAvailableLanguages = getUniqueLocales();
+ PreferenceGroup parent = getPreferenceScreen();
+ for (int i = 0; i < mAvailableLanguages.size(); i++) {
+ CheckBoxPreference pref = new CheckBoxPreference(this);
+ Locale locale = mAvailableLanguages.get(i).locale;
+ pref.setTitle(locale.getDisplayName(locale));
+ boolean checked = isLocaleIn(locale, languageList);
+ pref.setChecked(checked);
+ 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;
+ }
+ // If it matches the current locale
+ Locale displayLocale = getResources().getConfiguration().locale;
+ if (lang.equalsIgnoreCase(get5Code(displayLocale))) {
+ return true;
+ }
+ return false;
+ }
+
+ private String get5Code(Locale locale) {
+ return locale.getLanguage() + "_" + locale.getCountry();
+ }
+
+ @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()) {
+ Locale locale = mAvailableLanguages.get(i).locale;
+ checkedLanguages += get5Code(locale) + ",";
+ }
+ }
+ if (checkedLanguages.length() < 1) checkedLanguages = null; // Save null
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
+ Editor editor = sp.edit();
+ editor.putString(LatinIME.PREF_SELECTED_LANGUAGES, checkedLanguages);
+ editor.commit();
+ }
+
+ ArrayList getUniqueLocales() {
+ String[] locales = getAssets().getLocales();
+ Arrays.sort(locales);
+ ArrayList uniqueLocales = new ArrayList();
+
+ final int origSize = locales.length;
+ Loc[] preprocess = new Loc[origSize];
+ int finalSize = 0;
+ for (int i = 0 ; i < origSize; i++ ) {
+ String s = locales[i];
+ int len = s.length();
+ if (len == 5) {
+ String language = s.substring(0, 2);
+ String country = s.substring(3, 5);
+ Locale l = new Locale(language, country);
+
+ if (finalSize == 0) {
+ preprocess[finalSize++] =
+ new Loc(toTitleCase(l.getDisplayName(l)), l);
+ } else {
+ // check previous entry:
+ // same lang and a country -> upgrade to full name and
+ // insert ours with full name
+ // diff lang -> insert ours with lang-only name
+ if (preprocess[finalSize-1].locale.getLanguage().equals(
+ language)) {
+ preprocess[finalSize-1].label = toTitleCase(
+ preprocess[finalSize-1].locale.getDisplayName());
+ preprocess[finalSize++] =
+ new Loc(toTitleCase(l.getDisplayName()), l);
+ } else {
+ String displayName;
+ if (s.equals("zz_ZZ")) {
+ } else {
+ displayName = toTitleCase(l.getDisplayName(l));
+ preprocess[finalSize++] = new Loc(displayName, l);
+ }
+ }
+ }
+ }
+ }
+ for (int i = 0; i < finalSize ; i++) {
+ uniqueLocales.add(preprocess[i]);
+ }
+ return uniqueLocales;
+ }
+
+ private static String toTitleCase(String s) {
+ if (s.length() == 0) {
+ return s;
+ }
+
+ return Character.toUpperCase(s.charAt(0)) + s.substring(1);
+ }
+
+}
diff --git a/src/com/android/inputmethod/latin/KeyboardSwitcher.java b/src/com/android/inputmethod/latin/KeyboardSwitcher.java
index c7f90946d..03b008e34 100644
--- a/src/com/android/inputmethod/latin/KeyboardSwitcher.java
+++ b/src/com/android/inputmethod/latin/KeyboardSwitcher.java
@@ -17,8 +17,14 @@
package com.android.inputmethod.latin;
import java.util.HashMap;
+import java.util.Locale;
import java.util.Map;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.inputmethodservice.InputMethodService;
+
public class KeyboardSwitcher {
public static final int MODE_TEXT = 1;
@@ -42,7 +48,8 @@ public class KeyboardSwitcher {
private static final int SYMBOLS_MODE_STATE_SYMBOL = 2;
LatinKeyboardView mInputView;
- LatinIME mContext;
+ Context mContext;
+ InputMethodService mInputMethodService;
private KeyboardId mSymbolsId;
private KeyboardId mSymbolsShiftedId;
@@ -58,12 +65,26 @@ public class KeyboardSwitcher {
private int mSymbolsModeState = SYMBOLS_MODE_STATE_NONE;
private int mLastDisplayWidth;
+ private Locale mInputLocale;
+ private boolean mEnableMultipleLanguages;
- KeyboardSwitcher(LatinIME context) {
+ KeyboardSwitcher(Context context, InputMethodService ims) {
mContext = context;
mKeyboards = new HashMap();
mSymbolsId = new KeyboardId(R.xml.kbd_symbols);
mSymbolsShiftedId = new KeyboardId(R.xml.kbd_symbols_shift);
+ mInputMethodService = ims;
+ }
+
+ /**
+ * Sets the input locale, when there are multiple locales for input.
+ * If no locale switching is required, then the locale should be set to null.
+ * @param locale the current input locale, or null for default locale with no locale
+ * button.
+ */
+ void setInputLocale(Locale locale, boolean enableMultipleLanguages) {
+ mInputLocale = locale;
+ mEnableMultipleLanguages = enableMultipleLanguages;
}
void setInputView(LatinKeyboardView inputView) {
@@ -75,7 +96,7 @@ public class KeyboardSwitcher {
// Configuration change is coming after the keyboard gets recreated. So don't rely on that.
// If keyboards have already been made, check if we have a screen width change and
// create the keyboard layouts again at the correct orientation
- int displayWidth = mContext.getMaxWidth();
+ int displayWidth = mInputMethodService.getMaxWidth();
if (displayWidth == mLastDisplayWidth) return;
mLastDisplayWidth = displayWidth;
if (!forceCreate) mKeyboards.clear();
@@ -136,6 +157,11 @@ public class KeyboardSwitcher {
}
mCurrentId = id;
+ if (mEnableMultipleLanguages) {
+ keyboard.setLanguage(mInputLocale);
+ } else {
+ keyboard.setLanguage(null);
+ }
mInputView.setKeyboard(keyboard);
keyboard.setShifted(false);
keyboard.setShiftLocked(keyboard.isShiftLocked());
@@ -145,6 +171,11 @@ public class KeyboardSwitcher {
private LatinKeyboard getKeyboard(KeyboardId id) {
if (!mKeyboards.containsKey(id)) {
+ Resources orig = mContext.getResources();
+ Configuration conf = orig.getConfiguration();
+ Locale saveLocale = conf.locale;
+ conf.locale = mInputLocale;
+ orig.updateConfiguration(conf, null);
LatinKeyboard keyboard = new LatinKeyboard(
mContext, id.mXml, id.mMode);
if (id.mMode == KEYBOARDMODE_NORMAL
@@ -158,6 +189,9 @@ public class KeyboardSwitcher {
keyboard.enableShiftLock();
}
mKeyboards.put(id, keyboard);
+
+ conf.locale = saveLocale;
+ orig.updateConfiguration(conf, null);
}
return mKeyboards.get(id);
}
diff --git a/src/com/android/inputmethod/latin/LatinIME.java b/src/com/android/inputmethod/latin/LatinIME.java
index d72710e5b..1a08b2c0a 100644
--- a/src/com/android/inputmethod/latin/LatinIME.java
+++ b/src/com/android/inputmethod/latin/LatinIME.java
@@ -16,14 +16,24 @@
package com.android.inputmethod.latin;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
import android.app.AlertDialog;
+import android.backup.BackupManager;
import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.ContextWrapper;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.inputmethodservice.InputMethodService;
import android.inputmethodservice.Keyboard;
import android.inputmethodservice.KeyboardView;
@@ -49,16 +59,13 @@ import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-
/**
* Input method implementation for Qwerty'ish keyboard.
*/
public class LatinIME extends InputMethodService
- implements KeyboardView.OnKeyboardActionListener {
+ implements KeyboardView.OnKeyboardActionListener,
+ SharedPreferences.OnSharedPreferenceChangeListener {
+
static final boolean DEBUG = false;
static final boolean TRACE = false;
@@ -68,6 +75,8 @@ public class LatinIME extends InputMethodService
private static final String PREF_QUICK_FIXES = "quick_fixes";
private static final String PREF_SHOW_SUGGESTIONS = "show_suggestions";
private static final String PREF_AUTO_COMPLETE = "auto_complete";
+ public static final String PREF_SELECTED_LANGUAGES = "selected_languages";
+ public static final String PREF_INPUT_LANGUAGE = "input_language";
private static final int MSG_UPDATE_SUGGESTIONS = 0;
private static final int MSG_START_TUTORIAL = 1;
@@ -105,7 +114,9 @@ public class LatinIME extends InputMethodService
private UserDictionary mUserDictionary;
private ContactsDictionary mContactsDictionary;
private ExpandableDictionary mAutoDictionary;
-
+
+ Resources mResources;
+
private String mLocale;
private StringBuilder mComposing = new StringBuilder();
@@ -144,7 +155,12 @@ public class LatinIME extends InputMethodService
private String mWordSeparators;
private String mSentenceSeparators;
-
+ private int mCurrentInputLocale = 0;
+ private String mInputLanguage;
+ private String[] mSelectedLanguageArray;
+ private String mSelectedLanguagesList;
+ private boolean mRefreshKeyboardRequired;
+
Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
@@ -173,32 +189,61 @@ public class LatinIME extends InputMethodService
@Override public void onCreate() {
super.onCreate();
//setStatusIcon(R.drawable.ime_qwerty);
- mKeyboardSwitcher = new KeyboardSwitcher(this);
- final Configuration conf = getResources().getConfiguration();
- initSuggest(conf.locale.toString());
+ mKeyboardSwitcher = new KeyboardSwitcher(this, this);
+ mResources = getResources();
+ final Configuration conf = mResources.getConfiguration();
+ mInputLanguage = getPersistedInputLanguage();
+ mSelectedLanguagesList = getSelectedInputLanguages();
+ boolean enableMultipleLanguages = mSelectedLanguagesList != null
+ && mSelectedLanguagesList.split(",").length > 1;
+ if (mInputLanguage == null) {
+ mInputLanguage = conf.locale.toString();
+ }
+ initSuggest(mInputLanguage);
+ mKeyboardSwitcher.setInputLocale(conf.locale, enableMultipleLanguages);
mOrientation = conf.orientation;
- mVibrateDuration = getResources().getInteger(R.integer.vibrate_duration_ms);
+ mVibrateDuration = mResources.getInteger(R.integer.vibrate_duration_ms);
// register to receive ringer mode changes for silent mode
IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION);
registerReceiver(mReceiver, filter);
+ PreferenceManager.getDefaultSharedPreferences(this)
+ .registerOnSharedPreferenceChangeListener(this);
}
-
+
private void initSuggest(String locale) {
mLocale = locale;
+
+ Resources orig = getResources();
+ Configuration conf = orig.getConfiguration();
+ Locale saveLocale = conf.locale;
+ conf.locale = new Locale(locale);
+ orig.updateConfiguration(conf, orig.getDisplayMetrics());
+ if (mSuggest != null) {
+ mSuggest.close();
+ }
mSuggest = new Suggest(this, R.raw.main);
mSuggest.setCorrectionMode(mCorrectionMode);
mUserDictionary = new UserDictionary(this);
- mContactsDictionary = new ContactsDictionary(this);
- mAutoDictionary = new AutoDictionary(this);
+ if (mContactsDictionary == null) {
+ mContactsDictionary = new ContactsDictionary(this);
+ }
+ // TODO: Save and restore the dictionary for the current input language.
+ if (mAutoDictionary == null) {
+ mAutoDictionary = new AutoDictionary(this);
+ }
mSuggest.setUserDictionary(mUserDictionary);
mSuggest.setContactsDictionary(mContactsDictionary);
mSuggest.setAutoDictionary(mAutoDictionary);
- mWordSeparators = getResources().getString(R.string.word_separators);
- mSentenceSeparators = getResources().getString(R.string.sentence_separators);
+
+ mWordSeparators = mResources.getString(R.string.word_separators);
+ mSentenceSeparators = mResources.getString(R.string.sentence_separators);
+
+ conf.locale = saveLocale;
+ orig.updateConfiguration(conf, orig.getDisplayMetrics());
}
-
+
@Override public void onDestroy() {
mUserDictionary.close();
mContactsDictionary.close();
@@ -216,10 +261,7 @@ public class LatinIME extends InputMethodService
commitTyped(getCurrentInputConnection());
mOrientation = conf.orientation;
}
- if (mKeyboardSwitcher == null) {
- mKeyboardSwitcher = new KeyboardSwitcher(this);
- }
- mKeyboardSwitcher.makeKeyboards(true);
+ reloadKeyboards();
super.onConfigurationChanged(conf);
}
@@ -253,6 +295,11 @@ public class LatinIME extends InputMethodService
return;
}
+ if (mRefreshKeyboardRequired) {
+ mRefreshKeyboardRequired = false;
+ toggleLanguage(true);
+ }
+
mKeyboardSwitcher.makeKeyboards(false);
TextEntryState.newSession(this);
@@ -499,6 +546,15 @@ public class LatinIME extends InputMethodService
return super.onKeyUp(keyCode, event);
}
+ private void reloadKeyboards() {
+ if (mKeyboardSwitcher == null) {
+ mKeyboardSwitcher = new KeyboardSwitcher(this, this);
+ }
+ mKeyboardSwitcher.setInputLocale(new Locale(mInputLanguage),
+ getSelectedInputLanguages() != null);
+ mKeyboardSwitcher.makeKeyboards(true);
+ }
+
private void commitTyped(InputConnection inputConnection) {
if (mPredicting) {
mPredicting = false;
@@ -601,6 +657,9 @@ public class LatinIME extends InputMethodService
case LatinKeyboardView.KEYCODE_OPTIONS:
showOptionsMenu();
break;
+ case LatinKeyboardView.KEYCODE_F1:
+ toggleLanguage(false);
+ break;
case LatinKeyboardView.KEYCODE_SHIFT_LONGPRESS:
if (mCapsLock) {
handleShift();
@@ -674,7 +733,6 @@ public class LatinIME extends InputMethodService
private void handleShift() {
mHandler.removeMessages(MSG_UPDATE_SHIFT_STATE);
- Keyboard currentKeyboard = mInputView.getKeyboard();
if (mKeyboardSwitcher.isAlphabetMode()) {
// Alphabet keyboard
checkToggleCapsLock();
@@ -966,9 +1024,32 @@ public class LatinIME extends InputMethodService
}
}
}
-
+
+ private void toggleLanguage(boolean reset) {
+ final String [] languages = mSelectedLanguageArray;
+ if (reset) mCurrentInputLocale = -1;
+ mCurrentInputLocale = (mCurrentInputLocale + 1)
+ % (languages != null ? languages.length : 1);
+ mInputLanguage = languages != null ? languages[mCurrentInputLocale] :
+ getResources().getConfiguration().locale.getLanguage();
+ int currentKeyboardMode = mKeyboardSwitcher.getKeyboardMode();
+ reloadKeyboards();
+ mKeyboardSwitcher.makeKeyboards(true);
+ mKeyboardSwitcher.setKeyboardMode(currentKeyboardMode, 0);
+ initSuggest(mInputLanguage);
+ persistInputLanguage(mInputLanguage);
+ updateShiftKeyState(getCurrentInputEditorInfo());
+ }
+
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+ String key) {
+ if (PREF_SELECTED_LANGUAGES.equals(key)) {
+ updateSelectedLanguages(sharedPreferences.getString(key, null));
+ mRefreshKeyboardRequired = true;
+ }
+ }
+
public void swipeLeft() {
- //handleBackspace();
}
public void swipeDown() {
@@ -1089,11 +1170,38 @@ public class LatinIME extends InputMethodService
if (AutoText.getSize(mInputView) < 1) mQuickFixes = true;
mShowSuggestions = sp.getBoolean(PREF_SHOW_SUGGESTIONS, true) & mQuickFixes;
boolean autoComplete = sp.getBoolean(PREF_AUTO_COMPLETE,
- getResources().getBoolean(R.bool.enable_autocorrect)) & mShowSuggestions;
+ mResources.getBoolean(R.bool.enable_autocorrect)) & mShowSuggestions;
mAutoCorrectOn = mSuggest != null && (autoComplete || mQuickFixes);
mCorrectionMode = autoComplete
? Suggest.CORRECTION_FULL
: (mQuickFixes ? Suggest.CORRECTION_BASIC : Suggest.CORRECTION_NONE);
+ String languageList = sp.getString(PREF_SELECTED_LANGUAGES, null);
+ updateSelectedLanguages(languageList);
+ }
+
+ private void updateSelectedLanguages(String languageList) {
+ if (languageList != null && languageList.length() > 1) {
+ mSelectedLanguageArray = languageList.split(",");
+ } else {
+ mSelectedLanguageArray = null;
+ }
+ }
+
+ private String getPersistedInputLanguage() {
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
+ return sp.getString(PREF_INPUT_LANGUAGE, null);
+ }
+
+ private void persistInputLanguage(String inputLanguage) {
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
+ Editor editor = sp.edit();
+ editor.putString(PREF_INPUT_LANGUAGE, inputLanguage);
+ editor.commit();
+ }
+
+ private String getSelectedInputLanguages() {
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
+ return sp.getString(PREF_SELECTED_LANGUAGES, null);
}
private void showOptionsMenu() {
@@ -1120,7 +1228,7 @@ public class LatinIME extends InputMethodService
}
}
});
- builder.setTitle(getResources().getString(R.string.english_ime_name));
+ builder.setTitle(mResources.getString(R.string.english_ime_name));
mOptionsDialog = builder.create();
Window window = mOptionsDialog.getWindow();
WindowManager.LayoutParams lp = window.getAttributes();
@@ -1139,7 +1247,7 @@ public class LatinIME extends InputMethodService
updateShiftKeyState(getCurrentInputEditorInfo());
}
-
+
@Override protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
super.dump(fd, fout, args);
diff --git a/src/com/android/inputmethod/latin/LatinKeyboard.java b/src/com/android/inputmethod/latin/LatinKeyboard.java
index e68e01ded..05913122f 100644
--- a/src/com/android/inputmethod/latin/LatinKeyboard.java
+++ b/src/com/android/inputmethod/latin/LatinKeyboard.java
@@ -16,9 +16,17 @@
package com.android.inputmethod.latin;
+import java.util.Locale;
+
import android.content.Context;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.Paint.Align;
+import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.inputmethodservice.Keyboard;
import android.view.inputmethod.EditorInfo;
@@ -29,8 +37,14 @@ public class LatinKeyboard extends Keyboard {
private Drawable mShiftLockPreviewIcon;
private Drawable mOldShiftIcon;
private Drawable mOldShiftPreviewIcon;
+ private Drawable mSpaceIcon;
private Key mShiftKey;
private Key mEnterKey;
+ private Key mF1Key;
+ private Key mSpaceKey;
+ private Locale mLocale;
+ private Resources mRes;
+ private int mMode;
private int mExtensionResId;
@@ -48,12 +62,15 @@ public class LatinKeyboard extends Keyboard {
public LatinKeyboard(Context context, int xmlLayoutResId, int mode) {
super(context, xmlLayoutResId, mode);
- Resources res = context.getResources();
+ final Resources res = context.getResources();
+ mMode = mode;
+ mRes = res;
mShiftLockIcon = res.getDrawable(R.drawable.sym_keyboard_shift_locked);
mShiftLockPreviewIcon = res.getDrawable(R.drawable.sym_keyboard_feedback_shift_locked);
mShiftLockPreviewIcon.setBounds(0, 0,
mShiftLockPreviewIcon.getIntrinsicWidth(),
mShiftLockPreviewIcon.getIntrinsicHeight());
+ mSpaceIcon = res.getDrawable(R.drawable.sym_keyboard_space);
sSpacebarVerticalCorrection = res.getDimensionPixelOffset(
R.dimen.spacebar_vertical_correction);
}
@@ -67,12 +84,20 @@ public class LatinKeyboard extends Keyboard {
protected Key createKeyFromXml(Resources res, Row parent, int x, int y,
XmlResourceParser parser) {
Key key = new LatinKey(res, parent, x, y, parser);
- if (key.codes[0] == 10) {
+ switch (key.codes[0]) {
+ case 10:
mEnterKey = key;
+ break;
+ case LatinKeyboardView.KEYCODE_F1:
+ mF1Key = key;
+ break;
+ case 32:
+ mSpaceKey = key;
+ break;
}
return key;
}
-
+
void setImeOptions(Resources res, int mode, int options) {
if (mEnterKey != null) {
// Reset some of the rarely used attributes.
@@ -183,7 +208,7 @@ public class LatinKeyboard extends Keyboard {
}
return shiftChanged;
}
-
+
@Override
public boolean isShifted() {
if (mShiftKey != null) {
@@ -201,6 +226,62 @@ public class LatinKeyboard extends Keyboard {
return mExtensionResId;
}
+ private void setF1Key() {
+ if (mF1Key == null) return; // No function key on this keyboard
+ if (mLocale != null) {
+ // Create the graphic for spacebar
+ mF1Key.label = null;
+ mF1Key.icon = mRes.getDrawable(R.drawable.sym_keyboard_globe);
+ Bitmap buffer = Bitmap.createBitmap(mSpaceKey.width, mSpaceIcon.getIntrinsicHeight(),
+ Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(buffer);
+ canvas.drawColor(0x00000000, PorterDuff.Mode.CLEAR);
+ Paint paint = new Paint();
+ paint.setAntiAlias(true);
+ paint.setTextSize(22);
+ paint.setTextAlign(Align.CENTER);
+ // Draw a drop shadow for the text
+ paint.setShadowLayer(1f, 0, 0, 0xFF000000);
+ paint.setColor(0x80C0C0C0);
+ canvas.drawText(mLocale.getDisplayLanguage(mLocale),
+ buffer.getWidth() / 2, - paint.ascent() + 2, paint);
+ int x = (buffer.getWidth() - mSpaceIcon.getIntrinsicWidth()) / 2;
+ int y = buffer.getHeight() - mSpaceIcon.getIntrinsicHeight();
+ mSpaceIcon.setBounds(x, y,
+ x + mSpaceIcon.getIntrinsicWidth(), y + mSpaceIcon.getIntrinsicHeight());
+ mSpaceIcon.draw(canvas);
+ mSpaceKey.icon = new BitmapDrawable(mRes, buffer);
+ } else {
+ mSpaceKey.icon = mRes.getDrawable(R.drawable.sym_keyboard_space);
+ switch (mMode) {
+ case KeyboardSwitcher.KEYBOARDMODE_NORMAL:
+ case KeyboardSwitcher.KEYBOARDMODE_IM:
+ mF1Key.label = ",";
+ mF1Key.codes = new int[] { ',' };
+ mF1Key.icon = null;
+ mF1Key.iconPreview = null;
+ break;
+ case KeyboardSwitcher.KEYBOARDMODE_EMAIL:
+ case KeyboardSwitcher.KEYBOARDMODE_URL:
+ mF1Key.label = mRes.getString(R.string.popular_domain_0);
+ mF1Key.codes = new int[] { '.' };
+ mF1Key.text = mF1Key.label;
+ mF1Key.icon = null;
+ mF1Key.iconPreview = null;
+ mF1Key.popupResId = R.xml.popup_domains;
+ break;
+ }
+ }
+ }
+
+ public void setLanguage(Locale locale) {
+ if (mLocale != null && mLocale.equals(locale)) return;
+ mLocale = locale;
+ setF1Key();
+ if (mF1Key != null) {
+ }
+ }
+
static class LatinKey extends Keyboard.Key {
private boolean mShiftLockEnabled;
diff --git a/src/com/android/inputmethod/latin/LatinKeyboardView.java b/src/com/android/inputmethod/latin/LatinKeyboardView.java
index ecbd1adfb..163d824e0 100644
--- a/src/com/android/inputmethod/latin/LatinKeyboardView.java
+++ b/src/com/android/inputmethod/latin/LatinKeyboardView.java
@@ -35,6 +35,7 @@ public class LatinKeyboardView extends KeyboardView {
static final int KEYCODE_OPTIONS = -100;
static final int KEYCODE_SHIFT_LONGPRESS = -101;
+ static final int KEYCODE_F1 = -102;
private Keyboard mPhoneKeyboard;
diff --git a/src/com/android/inputmethod/latin/Suggest.java b/src/com/android/inputmethod/latin/Suggest.java
index c025566b7..cc9a39cb7 100755
--- a/src/com/android/inputmethod/latin/Suggest.java
+++ b/src/com/android/inputmethod/latin/Suggest.java
@@ -336,4 +336,10 @@ public class Suggest implements Dictionary.WordCallback {
}
mSuggestions.clear();
}
+
+ public void close() {
+ if (mMainDict != null) {
+ mMainDict.close();
+ }
+ }
}