Add language switch key only to the phone layouts

Bug: 5759092
Change-Id: Ic7d7d4812976654c0e85fecabd1128eadfc52c5c
main
Tadashi G. Takaoka 2012-02-17 17:46:01 -08:00
parent 168d2c094b
commit 81d4e3cd66
22 changed files with 206 additions and 21 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -216,6 +216,7 @@
<attr name="iconShiftKeyShifted" format="reference" /> <attr name="iconShiftKeyShifted" format="reference" />
<attr name="iconDisabledShortcutKey" format="reference" /> <attr name="iconDisabledShortcutKey" format="reference" />
<attr name="iconPreviewTabKey" format="reference" /> <attr name="iconPreviewTabKey" format="reference" />
<attr name="iconLanguageSwitchKey" format="reference" />
</declare-styleable> </declare-styleable>
<declare-styleable name="Keyboard_Key"> <declare-styleable name="Keyboard_Key">
@ -296,6 +297,7 @@
<enum name="iconShortcutForLabel" value="9" /> <enum name="iconShortcutForLabel" value="9" />
<enum name="iconSpaceKeyForNumberLayout" value="10" /> <enum name="iconSpaceKeyForNumberLayout" value="10" />
<enum name="iconShiftKeyShifted" value="11" /> <enum name="iconShiftKeyShifted" value="11" />
<enum name="iconLanguageSwitchKey" value="14" />
</attr> </attr>
<!-- The icon for disabled key --> <!-- The icon for disabled key -->
<attr name="keyIconDisabled" format="enum"> <attr name="keyIconDisabled" format="enum">
@ -361,6 +363,7 @@
<attr name="clobberSettingsKey" format="boolean" /> <attr name="clobberSettingsKey" format="boolean" />
<attr name="shortcutKeyEnabled" format="boolean" /> <attr name="shortcutKeyEnabled" format="boolean" />
<attr name="hasShortcutKey" format="boolean" /> <attr name="hasShortcutKey" format="boolean" />
<attr name="languageSwitchKeyEnabled" format="boolean" />
<attr name="isMultiLine" format="boolean" /> <attr name="isMultiLine" format="boolean" />
<attr name="imeAction" format="enum"> <attr name="imeAction" format="enum">
<!-- This should be aligned with EditorInfo.IME_ACTION_* --> <!-- This should be aligned with EditorInfo.IME_ACTION_* -->

View File

@ -34,5 +34,7 @@
<item name="iconShiftKeyShifted">@drawable/sym_bkeyboard_shift_locked</item> <item name="iconShiftKeyShifted">@drawable/sym_bkeyboard_shift_locked</item>
<item name="iconDisabledShortcutKey">@drawable/sym_bkeyboard_voice_off</item> <item name="iconDisabledShortcutKey">@drawable/sym_bkeyboard_voice_off</item>
<item name="iconPreviewTabKey">@drawable/sym_keyboard_feedback_tab</item> <item name="iconPreviewTabKey">@drawable/sym_keyboard_feedback_tab</item>
<!-- TODO: Needs dedicated black theme globe icon -->
<item name="iconLanguageSwitchKey">@drawable/sym_keyboard_language_switch</item>
</style> </style>
</resources> </resources>

View File

@ -33,5 +33,6 @@
<item name="iconShiftKeyShifted">@drawable/sym_keyboard_shift_locked_holo</item> <item name="iconShiftKeyShifted">@drawable/sym_keyboard_shift_locked_holo</item>
<item name="iconDisabledShortcutKey">@drawable/sym_keyboard_voice_off_holo</item> <item name="iconDisabledShortcutKey">@drawable/sym_keyboard_voice_off_holo</item>
<item name="iconPreviewTabKey">@drawable/sym_keyboard_feedback_tab</item> <item name="iconPreviewTabKey">@drawable/sym_keyboard_feedback_tab</item>
<item name="iconLanguageSwitchKey">@drawable/sym_keyboard_language_switch</item>
</style> </style>
</resources> </resources>

View File

@ -31,5 +31,6 @@
<!-- TODO: Needs non-holo disabled shortcut icon drawable --> <!-- TODO: Needs non-holo disabled shortcut icon drawable -->
<item name="iconDisabledShortcutKey">@drawable/sym_keyboard_voice_off_holo</item> <item name="iconDisabledShortcutKey">@drawable/sym_keyboard_voice_off_holo</item>
<item name="iconPreviewTabKey">@drawable/sym_keyboard_feedback_tab</item> <item name="iconPreviewTabKey">@drawable/sym_keyboard_feedback_tab</item>
<item name="iconLanguageSwitchKey">@drawable/sym_keyboard_language_switch</item>
</style> </style>
</resources> </resources>

View File

@ -32,5 +32,6 @@
<integer name="key_action_enter">-7</integer> <integer name="key_action_enter">-7</integer>
<integer name="key_action_next">-8</integer> <integer name="key_action_next">-8</integer>
<integer name="key_action_previous">-9</integer> <integer name="key_action_previous">-9</integer>
<integer name="key_unspecified">-10</integer> <integer name="key_language_switch">-10</integer>
<integer name="key_unspecified">-11</integer>
</resources> </resources>

View File

@ -64,6 +64,13 @@
<!-- Option summary for advanced settings screen [CHAR LIMIT=65 (two lines) or 30 (fits on one line, preferable)] --> <!-- Option summary for advanced settings screen [CHAR LIMIT=65 (two lines) or 30 (fits on one line, preferable)] -->
<string name="advanced_settings_summary">Options for experts</string> <string name="advanced_settings_summary">Options for experts</string>
<!-- Option name for including other IMEs in the language switch list [CHAR LIMIT=25] -->
<string name="include_other_imes_in_language_switch_list">Switch to other input methods</string>
<!-- Option summary for including other IMEs in the language switch list [CHAR LIMIT=65] -->
<string name="include_other_imes_in_language_switch_list_summary">Language switch key covers other input methods too</string>
<!-- Option to suppress language switch key [CHAR LIMIT=25] -->
<string name="suppress_language_switch_key">Suppress language switch key</string>
<!-- Option for the dismiss delay of the key popup [CHAR LIMIT=25] --> <!-- Option for the dismiss delay of the key popup [CHAR LIMIT=25] -->
<string name="key_preview_popup_dismiss_delay">Key popup dismiss delay</string> <string name="key_preview_popup_dismiss_delay">Key popup dismiss delay</string>
<!-- Description for delay for dismissing a popup on keypress: no delay [CHAR LIMIT=15] --> <!-- Description for delay for dismissing a popup on keypress: no delay [CHAR LIMIT=15] -->

View File

@ -117,10 +117,10 @@
latin:altCode="@integer/key_space" latin:altCode="@integer/key_space"
latin:parentStyle="f1MoreKeysStyle" /> latin:parentStyle="f1MoreKeysStyle" />
<key-style <key-style
latin:styleName="settingsKeyStyle" latin:styleName="languageSwitchKeyStyle"
latin:code="@integer/key_settings" latin:code="@integer/key_language_switch"
latin:keyIcon="iconSettingsKey" latin:keyIcon="iconLanguageSwitchKey"
latin:keyActionFlags="noKeyPreview|altCodeWhileTyping" latin:keyActionFlags="noKeyPreview|altCodeWhileTyping|enableLongPress"
latin:altCode="@integer/key_space" latin:altCode="@integer/key_space"
latin:backgroundType="functional" /> latin:backgroundType="functional" />
<key-style <key-style

View File

@ -92,6 +92,17 @@
android:key="pref_advanced_settings" android:key="pref_advanced_settings"
android:title="@string/advanced_settings" android:title="@string/advanced_settings"
android:summary="@string/advanced_settings_summary"> android:summary="@string/advanced_settings_summary">
<CheckBoxPreference
android:key="pref_suppress_language_switch_key"
android:title="@string/suppress_language_switch_key"
android:persistent="true"
android:defaultValue="false" />
<CheckBoxPreference
android:key="pref_include_other_imes_in_language_switch_list"
android:title="@string/include_other_imes_in_language_switch_list"
android:summary="@string/include_other_imes_in_language_switch_list_summary"
android:persistent="true"
android:defaultValue="false" />
<!-- Values for popup dismiss delay are added programatically --> <!-- Values for popup dismiss delay are added programatically -->
<ListPreference <ListPreference
android:key="pref_key_preview_popup_dismiss_delay" android:key="pref_key_preview_popup_dismiss_delay"

View File

@ -57,9 +57,23 @@
latin:keyStyle="f1MoreKeysStyle" /> latin:keyStyle="f1MoreKeysStyle" />
</default> </default>
</switch> </switch>
<switch>
<case
latin:languageSwitchKeyEnabled="true"
>
<Key
latin:keyStyle="languageSwitchKeyStyle" />
<Key
latin:keyStyle="spaceKeyStyle"
latin:keyWidth="40%p" />
</case>
<!-- languageSwitchKeyEnabled="false" -->
<default>
<Key <Key
latin:keyStyle="spaceKeyStyle" latin:keyStyle="spaceKeyStyle"
latin:keyWidth="50%p" /> latin:keyWidth="50%p" />
</default>
</switch>
<Key <Key
latin:keyStyle="punctuationKeyStyle" /> latin:keyStyle="punctuationKeyStyle" />
<Key <Key

View File

@ -49,6 +49,8 @@ public class InputMethodManagerCompatWrapper {
private static final String TAG = InputMethodManagerCompatWrapper.class.getSimpleName(); private static final String TAG = InputMethodManagerCompatWrapper.class.getSimpleName();
private static final Method METHOD_getCurrentInputMethodSubtype = private static final Method METHOD_getCurrentInputMethodSubtype =
CompatUtils.getMethod(InputMethodManager.class, "getCurrentInputMethodSubtype"); CompatUtils.getMethod(InputMethodManager.class, "getCurrentInputMethodSubtype");
private static final Method METHOD_getLastInputMethodSubtype =
CompatUtils.getMethod(InputMethodManager.class, "getLastInputMethodSubtype");
private static final Method METHOD_getEnabledInputMethodSubtypeList = private static final Method METHOD_getEnabledInputMethodSubtypeList =
CompatUtils.getMethod(InputMethodManager.class, "getEnabledInputMethodSubtypeList", CompatUtils.getMethod(InputMethodManager.class, "getEnabledInputMethodSubtypeList",
InputMethodInfo.class, boolean.class); InputMethodInfo.class, boolean.class);
@ -60,6 +62,8 @@ public class InputMethodManagerCompatWrapper {
String.class, InputMethodSubtypeCompatWrapper.CLASS_InputMethodSubtype); String.class, InputMethodSubtypeCompatWrapper.CLASS_InputMethodSubtype);
private static final Method METHOD_switchToLastInputMethod = CompatUtils.getMethod( private static final Method METHOD_switchToLastInputMethod = CompatUtils.getMethod(
InputMethodManager.class, "switchToLastInputMethod", IBinder.class); InputMethodManager.class, "switchToLastInputMethod", IBinder.class);
private static final Method METHOD_switchToNextInputMethod = CompatUtils.getMethod(
InputMethodManager.class, "switchToNextInputMethod", IBinder.class, Boolean.TYPE);
private static final InputMethodManagerCompatWrapper sInstance = private static final InputMethodManagerCompatWrapper sInstance =
new InputMethodManagerCompatWrapper(); new InputMethodManagerCompatWrapper();
@ -111,6 +115,15 @@ public class InputMethodManagerCompatWrapper {
return new InputMethodSubtypeCompatWrapper(o); return new InputMethodSubtypeCompatWrapper(o);
} }
public InputMethodSubtypeCompatWrapper getLastInputMethodSubtype() {
if (!SUBTYPE_SUPPORTED) {
return new InputMethodSubtypeCompatWrapper(
0, 0, mLanguageSwitcherProxy.getInputLocale().toString(), KEYBOARD_MODE, "");
}
Object o = CompatUtils.invoke(mImm, null, METHOD_getLastInputMethodSubtype);
return new InputMethodSubtypeCompatWrapper(o);
}
public List<InputMethodSubtypeCompatWrapper> getEnabledInputMethodSubtypeList( public List<InputMethodSubtypeCompatWrapper> getEnabledInputMethodSubtypeList(
InputMethodInfoCompatWrapper imi, boolean allowsImplicitlySelectedSubtypes) { InputMethodInfoCompatWrapper imi, boolean allowsImplicitlySelectedSubtypes) {
if (!SUBTYPE_SUPPORTED) { if (!SUBTYPE_SUPPORTED) {
@ -221,6 +234,14 @@ public class InputMethodManagerCompatWrapper {
return (Boolean)CompatUtils.invoke(mImm, false, METHOD_switchToLastInputMethod, token); return (Boolean)CompatUtils.invoke(mImm, false, METHOD_switchToLastInputMethod, token);
} }
public boolean switchToNextInputMethod(IBinder token, boolean onlyCurrentIme) {
if (SubtypeSwitcher.getInstance().isDummyVoiceMode()) {
return true;
}
return (Boolean)CompatUtils.invoke(mImm, false, METHOD_switchToNextInputMethod, token,
onlyCurrentIme);
}
public List<InputMethodInfoCompatWrapper> getEnabledInputMethodList() { public List<InputMethodInfoCompatWrapper> getEnabledInputMethodList() {
if (mImm == null) return null; if (mImm == null) return null;
List<InputMethodInfoCompatWrapper> imis = new ArrayList<InputMethodInfoCompatWrapper>(); List<InputMethodInfoCompatWrapper> imis = new ArrayList<InputMethodInfoCompatWrapper>();

View File

@ -99,8 +99,9 @@ public class Keyboard {
public static final int CODE_ACTION_ENTER = -7; public static final int CODE_ACTION_ENTER = -7;
public static final int CODE_ACTION_NEXT = -8; public static final int CODE_ACTION_NEXT = -8;
public static final int CODE_ACTION_PREVIOUS = -9; public static final int CODE_ACTION_PREVIOUS = -9;
public static final int CODE_LANGUAGE_SWITCH = -10;
// Code value representing the code is not specified. // Code value representing the code is not specified.
public static final int CODE_UNSPECIFIED = -10; public static final int CODE_UNSPECIFIED = -11;
public final KeyboardId mId; public final KeyboardId mId;
public final int mThemeId; public final int mThemeId;
@ -1076,6 +1077,9 @@ public class Keyboard {
R.styleable.Keyboard_Case_shortcutKeyEnabled, id.mShortcutKeyEnabled); R.styleable.Keyboard_Case_shortcutKeyEnabled, id.mShortcutKeyEnabled);
final boolean hasShortcutKeyMatched = matchBoolean(a, final boolean hasShortcutKeyMatched = matchBoolean(a,
R.styleable.Keyboard_Case_hasShortcutKey, id.mHasShortcutKey); R.styleable.Keyboard_Case_hasShortcutKey, id.mHasShortcutKey);
final boolean languageSwitchKeyEnabledMatched = matchBoolean(a,
R.styleable.Keyboard_Case_languageSwitchKeyEnabled,
id.mLanguageSwitchKeyEnabled);
final boolean isMultiLineMatched = matchBoolean(a, final boolean isMultiLineMatched = matchBoolean(a,
R.styleable.Keyboard_Case_isMultiLine, id.isMultiLine()); R.styleable.Keyboard_Case_isMultiLine, id.isMultiLine());
final boolean imeActionMatched = matchInteger(a, final boolean imeActionMatched = matchInteger(a,
@ -1089,11 +1093,12 @@ public class Keyboard {
final boolean selected = keyboardSetElementMatched && modeMatched final boolean selected = keyboardSetElementMatched && modeMatched
&& navigateNextMatched && navigatePreviousMatched && passwordInputMatched && navigateNextMatched && navigatePreviousMatched && passwordInputMatched
&& clobberSettingsKeyMatched && shortcutKeyEnabledMatched && clobberSettingsKeyMatched && shortcutKeyEnabledMatched
&& hasShortcutKeyMatched && isMultiLineMatched && imeActionMatched && hasShortcutKeyMatched && languageSwitchKeyEnabledMatched
&& localeCodeMatched && languageCodeMatched && countryCodeMatched; && isMultiLineMatched && imeActionMatched && localeCodeMatched
&& languageCodeMatched && countryCodeMatched;
if (DEBUG) { if (DEBUG) {
startTag("<%s%s%s%s%s%s%s%s%s%s%s%s%s%s>%s", TAG_CASE, startTag("<%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s>%s", TAG_CASE,
textAttr(a.getString(R.styleable.Keyboard_Case_keyboardSetElement), textAttr(a.getString(R.styleable.Keyboard_Case_keyboardSetElement),
"keyboardSetElement"), "keyboardSetElement"),
textAttr(a.getString(R.styleable.Keyboard_Case_mode), "mode"), textAttr(a.getString(R.styleable.Keyboard_Case_mode), "mode"),
@ -1111,6 +1116,8 @@ public class Keyboard {
"shortcutKeyEnabled"), "shortcutKeyEnabled"),
booleanAttr(a, R.styleable.Keyboard_Case_hasShortcutKey, booleanAttr(a, R.styleable.Keyboard_Case_hasShortcutKey,
"hasShortcutKey"), "hasShortcutKey"),
booleanAttr(a, R.styleable.Keyboard_Case_languageSwitchKeyEnabled,
"languageSwitchKeyEnabled"),
booleanAttr(a, R.styleable.Keyboard_Case_isMultiLine, booleanAttr(a, R.styleable.Keyboard_Case_isMultiLine,
"isMultiLine"), "isMultiLine"),
textAttr(a.getString(R.styleable.Keyboard_Case_localeCode), textAttr(a.getString(R.styleable.Keyboard_Case_localeCode),

View File

@ -62,13 +62,14 @@ public class KeyboardId {
public final boolean mClobberSettingsKey; public final boolean mClobberSettingsKey;
public final boolean mShortcutKeyEnabled; public final boolean mShortcutKeyEnabled;
public final boolean mHasShortcutKey; public final boolean mHasShortcutKey;
public final boolean mLanguageSwitchKeyEnabled;
public final String mCustomActionLabel; public final String mCustomActionLabel;
private final int mHashCode; private final int mHashCode;
public KeyboardId(int elementId, Locale locale, int orientation, int width, int mode, public KeyboardId(int elementId, Locale locale, int orientation, int width, int mode,
EditorInfo editorInfo, boolean clobberSettingsKey, boolean shortcutKeyEnabled, EditorInfo editorInfo, boolean clobberSettingsKey, boolean shortcutKeyEnabled,
boolean hasShortcutKey) { boolean hasShortcutKey, boolean languageSwitchKeyEnabled) {
this.mLocale = locale; this.mLocale = locale;
this.mOrientation = orientation; this.mOrientation = orientation;
this.mWidth = width; this.mWidth = width;
@ -78,6 +79,7 @@ public class KeyboardId {
this.mClobberSettingsKey = clobberSettingsKey; this.mClobberSettingsKey = clobberSettingsKey;
this.mShortcutKeyEnabled = shortcutKeyEnabled; this.mShortcutKeyEnabled = shortcutKeyEnabled;
this.mHasShortcutKey = hasShortcutKey; this.mHasShortcutKey = hasShortcutKey;
this.mLanguageSwitchKeyEnabled = languageSwitchKeyEnabled;
this.mCustomActionLabel = (editorInfo.actionLabel != null) this.mCustomActionLabel = (editorInfo.actionLabel != null)
? editorInfo.actionLabel.toString() : null; ? editorInfo.actionLabel.toString() : null;
@ -94,6 +96,7 @@ public class KeyboardId {
id.mClobberSettingsKey, id.mClobberSettingsKey,
id.mShortcutKeyEnabled, id.mShortcutKeyEnabled,
id.mHasShortcutKey, id.mHasShortcutKey,
id.mLanguageSwitchKeyEnabled,
id.isMultiLine(), id.isMultiLine(),
id.imeAction(), id.imeAction(),
id.mCustomActionLabel, id.mCustomActionLabel,
@ -114,6 +117,7 @@ public class KeyboardId {
&& other.mClobberSettingsKey == this.mClobberSettingsKey && other.mClobberSettingsKey == this.mClobberSettingsKey
&& other.mShortcutKeyEnabled == this.mShortcutKeyEnabled && other.mShortcutKeyEnabled == this.mShortcutKeyEnabled
&& other.mHasShortcutKey == this.mHasShortcutKey && other.mHasShortcutKey == this.mHasShortcutKey
&& other.mLanguageSwitchKeyEnabled == this.mLanguageSwitchKeyEnabled
&& other.isMultiLine() == this.isMultiLine() && other.isMultiLine() == this.isMultiLine()
&& other.imeAction() == this.imeAction() && other.imeAction() == this.imeAction()
&& TextUtils.equals(other.mCustomActionLabel, this.mCustomActionLabel) && TextUtils.equals(other.mCustomActionLabel, this.mCustomActionLabel)
@ -172,7 +176,7 @@ public class KeyboardId {
@Override @Override
public String toString() { public String toString() {
return String.format("[%s %s %s%d %s %s %s%s%s%s%s%s%s]", return String.format("[%s %s %s%d %s %s %s%s%s%s%s%s%s%s]",
elementIdToName(mElementId), elementIdToName(mElementId),
mLocale, mLocale,
(mOrientation == 1 ? "port" : "land"), mWidth, (mOrientation == 1 ? "port" : "land"), mWidth,
@ -184,6 +188,7 @@ public class KeyboardId {
(passwordInput() ? " passwordInput" : ""), (passwordInput() ? " passwordInput" : ""),
(mShortcutKeyEnabled ? " shortcutKeyEnabled" : ""), (mShortcutKeyEnabled ? " shortcutKeyEnabled" : ""),
(mHasShortcutKey ? " hasShortcutKey" : ""), (mHasShortcutKey ? " hasShortcutKey" : ""),
(mLanguageSwitchKeyEnabled ? " languageSwitchKeyEnabled" : ""),
(isMultiLine() ? "isMultiLine" : "") (isMultiLine() ? "isMultiLine" : "")
); );
} }

View File

@ -101,6 +101,7 @@ public class KeyboardSet {
boolean mVoiceKeyEnabled; boolean mVoiceKeyEnabled;
boolean mVoiceKeyOnMain; boolean mVoiceKeyOnMain;
boolean mNoSettingsKey; boolean mNoSettingsKey;
boolean mLanguageSwitchKeyEnabled;
Locale mLocale; Locale mLocale;
int mOrientation; int mOrientation;
int mWidth; int mWidth;
@ -196,7 +197,7 @@ public class KeyboardSet {
&& (isSymbols != params.mVoiceKeyOnMain); && (isSymbols != params.mVoiceKeyOnMain);
return new KeyboardId(keyboardSetElementId, params.mLocale, params.mOrientation, return new KeyboardId(keyboardSetElementId, params.mLocale, params.mOrientation,
params.mWidth, params.mMode, params.mEditorInfo, params.mNoSettingsKey, params.mWidth, params.mMode, params.mEditorInfo, params.mNoSettingsKey,
params.mVoiceKeyEnabled, hasShortcutKey); params.mVoiceKeyEnabled, hasShortcutKey, params.mLanguageSwitchKeyEnabled);
} }
public static class Builder { public static class Builder {
@ -239,7 +240,8 @@ public class KeyboardSet {
return this; return this;
} }
public Builder setOptions(boolean voiceKeyEnabled, boolean voiceKeyOnMain) { public Builder setOptions(boolean voiceKeyEnabled, boolean voiceKeyOnMain,
boolean languageSwitchKeyEnabled) {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
final boolean deprecatedNoMicrophone = Utils.inPrivateImeOptions( final boolean deprecatedNoMicrophone = Utils.inPrivateImeOptions(
null, LatinIME.IME_OPTION_NO_MICROPHONE_COMPAT, mEditorInfo); null, LatinIME.IME_OPTION_NO_MICROPHONE_COMPAT, mEditorInfo);
@ -248,6 +250,7 @@ public class KeyboardSet {
|| deprecatedNoMicrophone; || deprecatedNoMicrophone;
mParams.mVoiceKeyEnabled = voiceKeyEnabled && !noMicrophone; mParams.mVoiceKeyEnabled = voiceKeyEnabled && !noMicrophone;
mParams.mVoiceKeyOnMain = voiceKeyOnMain; mParams.mVoiceKeyOnMain = voiceKeyOnMain;
mParams.mLanguageSwitchKeyEnabled = languageSwitchKeyEnabled;
return this; return this;
} }

View File

@ -133,7 +133,8 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions,
LatinIME.SUBTYPE_EXTRA_VALUE_SUPPORT_TOUCH_POSITION_CORRECTION)); LatinIME.SUBTYPE_EXTRA_VALUE_SUPPORT_TOUCH_POSITION_CORRECTION));
builder.setOptions( builder.setOptions(
settingsValues.isVoiceKeyEnabled(editorInfo), settingsValues.isVoiceKeyEnabled(editorInfo),
settingsValues.isVoiceKeyOnMain()); settingsValues.isVoiceKeyOnMain(),
settingsValues.isLanguageSwitchKeyEnabled(mThemeContext));
mKeyboardSet = builder.build(); mKeyboardSet = builder.build();
try { try {
mState.onLoadKeyboard(mResources.getString(R.string.layout_switch_back_symbols)); mState.onLoadKeyboard(mResources.getString(R.string.layout_switch_back_symbols));

View File

@ -489,7 +489,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
KeyboardSwitcher.getInstance().hapticAndAudioFeedback(primaryCode); KeyboardSwitcher.getInstance().hapticAndAudioFeedback(primaryCode);
return true; return true;
} }
if (primaryCode == Keyboard.CODE_SPACE) { if (primaryCode == Keyboard.CODE_SPACE || primaryCode == Keyboard.CODE_LANGUAGE_SWITCH) {
// Long pressing the space key invokes IME switcher dialog. // Long pressing the space key invokes IME switcher dialog.
if (invokeCustomRequest(LatinIME.CODE_SHOW_INPUT_METHOD_PICKER)) { if (invokeCustomRequest(LatinIME.CODE_SHOW_INPUT_METHOD_PICKER)) {
tracker.onLongPressed(); tracker.onLongPressed();
@ -782,6 +782,11 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
&& Utils.hasMultipleEnabledIMEsOrSubtypes(true /* include aux subtypes */)) { && Utils.hasMultipleEnabledIMEsOrSubtypes(true /* include aux subtypes */)) {
drawKeyPopupHint(key, canvas, paint, params); drawKeyPopupHint(key, canvas, paint, params);
} }
} else if (key.mCode == Keyboard.CODE_LANGUAGE_SWITCH) {
super.onDrawKeyTopVisuals(key, canvas, paint, params);
if (Utils.hasMultipleEnabledIMEsOrSubtypes(true /* include aux subtypes */)) {
drawKeyPopupHint(key, canvas, paint, params);
}
} else { } else {
super.onDrawKeyTopVisuals(key, canvas, paint, params); super.onDrawKeyTopVisuals(key, canvas, paint, params);
} }

View File

@ -31,7 +31,7 @@ public class KeyboardIconsSet {
// The value should be aligned with the enum value of Key.keyIcon. // The value should be aligned with the enum value of Key.keyIcon.
public static final int ICON_UNDEFINED = 0; public static final int ICON_UNDEFINED = 0;
private static final int NUM_ICONS = 13; private static final int NUM_ICONS = 14;
private final Drawable[] mIcons = new Drawable[NUM_ICONS + 1]; private final Drawable[] mIcons = new Drawable[NUM_ICONS + 1];
@ -57,6 +57,7 @@ public class KeyboardIconsSet {
addIconIdMap(11, "shiftKeyShifted", R.styleable.Keyboard_iconShiftKeyShifted); addIconIdMap(11, "shiftKeyShifted", R.styleable.Keyboard_iconShiftKeyShifted);
addIconIdMap(12, "disabledShortcurKey", R.styleable.Keyboard_iconDisabledShortcutKey); addIconIdMap(12, "disabledShortcurKey", R.styleable.Keyboard_iconDisabledShortcutKey);
addIconIdMap(13, "previewTabKey", R.styleable.Keyboard_iconPreviewTabKey); addIconIdMap(13, "previewTabKey", R.styleable.Keyboard_iconPreviewTabKey);
addIconIdMap(14, "languageSwitchKey", R.styleable.Keyboard_iconLanguageSwitchKey);
} }
private static void addIconIdMap(int iconId, String name, int attrId) { private static void addIconIdMap(int iconId, String name, int attrId) {

View File

@ -29,6 +29,7 @@ import android.inputmethodservice.InputMethodService;
import android.media.AudioManager; import android.media.AudioManager;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.os.Debug; import android.os.Debug;
import android.os.IBinder;
import android.os.Message; import android.os.Message;
import android.os.SystemClock; import android.os.SystemClock;
import android.preference.PreferenceActivity; import android.preference.PreferenceActivity;
@ -55,6 +56,7 @@ import com.android.inputmethod.compat.EditorInfoCompatUtils;
import com.android.inputmethod.compat.InputConnectionCompatUtils; import com.android.inputmethod.compat.InputConnectionCompatUtils;
import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
import com.android.inputmethod.compat.InputMethodServiceCompatWrapper; import com.android.inputmethod.compat.InputMethodServiceCompatWrapper;
import com.android.inputmethod.compat.InputMethodSubtypeCompatWrapper;
import com.android.inputmethod.compat.InputTypeCompatUtils; import com.android.inputmethod.compat.InputTypeCompatUtils;
import com.android.inputmethod.compat.SuggestionSpanUtils; import com.android.inputmethod.compat.SuggestionSpanUtils;
import com.android.inputmethod.compat.VibratorCompatWrapper; import com.android.inputmethod.compat.VibratorCompatWrapper;
@ -196,6 +198,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
private KeyboardSwitcher mKeyboardSwitcher; private KeyboardSwitcher mKeyboardSwitcher;
private SubtypeSwitcher mSubtypeSwitcher; private SubtypeSwitcher mSubtypeSwitcher;
private VoiceProxy mVoiceProxy; private VoiceProxy mVoiceProxy;
private boolean mShouldSwitchToLastSubtype = true;
private UserDictionary mUserDictionary; private UserDictionary mUserDictionary;
private UserBigramDictionary mUserBigramDictionary; private UserBigramDictionary mUserBigramDictionary;
@ -1263,6 +1266,25 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
} }
} }
private void handleLanguageSwitchKey() {
final boolean includesOtherImes = !mSettingsValues.mIncludesOtherImesInLanguageSwitchList;
final IBinder token = getWindow().getWindow().getAttributes().token;
if (mShouldSwitchToLastSubtype) {
final InputMethodSubtypeCompatWrapper lastSubtype = mImm.getLastInputMethodSubtype();
final boolean lastSubtypeBelongsToThisIme = Utils.checkIfSubtypeBelongsToThisIme(
this, lastSubtype);
if ((includesOtherImes || lastSubtypeBelongsToThisIme)
&& mImm.switchToLastInputMethod(token)) {
mShouldSwitchToLastSubtype = false;
} else {
mImm.switchToNextInputMethod(token, !includesOtherImes);
mShouldSwitchToLastSubtype = true;
}
} else {
mImm.switchToNextInputMethod(token, !includesOtherImes);
}
}
private void sendKeyCodePoint(int code) { private void sendKeyCodePoint(int code) {
// TODO: Remove this special handling of digit letters. // TODO: Remove this special handling of digit letters.
// For backward compatibility. See {@link InputMethodService#sendKeyChar(char)}. // For backward compatibility. See {@link InputMethodService#sendKeyChar(char)}.
@ -1306,6 +1328,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
handleBackspace(spaceState); handleBackspace(spaceState);
mDeleteCount++; mDeleteCount++;
mExpectingUpdateSelection = true; mExpectingUpdateSelection = true;
mShouldSwitchToLastSubtype = true;
LatinImeLogger.logOnDelete(); LatinImeLogger.logOnDelete();
break; break;
case Keyboard.CODE_SHIFT: case Keyboard.CODE_SHIFT:
@ -1327,6 +1350,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
case Keyboard.CODE_ACTION_PREVIOUS: case Keyboard.CODE_ACTION_PREVIOUS:
EditorInfoCompatUtils.performEditorActionPrevious(getCurrentInputConnection()); EditorInfoCompatUtils.performEditorActionPrevious(getCurrentInputConnection());
break; break;
case Keyboard.CODE_LANGUAGE_SWITCH:
handleLanguageSwitchKey();
break;
default: default:
mSpaceState = SPACE_STATE_NONE; mSpaceState = SPACE_STATE_NONE;
if (mSettingsValues.isWordSeparator(primaryCode)) { if (mSettingsValues.isWordSeparator(primaryCode)) {
@ -1335,6 +1361,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
handleCharacter(primaryCode, x, y, spaceState); handleCharacter(primaryCode, x, y, spaceState);
} }
mExpectingUpdateSelection = true; mExpectingUpdateSelection = true;
mShouldSwitchToLastSubtype = true;
break; break;
} }
switcher.onCodeInput(primaryCode); switcher.onCodeInput(primaryCode);

View File

@ -43,7 +43,6 @@ import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView; import android.widget.TextView;
import com.android.inputmethod.compat.CompatUtils; import com.android.inputmethod.compat.CompatUtils;
import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
import com.android.inputmethod.compat.InputMethodServiceCompatWrapper; import com.android.inputmethod.compat.InputMethodServiceCompatWrapper;
import com.android.inputmethod.compat.VibratorCompatWrapper; import com.android.inputmethod.compat.VibratorCompatWrapper;
import com.android.inputmethod.deprecated.VoiceProxy; import com.android.inputmethod.deprecated.VoiceProxy;
@ -73,6 +72,10 @@ public class Settings extends InputMethodSettingsActivity
public static final String PREF_MISC_SETTINGS = "misc_settings"; public static final String PREF_MISC_SETTINGS = "misc_settings";
public static final String PREF_USABILITY_STUDY_MODE = "usability_study_mode"; public static final String PREF_USABILITY_STUDY_MODE = "usability_study_mode";
public static final String PREF_ADVANCED_SETTINGS = "pref_advanced_settings"; public static final String PREF_ADVANCED_SETTINGS = "pref_advanced_settings";
public static final String PREF_SUPPRESS_LANGUAGE_SWITCH_KEY =
"pref_suppress_language_switch_key";
public static final String PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST =
"pref_include_other_imes_in_language_switch_list";
public static final String PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY = public static final String PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY =
"pref_key_preview_popup_dismiss_delay"; "pref_key_preview_popup_dismiss_delay";
public static final String PREF_KEY_USE_CONTACTS_DICT = "pref_key_use_contacts_dict"; public static final String PREF_KEY_USE_CONTACTS_DICT = "pref_key_use_contacts_dict";
@ -204,6 +207,11 @@ public class Settings extends InputMethodSettingsActivity
} }
} }
final CheckBoxPreference includeOtherImesInLanguageSwitchList =
(CheckBoxPreference)findPreference(PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST);
includeOtherImesInLanguageSwitchList.setEnabled(
!SettingsValues.isLanguageSwitchKeySupressed(prefs));
mKeyPreviewPopupDismissDelay = mKeyPreviewPopupDismissDelay =
(ListPreference)findPreference(PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY); (ListPreference)findPreference(PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY);
final String[] entries = new String[] { final String[] entries = new String[] {
@ -316,6 +324,12 @@ public class Settings extends InputMethodSettingsActivity
if (null != popupDismissDelay) { if (null != popupDismissDelay) {
popupDismissDelay.setEnabled(prefs.getBoolean(PREF_POPUP_ON, true)); popupDismissDelay.setEnabled(prefs.getBoolean(PREF_POPUP_ON, true));
} }
} else if (key.equals(PREF_SUPPRESS_LANGUAGE_SWITCH_KEY)) {
final CheckBoxPreference includeOtherImesInLanguageSwicthList =
(CheckBoxPreference)findPreference(
PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST);
includeOtherImesInLanguageSwicthList.setEnabled(
!SettingsValues.isLanguageSwitchKeySupressed(prefs));
} }
ensureConsistencyOfAutoCorrectionSettings(); ensureConsistencyOfAutoCorrectionSettings();
mVoiceOn = !(prefs.getString(PREF_VOICE_MODE, mVoiceModeOff) mVoiceOn = !(prefs.getString(PREF_VOICE_MODE, mVoiceModeOff)

View File

@ -23,11 +23,14 @@ import android.os.Build;
import android.util.Log; import android.util.Log;
import android.view.inputmethod.EditorInfo; import android.view.inputmethod.EditorInfo;
import com.android.inputmethod.compat.InputMethodInfoCompatWrapper;
import com.android.inputmethod.compat.InputTypeCompatUtils; import com.android.inputmethod.compat.InputTypeCompatUtils;
import com.android.inputmethod.compat.VibratorCompatWrapper; import com.android.inputmethod.compat.VibratorCompatWrapper;
import com.android.inputmethod.keyboard.internal.KeySpecParser; import com.android.inputmethod.keyboard.internal.KeySpecParser;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale; import java.util.Locale;
public class SettingsValues { public class SettingsValues {
@ -55,6 +58,8 @@ public class SettingsValues {
public final String mShowSuggestionsSetting; public final String mShowSuggestionsSetting;
@SuppressWarnings("unused") // TODO: Use this @SuppressWarnings("unused") // TODO: Use this
private final boolean mUsabilityStudyMode; private final boolean mUsabilityStudyMode;
public final boolean mIncludesOtherImesInLanguageSwitchList;
public final boolean mIsLanguageSwitchKeySuppressed;
@SuppressWarnings("unused") // TODO: Use this @SuppressWarnings("unused") // TODO: Use this
private final String mKeyPreviewPopupDismissDelayRawValue; private final String mKeyPreviewPopupDismissDelayRawValue;
public final boolean mUseContactsDict; public final boolean mUseContactsDict;
@ -127,6 +132,9 @@ public class SettingsValues {
mShowSuggestionsSetting = prefs.getString(Settings.PREF_SHOW_SUGGESTIONS_SETTING, mShowSuggestionsSetting = prefs.getString(Settings.PREF_SHOW_SUGGESTIONS_SETTING,
res.getString(R.string.prefs_suggestion_visibility_default_value)); res.getString(R.string.prefs_suggestion_visibility_default_value));
mUsabilityStudyMode = getUsabilityStudyMode(prefs); mUsabilityStudyMode = getUsabilityStudyMode(prefs);
mIncludesOtherImesInLanguageSwitchList = prefs.getBoolean(
Settings.PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST, false);
mIsLanguageSwitchKeySuppressed = isLanguageSwitchKeySupressed(prefs);
mKeyPreviewPopupDismissDelayRawValue = prefs.getString( mKeyPreviewPopupDismissDelayRawValue = prefs.getString(
Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY, Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY,
Integer.toString(res.getInteger(R.integer.config_key_preview_linger_timeout))); Integer.toString(res.getInteger(R.integer.config_key_preview_linger_timeout)));
@ -309,6 +317,22 @@ public class SettingsValues {
return mVoiceKeyOnMain; return mVoiceKeyOnMain;
} }
public static boolean isLanguageSwitchKeySupressed(SharedPreferences sp) {
return sp.getBoolean(Settings.PREF_SUPPRESS_LANGUAGE_SWITCH_KEY, false);
}
public boolean isLanguageSwitchKeyEnabled(Context context) {
if (mIsLanguageSwitchKeySuppressed) {
return false;
}
if (mIncludesOtherImesInLanguageSwitchList) {
return Utils.hasMultipleEnabledIMEsOrSubtypes(/* include aux subtypes */false);
} else {
return Utils.hasMultipleEnabledSubtypesInThisIme(
context, /* include aux subtypes */false);
}
}
public boolean isFullscreenModeAllowed(Resources res) { public boolean isFullscreenModeAllowed(Resources res) {
return res.getBoolean(R.bool.config_use_fullscreen_mode); return res.getBoolean(R.bool.config_use_fullscreen_mode);
} }

View File

@ -52,6 +52,7 @@ import java.io.PrintWriter;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@ -117,16 +118,51 @@ public class Utils {
} }
} }
// TODO: Move InputMethodSubtype related utility methods to its own utility class.
// TODO: Cache my InputMethodInfo and/or InputMethodSubtype list.
public static boolean checkIfSubtypeBelongsToThisIme(Context context,
InputMethodSubtypeCompatWrapper ims) {
final InputMethodManagerCompatWrapper imm = InputMethodManagerCompatWrapper.getInstance();
if (imm == null) return false;
final InputMethodInfoCompatWrapper myImi = Utils.getInputMethodInfo(
context.getPackageName());
final List<InputMethodSubtypeCompatWrapper> subtypes =
imm.getEnabledInputMethodSubtypeList(myImi, true);
for (final InputMethodSubtypeCompatWrapper subtype : subtypes) {
if (subtype.equals(ims)) {
return true;
}
}
return false;
}
public static boolean hasMultipleEnabledIMEsOrSubtypes( public static boolean hasMultipleEnabledIMEsOrSubtypes(
final boolean shouldIncludeAuxiliarySubtypes) { final boolean shouldIncludeAuxiliarySubtypes) {
final InputMethodManagerCompatWrapper imm = InputMethodManagerCompatWrapper.getInstance(); final InputMethodManagerCompatWrapper imm = InputMethodManagerCompatWrapper.getInstance();
if (imm == null) return false; if (imm == null) return false;
final List<InputMethodInfoCompatWrapper> enabledImis = imm.getEnabledInputMethodList(); final List<InputMethodInfoCompatWrapper> enabledImis = imm.getEnabledInputMethodList();
return hasMultipleEnabledSubtypes(shouldIncludeAuxiliarySubtypes, enabledImis);
}
public static boolean hasMultipleEnabledSubtypesInThisIme(Context context,
final boolean shouldIncludeAuxiliarySubtypes) {
final InputMethodInfoCompatWrapper myImi = Utils.getInputMethodInfo(
context.getPackageName());
final List<InputMethodInfoCompatWrapper> imiList = Collections.singletonList(myImi);
return Utils.hasMultipleEnabledSubtypes(shouldIncludeAuxiliarySubtypes, imiList);
}
private static boolean hasMultipleEnabledSubtypes(final boolean shouldIncludeAuxiliarySubtypes,
List<InputMethodInfoCompatWrapper> imiList) {
final InputMethodManagerCompatWrapper imm = InputMethodManagerCompatWrapper.getInstance();
if (imm == null) return false;
// Number of the filtered IMEs // Number of the filtered IMEs
int filteredImisCount = 0; int filteredImisCount = 0;
for (InputMethodInfoCompatWrapper imi : enabledImis) { for (InputMethodInfoCompatWrapper imi : imiList) {
// We can return true immediately after we find two or more filtered IMEs. // We can return true immediately after we find two or more filtered IMEs.
if (filteredImisCount > 1) return true; if (filteredImisCount > 1) return true;
final List<InputMethodSubtypeCompatWrapper> subtypes = final List<InputMethodSubtypeCompatWrapper> subtypes =
@ -564,6 +600,7 @@ public class Utils {
} }
} }
// TODO: Move this method to KeyboardSet class.
public static int getKeyboardMode(EditorInfo editorInfo) { public static int getKeyboardMode(EditorInfo editorInfo) {
if (editorInfo == null) if (editorInfo == null)
return KeyboardId.MODE_TEXT; return KeyboardId.MODE_TEXT;