aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android')
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSet.java10
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java12
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardView.java49
-rw-r--r--java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java81
-rw-r--r--java/src/com/android/inputmethod/keyboard/PointerTracker.java53
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java15
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionary.java4
-rw-r--r--java/src/com/android/inputmethod/latin/Dictionary.java11
-rw-r--r--java/src/com/android/inputmethod/latin/ExpandableDictionary.java6
-rw-r--r--java/src/com/android/inputmethod/latin/LastComposedWord.java72
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java87
-rw-r--r--java/src/com/android/inputmethod/latin/LatinImeLogger.java3
-rw-r--r--java/src/com/android/inputmethod/latin/Settings.java2
-rw-r--r--java/src/com/android/inputmethod/latin/SettingsValues.java5
-rw-r--r--java/src/com/android/inputmethod/latin/Suggest.java12
-rw-r--r--java/src/com/android/inputmethod/latin/WordComposer.java169
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java3
17 files changed, 325 insertions, 269 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java
index cacb8a324..ae5e4e860 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java
@@ -244,9 +244,10 @@ public class KeyboardSet {
// TODO: Use InputMethodSubtype object as argument.
public Builder setSubtype(Locale inputLocale, boolean asciiCapable,
boolean touchPositionCorrectionEnabled) {
+ final boolean deprecatedForceAscii = Utils.inPrivateImeOptions(
+ mPackageName, LatinIME.IME_OPTION_FORCE_ASCII, mEditorInfo);
final boolean forceAscii = EditorInfoCompatUtils.hasFlagForceAscii(mParams.mImeOptions)
- || Utils.inPrivateImeOptions(
- mPackageName, LatinIME.IME_OPTION_FORCE_ASCII, mEditorInfo);
+ || deprecatedForceAscii;
mParams.mLocale = (forceAscii && !asciiCapable) ? Locale.US : inputLocale;
mParams.mTouchPositionCorrectionEnabled = touchPositionCorrectionEnabled;
return this;
@@ -256,10 +257,11 @@ public class KeyboardSet {
boolean voiceKeyOnMain) {
mParams.mSettingsKeyEnabled = settingsKeyEnabled;
@SuppressWarnings("deprecation")
+ final boolean deprecatedNoMicrophone = Utils.inPrivateImeOptions(
+ null, LatinIME.IME_OPTION_NO_MICROPHONE_COMPAT, mEditorInfo);
final boolean noMicrophone = Utils.inPrivateImeOptions(
mPackageName, LatinIME.IME_OPTION_NO_MICROPHONE, mEditorInfo)
- || Utils.inPrivateImeOptions(
- null, LatinIME.IME_OPTION_NO_MICROPHONE_COMPAT, mEditorInfo);
+ || deprecatedNoMicrophone;
mParams.mVoiceKeyEnabled = voiceKeyEnabled && !noMicrophone;
mParams.mVoiceKeyOnMain = voiceKeyOnMain;
return this;
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 1398bae2a..5a59cc1c7 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -240,6 +240,7 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions,
private static final int ALPHABET_MANUAL_SHIFTED = 1;
private static final int ALPHABET_AUTOMATIC_SHIFTED = 2;
private static final int ALPHABET_SHIFT_LOCKED = 3;
+ private static final int ALPHABET_SHIFT_LOCK_SHIFTED = 4;
// TODO: Remove this method.
private void updateAlphabetKeyboardShiftState(int shiftMode) {
@@ -260,6 +261,10 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions,
case ALPHABET_SHIFT_LOCKED:
keyboard.setShiftLocked(true);
break;
+ case ALPHABET_SHIFT_LOCK_SHIFTED:
+ keyboard.setShiftLocked(true);
+ keyboard.setShifted(true);
+ break;
}
mKeyboardView.invalidateAllKeys();
if (shiftMode != ALPHABET_SHIFT_LOCKED) {
@@ -300,6 +305,13 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions,
// Implements {@link KeyboardState.SwitchActions}.
@Override
+ public void setAlphabetShiftLockShiftedKeyboard() {
+ setKeyboard(mKeyboardSet.getMainKeyboard());
+ updateAlphabetKeyboardShiftState(ALPHABET_SHIFT_LOCK_SHIFTED);
+ }
+
+ // Implements {@link KeyboardState.SwitchActions}.
+ @Override
public void setSymbolsKeyboard() {
setKeyboard(mKeyboardSet.getSymbolsKeyboard());
}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index afcf51059..6f4ef2580 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -17,7 +17,6 @@
package com.android.inputmethod.keyboard;
import android.content.Context;
-import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
@@ -39,7 +38,6 @@ import android.widget.RelativeLayout;
import android.widget.TextView;
import com.android.inputmethod.compat.FrameLayoutCompatUtils;
-import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
@@ -103,7 +101,6 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
private final int mKeyPreviewLayoutId;
protected final KeyPreviewDrawParams mKeyPreviewDrawParams;
private boolean mShowKeyPreviewPopup = true;
- private final int mDelayBeforePreview;
private int mDelayAfterPreview;
private ViewGroup mPreviewPlacer;
@@ -135,8 +132,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
private final DrawingHandler mDrawingHandler = new DrawingHandler(this);
public static class DrawingHandler extends StaticInnerHandlerWrapper<KeyboardView> {
- private static final int MSG_SHOW_KEY_PREVIEW = 1;
- private static final int MSG_DISMISS_KEY_PREVIEW = 2;
+ private static final int MSG_DISMISS_KEY_PREVIEW = 1;
public DrawingHandler(KeyboardView outerInstance) {
super(outerInstance);
@@ -148,35 +144,12 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
if (keyboardView == null) return;
final PointerTracker tracker = (PointerTracker) msg.obj;
switch (msg.what) {
- case MSG_SHOW_KEY_PREVIEW:
- keyboardView.showKey(tracker);
- break;
case MSG_DISMISS_KEY_PREVIEW:
tracker.getKeyPreviewText().setVisibility(View.INVISIBLE);
break;
}
}
- public void showKeyPreview(long delay, PointerTracker tracker) {
- removeMessages(MSG_SHOW_KEY_PREVIEW);
- final KeyboardView keyboardView = getOuterInstance();
- if (keyboardView == null) return;
- if (tracker.getKeyPreviewText().getVisibility() == VISIBLE || delay == 0) {
- // Show right away, if it's already visible and finger is moving around
- keyboardView.showKey(tracker);
- } else {
- sendMessageDelayed(obtainMessage(MSG_SHOW_KEY_PREVIEW, tracker), delay);
- }
- }
-
- public void cancelShowKeyPreview(PointerTracker tracker) {
- removeMessages(MSG_SHOW_KEY_PREVIEW, tracker);
- }
-
- public void cancelAllShowKeyPreviews() {
- removeMessages(MSG_SHOW_KEY_PREVIEW);
- }
-
public void dismissKeyPreview(long delay, PointerTracker tracker) {
sendMessageDelayed(obtainMessage(MSG_DISMISS_KEY_PREVIEW, tracker), delay);
}
@@ -190,7 +163,6 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
}
public void cancelAllMessages() {
- cancelAllShowKeyPreviews();
cancelAllDismissKeyPreviews();
}
}
@@ -295,6 +267,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
public final int mPreviewOffset;
public final int mPreviewHeight;
public final Typeface mKeyTextStyle;
+ public final int mLingerTimeout;
private final float mPreviewTextRatio;
private final float mKeyLetterRatio;
@@ -324,6 +297,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
R.styleable.KeyboardView_keyPreviewHeight, 80);
mPreviewTextRatio = getRatio(a, R.styleable.KeyboardView_keyPreviewTextRatio);
mPreviewTextColor = a.getColor(R.styleable.KeyboardView_keyPreviewTextColor, 0);
+ mLingerTimeout = a.getInt(R.styleable.KeyboardView_keyPreviewLingerTimeout, 0);
mKeyLetterRatio = keyDrawParams.mKeyLetterRatio;
mKeyTextStyle = keyDrawParams.mKeyTextStyle;
@@ -363,10 +337,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
mBackgroundDimAmount = a.getFloat(R.styleable.KeyboardView_backgroundDimAmount, 0.5f);
a.recycle();
- final Resources res = getResources();
-
- mDelayBeforePreview = res.getInteger(R.integer.config_delay_before_preview);
- mDelayAfterPreview = res.getInteger(R.integer.config_delay_after_preview);
+ mDelayAfterPreview = mKeyPreviewDrawParams.mLingerTimeout;
mPaint.setAntiAlias(true);
mPaint.setTextAlign(Align.CENTER);
@@ -386,8 +357,8 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
* @param keyboard the keyboard to display in this view
*/
public void setKeyboard(Keyboard keyboard) {
- // Remove any pending dismissing preview
- mDrawingHandler.cancelAllShowKeyPreviews();
+ // Remove any pending messages.
+ mDrawingHandler.cancelAllMessages();
if (mKeyboard != null) {
PointerTracker.dismissAllKeyPreviews();
}
@@ -841,18 +812,12 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
@Override
public void showKeyPreview(PointerTracker tracker) {
if (mShowKeyPreviewPopup) {
- mDrawingHandler.showKeyPreview(mDelayBeforePreview, tracker);
+ showKey(tracker);
}
}
@Override
- public void cancelShowKeyPreview(PointerTracker tracker) {
- mDrawingHandler.cancelShowKeyPreview(tracker);
- }
-
- @Override
public void dismissKeyPreview(PointerTracker tracker) {
- mDrawingHandler.cancelShowKeyPreview(tracker);
mDrawingHandler.dismissKeyPreview(mDelayAfterPreview, tracker);
}
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
index f5b282df3..aee356a0c 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
@@ -18,7 +18,6 @@ package com.android.inputmethod.keyboard;
import android.content.Context;
import android.content.pm.PackageManager;
-import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
@@ -103,6 +102,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
new WeakHashMap<Key, MoreKeysPanel>();
private final boolean mConfigShowMiniKeyboardAtTouchedPoint;
+ private final PointerTrackerParams mPointerTrackerParams;
private final boolean mIsSpacebarTriggeringPopupByLongPress;
private final SuddenJumpingTouchEventHandler mTouchScreenRegulator;
@@ -114,7 +114,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
// To detect double tap.
protected GestureDetector mGestureDetector;
- private final KeyTimerHandler mKeyTimerHandler = new KeyTimerHandler(this);
+ private final KeyTimerHandler mKeyTimerHandler;
private static class KeyTimerHandler extends StaticInnerHandlerWrapper<LatinKeyboardView>
implements TimerProxy {
@@ -126,11 +126,9 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
private final int mKeyRepeatInterval;
private boolean mInKeyRepeat;
- public KeyTimerHandler(LatinKeyboardView outerInstance) {
+ public KeyTimerHandler(LatinKeyboardView outerInstance, int keyRepeatInterval) {
super(outerInstance);
- // TODO: This should be the attribute of LatinKeyboardView.
- final Resources res = outerInstance.getContext().getResources();
- mKeyRepeatInterval = res.getInteger(R.integer.config_key_repeat_interval);
+ mKeyRepeatInterval = keyRepeatInterval;
}
@Override
@@ -253,6 +251,49 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
}
}
+ public static class PointerTrackerParams {
+ public final boolean mSlidingKeyInputEnabled;
+ public final int mKeyRepeatStartTimeout;
+ public final int mLongPressKeyTimeout;
+ public final int mLongPressShiftKeyTimeout;
+ public final int mLongPressSpaceKeyTimeout;
+ public final int mIgnoreSpecialKeyTimeout;
+ public final int mTouchNoiseThresholdTime;
+ public final float mTouchNoiseThresholdDistance;
+
+ public static final PointerTrackerParams DEFAULT = new PointerTrackerParams();
+
+ private PointerTrackerParams() {
+ mSlidingKeyInputEnabled = false;
+ mKeyRepeatStartTimeout = 0;
+ mLongPressKeyTimeout = 0;
+ mLongPressShiftKeyTimeout = 0;
+ mLongPressSpaceKeyTimeout = 0;
+ mIgnoreSpecialKeyTimeout = 0;
+ mTouchNoiseThresholdTime =0;
+ mTouchNoiseThresholdDistance = 0;
+ }
+
+ public PointerTrackerParams(TypedArray latinKeyboardViewAttr) {
+ mSlidingKeyInputEnabled = latinKeyboardViewAttr.getBoolean(
+ R.styleable.LatinKeyboardView_slidingKeyInputEnable, false);
+ mKeyRepeatStartTimeout = latinKeyboardViewAttr.getInt(
+ R.styleable.LatinKeyboardView_keyRepeatStartTimeout, 0);
+ mLongPressKeyTimeout = latinKeyboardViewAttr.getInt(
+ R.styleable.LatinKeyboardView_longPressKeyTimeout, 0);
+ mLongPressShiftKeyTimeout = latinKeyboardViewAttr.getInt(
+ R.styleable.LatinKeyboardView_longPressShiftKeyTimeout, 0);
+ mLongPressSpaceKeyTimeout = latinKeyboardViewAttr.getInt(
+ R.styleable.LatinKeyboardView_longPressSpaceKeyTimeout, 0);
+ mIgnoreSpecialKeyTimeout = latinKeyboardViewAttr.getInt(
+ R.styleable.LatinKeyboardView_ignoreSpecialKeyTimeout, 0);
+ mTouchNoiseThresholdTime = latinKeyboardViewAttr.getInt(
+ R.styleable.LatinKeyboardView_touchNoiseThresholdTime, 0);
+ mTouchNoiseThresholdDistance = latinKeyboardViewAttr.getDimension(
+ R.styleable.LatinKeyboardView_touchNoiseThresholdDistance, 0);
+ }
+ }
+
public LatinKeyboardView(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.latinKeyboardViewStyle);
}
@@ -262,14 +303,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
mTouchScreenRegulator = new SuddenJumpingTouchEventHandler(getContext(), this);
- final Resources res = getResources();
- // TODO: This should be the attribute of LatinKeyboardView.
- mConfigShowMiniKeyboardAtTouchedPoint = res.getBoolean(
- R.bool.config_show_mini_keyboard_at_touched_point);
- // TODO: This should be the attribute of LatinKeyboardView.
- final float keyHysteresisDistance = res.getDimension(R.dimen.key_hysteresis_distance);
- mKeyDetector = new KeyDetector(keyHysteresisDistance);
-
final boolean ignoreMultitouch = true;
mGestureDetector = new GestureDetector(
getContext(), new DoubleTapListener(), null, ignoreMultitouch);
@@ -280,11 +313,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
PointerTracker.init(mHasDistinctMultitouch, getContext());
- // TODO: This should be the attribute of LatinKeyboardView.
- final int longPressSpaceKeyTimeout =
- res.getInteger(R.integer.config_long_press_space_key_timeout);
- mIsSpacebarTriggeringPopupByLongPress = (longPressSpaceKeyTimeout > 0);
-
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.LatinKeyboardView, defStyle, R.style.LatinKeyboardView);
mAutoCorrectionSpacebarLedEnabled = a.getBoolean(
@@ -296,7 +324,22 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
mSpacebarTextColor = a.getColor(R.styleable.LatinKeyboardView_spacebarTextColor, 0);
mSpacebarTextShadowColor = a.getColor(
R.styleable.LatinKeyboardView_spacebarTextShadowColor, 0);
+
+ mPointerTrackerParams = new PointerTrackerParams(a);
+ mIsSpacebarTriggeringPopupByLongPress = (
+ mPointerTrackerParams.mLongPressSpaceKeyTimeout > 0);
+
+ final float keyHysteresisDistance = a.getDimension(
+ R.styleable.LatinKeyboardView_keyHysteresisDistance, 0);
+ mKeyDetector = new KeyDetector(keyHysteresisDistance);
+ final int keyRepeatInterval = a.getInt(
+ R.styleable.LatinKeyboardView_keyRepeatInterval, 0);
+ mKeyTimerHandler = new KeyTimerHandler(this, keyRepeatInterval);
+ mConfigShowMiniKeyboardAtTouchedPoint = a.getBoolean(
+ R.styleable.LatinKeyboardView_showMiniKeyboardAtTouchedPoint, false);
a.recycle();
+
+ PointerTracker.setParameters(mPointerTrackerParams);
}
public void startIgnoringDoubleTap() {
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index 274bd0b31..a75b8f9e6 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -17,7 +17,6 @@
package com.android.inputmethod.keyboard;
import android.content.Context;
-import android.content.res.Resources;
import android.os.SystemClock;
import android.util.Log;
import android.view.MotionEvent;
@@ -25,7 +24,6 @@ import android.widget.TextView;
import com.android.inputmethod.keyboard.internal.PointerTrackerQueue;
import com.android.inputmethod.latin.LatinImeLogger;
-import com.android.inputmethod.latin.R;
import java.util.ArrayList;
import java.util.List;
@@ -69,7 +67,6 @@ public class PointerTracker {
public void invalidateKey(Key key);
public TextView inflateKeyPreviewText();
public void showKeyPreview(PointerTracker tracker);
- public void cancelShowKeyPreview(PointerTracker tracker);
public void dismissKeyPreview(PointerTracker tracker);
}
@@ -98,14 +95,8 @@ public class PointerTracker {
}
private static KeyboardSwitcher sKeyboardSwitcher;
- private static boolean sConfigSlidingKeyInputEnabled;
- // Timing constants
- private static int sDelayBeforeKeyRepeatStart;
- private static int sLongPressKeyTimeout;
- private static int sLongPressShiftKeyTimeout;
- private static int sLongPressSpaceKeyTimeout;
- private static int sIgnoreSpecialKeyTimeout;
- private static int sTouchNoiseThresholdMillis;
+ // Parameters for pointer handling.
+ private static LatinKeyboardView.PointerTrackerParams sParams;
private static int sTouchNoiseThresholdDistanceSquared;
private static final List<PointerTracker> sTrackers = new ArrayList<PointerTracker>();
@@ -169,20 +160,14 @@ public class PointerTracker {
sPointerTrackerQueue = null;
}
- final Resources res = context.getResources();
- sConfigSlidingKeyInputEnabled = res.getBoolean(R.bool.config_sliding_key_input_enabled);
- sDelayBeforeKeyRepeatStart = res.getInteger(R.integer.config_delay_before_key_repeat_start);
- sLongPressKeyTimeout = res.getInteger(R.integer.config_long_press_key_timeout);
- sLongPressShiftKeyTimeout = res.getInteger(R.integer.config_long_press_shift_key_timeout);
- sLongPressSpaceKeyTimeout = res.getInteger(R.integer.config_long_press_space_key_timeout);
- sIgnoreSpecialKeyTimeout = res.getInteger(R.integer.config_ignore_special_key_timeout);
- sTouchNoiseThresholdMillis = res.getInteger(R.integer.config_touch_noise_threshold_millis);
+ setParameters(LatinKeyboardView.PointerTrackerParams.DEFAULT);
+ sKeyboardSwitcher = KeyboardSwitcher.getInstance();
+ }
- final float touchNoiseThresholdDistance = res.getDimension(
- R.dimen.config_touch_noise_threshold_distance);
+ public static void setParameters(LatinKeyboardView.PointerTrackerParams params) {
+ sParams = params;
sTouchNoiseThresholdDistanceSquared = (int)(
- touchNoiseThresholdDistance * touchNoiseThresholdDistance);
- sKeyboardSwitcher = KeyboardSwitcher.getInstance();
+ params.mTouchNoiseThresholdDistance * params.mTouchNoiseThresholdDistance);
}
public static PointerTracker getPointerTracker(final int id, KeyEventHandler handler) {
@@ -278,7 +263,7 @@ public class PointerTracker {
mListener.onCodeInput(code, keyCodes, x, y);
}
if (!key.altCodeWhileTyping() && !key.isModifier()) {
- mTimerProxy.startKeyTypedTimer(sIgnoreSpecialKeyTimeout);
+ mTimerProxy.startKeyTypedTimer(sParams.mIgnoreSpecialKeyTimeout);
}
}
}
@@ -453,7 +438,7 @@ public class PointerTracker {
setKeyDetectorInner(handler.getKeyDetector());
// Naive up-to-down noise filter.
final long deltaT = eventTime - mUpTime;
- if (deltaT < sTouchNoiseThresholdMillis) {
+ if (deltaT < sParams.mTouchNoiseThresholdTime) {
final int dx = x - mLastX;
final int dy = y - mLastY;
final int distanceSquared = (dx * dx + dy * dy);
@@ -483,7 +468,7 @@ public class PointerTracker {
Key key = onDownKey(x, y, eventTime);
// Sliding key is allowed when 1) enabled by configuration, 2) this pointer starts sliding
// from modifier key, or 3) this pointer's KeyDetector always allows sliding input.
- mIsAllowedSlidingKeyInput = sConfigSlidingKeyInputEnabled
+ mIsAllowedSlidingKeyInput = sParams.mSlidingKeyInputEnabled
|| (key != null && key.isModifier())
|| mKeyDetector.alwaysAllowsSlidingInput();
mKeyboardLayoutHasBeenChanged = false;
@@ -620,7 +605,6 @@ public class PointerTracker {
private void onUpEventInternal(int x, int y, long eventTime) {
mTimerProxy.cancelKeyTimers();
- mDrawingProxy.cancelShowKeyPreview(this);
mIsInSlidingKeyInput = false;
final int keyX, keyY;
if (isMajorEnoughMoveToBeOnNewKey(x, y, onMoveKey(x, y))) {
@@ -673,7 +657,6 @@ public class PointerTracker {
private void onCancelEventInternal() {
mTimerProxy.cancelKeyTimers();
- mDrawingProxy.cancelShowKeyPreview(this);
setReleasedKeyGraphics(mCurrentKey);
mIsInSlidingKeyInput = false;
if (mIsShowingMoreKeysPanel) {
@@ -685,7 +668,7 @@ public class PointerTracker {
private void startRepeatKey(Key key) {
if (key != null && key.isRepeatable()) {
onRepeatKey(key);
- mTimerProxy.startKeyRepeatTimer(sDelayBeforeKeyRepeatStart, this);
+ mTimerProxy.startKeyRepeatTimer(sParams.mKeyRepeatStartTimeout, this);
mIsRepeatableKey = true;
} else {
mIsRepeatableKey = false;
@@ -715,12 +698,12 @@ public class PointerTracker {
private void startLongPressTimer(Key key) {
if (key == null) return;
if (key.mCode == Keyboard.CODE_SHIFT) {
- if (sLongPressShiftKeyTimeout > 0) {
- mTimerProxy.startLongPressTimer(sLongPressShiftKeyTimeout, this);
+ if (sParams.mLongPressShiftKeyTimeout > 0) {
+ mTimerProxy.startLongPressTimer(sParams.mLongPressShiftKeyTimeout, this);
}
} else if (key.mCode == Keyboard.CODE_SPACE) {
- if (sLongPressSpaceKeyTimeout > 0) {
- mTimerProxy.startLongPressTimer(sLongPressSpaceKeyTimeout, this);
+ if (sParams.mLongPressSpaceKeyTimeout > 0) {
+ mTimerProxy.startLongPressTimer(sParams.mLongPressSpaceKeyTimeout, this);
}
} else if (key.hasUppercaseLetter() && mKeyboard.isManualTemporaryUpperCase()) {
// We need not start long press timer on the key which has manual temporary upper case
@@ -728,9 +711,9 @@ public class PointerTracker {
return;
} else if (sKeyboardSwitcher.isInMomentarySwitchState()) {
// We use longer timeout for sliding finger input started from the symbols mode key.
- mTimerProxy.startLongPressTimer(sLongPressKeyTimeout * 3, this);
+ mTimerProxy.startLongPressTimer(sParams.mLongPressKeyTimeout * 3, this);
} else {
- mTimerProxy.startLongPressTimer(sLongPressKeyTimeout, this);
+ mTimerProxy.startLongPressTimer(sParams.mLongPressKeyTimeout, this);
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
index 38c31adce..a89356c50 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
@@ -43,8 +43,7 @@ public class KeyboardState {
public void setAlphabetManualShiftedKeyboard();
public void setAlphabetAutomaticShiftedKeyboard();
public void setAlphabetShiftLockedKeyboard();
- // TODO: Add this.
- //public void setAlphabetShiftLockShiftedKeyboard();
+ public void setAlphabetShiftLockShiftedKeyboard();
public void setSymbolsKeyboard();
public void setSymbolsShiftedKeyboard();
@@ -157,14 +156,10 @@ public class KeyboardState {
}
}
- // TODO: Remove this method.
- public boolean isShiftLocked() {
- return mAlphabetShiftState.isShiftLocked();
- }
-
private static final int UNSHIFT = 0;
private static final int MANUAL_SHIFT = 1;
private static final int AUTOMATIC_SHIFT = 2;
+ private static final int SHIFT_LOCK_SHIFTED = 3;
private void setShifted(int shiftMode) {
if (DEBUG_ACTION) {
@@ -198,6 +193,10 @@ public class KeyboardState {
mSwitchActions.setAlphabetKeyboard();
}
break;
+ case SHIFT_LOCK_SHIFTED:
+ mAlphabetShiftState.setShifted(true);
+ mSwitchActions.setAlphabetShiftLockShiftedKeyboard();
+ break;
}
}
@@ -349,7 +348,7 @@ public class KeyboardState {
if (mAlphabetShiftState.isShiftLocked()) {
// Shift key is pressed while caps lock state, we will treat this state as shifted
// caps lock state and mark as if shift key pressed while normal state.
- setShifted(MANUAL_SHIFT);
+ setShifted(SHIFT_LOCK_SHIFTED);
mShiftKeyState.onPress();
} else if (mAlphabetShiftState.isAutomaticTemporaryUpperCase()) {
// Shift key is pressed while automatic temporary upper case, we have to move to
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index 3692ac179..b82400046 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -162,7 +162,7 @@ public class BinaryDictionary extends Dictionary {
}
if (len > 0) {
callback.addWord(mOutputChars_bigrams, start, len, mBigramScores[j],
- mDicTypeId, DataType.BIGRAM);
+ mDicTypeId, Dictionary.BIGRAM);
}
}
}
@@ -182,7 +182,7 @@ public class BinaryDictionary extends Dictionary {
}
if (len > 0) {
callback.addWord(mOutputChars, start, len, mScores[j], mDicTypeId,
- DataType.UNIGRAM);
+ Dictionary.UNIGRAM);
}
}
}
diff --git a/java/src/com/android/inputmethod/latin/Dictionary.java b/java/src/com/android/inputmethod/latin/Dictionary.java
index c35b42877..79bf33850 100644
--- a/java/src/com/android/inputmethod/latin/Dictionary.java
+++ b/java/src/com/android/inputmethod/latin/Dictionary.java
@@ -33,9 +33,8 @@ public abstract class Dictionary {
*/
protected static final int FULL_WORD_SCORE_MULTIPLIER = 2;
- public static enum DataType {
- UNIGRAM, BIGRAM
- }
+ public static final int UNIGRAM = 0;
+ public static final int BIGRAM = 1;
/**
* Interface to be implemented by classes requesting words to be fetched from the dictionary.
@@ -51,11 +50,11 @@ public abstract class Dictionary {
* @param score the score of occurrence. This is normalized between 1 and 255, but
* can exceed those limits
* @param dicTypeId of the dictionary where word was from
- * @param dataType tells type of this data
+ * @param dataType tells type of this data, either UNIGRAM or BIGRAM
* @return true if the word was added, false if no more words are required
*/
boolean addWord(char[] word, int wordOffset, int wordLength, int score, int dicTypeId,
- DataType dataType);
+ int dataType);
}
/**
@@ -64,7 +63,7 @@ public abstract class Dictionary {
* @param composer the key sequence to match
* @param callback the callback object to send matched words to as possible candidates
* @param proximityInfo the object for key proximity. May be ignored by some implementations.
- * @see WordCallback#addWord(char[], int, int, int, int, DataType)
+ * @see WordCallback#addWord(char[], int, int, int, int, int)
*/
abstract public void getWords(final WordComposer composer, final WordCallback callback,
final ProximityInfo proximityInfo);
diff --git a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
index 7eec8e2ca..8e8adc1c2 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
@@ -301,7 +301,7 @@ public class ExpandableDictionary extends Dictionary {
finalFreq = computeSkippedWordFinalFreq(freq, snr, mInputLength);
}
if (!callback.addWord(word, 0, depth + 1, finalFreq, mDicTypeId,
- DataType.UNIGRAM)) {
+ Dictionary.UNIGRAM)) {
return;
}
}
@@ -342,7 +342,7 @@ public class ExpandableDictionary extends Dictionary {
snr * addedAttenuation, mInputLength);
}
callback.addWord(word, 0, depth + 1, finalFreq, mDicTypeId,
- DataType.UNIGRAM);
+ Dictionary.UNIGRAM);
}
}
if (children != null) {
@@ -506,7 +506,7 @@ public class ExpandableDictionary extends Dictionary {
} while (node != null);
callback.addWord(mLookedUpString, index, MAX_WORD_LENGTH - index, freq, mDicTypeId,
- DataType.BIGRAM);
+ Dictionary.BIGRAM);
}
}
diff --git a/java/src/com/android/inputmethod/latin/LastComposedWord.java b/java/src/com/android/inputmethod/latin/LastComposedWord.java
new file mode 100644
index 000000000..0c8c88f50
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/LastComposedWord.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.android.inputmethod.latin;
+
+import android.text.TextUtils;
+
+import java.util.ArrayList;
+
+/**
+ * This class encapsulates data about a word previously composed, but that has been
+ * committed already. This is used for resuming suggestion, and cancel auto-correction.
+ */
+public class LastComposedWord {
+ // COMMIT_TYPE_USER_TYPED_WORD is used when the word committed is the exact typed word, with
+ // no hinting from the IME. It happens when some external event happens (rotating the device,
+ // for example) or when auto-correction is off by settings or editor attributes.
+ public static final int COMMIT_TYPE_USER_TYPED_WORD = 0;
+ // COMMIT_TYPE_MANUAL_PICK is used when the user pressed a field in the suggestion strip.
+ public static final int COMMIT_TYPE_MANUAL_PICK = 1;
+ // COMMIT_TYPE_DECIDED_WORD is used when the IME commits the word it decided was best
+ // for the current user input. It may be different from what the user typed (true auto-correct)
+ // or it may be exactly what the user typed if it's in the dictionary or the IME does not have
+ // enough confidence in any suggestion to auto-correct (auto-correct to typed word).
+ public static final int COMMIT_TYPE_DECIDED_WORD = 2;
+ // COMMIT_TYPE_CANCEL_AUTO_CORRECT is used upon committing back the old word upon cancelling
+ // an auto-correction.
+ public static final int COMMIT_TYPE_CANCEL_AUTO_CORRECT = 3;
+
+ public final ArrayList<int[]> mCodes;
+ public final int[] mXCoordinates;
+ public final int[] mYCoordinates;
+ public final String mTypedWord;
+ public final String mAutoCorrection;
+
+ private boolean mActive;
+
+ public static final LastComposedWord NOT_A_COMPOSED_WORD =
+ new LastComposedWord(null, null, null, "", "");
+
+ public LastComposedWord(final ArrayList<int[]> codes, final int[] xCoordinates,
+ final int[] yCoordinates, final String typedWord, final String autoCorrection) {
+ mCodes = codes;
+ mXCoordinates = xCoordinates;
+ mYCoordinates = yCoordinates;
+ mTypedWord = typedWord;
+ mAutoCorrection = autoCorrection;
+ mActive = true;
+ }
+
+ public void deactivate() {
+ mActive = false;
+ }
+
+ public boolean canCancelAutoCorrect() {
+ return mActive && !TextUtils.isEmpty(mAutoCorrection)
+ && !TextUtils.equals(mTypedWord, mAutoCorrection);
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index d59497d6a..2e7e82637 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -104,7 +104,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
*/
public static final String IME_OPTION_NO_SETTINGS_KEY = "noSettingsKey";
- // TODO: Remove this private option.
/**
* The private IME option used to indicate that the given text field needs
* ASCII code points input.
@@ -200,6 +199,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
private UserUnigramDictionary mUserUnigramDictionary;
private boolean mIsUserDictionaryAvailable;
+ private LastComposedWord mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
private WordComposer mWordComposer = new WordComposer();
private int mCorrectionMode;
@@ -729,6 +729,17 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
: 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: "
+ + editorInfo.privateImeOptions);
+ Log.w(TAG, "Use " + getPackageName() + "." + IME_OPTION_NO_MICROPHONE + " instead");
+ }
+ if (Utils.inPrivateImeOptions(getPackageName(), IME_OPTION_FORCE_ASCII, editorInfo)) {
+ Log.w(TAG, "Deprecated private IME option specified: "
+ + editorInfo.privateImeOptions);
+ Log.w(TAG, "Use EditorInfo.IME_FLAG_FORCE_ASCII flag instead");
+ }
+
LatinImeLogger.onStartInputView(editorInfo);
// In landscape mode, this method gets called without the input view being created.
if (inputView == null) {
@@ -759,7 +770,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
inputView.closing();
mEnteredText = null;
- mWordComposer.reset();
+ resetComposingState(true /* alsoResetLastComposedWord */);
mDeleteCount = 0;
mSpaceState = SPACE_STATE_NONE;
@@ -871,7 +882,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
if (((mWordComposer.isComposingWord())
|| mVoiceProxy.isVoiceInputHighlighted())
&& (selectionChanged || candidatesCleared)) {
- mWordComposer.reset();
+ resetComposingState(true /* alsoResetLastComposedWord */);
updateSuggestions();
final InputConnection ic = getCurrentInputConnection();
if (ic != null) {
@@ -880,7 +891,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mComposingStateManager.onFinishComposingText();
mVoiceProxy.setVoiceInputHighlighted(false);
} else if (!mWordComposer.isComposingWord()) {
- mWordComposer.reset();
+ // TODO: is the following reset still needed, given that we are not composing
+ // a word?
+ resetComposingState(true /* alsoResetLastComposedWord */);
updateSuggestions();
}
}
@@ -964,7 +977,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
.setHasMinimalSuggestion(false);
// When in fullscreen mode, show completions generated by the application
setSuggestions(builder.build());
- mWordComposer.deleteAutoCorrection();
+ // TODO: is this the right thing to do? What should we auto-correct to in
+ // this case? This says to keep whatever the user typed.
+ mWordComposer.setAutoCorrection(mWordComposer.getTypedWord());
setSuggestionStripShown(true);
}
}
@@ -1083,10 +1098,16 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
return super.onKeyUp(keyCode, event);
}
+ private void resetComposingState(final boolean alsoResetLastComposedWord) {
+ mWordComposer.reset();
+ if (alsoResetLastComposedWord)
+ mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
+ }
+
public void commitTyped(final InputConnection ic) {
if (!mWordComposer.isComposingWord()) return;
final CharSequence typedWord = mWordComposer.getTypedWord();
- mWordComposer.onCommitWord(WordComposer.COMMIT_TYPE_USER_TYPED_WORD);
+ mLastComposedWord = mWordComposer.commitWord(LastComposedWord.COMMIT_TYPE_USER_TYPED_WORD);
if (typedWord.length() > 0) {
if (ic != null) {
ic.commitText(typedWord, 1);
@@ -1253,6 +1274,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mHandler.cancelDoubleSpacesTimer();
}
+ boolean didAutoCorrect = false;
switch (primaryCode) {
case Keyboard.CODE_DELETE:
mSpaceState = SPACE_STATE_NONE;
@@ -1289,7 +1311,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
default:
mSpaceState = SPACE_STATE_NONE;
if (mSettingsValues.isWordSeparator(primaryCode)) {
- handleSeparator(primaryCode, x, y, spaceState);
+ didAutoCorrect = handleSeparator(primaryCode, x, y, spaceState);
} else {
handleCharacter(primaryCode, keyCodes, x, y, spaceState);
}
@@ -1298,6 +1320,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
switcher.onCodeInput(primaryCode);
// Reset after any single keystroke
+ if (!didAutoCorrect)
+ mLastComposedWord.deactivate();
mEnteredText = null;
}
@@ -1315,7 +1339,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mKeyboardSwitcher.onCodeInput(Keyboard.CODE_OUTPUT_TEXT);
mSpaceState = SPACE_STATE_NONE;
mEnteredText = text;
- mWordComposer.reset();
+ resetComposingState(true /* alsoResetLastComposedWord */);
}
@Override
@@ -1373,7 +1397,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// resuming here. The behavior needs to be different according to text field types,
// and it would be much clearer to test for them explicitly here rather than
// relying on implicit values like "whether the suggestion strip is displayed".
- if (mWordComposer.didAutoCorrectToAnotherWord()) {
+ if (mLastComposedWord.canCancelAutoCorrect()) {
Utils.Stats.onAutoCorrectionCancellation();
cancelAutoCorrect(ic);
return;
@@ -1485,7 +1509,11 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// separator and it should be treated as a normal character, except in the first
// position where it should not start composing a word.
isComposingWord = (Keyboard.CODE_SINGLE_QUOTE != code);
- mWordComposer.reset();
+ // Here we don't need to reset the last composed word. It will be reset
+ // when we commit this one, if we ever do; if on the other hand we backspace
+ // it entirely and resume suggestions on the previous word, we'd like to still
+ // have touch coordinates for it.
+ resetComposingState(false /* alsoResetLastComposedWord */);
clearSuggestions();
mComposingStateManager.onFinishComposingText();
}
@@ -1537,7 +1565,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
}
- private void handleSeparator(final int primaryCode, final int x, final int y,
+ // Returns true if we did an autocorrection, false otherwise.
+ private boolean handleSeparator(final int primaryCode, final int x, final int y,
final int spaceState) {
mVoiceProxy.handleSeparator();
mComposingStateManager.onFinishComposingText();
@@ -1548,6 +1577,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mHandler.postUpdateSuggestions();
}
+ boolean didAutoCorrect = false;
// Handle separator
final InputConnection ic = getCurrentInputConnection();
if (ic != null) {
@@ -1562,6 +1592,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
&& !mInputAttributes.mInputTypeNoAutoCorrect;
if (shouldAutoCorrect && primaryCode != Keyboard.CODE_SINGLE_QUOTE) {
commitCurrentAutoCorrection(primaryCode, ic);
+ didAutoCorrect = true;
} else {
commitTyped(ic);
}
@@ -1617,12 +1648,13 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
if (ic != null) {
ic.endBatchEdit();
}
+ return didAutoCorrect;
}
private CharSequence getTextWithUnderline(final CharSequence text) {
return mComposingStateManager.isAutoCorrectionIndicatorOn()
? SuggestionSpanUtils.getTextWithAutoCorrectionIndicatorUnderline(this, text)
- : mWordComposer.getTypedWord();
+ : text;
}
private void handleClose() {
@@ -1837,7 +1869,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
Utils.Stats.onAutoCorrection(typedWord, autoCorrection.toString(), separatorCodePoint);
mExpectingUpdateSelection = true;
- commitChosenWord(autoCorrection, WordComposer.COMMIT_TYPE_DECIDED_WORD);
+ commitChosenWord(autoCorrection, LastComposedWord.COMMIT_TYPE_DECIDED_WORD);
// Add the word to the user unigram dictionary if it's not a known word
addToUserUnigramAndBigramDictionaries(autoCorrection,
UserUnigramDictionary.FREQUENCY_FOR_TYPED);
@@ -1907,7 +1939,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
LatinImeLogger.logOnManualSuggestion(mWordComposer.getTypedWord().toString(),
suggestion.toString(), index, suggestions.mWords);
mExpectingUpdateSelection = true;
- commitChosenWord(suggestion, WordComposer.COMMIT_TYPE_MANUAL_PICK);
+ commitChosenWord(suggestion, LastComposedWord.COMMIT_TYPE_MANUAL_PICK);
// Add the word to the auto dictionary if it's not a known word
if (index == 0) {
addToUserUnigramAndBigramDictionaries(suggestion,
@@ -1975,9 +2007,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
// TODO: figure out here if this is an auto-correct or if the best word is actually
// what user typed. Note: currently this is done much later in
- // WordComposer#didAutoCorrectToAnotherWord by string equality of the remembered
+ // LastComposedWord#canCancelAutoCorrect by string equality of the remembered
// strings.
- mWordComposer.onCommitWord(commitType);
+ mLastComposedWord = mWordComposer.commitWord(commitType);
}
private static final WordComposer sEmptyWordComposer = new WordComposer();
@@ -2141,12 +2173,14 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// "ic" must not be null
private void cancelAutoCorrect(final InputConnection ic) {
- mWordComposer.resumeSuggestionOnKeptWord();
- final String originallyTypedWord = mWordComposer.getTypedWord();
- final CharSequence autoCorrectedTo = mWordComposer.getAutoCorrectionOrNull();
+ final String originallyTypedWord = mLastComposedWord.mTypedWord;
+ final CharSequence autoCorrectedTo = mLastComposedWord.mAutoCorrection;
final int cancelLength = autoCorrectedTo.length();
final CharSequence separator = ic.getTextBeforeCursor(1, 0);
if (DEBUG) {
+ if (mWordComposer.isComposingWord()) {
+ throw new RuntimeException("cancelAutoCorrect, but we are composing a word");
+ }
final String wordBeforeCursor =
ic.getTextBeforeCursor(cancelLength + 1, 0).subSequence(0, cancelLength)
.toString();
@@ -2165,8 +2199,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
ic.commitText(originallyTypedWord, 1);
// Re-insert the separator
ic.commitText(separator, 1);
- mWordComposer.deleteAutoCorrection();
- mWordComposer.onCommitWord(WordComposer.COMMIT_TYPE_CANCEL_AUTO_CORRECT);
+ mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
Utils.Stats.onSeparator(separator.charAt(0), WordComposer.NOT_A_COORDINATE,
WordComposer.NOT_A_COORDINATE);
mHandler.cancelUpdateBigramPredictions();
@@ -2180,7 +2213,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// Note: in the interest of code simplicity, we may want to just call
// restartSuggestionsOnWordBeforeCursorIfAtEndOfWord instead, but retrieving
// the old WordComposer allows to reuse the actual typed coordinates.
- mWordComposer.resumeSuggestionOnKeptWord();
+ mWordComposer.resumeSuggestionOnLastComposedWord(mLastComposedWord);
// We resume suggestion, and then we want to set the composing text to the content
// of the word composer again. But since we just manually picked a word, there is
// no composing text at the moment, so we have to delete the word before we set a
@@ -2229,10 +2262,14 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
final CharSequence textBeforeCursor = ic.getTextBeforeCursor(2, 0);
// NOTE: This does not work with surrogate pairs. Hopefully when the keyboard is able to
// enter surrogate pairs this code will have been removed.
- if (Keyboard.CODE_SPACE != textBeforeCursor.charAt(1)) {
- // We should not have come here if the text before the cursor is not a space.
- throw new RuntimeException("Tried to revert a swap of punctuation but we didn't "
+ if (TextUtils.isEmpty(textBeforeCursor)
+ || (Keyboard.CODE_SPACE != textBeforeCursor.charAt(1))) {
+ // We may only come here if the application is changing the text while we are typing.
+ // This is quite a broken case, but not logically impossible, so we shouldn't crash,
+ // but some debugging log may be in order.
+ Log.d(TAG, "Tried to revert a swap of punctuation but we didn't "
+ "find a space just before the cursor.");
+ return false;
}
ic.beginBatchEdit();
ic.deleteSurroundingText(2, 0);
diff --git a/java/src/com/android/inputmethod/latin/LatinImeLogger.java b/java/src/com/android/inputmethod/latin/LatinImeLogger.java
index 6f1adfe71..e3dadf250 100644
--- a/java/src/com/android/inputmethod/latin/LatinImeLogger.java
+++ b/java/src/com/android/inputmethod/latin/LatinImeLogger.java
@@ -21,7 +21,6 @@ import android.content.SharedPreferences;
import android.view.inputmethod.EditorInfo;
import com.android.inputmethod.keyboard.Keyboard;
-import com.android.inputmethod.latin.Dictionary.DataType;
import java.util.List;
@@ -75,7 +74,7 @@ public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChang
public static void onStartSuggestion(CharSequence previousWords) {
}
- public static void onAddSuggestedWord(String word, int typeId, DataType dataType) {
+ public static void onAddSuggestedWord(String word, int typeId, int dataType) {
}
public static void onSetKeyboard(Keyboard kb) {
diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java
index 5af21452a..d32310096 100644
--- a/java/src/com/android/inputmethod/latin/Settings.java
+++ b/java/src/com/android/inputmethod/latin/Settings.java
@@ -218,7 +218,7 @@ public class Settings extends InputMethodSettingsActivity
res.getString(R.string.key_preview_popup_dismiss_default_delay),
};
final String popupDismissDelayDefaultValue = Integer.toString(res.getInteger(
- R.integer.config_delay_after_preview));
+ R.integer.config_key_preview_linger_timeout));
mKeyPreviewPopupDismissDelay.setEntries(entries);
mKeyPreviewPopupDismissDelay.setEntryValues(
new String[] { "0", popupDismissDelayDefaultValue });
diff --git a/java/src/com/android/inputmethod/latin/SettingsValues.java b/java/src/com/android/inputmethod/latin/SettingsValues.java
index 0ae28d3fc..e6ef3962e 100644
--- a/java/src/com/android/inputmethod/latin/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/SettingsValues.java
@@ -124,7 +124,7 @@ public class SettingsValues {
mUsabilityStudyMode = getUsabilityStudyMode(prefs);
mKeyPreviewPopupDismissDelayRawValue = prefs.getString(
Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY,
- Integer.toString(res.getInteger(R.integer.config_delay_after_preview)));
+ Integer.toString(res.getInteger(R.integer.config_key_preview_linger_timeout)));
mUseContactsDict = prefs.getBoolean(Settings.PREF_KEY_USE_CONTACTS_DICT, true);
mAutoCorrectEnabled = isAutoCorrectEnabled(res, mAutoCorrectionThresholdRawValue);
mBigramSuggestionEnabled = mAutoCorrectEnabled
@@ -234,7 +234,8 @@ public class SettingsValues {
Resources resources) {
// TODO: use mKeyPreviewPopupDismissDelayRawValue instead of reading it again here.
return Integer.parseInt(sp.getString(Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY,
- Integer.toString(resources.getInteger(R.integer.config_delay_after_preview))));
+ Integer.toString(resources.getInteger(
+ R.integer.config_key_preview_linger_timeout))));
}
private static boolean isBigramSuggestionEnabled(final SharedPreferences sp,
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 8e0d031f4..f6e177aaf 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -298,7 +298,7 @@ public class Suggest implements Dictionary.WordCallback {
if (typedWord != null) {
// Treating USER_TYPED as UNIGRAM suggestion for logging now.
LatinImeLogger.onAddSuggestedWord(typedWord, Suggest.DIC_USER_TYPED,
- Dictionary.DataType.UNIGRAM);
+ Dictionary.UNIGRAM);
}
mConsideredWord = consideredWord;
@@ -417,12 +417,12 @@ public class Suggest implements Dictionary.WordCallback {
@Override
public boolean addWord(final char[] word, final int offset, final int length, int score,
- final int dicTypeId, final Dictionary.DataType dataType) {
- Dictionary.DataType dataTypeForLog = dataType;
+ final int dicTypeId, final int dataType) {
+ int dataTypeForLog = dataType;
final ArrayList<CharSequence> suggestions;
final int[] sortedScores;
final int prefMaxSuggestions;
- if(dataType == Dictionary.DataType.BIGRAM) {
+ if (dataType == Dictionary.BIGRAM) {
suggestions = mBigramSuggestions;
sortedScores = mBigramScores;
prefMaxSuggestions = PREF_MAX_BIGRAMS;
@@ -450,11 +450,11 @@ public class Suggest implements Dictionary.WordCallback {
}
}
} else {
- if (dataType == Dictionary.DataType.UNIGRAM) {
+ if (dataType == Dictionary.UNIGRAM) {
// Check if the word was already added before (by bigram data)
int bigramSuggestion = searchBigramSuggestion(word,offset,length);
if(bigramSuggestion >= 0) {
- dataTypeForLog = Dictionary.DataType.BIGRAM;
+ dataTypeForLog = Dictionary.BIGRAM;
// turn freq from bigram into multiplier specified above
double multiplier = (((double) mBigramScores[bigramSuggestion])
/ MAXIMUM_BIGRAM_FREQUENCY)
diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java
index e95dcfdc9..b96b0842a 100644
--- a/java/src/com/android/inputmethod/latin/WordComposer.java
+++ b/java/src/com/android/inputmethod/latin/WordComposer.java
@@ -33,64 +33,17 @@ public class WordComposer {
public static final int NOT_A_CODE = KeyDetector.NOT_A_CODE;
public static final int NOT_A_COORDINATE = -1;
- // TODO: Straighten out commit behavior so that the flags here are more understandable,
- // and possibly adjust their names.
- // COMMIT_TYPE_USER_TYPED_WORD is used when the word committed is the exact typed word, with
- // no hinting from the IME. It happens when some external event happens (rotating the device,
- // for example) or when auto-correction is off by settings or editor attributes.
- public static final int COMMIT_TYPE_USER_TYPED_WORD = 0;
- // COMMIT_TYPE_MANUAL_PICK is used when the user pressed a field in the suggestion strip.
- public static final int COMMIT_TYPE_MANUAL_PICK = 1;
- // COMMIT_TYPE_DECIDED_WORD is used when the IME commits the word it decided was best
- // for the current user input. It may be different from what the user typed (true auto-correct)
- // or it may be exactly what the user typed if it's in the dictionary or the IME does not have
- // enough confidence in any suggestion to auto-correct (auto-correct to typed word).
- public static final int COMMIT_TYPE_DECIDED_WORD = 2;
- // COMMIT_TYPE_CANCEL_AUTO_CORRECT is used upon committing back the old word upon cancelling
- // an auto-correction.
- public static final int COMMIT_TYPE_CANCEL_AUTO_CORRECT = 3;
-
- // Storage for all the info about the current input.
- private static class CharacterStore {
- /**
- * The list of unicode values for each keystroke (including surrounding keys)
- */
- ArrayList<int[]> mCodes;
- int[] mXCoordinates;
- int[] mYCoordinates;
- StringBuilder mTypedWord;
- CharSequence mAutoCorrection;
- CharacterStore() {
- final int N = BinaryDictionary.MAX_WORD_LENGTH;
- mCodes = new ArrayList<int[]>(N);
- mTypedWord = new StringBuilder(N);
- mXCoordinates = new int[N];
- mYCoordinates = new int[N];
- mAutoCorrection = null;
- }
- CharacterStore(final CharacterStore that) {
- mCodes = new ArrayList<int[]>(that.mCodes);
- mTypedWord = new StringBuilder(that.mTypedWord);
- mXCoordinates = Arrays.copyOf(that.mXCoordinates, that.mXCoordinates.length);
- mYCoordinates = Arrays.copyOf(that.mYCoordinates, that.mYCoordinates.length);
- }
- void reset() {
- // For better performance than creating a new character store.
- mCodes.clear();
- mTypedWord.setLength(0);
- mAutoCorrection = null;
- }
- }
+ final int N = BinaryDictionary.MAX_WORD_LENGTH;
- // The currently typing word. May not be null.
- private CharacterStore mCurrentWord;
- // The information being kept for resuming suggestion. May be null if wiped.
- private CharacterStore mCommittedWordSavedForSuggestionResuming;
+ private ArrayList<int[]> mCodes;
+ private int[] mXCoordinates;
+ private int[] mYCoordinates;
+ private StringBuilder mTypedWord;
+ private CharSequence mAutoCorrection;
+ // Cache these values for performance
private int mCapsCount;
-
private boolean mAutoCapitalized;
- // Cache this value for performance
private int mTrailingSingleQuotesCount;
/**
@@ -99,8 +52,11 @@ public class WordComposer {
private boolean mIsFirstCharCapitalized;
public WordComposer() {
- mCurrentWord = new CharacterStore();
- mCommittedWordSavedForSuggestionResuming = null;
+ mCodes = new ArrayList<int[]>(N);
+ mTypedWord = new StringBuilder(N);
+ mXCoordinates = new int[N];
+ mYCoordinates = new int[N];
+ mAutoCorrection = null;
mTrailingSingleQuotesCount = 0;
}
@@ -109,8 +65,10 @@ public class WordComposer {
}
public void init(WordComposer source) {
- mCurrentWord = new CharacterStore(source.mCurrentWord);
- mCommittedWordSavedForSuggestionResuming = source.mCommittedWordSavedForSuggestionResuming;
+ mCodes = new ArrayList<int[]>(source.mCodes);
+ mTypedWord = new StringBuilder(source.mTypedWord);
+ mXCoordinates = Arrays.copyOf(source.mXCoordinates, source.mXCoordinates.length);
+ mYCoordinates = Arrays.copyOf(source.mYCoordinates, source.mYCoordinates.length);
mCapsCount = source.mCapsCount;
mIsFirstCharCapitalized = source.mIsFirstCharCapitalized;
mAutoCapitalized = source.mAutoCapitalized;
@@ -121,8 +79,9 @@ public class WordComposer {
* Clear out the keys registered so far.
*/
public void reset() {
- mCurrentWord.reset();
- mCommittedWordSavedForSuggestionResuming = null;
+ mCodes.clear();
+ mTypedWord.setLength(0);
+ mAutoCorrection = null;
mCapsCount = 0;
mIsFirstCharCapitalized = false;
mTrailingSingleQuotesCount = 0;
@@ -133,7 +92,7 @@ public class WordComposer {
* @return the number of keystrokes
*/
public final int size() {
- return mCurrentWord.mTypedWord.length();
+ return mTypedWord.length();
}
public final boolean isComposingWord() {
@@ -146,15 +105,15 @@ public class WordComposer {
* @return the unicode for the pressed and surrounding keys
*/
public int[] getCodesAt(int index) {
- return mCurrentWord.mCodes.get(index);
+ return mCodes.get(index);
}
public int[] getXCoordinates() {
- return mCurrentWord.mXCoordinates;
+ return mXCoordinates;
}
public int[] getYCoordinates() {
- return mCurrentWord.mYCoordinates;
+ return mYCoordinates;
}
private static boolean isFirstCharCapitalized(int index, int codePoint, boolean previous) {
@@ -169,12 +128,12 @@ public class WordComposer {
*/
public void add(int primaryCode, int[] codes, int x, int y) {
final int newIndex = size();
- mCurrentWord.mTypedWord.append((char) primaryCode);
+ mTypedWord.append((char) primaryCode);
correctPrimaryJuxtapos(primaryCode, codes);
- mCurrentWord.mCodes.add(codes);
+ mCodes.add(codes);
if (newIndex < BinaryDictionary.MAX_WORD_LENGTH) {
- mCurrentWord.mXCoordinates[newIndex] = x;
- mCurrentWord.mYCoordinates[newIndex] = y;
+ mXCoordinates[newIndex] = x;
+ mYCoordinates[newIndex] = y;
}
mIsFirstCharCapitalized = isFirstCharCapitalized(
newIndex, primaryCode, mIsFirstCharCapitalized);
@@ -184,7 +143,7 @@ public class WordComposer {
} else {
mTrailingSingleQuotesCount = 0;
}
- mCurrentWord.mAutoCorrection = null;
+ mAutoCorrection = null;
}
/**
@@ -218,7 +177,6 @@ public class WordComposer {
int codePoint = word.charAt(i);
addKeyInfo(codePoint, keyboard, keyDetector);
}
- mCommittedWordSavedForSuggestionResuming = null;
}
/**
@@ -254,9 +212,9 @@ public class WordComposer {
final int size = size();
if (size > 0) {
final int lastPos = size - 1;
- char lastChar = mCurrentWord.mTypedWord.charAt(lastPos);
- mCurrentWord.mCodes.remove(lastPos);
- mCurrentWord.mTypedWord.deleteCharAt(lastPos);
+ char lastChar = mTypedWord.charAt(lastPos);
+ mCodes.remove(lastPos);
+ mTypedWord.deleteCharAt(lastPos);
if (Character.isUpperCase(lastChar)) mCapsCount--;
}
if (size() == 0) {
@@ -265,12 +223,12 @@ public class WordComposer {
if (mTrailingSingleQuotesCount > 0) {
--mTrailingSingleQuotesCount;
} else {
- for (int i = mCurrentWord.mTypedWord.length() - 1; i >= 0; --i) {
- if (Keyboard.CODE_SINGLE_QUOTE != mCurrentWord.mTypedWord.codePointAt(i)) break;
+ for (int i = mTypedWord.length() - 1; i >= 0; --i) {
+ if (Keyboard.CODE_SINGLE_QUOTE != mTypedWord.codePointAt(i)) break;
++mTrailingSingleQuotesCount;
}
}
- mCurrentWord.mAutoCorrection = null;
+ mAutoCorrection = null;
}
/**
@@ -278,7 +236,7 @@ public class WordComposer {
* @return the word that was typed so far. Never returns null.
*/
public String getTypedWord() {
- return mCurrentWord.mTypedWord.toString();
+ return mTypedWord.toString();
}
/**
@@ -329,26 +287,18 @@ public class WordComposer {
* Sets the auto-correction for this word.
*/
public void setAutoCorrection(final CharSequence correction) {
- mCurrentWord.mAutoCorrection = correction;
- }
-
- /**
- * Remove any auto-correction that may have been set.
- */
- public void deleteAutoCorrection() {
- mCurrentWord.mAutoCorrection = null;
+ mAutoCorrection = correction;
}
/**
* @return the auto-correction for this word, or null if none.
*/
public CharSequence getAutoCorrectionOrNull() {
- return mCurrentWord.mAutoCorrection;
+ return mAutoCorrection;
}
- // `type' should be one of the COMMIT_TYPE_* constants above.
- public void onCommitWord(final int type) {
- mCommittedWordSavedForSuggestionResuming = mCurrentWord;
+ // `type' should be one of the LastComposedWord.COMMIT_TYPE_* constants above.
+ public LastComposedWord commitWord(final int type) {
// Note: currently, we come here whenever we commit a word. If it's any *other* kind than
// DECIDED_WORD, we should reset mAutoCorrection so that we don't attempt to cancel later.
// If it's a DECIDED_WORD, it may be an actual auto-correction by the IME, or what the user
@@ -356,30 +306,25 @@ public class WordComposer {
// Ideally we would also null it when it was a DECIDED_WORD that was not an auto-correct.
// As it happens these two cases should behave differently, because the former can be
// canceled while the latter can't. Currently, we figure this out in
- // #didAutoCorrectToAnotherWord with #equals(). It would be marginally cleaner to do it
- // here, but it would be slower (since we would #equals() for each commit, instead of
- // only on cancel), and ultimately we want to figure it out even earlier anyway.
- if (type != COMMIT_TYPE_DECIDED_WORD) {
- // Only ever revert an auto-correct.
- mCommittedWordSavedForSuggestionResuming.mAutoCorrection = null;
- }
- // TODO: improve performance by swapping buffers instead of creating a new object.
- mCurrentWord = new CharacterStore();
- }
-
- public boolean hasWordKeptForSuggestionResuming() {
- return null != mCommittedWordSavedForSuggestionResuming;
- }
-
- public void resumeSuggestionOnKeptWord() {
- mCurrentWord = mCommittedWordSavedForSuggestionResuming;
- mCommittedWordSavedForSuggestionResuming = null;
+ // LastComposedWord#didAutoCorrectToAnotherWord with #equals(). It would be marginally
+ // cleaner to do it here, but it would be slower (since we would #equals() for each commit,
+ // instead of only on cancel), and ultimately we want to figure it out even earlier anyway.
+ final LastComposedWord lastComposedWord = new LastComposedWord(mCodes,
+ mXCoordinates, mYCoordinates, mTypedWord.toString(),
+ (type != LastComposedWord.COMMIT_TYPE_DECIDED_WORD) || (null == mAutoCorrection)
+ ? null : mAutoCorrection.toString());
+ mCodes.clear();
+ mTypedWord.setLength(0);
+ mAutoCorrection = null;
+ return lastComposedWord;
}
- public boolean didAutoCorrectToAnotherWord() {
- return null != mCommittedWordSavedForSuggestionResuming
- && !TextUtils.isEmpty(mCommittedWordSavedForSuggestionResuming.mAutoCorrection)
- && !TextUtils.equals(mCommittedWordSavedForSuggestionResuming.mTypedWord,
- mCommittedWordSavedForSuggestionResuming.mAutoCorrection);
+ public void resumeSuggestionOnLastComposedWord(final LastComposedWord lastComposedWord) {
+ mCodes = lastComposedWord.mCodes;
+ mXCoordinates = lastComposedWord.mXCoordinates;
+ mYCoordinates = lastComposedWord.mYCoordinates;
+ mTypedWord.setLength(0);
+ mTypedWord.append(lastComposedWord.mTypedWord);
+ mAutoCorrection = lastComposedWord.mAutoCorrection;
}
}
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
index 39e47f661..88ac043ed 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
@@ -31,7 +31,6 @@ import com.android.inputmethod.compat.SuggestionsInfoCompatUtils;
import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.BinaryDictionary;
import com.android.inputmethod.latin.Dictionary;
-import com.android.inputmethod.latin.Dictionary.DataType;
import com.android.inputmethod.latin.Dictionary.WordCallback;
import com.android.inputmethod.latin.DictionaryCollection;
import com.android.inputmethod.latin.DictionaryFactory;
@@ -237,7 +236,7 @@ public class AndroidSpellCheckerService extends SpellCheckerService
@Override
synchronized public boolean addWord(char[] word, int wordOffset, int wordLength, int score,
- int dicTypeId, DataType dataType) {
+ int dicTypeId, int dataType) {
final int positionIndex = ArraysCompatUtils.binarySearch(mScores, 0, mLength, score);
// binarySearch returns the index if the element exists, and -<insertion index> - 1
// if it doesn't. See documentation for binarySearch.