Merge change I8c9748c8 into eclair-mr2

* changes:
  Input language switching. Bug: 2331173
main
Android (Google) Code Review 2009-12-16 17:49:59 -08:00
commit 0ee83f27d7
19 changed files with 689 additions and 61 deletions

View File

@ -23,6 +23,13 @@
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
</intent-filter>
</activity>
<activity android:name="InputLanguageSelection"
android:label="@string/language_selection_title">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
</intent-filter>
</activity>
</application>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

24
res/values/keycodes.xml Normal file
View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
**
** Copyright 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.
*/
-->
<resources>
<!-- Keycode for F1 (function) key. This one switches between language switch & comma/.com -->
<integer name="key_f1">-102</integer>
</resources>

View File

@ -208,4 +208,7 @@
<string name="popular_domain_3">".gov"</string>
<!-- popular web domains for the locale - item 4, displayed in the popup -->
<string name="popular_domain_4">".edu"</string>
<!-- Title for input language selection screen -->
<string name="language_selection_title">Select input languages</string>
</resources>

View File

@ -100,7 +100,8 @@
android:popupKeyboard="@xml/kbd_popup_template"
android:popupCharacters="_"
android:keyWidth="20%p" android:keyEdgeFlags="left"/>
<Key android:keyLabel="," android:keyWidth="10%p" />
<Key android:codes="@integer/key_f1" android:keyIcon="@drawable/sym_keyboard_globe"
android:keyWidth="10%p"/>
<Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
android:iconPreview="@drawable/sym_keyboard_feedback_space"
android:keyWidth="40%p" android:isRepeatable="true"/>
@ -116,9 +117,7 @@
android:popupKeyboard="@xml/kbd_popup_template"
android:popupCharacters="_"
android:keyWidth="20%p" android:keyEdgeFlags="left"/>
<Key android:keyLabel="@string/popular_domain_0"
android:keyOutputText="@string/popular_domain_0"
android:popupKeyboard="@xml/popup_domains"
<Key android:codes="@integer/key_f1" android:keyIcon="@drawable/sym_keyboard_globe"
android:keyWidth="15%p"/>
<Key android:keyLabel="/" android:keyWidth="15%p"/>
<Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
@ -136,11 +135,9 @@
android:popupKeyboard="@xml/kbd_popup_template"
android:popupCharacters="_"
android:keyWidth="20%p" android:keyEdgeFlags="left"/>
<Key android:keyLabel="\@" android:keyWidth="15%p"/>
<Key android:keyLabel="@string/popular_domain_0"
android:keyOutputText="@string/popular_domain_0"
android:popupKeyboard="@xml/popup_domains"
<Key android:codes="@integer/key_f1" android:keyIcon="@drawable/sym_keyboard_globe"
android:keyWidth="15%p"/>
<Key android:keyLabel="\@" android:keyWidth="15%p"/>
<Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
android:iconPreview="@drawable/sym_keyboard_feedback_space"
android:keyWidth="15%p" android:isRepeatable="true"/>
@ -156,7 +153,8 @@
android:popupKeyboard="@xml/kbd_popup_template"
android:popupCharacters="_"
android:keyWidth="20%p" android:keyEdgeFlags="left"/>
<Key android:keyLabel="," android:keyWidth="10%p"/>
<Key android:codes="@integer/key_f1" android:keyIcon="@drawable/sym_keyboard_globe"
android:keyWidth="10%p"/>
<Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
android:iconPreview="@drawable/sym_keyboard_feedback_space"
android:keyWidth="40%p" android:isRepeatable="true"/>

View File

@ -102,7 +102,8 @@
android:popupKeyboard="@xml/kbd_popup_template"
android:popupCharacters=""
android:keyWidth="20%p" android:keyEdgeFlags="left"/>
<Key android:keyLabel="," android:keyWidth="10%p" />
<Key android:codes="@integer/key_f1" android:keyIcon="@drawable/sym_keyboard_globe"
android:keyWidth="10%p"/>
<Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
android:iconPreview="@drawable/sym_keyboard_feedback_space"
android:keyWidth="40%p" android:isRepeatable="true"/>
@ -118,9 +119,7 @@
android:popupKeyboard="@xml/kbd_popup_template"
android:popupCharacters=""
android:keyWidth="20%p" android:keyEdgeFlags="left"/>
<Key android:keyLabel="@string/popular_domain_0"
android:keyOutputText="@string/popular_domain_0"
android:popupKeyboard="@xml/popup_domains"
<Key android:codes="@integer/key_f1" android:keyIcon="@drawable/sym_keyboard_globe"
android:keyWidth="15%p"/>
<Key android:keyLabel="/" android:keyWidth="15%p"/>
<Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
@ -138,11 +137,9 @@
android:popupKeyboard="@xml/kbd_popup_template"
android:popupCharacters=""
android:keyWidth="20%p" android:keyEdgeFlags="left"/>
<Key android:keyLabel="\@" android:keyWidth="15%p"/>
<Key android:keyLabel="@string/popular_domain_0"
android:keyOutputText="@string/popular_domain_0"
android:popupKeyboard="@xml/popup_domains"
<Key android:codes="@integer/key_f1" android:keyIcon="@drawable/sym_keyboard_globe"
android:keyWidth="15%p"/>
<Key android:keyLabel="\@" android:keyWidth="15%p"/>
<Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
android:iconPreview="@drawable/sym_keyboard_feedback_space"
android:keyWidth="15%p" android:isRepeatable="true"/>
@ -158,7 +155,8 @@
android:popupKeyboard="@xml/kbd_popup_template"
android:popupCharacters=""
android:keyWidth="20%p" android:keyEdgeFlags="left"/>
<Key android:keyLabel="," android:keyWidth="10%p"/>
<Key android:codes="@integer/key_f1" android:keyIcon="@drawable/sym_keyboard_globe"
android:keyWidth="10%p"/>
<Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
android:iconPreview="@drawable/sym_keyboard_feedback_space"
android:keyWidth="40%p" android:isRepeatable="true"/>

150
res/xml-ru/kbd_qwerty.xml Executable file
View File

@ -0,0 +1,150 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
**
** Copyright 2008, 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.
*/
-->
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="9.09%p"
android:horizontalGap="0px"
android:verticalGap="0px"
android:keyHeight="@dimen/key_height"
>
<Row>
<Key android:keyLabel="й"
android:keyEdgeFlags="left"/>
<Key android:keyLabel="ц"/>
<Key android:keyLabel="у"/>
<Key android:keyLabel="к"/>
<Key android:keyLabel="е"/>
<Key android:keyLabel="н"/>
<Key android:keyLabel="г"/>
<Key android:keyLabel="ш"/>
<Key android:keyLabel="щ"/>
<Key android:keyLabel="з"/>
<Key android:keyLabel="х"
android:keyEdgeFlags="right"/>
</Row>
<Row>
<Key android:keyLabel="ф"
android:keyEdgeFlags="left"/>
<Key android:keyLabel="ы"/>
<Key android:keyLabel="в"/>
<Key android:keyLabel="а"/>
<Key android:keyLabel="п"/>
<Key android:keyLabel="р"/>
<Key android:keyLabel="о"/>
<Key android:keyLabel="л"/>
<Key android:keyLabel="д"/>
<Key android:keyLabel="ж"/>
<Key android:keyLabel="э"
android:keyEdgeFlags="right"/>
</Row>
<Row android:keyWidth="8.5%p">
<Key android:codes="-1" android:keyIcon="@drawable/sym_keyboard_shift"
android:keyWidth="11.75%p" android:isModifier="true"
android:iconPreview="@drawable/sym_keyboard_feedback_shift"
android:isSticky="true" android:keyEdgeFlags="left"/>
<Key android:keyLabel="я"/>
<Key android:keyLabel="ч"/>
<Key android:keyLabel="с"/>
<Key android:keyLabel="м"/>
<Key android:keyLabel="и"/>
<Key android:keyLabel="т"/>
<Key android:keyLabel="ь"/>
<Key android:keyLabel="б"/>
<Key android:keyLabel="ю"/>
<Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete"
android:keyWidth="11.75%p" android:keyEdgeFlags="right"
android:iconPreview="@drawable/sym_keyboard_feedback_delete"
android:isRepeatable="true"/>
</Row>
<Row android:keyboardMode="@+id/mode_normal" android:rowEdgeFlags="bottom">
<Key android:codes="-2" android:keyLabel="@string/label_symbol_key"
android:popupKeyboard="@xml/kbd_popup_template"
android:popupCharacters="_"
android:keyWidth="20%p" android:keyEdgeFlags="left"/>
<Key android:codes="@integer/key_f1" android:keyIcon="@drawable/sym_keyboard_globe"
android:keyWidth="10%p"/>
<Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
android:iconPreview="@drawable/sym_keyboard_feedback_space"
android:keyWidth="40%p" android:isRepeatable="true"/>
<Key android:codes="46" android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation"
android:keyWidth="10%p"/>
<Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return"
android:iconPreview="@drawable/sym_keyboard_feedback_return"
android:keyWidth="20%p" android:keyEdgeFlags="right"/>
</Row>
<Row android:keyboardMode="@+id/mode_url" android:rowEdgeFlags="bottom">
<Key android:codes="-2" android:keyLabel="@string/label_symbol_key"
android:popupKeyboard="@xml/kbd_popup_template"
android:popupCharacters="_"
android:keyWidth="20%p" android:keyEdgeFlags="left"/>
<Key android:codes="@integer/key_f1" android:keyIcon="@drawable/sym_keyboard_globe"
android:keyWidth="15%p"/>
<Key android:keyLabel="/" android:keyWidth="15%p"/>
<Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
android:iconPreview="@drawable/sym_keyboard_feedback_space"
android:keyWidth="15%p" android:isRepeatable="true"/>
<Key android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation"
android:keyWidth="15%p"/>
<Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return"
android:iconPreview="@drawable/sym_keyboard_feedback_return"
android:keyWidth="20%p" android:keyEdgeFlags="right"/>
</Row>
<Row android:keyboardMode="@+id/mode_email" android:rowEdgeFlags="bottom">
<Key android:codes="-2" android:keyLabel="@string/label_symbol_key"
android:popupKeyboard="@xml/kbd_popup_template"
android:popupCharacters="_"
android:keyWidth="20%p" android:keyEdgeFlags="left"/>
<Key android:codes="@integer/key_f1" android:keyIcon="@drawable/sym_keyboard_globe"
android:keyWidth="15%p"/>
<Key android:keyLabel="\@" android:keyWidth="15%p"/>
<Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
android:iconPreview="@drawable/sym_keyboard_feedback_space"
android:keyWidth="15%p" android:isRepeatable="true"/>
<Key android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation"
android:keyWidth="15%p"/>
<Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return"
android:iconPreview="@drawable/sym_keyboard_feedback_return"
android:keyWidth="20%p" android:keyEdgeFlags="right"/>
</Row>
<Row android:keyboardMode="@+id/mode_im" android:rowEdgeFlags="bottom">
<Key android:codes="-2" android:keyLabel="@string/label_symbol_key"
android:popupKeyboard="@xml/kbd_popup_template"
android:popupCharacters="_"
android:keyWidth="20%p" android:keyEdgeFlags="left"/>
<Key android:codes="@integer/key_f1" android:keyIcon="@drawable/sym_keyboard_globe"
android:keyWidth="10%p"/>
<Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
android:iconPreview="@drawable/sym_keyboard_feedback_space"
android:keyWidth="40%p" android:isRepeatable="true"/>
<Key android:codes="46" android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation"
android:keyWidth="10%p"/>
<Key android:keyLabel=":-)" android:keyOutputText=":-) "
android:popupKeyboard="@xml/popup_smileys"
android:keyWidth="20%p" android:keyEdgeFlags="right"/>
</Row>
</Keyboard>

View File

@ -114,7 +114,8 @@
android:popupKeyboard="@xml/kbd_popup_template"
android:popupCharacters="_"
android:keyWidth="20%p" android:keyEdgeFlags="left"/>
<Key android:keyLabel="," android:keyWidth="10%p" />
<Key android:codes="@integer/key_f1" android:keyIcon="@drawable/sym_keyboard_globe"
android:keyWidth="10%p"/>
<Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
android:iconPreview="@drawable/sym_keyboard_feedback_space"
android:keyWidth="40%p" android:isRepeatable="true"/>
@ -130,10 +131,12 @@
android:popupKeyboard="@xml/kbd_popup_template"
android:popupCharacters="_"
android:keyWidth="20%p" android:keyEdgeFlags="left"/>
<Key android:keyLabel="@string/popular_domain_0"
<Key android:codes="@integer/key_f1" android:keyIcon="@drawable/sym_keyboard_globe"
android:keyWidth="15%p"/>
<!--Key android:keyLabel="@string/popular_domain_0"
android:keyOutputText="@string/popular_domain_0"
android:popupKeyboard="@xml/popup_domains"
android:keyWidth="15%p"/>
android:keyWidth="15%p"/-->
<Key android:keyLabel="/" android:keyWidth="15%p"/>
<Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
android:iconPreview="@drawable/sym_keyboard_feedback_space"
@ -150,11 +153,13 @@
android:popupKeyboard="@xml/kbd_popup_template"
android:popupCharacters="_"
android:keyWidth="20%p" android:keyEdgeFlags="left"/>
<Key android:codes="@integer/key_f1" android:keyIcon="@drawable/sym_keyboard_globe"
android:keyWidth="15%p"/>
<Key android:keyLabel="\@" android:keyWidth="15%p"/>
<Key android:keyLabel="@string/popular_domain_0"
<!--Key android:keyLabel="@string/popular_domain_0"
android:keyOutputText="@string/popular_domain_0"
android:popupKeyboard="@xml/popup_domains"
android:keyWidth="15%p"/>
android:keyWidth="15%p"/-->
<Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
android:iconPreview="@drawable/sym_keyboard_feedback_space"
android:keyWidth="15%p" android:isRepeatable="true"/>
@ -170,7 +175,8 @@
android:popupKeyboard="@xml/kbd_popup_template"
android:popupCharacters="_"
android:keyWidth="20%p" android:keyEdgeFlags="left"/>
<Key android:keyLabel="," android:keyWidth="10%p"/>
<Key android:codes="@integer/key_f1" android:keyIcon="@drawable/sym_keyboard_globe"
android:keyWidth="10%p"/>
<Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
android:iconPreview="@drawable/sym_keyboard_feedback_space"
android:keyWidth="40%p" android:isRepeatable="true"/>
@ -181,4 +187,4 @@
android:keyWidth="20%p" android:keyEdgeFlags="right"/>
</Row>
</Keyboard>

View File

@ -120,7 +120,7 @@
android:iconPreview="@drawable/sym_keyboard_feedback_delete"
android:isRepeatable="true"/>
</Row>
<Row android:rowEdgeFlags="bottom">
<Key android:codes="-2" android:keyLabel="@string/label_alpha_key"
android:popupKeyboard="@xml/kbd_popup_template"

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/language_selection_title">
</PreferenceScreen>

View File

@ -37,6 +37,14 @@
android:defaultValue="true"
/>
<PreferenceScreen
android:title="@string/language_selection_title">
<intent
android:action="android.intent.action.MAIN"
android:targetPackage="com.android.inputmethod.latin"
android:targetClass="com.android.inputmethod.latin.InputLanguageSelection" />
</PreferenceScreen>
<PreferenceCategory
android:title="@string/prediction_category"
android:key="prediction_settings">

View File

@ -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;
}

View File

@ -86,4 +86,9 @@ abstract public class Dictionary {
return true;
}
/**
* Override to clean up any resources.
*/
public void close() {
}
}

View File

@ -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<Loc> mAvailableLanguages = new ArrayList<Loc>();
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<Loc> getUniqueLocales() {
String[] locales = getAssets().getLocales();
Arrays.sort(locales);
ArrayList<Loc> uniqueLocales = new ArrayList<Loc>();
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);
}
}

View File

@ -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<KeyboardId, LatinKeyboard>();
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);
}

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -336,4 +336,10 @@ public class Suggest implements Dictionary.WordCallback {
}
mSuggestions.clear();
}
public void close() {
if (mMainDict != null) {
mMainDict.close();
}
}
}