am b128b1cd: Merge "Take space state into account for caps (A11)" into jb-mr1-dev
* commit 'b128b1cdfee1956dff2cefc6d5308706a7fc186f': Take space state into account for caps (A11)main
commit
d287c369b6
|
@ -741,6 +741,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
// switcher.loadKeyboard; in apps like Talk, we come here when the text is sent and the
|
// switcher.loadKeyboard; in apps like Talk, we come here when the text is sent and the
|
||||||
// field gets emptied and we need to re-evaluate the shift state, but not the whole layout
|
// field gets emptied and we need to re-evaluate the shift state, but not the whole layout
|
||||||
// which would be disruptive.
|
// which would be disruptive.
|
||||||
|
// Space state must be updated before calling updateShiftState
|
||||||
mKeyboardSwitcher.updateShiftState();
|
mKeyboardSwitcher.updateShiftState();
|
||||||
|
|
||||||
mHandler.cancelUpdateSuggestionStrip();
|
mHandler.cancelUpdateSuggestionStrip();
|
||||||
|
@ -1114,11 +1115,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
// unless needed.
|
// unless needed.
|
||||||
if (mWordComposer.isComposingWord()) return Constants.TextUtils.CAP_MODE_OFF;
|
if (mWordComposer.isComposingWord()) return Constants.TextUtils.CAP_MODE_OFF;
|
||||||
|
|
||||||
// TODO: This blocking IPC call is heavy. Consider doing this without using IPC calls.
|
// Warning: this depends on mSpaceState, which may not be the most current value. If
|
||||||
// Note: getCursorCapsMode() returns the current capitalization mode that is any
|
// mSpaceState gets updated later, whoever called this may need to be told about it.
|
||||||
// combination of CAP_MODE_CHARACTERS, CAP_MODE_WORDS, and CAP_MODE_SENTENCES. 0 means none
|
return mConnection.getCursorCapsMode(inputType, mSubtypeSwitcher.getCurrentSubtypeLocale(),
|
||||||
// of them.
|
SPACE_STATE_PHANTOM == mSpaceState);
|
||||||
return mConnection.getCursorCapsMode(inputType, mSubtypeSwitcher.getCurrentSubtypeLocale());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Factor in auto-caps and manual caps and compute the current caps mode.
|
// Factor in auto-caps and manual caps and compute the current caps mode.
|
||||||
|
@ -1391,9 +1391,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
}
|
}
|
||||||
mConnection.commitText(text, 1);
|
mConnection.commitText(text, 1);
|
||||||
mConnection.endBatchEdit();
|
mConnection.endBatchEdit();
|
||||||
|
// Space state must be updated before calling updateShiftState
|
||||||
|
mSpaceState = SPACE_STATE_NONE;
|
||||||
mKeyboardSwitcher.updateShiftState();
|
mKeyboardSwitcher.updateShiftState();
|
||||||
mKeyboardSwitcher.onCodeInput(Keyboard.CODE_OUTPUT_TEXT);
|
mKeyboardSwitcher.onCodeInput(Keyboard.CODE_OUTPUT_TEXT);
|
||||||
mSpaceState = SPACE_STATE_NONE;
|
|
||||||
mEnteredText = text;
|
mEnteredText = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1509,8 +1510,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
mConnection.setComposingText(batchInputText, 1);
|
mConnection.setComposingText(batchInputText, 1);
|
||||||
mExpectingUpdateSelection = true;
|
mExpectingUpdateSelection = true;
|
||||||
mConnection.endBatchEdit();
|
mConnection.endBatchEdit();
|
||||||
mKeyboardSwitcher.updateShiftState();
|
// Space state must be updated before calling updateShiftState
|
||||||
mSpaceState = SPACE_STATE_PHANTOM;
|
mSpaceState = SPACE_STATE_PHANTOM;
|
||||||
|
mKeyboardSwitcher.updateShiftState();
|
||||||
}
|
}
|
||||||
|
|
||||||
private CharSequence specificTldProcessingOnTextInput(final CharSequence text) {
|
private CharSequence specificTldProcessingOnTextInput(final CharSequence text) {
|
||||||
|
@ -2019,8 +2021,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
mConnection.endBatchEdit();
|
mConnection.endBatchEdit();
|
||||||
// Don't allow cancellation of manual pick
|
// Don't allow cancellation of manual pick
|
||||||
mLastComposedWord.deactivate();
|
mLastComposedWord.deactivate();
|
||||||
|
// Space state must be updated before calling updateShiftState
|
||||||
mSpaceState = SPACE_STATE_PHANTOM;
|
mSpaceState = SPACE_STATE_PHANTOM;
|
||||||
// TODO: is this necessary?
|
|
||||||
mKeyboardSwitcher.updateShiftState();
|
mKeyboardSwitcher.updateShiftState();
|
||||||
|
|
||||||
// We should show the "Touch again to save" hint if the user pressed the first entry
|
// We should show the "Touch again to save" hint if the user pressed the first entry
|
||||||
|
|
|
@ -190,7 +190,23 @@ public class RichInputConnection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCursorCapsMode(final int inputType, final Locale locale) {
|
/**
|
||||||
|
* Gets the caps modes we should be in after this specific string.
|
||||||
|
*
|
||||||
|
* This returns a bit set of TextUtils#CAP_MODE_*, masked by the inputType argument.
|
||||||
|
* This method also supports faking an additional space after the string passed in argument,
|
||||||
|
* to support cases where a space will be added automatically, like in phantom space
|
||||||
|
* state for example.
|
||||||
|
* Note that for English, we are using American typography rules (which are not specific to
|
||||||
|
* American English, it's just the most common set of rules for English).
|
||||||
|
*
|
||||||
|
* @param inputType a mask of the caps modes to test for.
|
||||||
|
* @param locale what language should be considered.
|
||||||
|
* @param hasSpaceBefore if we should consider there should be a space after the string.
|
||||||
|
* @return the caps modes that should be on as a set of bits
|
||||||
|
*/
|
||||||
|
public int getCursorCapsMode(final int inputType, final Locale locale,
|
||||||
|
final boolean hasSpaceBefore) {
|
||||||
mIC = mParent.getCurrentInputConnection();
|
mIC = mParent.getCurrentInputConnection();
|
||||||
if (null == mIC) return Constants.TextUtils.CAP_MODE_OFF;
|
if (null == mIC) return Constants.TextUtils.CAP_MODE_OFF;
|
||||||
if (!TextUtils.isEmpty(mComposingText)) return Constants.TextUtils.CAP_MODE_OFF;
|
if (!TextUtils.isEmpty(mComposingText)) return Constants.TextUtils.CAP_MODE_OFF;
|
||||||
|
@ -205,7 +221,8 @@ public class RichInputConnection {
|
||||||
}
|
}
|
||||||
// This never calls InputConnection#getCapsMode - in fact, it's a static method that
|
// This never calls InputConnection#getCapsMode - in fact, it's a static method that
|
||||||
// never blocks or initiates IPC.
|
// never blocks or initiates IPC.
|
||||||
return StringUtils.getCapsMode(mCommittedTextBeforeComposingText, inputType, locale);
|
return StringUtils.getCapsMode(mCommittedTextBeforeComposingText, inputType, locale,
|
||||||
|
hasSpaceBefore);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CharSequence getTextBeforeCursor(final int i, final int j) {
|
public CharSequence getTextBeforeCursor(final int i, final int j) {
|
||||||
|
|
|
@ -197,13 +197,15 @@ public final class StringUtils {
|
||||||
* {@link TextUtils#CAP_MODE_CHARACTERS}, {@link TextUtils#CAP_MODE_WORDS}, and
|
* {@link TextUtils#CAP_MODE_CHARACTERS}, {@link TextUtils#CAP_MODE_WORDS}, and
|
||||||
* {@link TextUtils#CAP_MODE_SENTENCES}.
|
* {@link TextUtils#CAP_MODE_SENTENCES}.
|
||||||
* @param locale The locale to consider for capitalization rules
|
* @param locale The locale to consider for capitalization rules
|
||||||
|
* @param hasSpaceBefore Whether we should consider there is a space inserted at the end of cs
|
||||||
*
|
*
|
||||||
* @return Returns the actual capitalization modes that can be in effect
|
* @return Returns the actual capitalization modes that can be in effect
|
||||||
* at the current position, which is any combination of
|
* at the current position, which is any combination of
|
||||||
* {@link TextUtils#CAP_MODE_CHARACTERS}, {@link TextUtils#CAP_MODE_WORDS}, and
|
* {@link TextUtils#CAP_MODE_CHARACTERS}, {@link TextUtils#CAP_MODE_WORDS}, and
|
||||||
* {@link TextUtils#CAP_MODE_SENTENCES}.
|
* {@link TextUtils#CAP_MODE_SENTENCES}.
|
||||||
*/
|
*/
|
||||||
public static int getCapsMode(final CharSequence cs, final int reqModes, final Locale locale) {
|
public static int getCapsMode(final CharSequence cs, final int reqModes, final Locale locale,
|
||||||
|
final boolean hasSpaceBefore) {
|
||||||
// Quick description of what we want to do:
|
// Quick description of what we want to do:
|
||||||
// CAP_MODE_CHARACTERS is always on.
|
// CAP_MODE_CHARACTERS is always on.
|
||||||
// CAP_MODE_WORDS is on if there is some whitespace before the cursor.
|
// CAP_MODE_WORDS is on if there is some whitespace before the cursor.
|
||||||
|
@ -230,6 +232,9 @@ public final class StringUtils {
|
||||||
// single quote since they aren't start punctuation in the unicode sense, but should still
|
// single quote since they aren't start punctuation in the unicode sense, but should still
|
||||||
// be skipped for English. TODO: does this depend on the language?
|
// be skipped for English. TODO: does this depend on the language?
|
||||||
int i;
|
int i;
|
||||||
|
if (hasSpaceBefore) {
|
||||||
|
i = cs.length() + 1;
|
||||||
|
} else {
|
||||||
for (i = cs.length(); i > 0; i--) {
|
for (i = cs.length(); i > 0; i--) {
|
||||||
final char c = cs.charAt(i - 1);
|
final char c = cs.charAt(i - 1);
|
||||||
if (c != Keyboard.CODE_DOUBLE_QUOTE && c != Keyboard.CODE_SINGLE_QUOTE
|
if (c != Keyboard.CODE_DOUBLE_QUOTE && c != Keyboard.CODE_SINGLE_QUOTE
|
||||||
|
@ -237,6 +242,7 @@ public final class StringUtils {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// We are now on the character that precedes any starting punctuation, so in the most
|
// We are now on the character that precedes any starting punctuation, so in the most
|
||||||
// frequent case this will be whitespace or a letter, although it may occasionally be a
|
// frequent case this will be whitespace or a letter, although it may occasionally be a
|
||||||
|
@ -247,6 +253,7 @@ public final class StringUtils {
|
||||||
// if the first char that's not a space or tab is a start of line (as in, either \n or
|
// if the first char that's not a space or tab is a start of line (as in, either \n or
|
||||||
// start of text).
|
// start of text).
|
||||||
int j = i;
|
int j = i;
|
||||||
|
if (hasSpaceBefore) --j;
|
||||||
while (j > 0 && Character.isWhitespace(cs.charAt(j - 1))) {
|
while (j > 0 && Character.isWhitespace(cs.charAt(j - 1))) {
|
||||||
j--;
|
j--;
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,22 +93,24 @@ public class StringUtilsTests extends AndroidTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onePathForCaps(final CharSequence cs, final int expectedResult, final int mask,
|
private void onePathForCaps(final CharSequence cs, final int expectedResult, final int mask,
|
||||||
final Locale l) {
|
final Locale l, final boolean hasSpaceBefore) {
|
||||||
int oneTimeResult = expectedResult & mask;
|
int oneTimeResult = expectedResult & mask;
|
||||||
assertEquals("After >" + cs + "<", oneTimeResult, StringUtils.getCapsMode(cs, mask, l));
|
assertEquals("After >" + cs + "<", oneTimeResult,
|
||||||
|
StringUtils.getCapsMode(cs, mask, l, hasSpaceBefore));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void allPathsForCaps(final CharSequence cs, final int expectedResult, final Locale l) {
|
private void allPathsForCaps(final CharSequence cs, final int expectedResult, final Locale l,
|
||||||
|
final boolean hasSpaceBefore) {
|
||||||
final int c = TextUtils.CAP_MODE_CHARACTERS;
|
final int c = TextUtils.CAP_MODE_CHARACTERS;
|
||||||
final int w = TextUtils.CAP_MODE_WORDS;
|
final int w = TextUtils.CAP_MODE_WORDS;
|
||||||
final int s = TextUtils.CAP_MODE_SENTENCES;
|
final int s = TextUtils.CAP_MODE_SENTENCES;
|
||||||
onePathForCaps(cs, expectedResult, c | w | s, l);
|
onePathForCaps(cs, expectedResult, c | w | s, l, hasSpaceBefore);
|
||||||
onePathForCaps(cs, expectedResult, w | s, l);
|
onePathForCaps(cs, expectedResult, w | s, l, hasSpaceBefore);
|
||||||
onePathForCaps(cs, expectedResult, c | s, l);
|
onePathForCaps(cs, expectedResult, c | s, l, hasSpaceBefore);
|
||||||
onePathForCaps(cs, expectedResult, c | w, l);
|
onePathForCaps(cs, expectedResult, c | w, l, hasSpaceBefore);
|
||||||
onePathForCaps(cs, expectedResult, c, l);
|
onePathForCaps(cs, expectedResult, c, l, hasSpaceBefore);
|
||||||
onePathForCaps(cs, expectedResult, w, l);
|
onePathForCaps(cs, expectedResult, w, l, hasSpaceBefore);
|
||||||
onePathForCaps(cs, expectedResult, s, l);
|
onePathForCaps(cs, expectedResult, s, l, hasSpaceBefore);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetCapsMode() {
|
public void testGetCapsMode() {
|
||||||
|
@ -116,26 +118,31 @@ public class StringUtilsTests extends AndroidTestCase {
|
||||||
final int w = TextUtils.CAP_MODE_WORDS;
|
final int w = TextUtils.CAP_MODE_WORDS;
|
||||||
final int s = TextUtils.CAP_MODE_SENTENCES;
|
final int s = TextUtils.CAP_MODE_SENTENCES;
|
||||||
Locale l = Locale.ENGLISH;
|
Locale l = Locale.ENGLISH;
|
||||||
allPathsForCaps("", c | w | s, l);
|
allPathsForCaps("", c | w | s, l, false);
|
||||||
allPathsForCaps("Word", c, l);
|
allPathsForCaps("Word", c, l, false);
|
||||||
allPathsForCaps("Word.", c, l);
|
allPathsForCaps("Word.", c, l, false);
|
||||||
allPathsForCaps("Word ", c | w, l);
|
allPathsForCaps("Word ", c | w, l, false);
|
||||||
allPathsForCaps("Word. ", c | w | s, l);
|
allPathsForCaps("Word. ", c | w | s, l, false);
|
||||||
allPathsForCaps("Word..", c, l);
|
allPathsForCaps("Word..", c, l, false);
|
||||||
allPathsForCaps("Word.. ", c | w | s, l);
|
allPathsForCaps("Word.. ", c | w | s, l, false);
|
||||||
allPathsForCaps("Word... ", c | w | s, l);
|
allPathsForCaps("Word... ", c | w | s, l, false);
|
||||||
allPathsForCaps("Word ... ", c | w | s, l);
|
allPathsForCaps("Word ... ", c | w | s, l, false);
|
||||||
allPathsForCaps("Word . ", c | w, l);
|
allPathsForCaps("Word . ", c | w, l, false);
|
||||||
allPathsForCaps("In the U.S ", c | w, l);
|
allPathsForCaps("In the U.S ", c | w, l, false);
|
||||||
allPathsForCaps("In the U.S. ", c | w, l);
|
allPathsForCaps("In the U.S. ", c | w, l, false);
|
||||||
allPathsForCaps("Some stuff (e.g. ", c | w, l);
|
allPathsForCaps("Some stuff (e.g. ", c | w, l, false);
|
||||||
allPathsForCaps("In the U.S.. ", c | w | s, l);
|
allPathsForCaps("In the U.S.. ", c | w | s, l, false);
|
||||||
allPathsForCaps("\"Word.\" ", c | w | s, l);
|
allPathsForCaps("\"Word.\" ", c | w | s, l, false);
|
||||||
allPathsForCaps("\"Word\". ", c | w | s, l);
|
allPathsForCaps("\"Word\". ", c | w | s, l, false);
|
||||||
allPathsForCaps("\"Word\" ", c | w, l);
|
allPathsForCaps("\"Word\" ", c | w, l, false);
|
||||||
|
|
||||||
|
// Test for phantom space
|
||||||
|
allPathsForCaps("Word", c | w, l, true);
|
||||||
|
allPathsForCaps("Word.", c | w | s, l, true);
|
||||||
|
|
||||||
l = Locale.FRENCH;
|
l = Locale.FRENCH;
|
||||||
allPathsForCaps("\"Word.\" ", c | w, l);
|
allPathsForCaps("\"Word.\" ", c | w, l, false);
|
||||||
allPathsForCaps("\"Word\". ", c | w | s, l);
|
allPathsForCaps("\"Word\". ", c | w | s, l, false);
|
||||||
allPathsForCaps("\"Word\" ", c | w, l);
|
allPathsForCaps("\"Word\" ", c | w, l, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue