am 52fdaa2c: Merge "Fix some auto-caps problems: - (mainly for Spanish) auto-caps after inverted bang and what - (German only) don\'t auto-cap after digits-period-space"
* commit '52fdaa2cd8b6903fcf1dcab23b786e917323241c': Fix some auto-caps problems: - (mainly for Spanish) auto-caps after inverted bang and what - (German only) don't auto-cap after digits-period-spacemain
commit
f4d447e40a
|
@ -192,7 +192,6 @@ public final class Constants {
|
||||||
public static final int CODE_SPACE = ' ';
|
public static final int CODE_SPACE = ' ';
|
||||||
public static final int CODE_PERIOD = '.';
|
public static final int CODE_PERIOD = '.';
|
||||||
public static final int CODE_COMMA = ',';
|
public static final int CODE_COMMA = ',';
|
||||||
public static final int CODE_ARMENIAN_PERIOD = 0x0589;
|
|
||||||
public static final int CODE_DASH = '-';
|
public static final int CODE_DASH = '-';
|
||||||
public static final int CODE_SINGLE_QUOTE = '\'';
|
public static final int CODE_SINGLE_QUOTE = '\'';
|
||||||
public static final int CODE_DOUBLE_QUOTE = '"';
|
public static final int CODE_DOUBLE_QUOTE = '"';
|
||||||
|
@ -208,6 +207,8 @@ public final class Constants {
|
||||||
public static final int CODE_CLOSING_SQUARE_BRACKET = ']';
|
public static final int CODE_CLOSING_SQUARE_BRACKET = ']';
|
||||||
public static final int CODE_CLOSING_CURLY_BRACKET = '}';
|
public static final int CODE_CLOSING_CURLY_BRACKET = '}';
|
||||||
public static final int CODE_CLOSING_ANGLE_BRACKET = '>';
|
public static final int CODE_CLOSING_ANGLE_BRACKET = '>';
|
||||||
|
public static final int CODE_INVERTED_QUESTION_MARK = 0xBF; // ¿
|
||||||
|
public static final int CODE_INVERTED_EXCLAMATION_MARK = 0xA1; // ¡
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Special keys code. Must be negative.
|
* Special keys code. Must be negative.
|
||||||
|
|
|
@ -61,6 +61,22 @@ public final class CapsModeUtils {
|
||||||
|| WordComposer.CAPS_MODE_AUTO_SHIFT_LOCKED == mode;
|
|| WordComposer.CAPS_MODE_AUTO_SHIFT_LOCKED == mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to find out if a code point is starting punctuation.
|
||||||
|
*
|
||||||
|
* This include the Unicode START_PUNCTUATION category, but also some other symbols that are
|
||||||
|
* starting, like the inverted question mark or the double quote.
|
||||||
|
*
|
||||||
|
* @param codePoint the code point
|
||||||
|
* @return true if it's starting punctuation, false otherwise.
|
||||||
|
*/
|
||||||
|
private static boolean isStartPunctuation(final int codePoint) {
|
||||||
|
return (codePoint == Constants.CODE_DOUBLE_QUOTE || codePoint == Constants.CODE_SINGLE_QUOTE
|
||||||
|
|| codePoint == Constants.CODE_INVERTED_QUESTION_MARK
|
||||||
|
|| codePoint == Constants.CODE_INVERTED_EXCLAMATION_MARK
|
||||||
|
|| Character.getType(codePoint) == Character.START_PUNCTUATION);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine what caps mode should be in effect at the current offset in
|
* Determine what caps mode should be in effect at the current offset in
|
||||||
* the text. Only the mode bits set in <var>reqModes</var> will be
|
* the text. Only the mode bits set in <var>reqModes</var> will be
|
||||||
|
@ -115,8 +131,7 @@ public final class CapsModeUtils {
|
||||||
} else {
|
} 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 != Constants.CODE_DOUBLE_QUOTE && c != Constants.CODE_SINGLE_QUOTE
|
if (!isStartPunctuation(c)) {
|
||||||
&& Character.getType(c) != Character.START_PUNCTUATION) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -210,11 +225,14 @@ public final class CapsModeUtils {
|
||||||
|
|
||||||
// We found out that we have a period. We need to determine if this is a full stop or
|
// We found out that we have a period. We need to determine if this is a full stop or
|
||||||
// otherwise sentence-ending period, or an abbreviation like "e.g.". An abbreviation
|
// otherwise sentence-ending period, or an abbreviation like "e.g.". An abbreviation
|
||||||
// looks like (\w\.){2,}
|
// looks like (\w\.){2,}. Moreover, in German, you put periods after digits for dates
|
||||||
|
// and some other things, and in German specifically we need to not go into autocaps after
|
||||||
|
// a whitespace-digits-period sequence.
|
||||||
// To find out, we will have a simple state machine with the following states :
|
// To find out, we will have a simple state machine with the following states :
|
||||||
// START, WORD, PERIOD, ABBREVIATION
|
// START, WORD, PERIOD, ABBREVIATION, NUMBER
|
||||||
// On START : (just before the first period)
|
// On START : (just before the first period)
|
||||||
// letter => WORD
|
// letter => WORD
|
||||||
|
// digit => NUMBER if German; end with caps otherwise
|
||||||
// whitespace => end with no caps (it was a stand-alone period)
|
// whitespace => end with no caps (it was a stand-alone period)
|
||||||
// otherwise => end with caps (several periods/symbols in a row)
|
// otherwise => end with caps (several periods/symbols in a row)
|
||||||
// On WORD : (within the word just before the first period)
|
// On WORD : (within the word just before the first period)
|
||||||
|
@ -228,6 +246,11 @@ public final class CapsModeUtils {
|
||||||
// letter => LETTER
|
// letter => LETTER
|
||||||
// period => PERIOD
|
// period => PERIOD
|
||||||
// otherwise => end with no caps (it was an abbreviation)
|
// otherwise => end with no caps (it was an abbreviation)
|
||||||
|
// On NUMBER : (period immediately preceded by one or more digits)
|
||||||
|
// digit => NUMBER
|
||||||
|
// letter => LETTER (promote to word)
|
||||||
|
// otherwise => end with no caps (it was a whitespace-digits-period sequence,
|
||||||
|
// or a punctuation-digits-period sequence like "11.11.")
|
||||||
// "Not an abbreviation" in the above chart essentially covers cases like "...yes.". This
|
// "Not an abbreviation" in the above chart essentially covers cases like "...yes.". This
|
||||||
// should capitalize.
|
// should capitalize.
|
||||||
|
|
||||||
|
@ -235,6 +258,7 @@ public final class CapsModeUtils {
|
||||||
final int WORD = 1;
|
final int WORD = 1;
|
||||||
final int PERIOD = 2;
|
final int PERIOD = 2;
|
||||||
final int LETTER = 3;
|
final int LETTER = 3;
|
||||||
|
final int NUMBER = 4;
|
||||||
final int caps = (TextUtils.CAP_MODE_CHARACTERS | TextUtils.CAP_MODE_WORDS
|
final int caps = (TextUtils.CAP_MODE_CHARACTERS | TextUtils.CAP_MODE_WORDS
|
||||||
| TextUtils.CAP_MODE_SENTENCES) & reqModes;
|
| TextUtils.CAP_MODE_SENTENCES) & reqModes;
|
||||||
final int noCaps = (TextUtils.CAP_MODE_CHARACTERS | TextUtils.CAP_MODE_WORDS) & reqModes;
|
final int noCaps = (TextUtils.CAP_MODE_CHARACTERS | TextUtils.CAP_MODE_WORDS) & reqModes;
|
||||||
|
@ -247,6 +271,8 @@ public final class CapsModeUtils {
|
||||||
state = WORD;
|
state = WORD;
|
||||||
} else if (Character.isWhitespace(c)) {
|
} else if (Character.isWhitespace(c)) {
|
||||||
return noCaps;
|
return noCaps;
|
||||||
|
} else if (Character.isDigit(c) && spacingAndPunctuations.mUsesGermanRules) {
|
||||||
|
state = NUMBER;
|
||||||
} else {
|
} else {
|
||||||
return caps;
|
return caps;
|
||||||
}
|
}
|
||||||
|
@ -275,6 +301,15 @@ public final class CapsModeUtils {
|
||||||
} else {
|
} else {
|
||||||
return noCaps;
|
return noCaps;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case NUMBER:
|
||||||
|
if (Character.isLetter(c)) {
|
||||||
|
state = WORD;
|
||||||
|
} else if (Character.isDigit(c)) {
|
||||||
|
state = NUMBER;
|
||||||
|
} else {
|
||||||
|
return noCaps;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Here we arrived at the start of the line. This should behave exactly like whitespace.
|
// Here we arrived at the start of the line. This should behave exactly like whitespace.
|
||||||
|
|
|
@ -78,4 +78,35 @@ public class ShiftModeTests extends InputTestsBase {
|
||||||
runMessages();
|
runMessages();
|
||||||
assertTrue("Caps after a while after repeating Backspace a lot", isCapsModeAutoShifted());
|
assertTrue("Caps after a while after repeating Backspace a lot", isCapsModeAutoShifted());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testAutoCapsAfterDigitsPeriod() {
|
||||||
|
changeLanguage("en");
|
||||||
|
type("On 22.11.");
|
||||||
|
assertFalse("(English) Auto caps after digits-period", isCapsModeAutoShifted());
|
||||||
|
type(" ");
|
||||||
|
assertTrue("(English) Auto caps after digits-period-whitespace", isCapsModeAutoShifted());
|
||||||
|
mEditText.setText("");
|
||||||
|
changeLanguage("fr");
|
||||||
|
type("Le 22.");
|
||||||
|
assertFalse("(French) Auto caps after digits-period", isCapsModeAutoShifted());
|
||||||
|
type(" ");
|
||||||
|
assertTrue("(French) Auto caps after digits-period-whitespace", isCapsModeAutoShifted());
|
||||||
|
mEditText.setText("");
|
||||||
|
changeLanguage("de");
|
||||||
|
type("Am 22.");
|
||||||
|
assertFalse("(German) Auto caps after digits-period", isCapsModeAutoShifted());
|
||||||
|
type(" ");
|
||||||
|
// For German, no auto-caps in this case
|
||||||
|
assertFalse("(German) Auto caps after digits-period-whitespace", isCapsModeAutoShifted());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAutoCapsAfterInvertedMarks() {
|
||||||
|
changeLanguage("es");
|
||||||
|
assertTrue("(Spanish) Auto caps at start", isCapsModeAutoShifted());
|
||||||
|
type("Hey. ¿");
|
||||||
|
assertTrue("(Spanish) Auto caps after inverted what", isCapsModeAutoShifted());
|
||||||
|
mEditText.setText("");
|
||||||
|
type("¡");
|
||||||
|
assertTrue("(Spanish) Auto caps after inverted bang", isCapsModeAutoShifted());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue