aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java21
-rw-r--r--java/src/com/android/inputmethod/deprecated/VoiceProxy.java17
-rw-r--r--java/src/com/android/inputmethod/keyboard/Key.java4
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyDetector.java4
-rw-r--r--java/src/com/android/inputmethod/keyboard/Keyboard.java15
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java10
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardId.java9
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSet.java7
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java3
-rw-r--r--java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java10
-rw-r--r--java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java4
-rw-r--r--java/src/com/android/inputmethod/keyboard/PointerTracker.java13
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java3
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java129
-rw-r--r--java/src/com/android/inputmethod/latin/Settings.java16
-rw-r--r--java/src/com/android/inputmethod/latin/SettingsValues.java24
-rw-r--r--java/src/com/android/inputmethod/latin/Suggest.java1
-rw-r--r--java/src/com/android/inputmethod/latin/Utils.java39
-rw-r--r--java/src/com/android/inputmethod/latin/WordComposer.java56
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java18
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java2
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java30
22 files changed, 341 insertions, 94 deletions
diff --git a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java
index 7e216e5c8..9dd0a599d 100644
--- a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java
+++ b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java
@@ -49,6 +49,8 @@ public class InputMethodManagerCompatWrapper {
private static final String TAG = InputMethodManagerCompatWrapper.class.getSimpleName();
private static final Method METHOD_getCurrentInputMethodSubtype =
CompatUtils.getMethod(InputMethodManager.class, "getCurrentInputMethodSubtype");
+ private static final Method METHOD_getLastInputMethodSubtype =
+ CompatUtils.getMethod(InputMethodManager.class, "getLastInputMethodSubtype");
private static final Method METHOD_getEnabledInputMethodSubtypeList =
CompatUtils.getMethod(InputMethodManager.class, "getEnabledInputMethodSubtypeList",
InputMethodInfo.class, boolean.class);
@@ -60,6 +62,8 @@ public class InputMethodManagerCompatWrapper {
String.class, InputMethodSubtypeCompatWrapper.CLASS_InputMethodSubtype);
private static final Method METHOD_switchToLastInputMethod = CompatUtils.getMethod(
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 =
new InputMethodManagerCompatWrapper();
@@ -111,6 +115,15 @@ public class InputMethodManagerCompatWrapper {
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(
InputMethodInfoCompatWrapper imi, boolean allowsImplicitlySelectedSubtypes) {
if (!SUBTYPE_SUPPORTED) {
@@ -221,6 +234,14 @@ public class InputMethodManagerCompatWrapper {
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() {
if (mImm == null) return null;
List<InputMethodInfoCompatWrapper> imis = new ArrayList<InputMethodInfoCompatWrapper>();
diff --git a/java/src/com/android/inputmethod/deprecated/VoiceProxy.java b/java/src/com/android/inputmethod/deprecated/VoiceProxy.java
index 700709d50..c1c6d31cd 100644
--- a/java/src/com/android/inputmethod/deprecated/VoiceProxy.java
+++ b/java/src/com/android/inputmethod/deprecated/VoiceProxy.java
@@ -92,6 +92,7 @@ public class VoiceProxy implements VoiceInput.UiListener {
private static final boolean DEBUG = LatinImeLogger.sDBG;
private boolean mAfterVoiceInput;
+ private boolean mConfigurationChanging;
private boolean mHasUsedVoiceInput;
private boolean mHasUsedVoiceInputUnsupportedLocale;
private boolean mImmediatelyAfterVoiceInput;
@@ -159,11 +160,11 @@ public class VoiceProxy implements VoiceInput.UiListener {
mPasswordText = isPasswordText;
}
- public void flushVoiceInputLogs(boolean configurationChanged) {
+ public void flushVoiceInputLogs() {
if (!VOICE_INSTALLED) {
return;
}
- if (!configurationChanged) {
+ if (!mConfigurationChanging) {
if (mAfterVoiceInput) {
mVoiceInput.flushAllTextModificationCounters();
mVoiceInput.logInputEnded();
@@ -318,11 +319,11 @@ public class VoiceProxy implements VoiceInput.UiListener {
mImmediatelyAfterVoiceInput = false;
}
- public void hideVoiceWindow(boolean configurationChanging) {
+ public void hideVoiceWindow() {
if (!VOICE_INSTALLED) {
return;
}
- if (!configurationChanging) {
+ if (!mConfigurationChanging) {
if (mAfterVoiceInput)
mVoiceInput.logInputEnded();
if (mVoiceWarningDialog != null && mVoiceWarningDialog.isShowing()) {
@@ -842,4 +843,12 @@ public class VoiceProxy implements VoiceInput.UiListener {
SettingsUtil.LATIN_IME_VOICE_INPUT_SUPPORTED_LOCALES,
DEFAULT_VOICE_INPUT_SUPPORTED_LOCALES);
}
+
+ public void startChangingConfiguration() {
+ mConfigurationChanging = true;
+ }
+
+ public void finishChangingConfiguration() {
+ mConfigurationChanging = false;
+ }
}
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index 79c7ce0fd..f3923834b 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -108,8 +108,8 @@ public class Key {
private static final int MORE_KEYS_COLUMN_MASK = 0x000000ff;
private static final int MORE_KEYS_FLAGS_FIXED_COLUMN_ORDER = 0x80000000;
private static final int MORE_KEYS_FLAGS_HAS_LABELS = 0x40000000;
- private static final int MORE_KEYS_FLAGS_NEEDS_DIVIDERS = 0x40000000;
- private static final int MORE_KEYS_FLAGS_EMBEDDED_MORE_KEY = 0x20000000;
+ private static final int MORE_KEYS_FLAGS_NEEDS_DIVIDERS = 0x20000000;
+ private static final int MORE_KEYS_FLAGS_EMBEDDED_MORE_KEY = 0x10000000;
private static final String MORE_KEYS_AUTO_COLUMN_ORDER = "!autoColumnOrder!";
private static final String MORE_KEYS_FIXED_COLUMN_ORDER = "!fixedColumnOrder!";
private static final String MORE_KEYS_HAS_LABELS = "!hasLabels!";
diff --git a/java/src/com/android/inputmethod/keyboard/KeyDetector.java b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
index 10cf1d1f4..3638eae8d 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyDetector.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
@@ -65,11 +65,11 @@ public class KeyDetector {
return mKeyHysteresisDistanceSquared;
}
- protected int getTouchX(int x) {
+ public int getTouchX(int x) {
return x + mCorrectionX;
}
- protected int getTouchY(int y) {
+ public int getTouchY(int y) {
return y + mCorrectionY;
}
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index c6cdf7986..5660d1942 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -99,8 +99,9 @@ public class Keyboard {
public static final int CODE_ACTION_ENTER = -7;
public static final int CODE_ACTION_NEXT = -8;
public static final int CODE_ACTION_PREVIOUS = -9;
+ public static final int CODE_LANGUAGE_SWITCH = -10;
// 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 int mThemeId;
@@ -1076,6 +1077,9 @@ public class Keyboard {
R.styleable.Keyboard_Case_shortcutKeyEnabled, id.mShortcutKeyEnabled);
final boolean hasShortcutKeyMatched = matchBoolean(a,
R.styleable.Keyboard_Case_hasShortcutKey, id.mHasShortcutKey);
+ final boolean languageSwitchKeyEnabledMatched = matchBoolean(a,
+ R.styleable.Keyboard_Case_languageSwitchKeyEnabled,
+ id.mLanguageSwitchKeyEnabled);
final boolean isMultiLineMatched = matchBoolean(a,
R.styleable.Keyboard_Case_isMultiLine, id.isMultiLine());
final boolean imeActionMatched = matchInteger(a,
@@ -1089,11 +1093,12 @@ public class Keyboard {
final boolean selected = keyboardSetElementMatched && modeMatched
&& navigateNextMatched && navigatePreviousMatched && passwordInputMatched
&& clobberSettingsKeyMatched && shortcutKeyEnabledMatched
- && hasShortcutKeyMatched && isMultiLineMatched && imeActionMatched
- && localeCodeMatched && languageCodeMatched && countryCodeMatched;
+ && hasShortcutKeyMatched && languageSwitchKeyEnabledMatched
+ && isMultiLineMatched && imeActionMatched && localeCodeMatched
+ && languageCodeMatched && countryCodeMatched;
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),
"keyboardSetElement"),
textAttr(a.getString(R.styleable.Keyboard_Case_mode), "mode"),
@@ -1111,6 +1116,8 @@ public class Keyboard {
"shortcutKeyEnabled"),
booleanAttr(a, R.styleable.Keyboard_Case_hasShortcutKey,
"hasShortcutKey"),
+ booleanAttr(a, R.styleable.Keyboard_Case_languageSwitchKeyEnabled,
+ "languageSwitchKeyEnabled"),
booleanAttr(a, R.styleable.Keyboard_Case_isMultiLine,
"isMultiLine"),
textAttr(a.getString(R.styleable.Keyboard_Case_localeCode),
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java b/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java
index 6e13b95b5..16b4eafc9 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java
@@ -41,11 +41,6 @@ public interface KeyboardActionListener {
* Send a key code to the listener.
*
* @param primaryCode this is the code of the key that was pressed
- * @param keyCodes the codes for all the possible alternative keys with the primary code being
- * the first. If the primary key code is a single character such as an alphabet or
- * number or symbol, the alternatives will include other characters that may be on
- * the same key or adjacent keys. These codes are useful to correct for accidental
- * presses of a key adjacent to the intended key.
* @param x x-coordinate pixel of touched event. If {@link #onCodeInput} is not called by
* {@link PointerTracker#onTouchEvent} or so, the value should be
* {@link #NOT_A_TOUCH_COORDINATE}. If it's called on insertion from the suggestion
@@ -55,10 +50,11 @@ public interface KeyboardActionListener {
* {@link #NOT_A_TOUCH_COORDINATE}. If it's called on insertion from the suggestion
* strip, it should be {@link #SUGGESTION_STRIP_COORDINATE}.
*/
- public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y);
+ public void onCodeInput(int primaryCode, int x, int y);
public static final int NOT_A_TOUCH_COORDINATE = -1;
public static final int SUGGESTION_STRIP_COORDINATE = -2;
+ public static final int SPELL_CHECKER_COORDINATE = -3;
/**
* Sends a sequence of characters to the listener.
@@ -84,7 +80,7 @@ public interface KeyboardActionListener {
@Override
public void onReleaseKey(int primaryCode, boolean withSliding) {}
@Override
- public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y) {}
+ public void onCodeInput(int primaryCode, int x, int y) {}
@Override
public void onTextInput(CharSequence text) {}
@Override
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
index f5752962e..6703b9301 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
@@ -62,13 +62,14 @@ public class KeyboardId {
public final boolean mClobberSettingsKey;
public final boolean mShortcutKeyEnabled;
public final boolean mHasShortcutKey;
+ public final boolean mLanguageSwitchKeyEnabled;
public final String mCustomActionLabel;
private final int mHashCode;
public KeyboardId(int elementId, Locale locale, int orientation, int width, int mode,
EditorInfo editorInfo, boolean clobberSettingsKey, boolean shortcutKeyEnabled,
- boolean hasShortcutKey) {
+ boolean hasShortcutKey, boolean languageSwitchKeyEnabled) {
this.mLocale = locale;
this.mOrientation = orientation;
this.mWidth = width;
@@ -78,6 +79,7 @@ public class KeyboardId {
this.mClobberSettingsKey = clobberSettingsKey;
this.mShortcutKeyEnabled = shortcutKeyEnabled;
this.mHasShortcutKey = hasShortcutKey;
+ this.mLanguageSwitchKeyEnabled = languageSwitchKeyEnabled;
this.mCustomActionLabel = (editorInfo.actionLabel != null)
? editorInfo.actionLabel.toString() : null;
@@ -94,6 +96,7 @@ public class KeyboardId {
id.mClobberSettingsKey,
id.mShortcutKeyEnabled,
id.mHasShortcutKey,
+ id.mLanguageSwitchKeyEnabled,
id.isMultiLine(),
id.imeAction(),
id.mCustomActionLabel,
@@ -114,6 +117,7 @@ public class KeyboardId {
&& other.mClobberSettingsKey == this.mClobberSettingsKey
&& other.mShortcutKeyEnabled == this.mShortcutKeyEnabled
&& other.mHasShortcutKey == this.mHasShortcutKey
+ && other.mLanguageSwitchKeyEnabled == this.mLanguageSwitchKeyEnabled
&& other.isMultiLine() == this.isMultiLine()
&& other.imeAction() == this.imeAction()
&& TextUtils.equals(other.mCustomActionLabel, this.mCustomActionLabel)
@@ -172,7 +176,7 @@ public class KeyboardId {
@Override
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),
mLocale,
(mOrientation == 1 ? "port" : "land"), mWidth,
@@ -184,6 +188,7 @@ public class KeyboardId {
(passwordInput() ? " passwordInput" : ""),
(mShortcutKeyEnabled ? " shortcutKeyEnabled" : ""),
(mHasShortcutKey ? " hasShortcutKey" : ""),
+ (mLanguageSwitchKeyEnabled ? " languageSwitchKeyEnabled" : ""),
(isMultiLine() ? "isMultiLine" : "")
);
}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java
index ee882edc0..731aaf7c5 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java
@@ -101,6 +101,7 @@ public class KeyboardSet {
boolean mVoiceKeyEnabled;
boolean mVoiceKeyOnMain;
boolean mNoSettingsKey;
+ boolean mLanguageSwitchKeyEnabled;
Locale mLocale;
int mOrientation;
int mWidth;
@@ -196,7 +197,7 @@ public class KeyboardSet {
&& (isSymbols != params.mVoiceKeyOnMain);
return new KeyboardId(keyboardSetElementId, params.mLocale, params.mOrientation,
params.mWidth, params.mMode, params.mEditorInfo, params.mNoSettingsKey,
- params.mVoiceKeyEnabled, hasShortcutKey);
+ params.mVoiceKeyEnabled, hasShortcutKey, params.mLanguageSwitchKeyEnabled);
}
public static class Builder {
@@ -239,7 +240,8 @@ public class KeyboardSet {
return this;
}
- public Builder setOptions(boolean voiceKeyEnabled, boolean voiceKeyOnMain) {
+ public Builder setOptions(boolean voiceKeyEnabled, boolean voiceKeyOnMain,
+ boolean languageSwitchKeyEnabled) {
@SuppressWarnings("deprecation")
final boolean deprecatedNoMicrophone = Utils.inPrivateImeOptions(
null, LatinIME.IME_OPTION_NO_MICROPHONE_COMPAT, mEditorInfo);
@@ -248,6 +250,7 @@ public class KeyboardSet {
|| deprecatedNoMicrophone;
mParams.mVoiceKeyEnabled = voiceKeyEnabled && !noMicrophone;
mParams.mVoiceKeyOnMain = voiceKeyOnMain;
+ mParams.mLanguageSwitchKeyEnabled = languageSwitchKeyEnabled;
return this;
}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index e1c6f2604..ac8dd1b95 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -133,7 +133,8 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions,
LatinIME.SUBTYPE_EXTRA_VALUE_SUPPORT_TOUCH_POSITION_CORRECTION));
builder.setOptions(
settingsValues.isVoiceKeyEnabled(editorInfo),
- settingsValues.isVoiceKeyOnMain());
+ settingsValues.isVoiceKeyOnMain(),
+ settingsValues.isLanguageSwitchKeyEnabled(mThemeContext));
mKeyboardSet = builder.build();
try {
mState.onLoadKeyboard(mResources.getString(R.string.layout_switch_back_symbols));
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
index 8a2f89257..afc4932e9 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
@@ -489,7 +489,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
KeyboardSwitcher.getInstance().hapticAndAudioFeedback(primaryCode);
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.
if (invokeCustomRequest(LatinIME.CODE_SHOW_INPUT_METHOD_PICKER)) {
tracker.onLongPressed();
@@ -505,7 +505,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
}
private void invokeCodeInput(int primaryCode) {
- mKeyboardActionListener.onCodeInput(primaryCode, null,
+ mKeyboardActionListener.onCodeInput(primaryCode,
KeyboardActionListener.NOT_A_TOUCH_COORDINATE,
KeyboardActionListener.NOT_A_TOUCH_COORDINATE);
}
@@ -740,6 +740,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
* @return {@code true} if the event was handled by the view, {@code false}
* otherwise
*/
+ //Should not annotate @override
public boolean dispatchHoverEvent(MotionEvent event) {
if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
final PointerTracker tracker = PointerTracker.getPointerTracker(0, this);
@@ -781,6 +782,11 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
&& Utils.hasMultipleEnabledIMEsOrSubtypes(true /* include aux subtypes */)) {
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 {
super.onDrawKeyTopVisuals(key, canvas, paint, params);
}
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
index b030dd95a..9970d1d0b 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
@@ -46,8 +46,8 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel
private final KeyboardActionListener mMoreKeysKeyboardListener =
new KeyboardActionListener.Adapter() {
@Override
- public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y) {
- mListener.onCodeInput(primaryCode, keyCodes, x, y);
+ public void onCodeInput(int primaryCode, int x, int y) {
+ mListener.onCodeInput(primaryCode, x, y);
}
@Override
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index f8f17bdd9..7a9915be0 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -105,7 +105,6 @@ public class PointerTracker {
}
}
- private static KeyboardSwitcher sKeyboardSwitcher;
// Parameters for pointer handling.
private static LatinKeyboardView.PointerTrackerParams sParams;
private static int sTouchNoiseThresholdDistanceSquared;
@@ -172,7 +171,6 @@ public class PointerTracker {
}
setParameters(LatinKeyboardView.PointerTrackerParams.DEFAULT);
- sKeyboardSwitcher = KeyboardSwitcher.getInstance();
}
public static void setParameters(LatinKeyboardView.PointerTrackerParams params) {
@@ -254,13 +252,13 @@ public class PointerTracker {
// Note that we need primaryCode argument because the keyboard may in shifted state and the
// primaryCode is different from {@link Key#mCode}.
- private void callListenerOnCodeInput(Key key, int primaryCode, int[] keyCodes, int x, int y) {
+ private void callListenerOnCodeInput(Key key, int primaryCode, int x, int y) {
final boolean ignoreModifierKey = mIgnoreModifierKey && key.isModifier();
final boolean alterCode = key.altCodeWhileTyping() && mTimerProxy.isTyping();
final int code = alterCode ? key.mAltCode : primaryCode;
if (DEBUG_LISTENER) {
Log.d(TAG, "onCodeInput: " + Keyboard.printableCode(code) + " text=" + key.mOutputText
- + " codes="+ KeyDetector.printableCodes(keyCodes) + " x=" + x + " y=" + y
+ + " x=" + x + " y=" + y
+ " ignoreModifier=" + ignoreModifierKey + " alterCode=" + alterCode
+ " enabled=" + key.isEnabled());
}
@@ -271,7 +269,7 @@ public class PointerTracker {
if (code == Keyboard.CODE_OUTPUT_TEXT) {
mListener.onTextInput(key.mOutputText);
} else if (code != Keyboard.CODE_UNSPECIFIED) {
- mListener.onCodeInput(code, keyCodes, x, y);
+ mListener.onCodeInput(code, x, y);
}
if (!key.altCodeWhileTyping() && !key.isModifier()) {
mTimerProxy.startKeyTypedTimer();
@@ -719,10 +717,7 @@ public class PointerTracker {
}
int code = key.mCode;
- final int[] codes = mKeyDetector.newCodeArray();
- mKeyDetector.getKeyAndNearbyCodes(x, y, codes);
-
- callListenerOnCodeInput(key, code, codes, x, y);
+ callListenerOnCodeInput(key, code, x, y);
callListenerOnRelease(key, code, false);
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java
index 7c8fd1225..ca711ec7d 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java
@@ -31,7 +31,7 @@ public class KeyboardIconsSet {
// The value should be aligned with the enum value of Key.keyIcon.
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];
@@ -57,6 +57,7 @@ public class KeyboardIconsSet {
addIconIdMap(11, "shiftKeyShifted", R.styleable.Keyboard_iconShiftKeyShifted);
addIconIdMap(12, "disabledShortcurKey", R.styleable.Keyboard_iconDisabledShortcutKey);
addIconIdMap(13, "previewTabKey", R.styleable.Keyboard_iconPreviewTabKey);
+ addIconIdMap(14, "languageSwitchKey", R.styleable.Keyboard_iconLanguageSwitchKey);
}
private static void addIconIdMap(int iconId, String name, int attrId) {
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 742328256..1858db949 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -25,10 +25,12 @@ import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.graphics.Rect;
import android.inputmethodservice.InputMethodService;
import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.os.Debug;
+import android.os.IBinder;
import android.os.Message;
import android.os.SystemClock;
import android.preference.PreferenceActivity;
@@ -43,6 +45,7 @@ import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
+import android.view.ViewGroup.LayoutParams;
import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.ExtractedText;
@@ -55,6 +58,7 @@ import com.android.inputmethod.compat.EditorInfoCompatUtils;
import com.android.inputmethod.compat.InputConnectionCompatUtils;
import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
import com.android.inputmethod.compat.InputMethodServiceCompatWrapper;
+import com.android.inputmethod.compat.InputMethodSubtypeCompatWrapper;
import com.android.inputmethod.compat.InputTypeCompatUtils;
import com.android.inputmethod.compat.SuggestionSpanUtils;
import com.android.inputmethod.compat.VibratorCompatWrapper;
@@ -193,9 +197,10 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
private InputMethodManagerCompatWrapper mImm;
private Resources mResources;
private SharedPreferences mPrefs;
- private KeyboardSwitcher mKeyboardSwitcher;
- private SubtypeSwitcher mSubtypeSwitcher;
+ private final KeyboardSwitcher mKeyboardSwitcher;
+ private final SubtypeSwitcher mSubtypeSwitcher;
private VoiceProxy mVoiceProxy;
+ private boolean mShouldSwitchToLastSubtype = true;
private UserDictionary mUserDictionary;
private UserBigramDictionary mUserBigramDictionary;
@@ -223,9 +228,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
private VibratorCompatWrapper mVibrator;
- // TODO: Move this flag to VoiceProxy
- private boolean mConfigurationChanging;
-
// Member variables for remembering the current device orientation.
private int mDisplayOrientation;
@@ -489,6 +491,12 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
}
+ public LatinIME() {
+ super();
+ mSubtypeSwitcher = SubtypeSwitcher.getInstance();
+ mKeyboardSwitcher = KeyboardSwitcher.getInstance();
+ }
+
@Override
public void onCreate() {
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
@@ -503,8 +511,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
super.onCreate();
mImm = InputMethodManagerCompatWrapper.getInstance();
- mSubtypeSwitcher = SubtypeSwitcher.getInstance();
- mKeyboardSwitcher = KeyboardSwitcher.getInstance();
mVibrator = VibratorCompatWrapper.getInstance(this);
mHandler.onCreate();
DEBUG = LatinImeLogger.sDBG;
@@ -552,7 +558,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// Has to be package-visible for unit tests
/* package */ void loadSettings() {
if (null == mPrefs) mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
- if (null == mSubtypeSwitcher) mSubtypeSwitcher = SubtypeSwitcher.getInstance();
mSettingsValues = new SettingsValues(mPrefs, this, mSubtypeSwitcher.getInputLocaleStr());
resetContactsDictionary(null == mSuggest ? null : mSuggest.getContactsDictionary());
}
@@ -664,10 +669,10 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mOptionsDialog.dismiss();
}
- mConfigurationChanging = true;
+ mVoiceProxy.startChangingConfiguration();
super.onConfigurationChanged(conf);
mVoiceProxy.onConfigurationChanged(conf);
- mConfigurationChanging = false;
+ mVoiceProxy.finishChangingConfiguration();
// This will work only when the subtype is not supported.
LanguageSwitcherProxy.onConfigurationChanged(conf);
@@ -728,10 +733,17 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
final KeyboardSwitcher switcher = mKeyboardSwitcher;
LatinKeyboardView inputView = switcher.getKeyboardView();
+ if (editorInfo == null) {
+ Log.e(TAG, "Null EditorInfo in onStartInputView()");
+ if (LatinImeLogger.sDBG) {
+ throw new NullPointerException("Null EditorInfo in onStartInputView()");
+ }
+ return;
+ }
if (DEBUG) {
- Log.d(TAG, "onStartInputView: editorInfo:" + ((editorInfo == null) ? "none"
- : String.format("inputType=0x%08x imeOptions=0x%08x",
- editorInfo.inputType, editorInfo.imeOptions)));
+ Log.d(TAG, "onStartInputView: editorInfo:"
+ + String.format("inputType=0x%08x imeOptions=0x%08x",
+ editorInfo.inputType, editorInfo.imeOptions));
}
if (Utils.inPrivateImeOptions(null, IME_OPTION_NO_MICROPHONE_COMPAT, editorInfo)) {
Log.w(TAG, "Deprecated private IME option specified: "
@@ -761,7 +773,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// Most such things we decide below in initializeInputAttributesAndGetMode, but we need to
// know now whether this is a password text field, because we need to know now whether we
// want to enable the voice button.
- final int inputType = (editorInfo != null) ? editorInfo.inputType : 0;
+ final int inputType = editorInfo.inputType;
mVoiceProxy.resetVoiceStates(InputTypeCompatUtils.isPasswordInputType(inputType)
|| InputTypeCompatUtils.isVisiblePasswordInputType(inputType));
@@ -823,7 +835,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
LatinImeLogger.commit();
- mVoiceProxy.flushVoiceInputLogs(mConfigurationChanging);
+ mVoiceProxy.flushVoiceInputLogs();
KeyboardView inputView = mKeyboardSwitcher.getKeyboardView();
if (inputView != null) inputView.closing();
@@ -953,7 +965,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mOptionsDialog.dismiss();
mOptionsDialog = null;
}
- mVoiceProxy.hideVoiceWindow(mConfigurationChanging);
+ mVoiceProxy.hideVoiceWindow();
super.hideWindow();
}
@@ -1011,12 +1023,34 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
setSuggestionStripShownInternal(shown, /* needsInputViewShown */true);
}
+ private void adjustInputViewHeight() {
+ if (mKeyPreviewBackingView.getHeight() > 0) {
+ return;
+ }
+
+ final KeyboardView keyboardView = mKeyboardSwitcher.getKeyboardView();
+ if (keyboardView == null) return;
+ final int keyboardHeight = keyboardView.getHeight();
+ final int suggestionsHeight = mSuggestionsContainer.getHeight();
+ final int displayHeight = mResources.getDisplayMetrics().heightPixels;
+ final Rect rect = new Rect();
+ mKeyPreviewBackingView.getWindowVisibleDisplayFrame(rect);
+ final int notificationBarHeight = rect.top;
+ final int remainingHeight = displayHeight - notificationBarHeight - suggestionsHeight
+ - keyboardHeight;
+
+ final LayoutParams params = mKeyPreviewBackingView.getLayoutParams();
+ params.height = mSuggestionsView.setMoreSuggestionsHeight(remainingHeight);
+ mKeyPreviewBackingView.setLayoutParams(params);
+ }
+
@Override
public void onComputeInsets(InputMethodService.Insets outInsets) {
super.onComputeInsets(outInsets);
final KeyboardView inputView = mKeyboardSwitcher.getKeyboardView();
if (inputView == null || mSuggestionsContainer == null)
return;
+ adjustInputViewHeight();
// In fullscreen mode, the height of the extract area managed by InputMethodService should
// be considered.
// See {@link android.inputmethodservice.InputMethodService#onComputeInsets}.
@@ -1245,12 +1279,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
return mOptionsDialog != null && mOptionsDialog.isShowing();
}
- private void insertPunctuationFromSuggestionStrip(final int code) {
- onCodeInput(code, new int[] { code },
- KeyboardActionListener.SUGGESTION_STRIP_COORDINATE,
- KeyboardActionListener.SUGGESTION_STRIP_COORDINATE);
- }
-
private static int getActionId(Keyboard keyboard) {
return keyboard != null ? keyboard.mId.imeActionId() : EditorInfo.IME_ACTION_NONE;
}
@@ -1262,6 +1290,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) {
// TODO: Remove this special handling of digit letters.
// For backward compatibility. See {@link InputMethodService#sendKeyChar(char)}.
@@ -1279,7 +1326,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// Implementation of {@link KeyboardActionListener}.
@Override
- public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y) {
+ public void onCodeInput(int primaryCode, int x, int y) {
final long when = SystemClock.uptimeMillis();
if (primaryCode != Keyboard.CODE_DELETE || when > mLastKeyTime + QUICK_PRESS) {
mDeleteCount = 0;
@@ -1305,6 +1352,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
handleBackspace(spaceState);
mDeleteCount++;
mExpectingUpdateSelection = true;
+ mShouldSwitchToLastSubtype = true;
LatinImeLogger.logOnDelete();
break;
case Keyboard.CODE_SHIFT:
@@ -1326,14 +1374,18 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
case Keyboard.CODE_ACTION_PREVIOUS:
EditorInfoCompatUtils.performEditorActionPrevious(getCurrentInputConnection());
break;
+ case Keyboard.CODE_LANGUAGE_SWITCH:
+ handleLanguageSwitchKey();
+ break;
default:
mSpaceState = SPACE_STATE_NONE;
if (mSettingsValues.isWordSeparator(primaryCode)) {
didAutoCorrect = handleSeparator(primaryCode, x, y, spaceState);
} else {
- handleCharacter(primaryCode, keyCodes, x, y, spaceState);
+ handleCharacter(primaryCode, x, y, spaceState);
}
mExpectingUpdateSelection = true;
+ mShouldSwitchToLastSubtype = true;
break;
}
switcher.onCodeInput(primaryCode);
@@ -1498,18 +1550,18 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
}
- private void handleCharacter(final int primaryCode, final int[] keyCodes, final int x,
+ private void handleCharacter(final int primaryCode, final int x,
final int y, final int spaceState) {
mVoiceProxy.handleCharacter();
final InputConnection ic = getCurrentInputConnection();
if (null != ic) ic.beginBatchEdit();
// TODO: if ic is null, does it make any sense to call this?
- handleCharacterWhileInBatchEdit(primaryCode, keyCodes, x, y, spaceState, ic);
+ handleCharacterWhileInBatchEdit(primaryCode, x, y, spaceState, ic);
if (null != ic) ic.endBatchEdit();
}
// "ic" may be null without this crashing, but the behavior will be really strange
- private void handleCharacterWhileInBatchEdit(final int primaryCode, final int[] keyCodes,
+ private void handleCharacterWhileInBatchEdit(final int primaryCode,
final int x, final int y, final int spaceState, final InputConnection ic) {
boolean isComposingWord = mWordComposer.isComposingWord();
@@ -1541,7 +1593,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
}
if (isComposingWord) {
- mWordComposer.add(primaryCode, keyCodes, x, y);
+ mWordComposer.add(
+ primaryCode, x, y, mKeyboardSwitcher.getKeyboardView().getKeyDetector());
if (ic != null) {
// If it's the first letter, make note of auto-caps state
if (mWordComposer.size() == 1) {
@@ -1893,6 +1946,14 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mVoiceProxy.flushAndLogAllTextModificationCounters(index, suggestion,
mSettingsValues.mWordSeparators);
+ if (SPACE_STATE_PHANTOM == mSpaceState && suggestion.length() > 0) {
+ int firstChar = Character.codePointAt(suggestion, 0);
+ if ((!mSettingsValues.isWeakSpaceStripper(firstChar))
+ && (!mSettingsValues.isWeakSpaceSwapper(firstChar))) {
+ sendKeyCodePoint(Keyboard.CODE_SPACE);
+ }
+ }
+
if (mInputAttributes.mApplicationSpecifiedCompletionOn
&& mApplicationSpecifiedCompletions != null
&& index >= 0 && index < mApplicationSpecifiedCompletions.length) {
@@ -1916,7 +1977,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
LatinImeLogger.logOnManualSuggestion("", suggestion.toString(), index, suggestedWords);
// Rely on onCodeInput to do the complicated swapping/stripping logic consistently.
final int primaryCode = suggestion.charAt(0);
- onCodeInput(primaryCode, new int[] { primaryCode },
+ onCodeInput(primaryCode,
KeyboardActionListener.SUGGESTION_STRIP_COORDINATE,
KeyboardActionListener.SUGGESTION_STRIP_COORDINATE);
return;
@@ -2162,7 +2223,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
final String originallyTypedWord = mLastComposedWord.mTypedWord;
final CharSequence committedWord = mLastComposedWord.mCommittedWord;
final int cancelLength = committedWord.length();
- final int separatorLength = mLastComposedWord.getSeparatorLength(
+ final int separatorLength = LastComposedWord.getSeparatorLength(
mLastComposedWord.mSeparatorCode);
// TODO: should we check our saved separator against the actual contents of the text view?
if (DEBUG) {
@@ -2264,6 +2325,14 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
initSuggest();
loadSettings();
+ // Since we just changed languages, we should re-evaluate suggestions with whatever word
+ // we are currently composing. If we are not composing anything, we may want to display
+ // predictions or punctuation signs (which is done by updateBigramPredictions anyway).
+ if (isCursorTouchingWord()) {
+ mHandler.postUpdateSuggestions();
+ } else {
+ mHandler.postUpdateBigramPredictions();
+ }
}
public void hapticAndAudioFeedback(int primaryCode) {
diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java
index 3029057be..305cef22d 100644
--- a/java/src/com/android/inputmethod/latin/Settings.java
+++ b/java/src/com/android/inputmethod/latin/Settings.java
@@ -43,7 +43,6 @@ import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import com.android.inputmethod.compat.CompatUtils;
-import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
import com.android.inputmethod.compat.InputMethodServiceCompatWrapper;
import com.android.inputmethod.compat.VibratorCompatWrapper;
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_USABILITY_STUDY_MODE = "usability_study_mode";
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 =
"pref_key_preview_popup_dismiss_delay";
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 =
(ListPreference)findPreference(PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY);
final String[] entries = new String[] {
@@ -316,6 +324,12 @@ public class Settings extends InputMethodSettingsActivity
if (null != popupDismissDelay) {
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();
mVoiceOn = !(prefs.getString(PREF_VOICE_MODE, mVoiceModeOff)
diff --git a/java/src/com/android/inputmethod/latin/SettingsValues.java b/java/src/com/android/inputmethod/latin/SettingsValues.java
index 6d65a74c8..69e45f619 100644
--- a/java/src/com/android/inputmethod/latin/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/SettingsValues.java
@@ -23,11 +23,14 @@ import android.os.Build;
import android.util.Log;
import android.view.inputmethod.EditorInfo;
+import com.android.inputmethod.compat.InputMethodInfoCompatWrapper;
import com.android.inputmethod.compat.InputTypeCompatUtils;
import com.android.inputmethod.compat.VibratorCompatWrapper;
import com.android.inputmethod.keyboard.internal.KeySpecParser;
import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
import java.util.Locale;
public class SettingsValues {
@@ -55,6 +58,8 @@ public class SettingsValues {
public final String mShowSuggestionsSetting;
@SuppressWarnings("unused") // TODO: Use this
private final boolean mUsabilityStudyMode;
+ public final boolean mIncludesOtherImesInLanguageSwitchList;
+ public final boolean mIsLanguageSwitchKeySuppressed;
@SuppressWarnings("unused") // TODO: Use this
private final String mKeyPreviewPopupDismissDelayRawValue;
public final boolean mUseContactsDict;
@@ -127,6 +132,9 @@ public class SettingsValues {
mShowSuggestionsSetting = prefs.getString(Settings.PREF_SHOW_SUGGESTIONS_SETTING,
res.getString(R.string.prefs_suggestion_visibility_default_value));
mUsabilityStudyMode = getUsabilityStudyMode(prefs);
+ mIncludesOtherImesInLanguageSwitchList = prefs.getBoolean(
+ Settings.PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST, false);
+ mIsLanguageSwitchKeySuppressed = isLanguageSwitchKeySupressed(prefs);
mKeyPreviewPopupDismissDelayRawValue = prefs.getString(
Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY,
Integer.toString(res.getInteger(R.integer.config_key_preview_linger_timeout)));
@@ -309,6 +317,22 @@ public class SettingsValues {
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) {
return res.getBoolean(R.bool.config_use_fullscreen_mode);
}
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index f6e177aaf..298ead665 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -323,7 +323,6 @@ public class Suggest implements Dictionary.WordCallback {
}
} else {
// Word entered: return only bigrams that match the first char of the typed word
- @SuppressWarnings("null")
final char currentChar = consideredWord.charAt(0);
// TODO: Must pay attention to locale when changing case.
final char currentCharUpper = Character.toUpperCase(currentChar);
diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java
index 33d4b877e..a8679e07a 100644
--- a/java/src/com/android/inputmethod/latin/Utils.java
+++ b/java/src/com/android/inputmethod/latin/Utils.java
@@ -52,6 +52,7 @@ import java.io.PrintWriter;
import java.nio.channels.FileChannel;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Date;
import java.util.List;
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(
final boolean shouldIncludeAuxiliarySubtypes) {
final InputMethodManagerCompatWrapper imm = InputMethodManagerCompatWrapper.getInstance();
if (imm == null) return false;
+
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
int filteredImisCount = 0;
- for (InputMethodInfoCompatWrapper imi : enabledImis) {
+ for (InputMethodInfoCompatWrapper imi : imiList) {
// We can return true immediately after we find two or more filtered IMEs.
if (filteredImisCount > 1) return true;
final List<InputMethodSubtypeCompatWrapper> subtypes =
@@ -564,6 +600,7 @@ public class Utils {
}
}
+ // TODO: Move this method to KeyboardSet class.
public static int getKeyboardMode(EditorInfo editorInfo) {
if (editorInfo == null)
return KeyboardId.MODE_TEXT;
diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java
index 8121ada7f..3324a3793 100644
--- a/java/src/com/android/inputmethod/latin/WordComposer.java
+++ b/java/src/com/android/inputmethod/latin/WordComposer.java
@@ -19,6 +19,9 @@ package com.android.inputmethod.latin;
import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.KeyDetector;
import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.keyboard.KeyboardActionListener;
+import com.android.inputmethod.latin.spellcheck.AndroidSpellCheckerService;
+import com.android.inputmethod.latin.spellcheck.SpellCheckerProximityInfo;
import java.util.ArrayList;
import java.util.Arrays;
@@ -119,19 +122,66 @@ public class WordComposer {
return previous && !Character.isUpperCase(codePoint);
}
+ // TODO: remove input keyDetector
+ public void add(int primaryCode, int x, int y, KeyDetector keyDetector) {
+ final int[] codes;
+ final int keyX;
+ final int keyY;
+ if (x == KeyboardActionListener.SPELL_CHECKER_COORDINATE
+ || y == KeyboardActionListener.SPELL_CHECKER_COORDINATE) {
+ // only used for tests in InputLogicTests
+ addKeyForSpellChecker(primaryCode, AndroidSpellCheckerService.SCRIPT_LATIN);
+ return;
+ } else if (x == KeyboardActionListener.SUGGESTION_STRIP_COORDINATE
+ || y == KeyboardActionListener.SUGGESTION_STRIP_COORDINATE
+ || x == KeyboardActionListener.NOT_A_TOUCH_COORDINATE
+ || y == KeyboardActionListener.NOT_A_TOUCH_COORDINATE) {
+ codes = new int[] { primaryCode };
+ keyX = x;
+ keyY = y;
+ } else {
+ codes = keyDetector.newCodeArray();
+ keyDetector.getKeyAndNearbyCodes(x, y, codes);
+ keyX = keyDetector.getTouchX(x);
+ keyY = keyDetector.getTouchX(y);
+ }
+ add(primaryCode, codes, keyX, keyY);
+ }
+
+ // TODO: remove this function
+ public void addKeyForSpellChecker(int primaryCode, int script) {
+ final int[] proximities;
+ final int proximityIndex =
+ SpellCheckerProximityInfo.getIndexOfCodeForScript(primaryCode, script);
+ if (-1 == proximityIndex) {
+ proximities = new int[] { primaryCode };
+ } else {
+ // TODO: an initial examination seems to reveal this is actually used
+ // read-only. It should be possible to compute the arrays statically once
+ // and skip doing a copy each time here.
+ proximities = Arrays.copyOfRange(
+ SpellCheckerProximityInfo.getProximityForScript(script),
+ proximityIndex,
+ proximityIndex + SpellCheckerProximityInfo.ROW_SIZE);
+ }
+ add(primaryCode, proximities,
+ KeyboardActionListener.NOT_A_TOUCH_COORDINATE,
+ KeyboardActionListener.NOT_A_TOUCH_COORDINATE);
+ }
+
/**
* Add a new keystroke, with codes[0] containing the pressed key's unicode and the rest of
* the array containing unicode for adjacent keys, sorted by reducing probability/proximity.
* @param codes the array of unicode values
*/
- public void add(int primaryCode, int[] codes, int x, int y) {
+ private void add(int primaryCode, int[] codes, int keyX, int keyY) {
final int newIndex = mCodes.size();
mTypedWord.appendCodePoint(primaryCode);
correctPrimaryJuxtapos(primaryCode, codes);
mCodes.add(codes);
if (newIndex < BinaryDictionary.MAX_WORD_LENGTH) {
- mXCoordinates[newIndex] = x;
- mYCoordinates[newIndex] = y;
+ mXCoordinates[newIndex] = keyX;
+ mYCoordinates[newIndex] = keyY;
}
mIsFirstCharCapitalized = isFirstCharCapitalized(
newIndex, primaryCode, mIsFirstCharCapitalized);
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
index 8ac82ee5b..755c75b2e 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
@@ -570,23 +570,7 @@ public class AndroidSpellCheckerService extends SpellCheckerService
final WordComposer composer = new WordComposer();
final int length = text.length();
for (int i = 0; i < length; i = text.offsetByCodePoints(i, 1)) {
- final int character = text.codePointAt(i);
- final int proximityIndex =
- SpellCheckerProximityInfo.getIndexOfCodeForScript(character, mScript);
- final int[] proximities;
- if (-1 == proximityIndex) {
- proximities = new int[] { character };
- } else {
- // TODO: an initial examination seems to reveal this is actually used
- // read-only. It should be possible to compute the arrays statically once
- // and skip doing a copy each time here.
- proximities = Arrays.copyOfRange(
- SpellCheckerProximityInfo.getProximityForScript(mScript),
- proximityIndex,
- proximityIndex + SpellCheckerProximityInfo.ROW_SIZE);
- }
- composer.add(character, proximities,
- WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE);
+ composer.addKeyForSpellChecker(text.codePointAt(i), mScript);
}
final int capitalizeType = getCapitalizationType(text);
diff --git a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java
index cd83c3e21..1f7214777 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java
@@ -66,7 +66,7 @@ public class MoreSuggestionsView extends KeyboardView implements MoreKeysPanel {
}
@Override
- public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y) {
+ public void onCodeInput(int primaryCode, int x, int y) {
final int index = primaryCode - MoreSuggestions.SUGGESTION_CODE_BASE;
if (index >= 0 && index < SuggestionsView.MAX_SUGGESTIONS) {
mListener.onCustomRequest(index);
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java
index d3362940f..075fb68ee 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java
@@ -137,7 +137,8 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener,
public final int mDividerWidth;
public final int mSuggestionsStripHeight;
public final int mSuggestionsCountInStrip;
- public final int mMaxMoreSuggestionsRow;
+ public final int mMoreSuggestionsRowHeight;
+ private int mMaxMoreSuggestionsRow;
public final float mMinMoreSuggestionsWidth;
public final int mMoreSuggestionsBottomGap;
@@ -225,12 +226,34 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener,
mCenterSuggestionIndex = mSuggestionsCountInStrip / 2;
mMoreSuggestionsBottomGap = res.getDimensionPixelOffset(
R.dimen.more_suggestions_bottom_gap);
+ mMoreSuggestionsRowHeight = res.getDimensionPixelSize(
+ R.dimen.more_suggestions_row_height);
final LayoutInflater inflater = LayoutInflater.from(context);
mWordToSaveView = (TextView)inflater.inflate(R.layout.suggestion_word, null);
mHintToSaveView = (TextView)inflater.inflate(R.layout.suggestion_word, null);
}
+ public int getMaxMoreSuggestionsRow() {
+ return mMaxMoreSuggestionsRow;
+ }
+
+ private int getMoreSuggestionsHeight() {
+ return mMaxMoreSuggestionsRow * mMoreSuggestionsRowHeight + mMoreSuggestionsBottomGap;
+ }
+
+ public int setMoreSuggestionsHeight(int remainingHeight) {
+ final int currentHeight = getMoreSuggestionsHeight();
+ if (currentHeight <= remainingHeight) {
+ return currentHeight;
+ }
+
+ mMaxMoreSuggestionsRow = (remainingHeight - mMoreSuggestionsBottomGap)
+ / mMoreSuggestionsRowHeight;
+ final int newHeight = getMoreSuggestionsHeight();
+ return newHeight;
+ }
+
private static Drawable getMoreSuggestionsHint(Resources res, float textSize, int color) {
final Paint paint = new Paint();
paint.setAntiAlias(true);
@@ -645,6 +668,9 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener,
mParams.layout(mSuggestedWords, mSuggestionsStrip, this, getWidth());
}
+ public int setMoreSuggestionsHeight(int remainingHeight) {
+ return mParams.setMoreSuggestionsHeight(remainingHeight);
+ }
public boolean isShowingAddToDictionaryHint() {
return mSuggestionsStrip.getChildCount() > 0
@@ -735,7 +761,7 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener,
final MoreSuggestions.Builder builder = mMoreSuggestionsBuilder;
builder.layout(mSuggestedWords, params.mSuggestionsCountInStrip, maxWidth,
(int)(maxWidth * params.mMinMoreSuggestionsWidth),
- params.mMaxMoreSuggestionsRow);
+ params.getMaxMoreSuggestionsRow());
mMoreSuggestionsView.setKeyboard(builder.build());
container.measure(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);