am ec163119: am 252da38f: Take locale into account for caps (A10)
* commit 'ec1631199dad501868487156a637861645532ff5': Take locale into account for caps (A10)main
commit
e11dcc8b30
|
@ -1118,7 +1118,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
// Note: getCursorCapsMode() returns the current capitalization mode that is any
|
// Note: getCursorCapsMode() returns the current capitalization mode that is any
|
||||||
// combination of CAP_MODE_CHARACTERS, CAP_MODE_WORDS, and CAP_MODE_SENTENCES. 0 means none
|
// combination of CAP_MODE_CHARACTERS, CAP_MODE_WORDS, and CAP_MODE_SENTENCES. 0 means none
|
||||||
// of them.
|
// of them.
|
||||||
return mConnection.getCursorCapsMode(inputType);
|
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.
|
||||||
|
|
|
@ -30,6 +30,7 @@ import com.android.inputmethod.keyboard.Keyboard;
|
||||||
import com.android.inputmethod.latin.define.ProductionFlag;
|
import com.android.inputmethod.latin.define.ProductionFlag;
|
||||||
import com.android.inputmethod.research.ResearchLogger;
|
import com.android.inputmethod.research.ResearchLogger;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -189,7 +190,7 @@ public class RichInputConnection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCursorCapsMode(final int inputType) {
|
public int getCursorCapsMode(final int inputType, final Locale locale) {
|
||||||
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;
|
||||||
|
@ -204,7 +205,7 @@ 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);
|
return StringUtils.getCapsMode(mCommittedTextBeforeComposingText, inputType, locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CharSequence getTextBeforeCursor(final int i, final int j) {
|
public CharSequence getTextBeforeCursor(final int i, final int j) {
|
||||||
|
|
|
@ -196,13 +196,14 @@ public final class StringUtils {
|
||||||
* @param reqModes The modes to be checked: may be any combination of
|
* @param reqModes The modes to be checked: may be 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}.
|
||||||
|
* @param locale The locale to consider for capitalization rules
|
||||||
*
|
*
|
||||||
* @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) {
|
public static int getCapsMode(final CharSequence cs, final int reqModes, final Locale locale) {
|
||||||
// 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.
|
||||||
|
@ -270,21 +271,26 @@ public final class StringUtils {
|
||||||
// we know that MODE_SENTENCES is being requested.
|
// we know that MODE_SENTENCES is being requested.
|
||||||
|
|
||||||
// Step 4 : Search for MODE_SENTENCES.
|
// Step 4 : Search for MODE_SENTENCES.
|
||||||
|
// English is a special case in that "American typography" rules, which are the most common
|
||||||
|
// in English, state that a sentence terminator immediately following a quotation mark
|
||||||
|
// should be swapped with it and de-duplicated (included in the quotation mark),
|
||||||
|
// e.g. <<Did he say, "let's go home?">>
|
||||||
|
// No other language has such a rule as far as I know, instead putting inside the quotation
|
||||||
|
// mark as the exact thing quoted and handling the surrounding punctuation independently,
|
||||||
|
// e.g. <<Did he say, "let's go home"?>>
|
||||||
|
// Hence, specifically for English, we treat this special case here.
|
||||||
|
if (Locale.ENGLISH.getLanguage().equals(locale.getLanguage())) {
|
||||||
for (; j > 0; j--) {
|
for (; j > 0; j--) {
|
||||||
// Here we look to go over any closing punctuation. This is because in dominant variants
|
// Here we look to go over any closing punctuation. This is because in dominant
|
||||||
// of English, the final period is placed within double quotes and maybe other closing
|
// variants of English, the final period is placed within double quotes and maybe
|
||||||
// punctuation signs.
|
// other closing punctuation signs. This is generally not true in other languages.
|
||||||
// TODO: this is wrong for almost everything except American typography rules for
|
|
||||||
// English. It's wrong for British typography rules for English, it's wrong for French,
|
|
||||||
// it's wrong for German, it's wrong for Spanish, and possibly everything else.
|
|
||||||
// (note that American rules and British rules have nothing to do with en_US and en_GB,
|
|
||||||
// as both rules are used in both countries - it's merely a name for the set of rules)
|
|
||||||
final char c = cs.charAt(j - 1);
|
final char c = cs.charAt(j - 1);
|
||||||
if (c != Keyboard.CODE_DOUBLE_QUOTE && c != Keyboard.CODE_SINGLE_QUOTE
|
if (c != Keyboard.CODE_DOUBLE_QUOTE && c != Keyboard.CODE_SINGLE_QUOTE
|
||||||
&& Character.getType(c) != Character.END_PUNCTUATION) {
|
&& Character.getType(c) != Character.END_PUNCTUATION) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (j <= 0) return TextUtils.CAP_MODE_CHARACTERS & reqModes;
|
if (j <= 0) return TextUtils.CAP_MODE_CHARACTERS & reqModes;
|
||||||
char c = cs.charAt(--j);
|
char c = cs.charAt(--j);
|
||||||
|
|
|
@ -19,6 +19,8 @@ package com.android.inputmethod.latin;
|
||||||
import android.test.AndroidTestCase;
|
import android.test.AndroidTestCase;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
public class StringUtilsTests extends AndroidTestCase {
|
public class StringUtilsTests extends AndroidTestCase {
|
||||||
public void testContainsInArray() {
|
public void testContainsInArray() {
|
||||||
assertFalse("empty array", StringUtils.containsInArray("key", new String[0]));
|
assertFalse("empty array", StringUtils.containsInArray("key", new String[0]));
|
||||||
|
@ -90,43 +92,50 @@ public class StringUtilsTests extends AndroidTestCase {
|
||||||
StringUtils.removeFromCsvIfExists("key", "key1,key,key3,key,key5"));
|
StringUtils.removeFromCsvIfExists("key", "key1,key,key3,key,key5"));
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
int oneTimeResult = expectedResult & mask;
|
int oneTimeResult = expectedResult & mask;
|
||||||
assertEquals("After >" + cs + "<", oneTimeResult, StringUtils.getCapsMode(cs, mask));
|
assertEquals("After >" + cs + "<", oneTimeResult, StringUtils.getCapsMode(cs, mask, l));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void allPathsForCaps(final CharSequence cs, final int expectedResult) {
|
private void allPathsForCaps(final CharSequence cs, final int expectedResult, final Locale l) {
|
||||||
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);
|
onePathForCaps(cs, expectedResult, c | w | s, l);
|
||||||
onePathForCaps(cs, expectedResult, w | s);
|
onePathForCaps(cs, expectedResult, w | s, l);
|
||||||
onePathForCaps(cs, expectedResult, c | s);
|
onePathForCaps(cs, expectedResult, c | s, l);
|
||||||
onePathForCaps(cs, expectedResult, c | w);
|
onePathForCaps(cs, expectedResult, c | w, l);
|
||||||
onePathForCaps(cs, expectedResult, c);
|
onePathForCaps(cs, expectedResult, c, l);
|
||||||
onePathForCaps(cs, expectedResult, w);
|
onePathForCaps(cs, expectedResult, w, l);
|
||||||
onePathForCaps(cs, expectedResult, s);
|
onePathForCaps(cs, expectedResult, s, l);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetCapsMode() {
|
public void testGetCapsMode() {
|
||||||
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;
|
||||||
allPathsForCaps("", c | w | s);
|
Locale l = Locale.ENGLISH;
|
||||||
allPathsForCaps("Word", c);
|
allPathsForCaps("", c | w | s, l);
|
||||||
allPathsForCaps("Word.", c);
|
allPathsForCaps("Word", c, l);
|
||||||
allPathsForCaps("Word ", c | w);
|
allPathsForCaps("Word.", c, l);
|
||||||
allPathsForCaps("Word. ", c | w | s);
|
allPathsForCaps("Word ", c | w, l);
|
||||||
allPathsForCaps("Word..", c);
|
allPathsForCaps("Word. ", c | w | s, l);
|
||||||
allPathsForCaps("Word.. ", c | w | s);
|
allPathsForCaps("Word..", c, l);
|
||||||
allPathsForCaps("Word... ", c | w | s);
|
allPathsForCaps("Word.. ", c | w | s, l);
|
||||||
allPathsForCaps("Word ... ", c | w | s);
|
allPathsForCaps("Word... ", c | w | s, l);
|
||||||
allPathsForCaps("Word . ", c | w);
|
allPathsForCaps("Word ... ", c | w | s, l);
|
||||||
allPathsForCaps("In the U.S ", c | w);
|
allPathsForCaps("Word . ", c | w, l);
|
||||||
allPathsForCaps("In the U.S. ", c | w);
|
allPathsForCaps("In the U.S ", c | w, l);
|
||||||
allPathsForCaps("Some stuff (e.g. ", c | w);
|
allPathsForCaps("In the U.S. ", c | w, l);
|
||||||
allPathsForCaps("In the U.S.. ", c | w | s);
|
allPathsForCaps("Some stuff (e.g. ", c | w, l);
|
||||||
allPathsForCaps("\"Word.\" ", c | w | s);
|
allPathsForCaps("In the U.S.. ", c | w | s, l);
|
||||||
allPathsForCaps("\"Word\" ", c | w);
|
allPathsForCaps("\"Word.\" ", c | w | s, l);
|
||||||
|
allPathsForCaps("\"Word\". ", c | w | s, l);
|
||||||
|
allPathsForCaps("\"Word\" ", c | w, l);
|
||||||
|
l = Locale.FRENCH;
|
||||||
|
allPathsForCaps("\"Word.\" ", c | w, l);
|
||||||
|
allPathsForCaps("\"Word\". ", c | w | s, l);
|
||||||
|
allPathsForCaps("\"Word\" ", c | w, l);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue