aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java6
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java49
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java33
-rw-r--r--java/src/com/android/inputmethod/latin/RecapitalizeStatus.java68
4 files changed, 114 insertions, 42 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index d15f14f88..4e41b77ce 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 95d9ccb58..b1d499702 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.
@@ -29,7 +30,7 @@ import com.android.inputmethod.latin.Constants;
* The input events are {@link #onLoadKeyboard()}, {@link #onSaveKeyboardState()},
* {@link #onPressKey(int, boolean, int)}, {@link #onReleaseKey(int, boolean)},
* {@link #onCodeInput(int, boolean, int)}, {@link #onCancelInput(boolean)},
- * {@link #onUpdateShiftState(int)}, {@link #onLongPressTimeout(int)}.
+ * {@link #onUpdateShiftState(int, int)}, {@link #onLongPressTimeout(int)}.
*
* The actions are {@link SwitchActions}'s methods.
*/
@@ -48,7 +49,7 @@ public final class KeyboardState {
public void setSymbolsShiftedKeyboard();
/**
- * Request to call back {@link KeyboardState#onUpdateShiftState(int)}.
+ * Request to call back {@link KeyboardState#onUpdateShiftState(int, int)}.
*/
public void requestUpdatingShiftState();
@@ -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 bf4c22d23..0a6f2ab00 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -161,7 +161,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
mPositionalInfoForUserDictPendingAddition = null;
private final WordComposer mWordComposer = new WordComposer();
private final RichInputConnection mConnection = new RichInputConnection(this);
- private RecapitalizeStatus mRecapitalizeStatus = null;
+ private final RecapitalizeStatus mRecapitalizeStatus = new RecapitalizeStatus();
// Keep track of the last selection range to decide if we need to show word alternatives
private static final int NOT_A_CURSOR_POSITION = -1;
@@ -742,6 +742,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
resetComposingState(true /* alsoResetLastComposedWord */);
mDeleteCount = 0;
mSpaceState = SPACE_STATE_NONE;
+ mRecapitalizeStatus.deactivate();
mCurrentlyPressedHardwareKeys.clear();
if (mSuggestionStripView != null) {
@@ -925,7 +926,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// We moved the cursor. If we are touching a word, we need to resume suggestion.
mHandler.postResumeSuggestions();
// Reset the last recapitalization.
- mRecapitalizeStatus = null;
+ mRecapitalizeStatus.deactivate();
mKeyboardSwitcher.updateShiftState();
}
mExpectingUpdateSelection = false;
@@ -995,8 +996,6 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
}
}
if (!mSettings.getCurrent().isApplicationSpecifiedCompletionsOn()) return;
- mApplicationSpecifiedCompletions =
- CompletionInfoUtils.removeNulls(applicationSpecifiedCompletions);
if (applicationSpecifiedCompletions == null) {
clearSuggestionStrip();
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
@@ -1004,6 +1003,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
}
return;
}
+ mApplicationSpecifiedCompletions =
+ CompletionInfoUtils.removeNulls(applicationSpecifiedCompletions);
final ArrayList<SuggestedWords.SuggestedWordInfo> applicationSuggestedWords =
SuggestedWords.getFromApplicationSpecifiedCompletions(
@@ -1179,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();
@@ -1391,7 +1401,12 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
case Constants.CODE_SHIFT:
// Note: calling back to the keyboard on Shift key is handled in onPressKey()
// and onReleaseKey().
- handleRecapitalize();
+ final Keyboard currentKeyboard = switcher.getKeyboard();
+ if (null != currentKeyboard && currentKeyboard.mId.isAlphabetKeyboard()) {
+ // TODO: Instead of checking for alphabetic keyboard here, separate keycodes for
+ // alphabetic shift and shift while in symbol layout.
+ handleRecapitalize();
+ }
break;
case Constants.CODE_SWITCH_ALPHA_SYMBOL:
// Note: calling back to the keyboard on symbol key is handled in onPressKey()
@@ -1953,10 +1968,9 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
private void handleRecapitalize() {
if (mLastSelectionStart == mLastSelectionEnd) return; // No selection
// If we have a recapitalize in progress, use it; otherwise, create a new one.
- if (null == mRecapitalizeStatus
+ if (!mRecapitalizeStatus.isActive()
|| !mRecapitalizeStatus.isSetAt(mLastSelectionStart, mLastSelectionEnd)) {
- mRecapitalizeStatus =
- new RecapitalizeStatus(mLastSelectionStart, mLastSelectionEnd,
+ mRecapitalizeStatus.initialize(mLastSelectionStart, mLastSelectionEnd,
mConnection.getSelectedText(0 /* flags, 0 for no styles */).toString(),
mSettings.getCurrentLocale(), mSettings.getWordSeparators());
// We trim leading and trailing whitespace.
@@ -1979,6 +1993,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.
@@ -2413,6 +2429,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
if (!mConnection.isCursorTouchingWord(mSettings.getCurrent())) return;
final Range range = mConnection.getWordRangeAtCursor(mSettings.getWordSeparators(),
0 /* additionalPrecedingWordsCount */);
+ if (null == range) return; // Happens if we don't have an input connection at all
final ArrayList<SuggestedWordInfo> suggestions = CollectionUtils.newArrayList();
final String typedWord = range.mWord.toString();
if (range.mWord instanceof SpannableString) {
diff --git a/java/src/com/android/inputmethod/latin/RecapitalizeStatus.java b/java/src/com/android/inputmethod/latin/RecapitalizeStatus.java
index 9edd3a160..8a704ab42 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;
@@ -37,6 +38,7 @@ public class RecapitalizeStatus {
CAPS_MODE_FIRST_WORD_UPPER,
CAPS_MODE_ALL_UPPER
};
+
private static final int getStringMode(final String string, final String separators) {
if (StringUtils.isIdenticalAfterUpcase(string)) {
return CAPS_MODE_ALL_UPPER;
@@ -50,24 +52,29 @@ public class RecapitalizeStatus {
}
/**
- * We store the location of the cursor and the string that was there before the undoable
+ * We store the location of the cursor and the string that was there before the recapitalize
* action was done, and the location of the cursor and the string that was there after.
*/
private int mCursorStartBefore;
- private int mCursorEndBefore;
private String mStringBefore;
private int mCursorStartAfter;
private int mCursorEndAfter;
private int mRotationStyleCurrentIndex;
- private final boolean mSkipOriginalMixedCaseMode;
- private final Locale mLocale;
- private final String mSeparators;
+ private boolean mSkipOriginalMixedCaseMode;
+ private Locale mLocale;
+ private String mSeparators;
private String mStringAfter;
+ private boolean mIsActive;
+
+ public RecapitalizeStatus() {
+ // By default, initialize with dummy values that won't match any real recapitalize.
+ initialize(-1, -1, "", Locale.getDefault(), "");
+ deactivate();
+ }
- public RecapitalizeStatus(final int cursorStart, final int cursorEnd, final String string,
+ public void initialize(final int cursorStart, final int cursorEnd, final String string,
final Locale locale, final String separators) {
mCursorStartBefore = cursorStart;
- mCursorEndBefore = cursorEnd;
mStringBefore = string;
mCursorStartAfter = cursorStart;
mCursorEndAfter = cursorEnd;
@@ -89,6 +96,15 @@ public class RecapitalizeStatus {
mRotationStyleCurrentIndex = currentMode;
mSkipOriginalMixedCaseMode = true;
}
+ mIsActive = true;
+ }
+
+ public void deactivate() {
+ mIsActive = false;
+ }
+
+ public boolean isActive() {
+ return mIsActive;
}
public boolean isSetAt(final int cursorStart, final int cursorEnd) {
@@ -110,23 +126,23 @@ public class RecapitalizeStatus {
}
++count;
switch (ROTATION_STYLE[mRotationStyleCurrentIndex]) {
- case CAPS_MODE_ORIGINAL_MIXED_CASE:
- mStringAfter = mStringBefore;
- break;
- case CAPS_MODE_ALL_LOWER:
- mStringAfter = mStringBefore.toLowerCase(mLocale);
- break;
- case CAPS_MODE_FIRST_WORD_UPPER:
- mStringAfter = StringUtils.capitalizeEachWord(mStringBefore, mSeparators,
- mLocale);
- break;
- case CAPS_MODE_ALL_UPPER:
- mStringAfter = mStringBefore.toUpperCase(mLocale);
- break;
- default:
- mStringAfter = mStringBefore;
+ case CAPS_MODE_ORIGINAL_MIXED_CASE:
+ mStringAfter = mStringBefore;
+ break;
+ case CAPS_MODE_ALL_LOWER:
+ mStringAfter = mStringBefore.toLowerCase(mLocale);
+ break;
+ case CAPS_MODE_FIRST_WORD_UPPER:
+ mStringAfter = StringUtils.capitalizeEachWord(mStringBefore, mSeparators,
+ mLocale);
+ break;
+ case CAPS_MODE_ALL_UPPER:
+ mStringAfter = mStringBefore.toUpperCase(mLocale);
+ break;
+ default:
+ mStringAfter = mStringBefore;
}
- } while (mStringAfter.equals(oldResult) && count < 5);
+ } while (mStringAfter.equals(oldResult) && count < ROTATION_STYLE.length + 1);
mCursorEndAfter = mCursorStartAfter + mStringAfter.length();
}
@@ -148,7 +164,7 @@ public class RecapitalizeStatus {
if (!Character.isWhitespace(codePoint)) break;
}
if (0 != nonWhitespaceStart || len != nonWhitespaceEnd) {
- mCursorEndBefore = mCursorEndAfter = mCursorStartBefore + nonWhitespaceEnd;
+ mCursorEndAfter = mCursorStartBefore + nonWhitespaceEnd;
mCursorStartBefore = mCursorStartAfter = mCursorStartBefore + nonWhitespaceStart;
mStringAfter = mStringBefore =
mStringBefore.substring(nonWhitespaceStart, nonWhitespaceEnd);
@@ -166,4 +182,8 @@ public class RecapitalizeStatus {
public int getNewCursorEnd() {
return mCursorEndAfter;
}
+
+ public int getCurrentMode() {
+ return ROTATION_STYLE[mRotationStyleCurrentIndex];
+ }
}