From 8094bf45d73a5f7257076afc97d91d6708ee03c4 Mon Sep 17 00:00:00 2001
From: Jean Chalard <jchalard@google.com>
Date: Mon, 15 Apr 2013 22:00:29 +0900
Subject: [PATCH] Match the keyboard state to the recapitalize state.

Bug: 7657025
Change-Id: I2f8fe7fc4596a498322ba5ccabbd0c18a2bc36cf
---
 .../keyboard/KeyboardSwitcher.java            |  6 ++-
 .../keyboard/internal/KeyboardState.java      | 45 ++++++++++++++++---
 .../android/inputmethod/latin/LatinIME.java   | 11 +++++
 .../inputmethod/latin/RecapitalizeStatus.java |  5 +++
 .../internal/MockKeyboardSwitcher.java        |  5 ++-
 5 files changed, 62 insertions(+), 10 deletions(-)

diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index d15f14f886..4e41b77ce4 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -207,7 +207,8 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
      * Update keyboard shift state triggered by connected EditText status change.
      */
     public void updateShiftState() {
-        mState.onUpdateShiftState(mLatinIME.getCurrentAutoCapsState());
+        mState.onUpdateShiftState(mLatinIME.getCurrentAutoCapsState(),
+                mLatinIME.getCurrentRecapitalizeState());
     }
 
     // TODO: Remove this method. Come up with a more comprehensive way to reset the keyboard layout
@@ -276,7 +277,8 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
     // Implements {@link KeyboardState.SwitchActions}.
     @Override
     public void requestUpdatingShiftState() {
-        mState.onUpdateShiftState(mLatinIME.getCurrentAutoCapsState());
+        mState.onUpdateShiftState(mLatinIME.getCurrentAutoCapsState(),
+                mLatinIME.getCurrentRecapitalizeState());
     }
 
     // Implements {@link KeyboardState.SwitchActions}.
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
index 95d9ccb582..efe0175ed4 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
@@ -20,6 +20,7 @@ import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.RecapitalizeStatus;
 
 /**
  * Keyboard state machine.
@@ -80,6 +81,7 @@ public final class KeyboardState {
     private boolean mIsSymbolShifted;
     private boolean mPrevMainKeyboardWasShiftLocked;
     private boolean mPrevSymbolsKeyboardWasShifted;
+    private int mRecapitalizeMode;
 
     // For handling long press.
     private boolean mLongPressShiftLockFired;
@@ -110,6 +112,7 @@ public final class KeyboardState {
 
     public KeyboardState(final SwitchActions switchActions) {
         mSwitchActions = switchActions;
+        mRecapitalizeMode = RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE;
     }
 
     public void onLoadKeyboard() {
@@ -283,6 +286,7 @@ public final class KeyboardState {
         mSwitchActions.setAlphabetKeyboard();
         mIsAlphabetMode = true;
         mIsSymbolShifted = false;
+        mRecapitalizeMode = RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE;
         mSwitchState = SWITCH_STATE_ALPHA;
         mSwitchActions.requestUpdatingShiftState();
     }
@@ -386,11 +390,13 @@ public final class KeyboardState {
         }
     }
 
-    public void onUpdateShiftState(final int autoCaps) {
+    public void onUpdateShiftState(final int autoCaps, final int recapitalizeMode) {
         if (DEBUG_EVENT) {
-            Log.d(TAG, "onUpdateShiftState: autoCaps=" + autoCaps + " " + this);
+            Log.d(TAG, "onUpdateShiftState: autoCaps=" + autoCaps + ", recapitalizeMode="
+                    + recapitalizeMode + this);
         }
-        updateAlphabetShiftState(autoCaps);
+        mRecapitalizeMode = recapitalizeMode;
+        updateAlphabetShiftState(autoCaps, recapitalizeMode);
     }
 
     // TODO: Remove this method. Come up with a more comprehensive way to reset the keyboard layout
@@ -402,8 +408,28 @@ public final class KeyboardState {
         resetKeyboardStateToAlphabet();
     }
 
-    private void updateAlphabetShiftState(final int autoCaps) {
+    private void updateShiftStateForRecapitalize(final int recapitalizeMode) {
+        switch (recapitalizeMode) {
+        case RecapitalizeStatus.CAPS_MODE_ALL_UPPER:
+            setShifted(SHIFT_LOCK_SHIFTED);
+            break;
+        case RecapitalizeStatus.CAPS_MODE_FIRST_WORD_UPPER:
+            setShifted(AUTOMATIC_SHIFT);
+            break;
+        case RecapitalizeStatus.CAPS_MODE_ALL_LOWER:
+        case RecapitalizeStatus.CAPS_MODE_ORIGINAL_MIXED_CASE:
+        default:
+            setShifted(UNSHIFT);
+        }
+    }
+
+    private void updateAlphabetShiftState(final int autoCaps, final int recapitalizeMode) {
         if (!mIsAlphabetMode) return;
+        if (RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE != recapitalizeMode) {
+            // We are recapitalizing. Match the keyboard to the current recapitalize state.
+            updateShiftStateForRecapitalize(recapitalizeMode);
+            return;
+        }
         if (!mShiftKeyState.isReleasing()) {
             // Ignore update shift state event while the shift key is being pressed (including
             // chording).
@@ -421,6 +447,9 @@ public final class KeyboardState {
 
     private void onPressShift() {
         mLongPressShiftLockFired = false;
+        // If we are recapitalizing, we don't do any of the normal processing, including
+        // importantly the double tap timer.
+        if (RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE != mRecapitalizeMode) return;
         if (mIsAlphabetMode) {
             mIsInDoubleTapShiftKey = mSwitchActions.isInDoubleTapTimeout();
             if (!mIsInDoubleTapShiftKey) {
@@ -467,7 +496,11 @@ public final class KeyboardState {
     }
 
     private void onReleaseShift(final boolean withSliding) {
-        if (mIsAlphabetMode) {
+        if (RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE != mRecapitalizeMode) {
+            // We are recapitalizing. We should match the keyboard state to the recapitalize
+            // state in priority.
+            updateShiftStateForRecapitalize(mRecapitalizeMode);
+        } else if (mIsAlphabetMode) {
             final boolean isShiftLocked = mAlphabetShiftState.isShiftLocked();
             mIsInAlphabetUnshiftedFromShifted = false;
             if (mIsInDoubleTapShiftKey) {
@@ -597,7 +630,7 @@ public final class KeyboardState {
 
         // If the code is a letter, update keyboard shift state.
         if (Constants.isLetterCode(code)) {
-            updateAlphabetShiftState(autoCaps);
+            updateAlphabetShiftState(autoCaps, RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE);
         }
     }
 
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 4b33867c04..99463ae5f6 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1180,6 +1180,15 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
                 SPACE_STATE_PHANTOM == mSpaceState);
     }
 
+    public int getCurrentRecapitalizeState() {
+        if (!mRecapitalizeStatus.isActive()
+                || !mRecapitalizeStatus.isSetAt(mLastSelectionStart, mLastSelectionEnd)) {
+            // Not recapitalizing at the moment
+            return RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE;
+        }
+        return mRecapitalizeStatus.getCurrentMode();
+    }
+
     // Factor in auto-caps and manual caps and compute the current caps mode.
     private int getActualCapsMode() {
         final int keyboardShiftMode = mKeyboardSwitcher.getKeyboardShiftMode();
@@ -1979,6 +1988,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
         mLastSelectionStart = mRecapitalizeStatus.getNewCursorStart();
         mLastSelectionEnd = mRecapitalizeStatus.getNewCursorEnd();
         mConnection.setSelection(mLastSelectionStart, mLastSelectionEnd);
+        // Match the keyboard to the new state.
+        mKeyboardSwitcher.updateShiftState();
     }
 
     // Returns true if we did an autocorrection, false otherwise.
diff --git a/java/src/com/android/inputmethod/latin/RecapitalizeStatus.java b/java/src/com/android/inputmethod/latin/RecapitalizeStatus.java
index a121dd9e8d..8a704ab42c 100644
--- a/java/src/com/android/inputmethod/latin/RecapitalizeStatus.java
+++ b/java/src/com/android/inputmethod/latin/RecapitalizeStatus.java
@@ -24,6 +24,7 @@ import java.util.Locale;
  * The status of the current recapitalize process.
  */
 public class RecapitalizeStatus {
+    public static final int NOT_A_RECAPITALIZE_MODE = -1;
     public static final int CAPS_MODE_ORIGINAL_MIXED_CASE = 0;
     public static final int CAPS_MODE_ALL_LOWER = 1;
     public static final int CAPS_MODE_FIRST_WORD_UPPER = 2;
@@ -181,4 +182,8 @@ public class RecapitalizeStatus {
     public int getNewCursorEnd() {
         return mCursorEndAfter;
     }
+
+    public int getCurrentMode() {
+        return ROTATION_STYLE[mRotationStyleCurrentIndex];
+    }
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java b/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java
index eb484084e3..74506d26ae 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java
@@ -19,6 +19,7 @@ package com.android.inputmethod.keyboard.internal;
 import android.text.TextUtils;
 
 import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.RecapitalizeStatus;
 
 public class MockKeyboardSwitcher implements KeyboardState.SwitchActions {
     public interface MockConstants {
@@ -120,7 +121,7 @@ public class MockKeyboardSwitcher implements KeyboardState.SwitchActions {
 
     @Override
     public void requestUpdatingShiftState() {
-        mState.onUpdateShiftState(mAutoCapsState);
+        mState.onUpdateShiftState(mAutoCapsState, RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE);
     }
 
     @Override
@@ -162,7 +163,7 @@ public class MockKeyboardSwitcher implements KeyboardState.SwitchActions {
     }
 
     public void updateShiftState() {
-        mState.onUpdateShiftState(mAutoCapsState);
+        mState.onUpdateShiftState(mAutoCapsState, RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE);
     }
 
     public void loadKeyboard() {
-- 
GitLab