Merge "Improve magic space handling."

main
Jean Chalard 2011-05-09 04:07:16 -07:00 committed by Android (Google) Code Review
commit 3d994a48a2
4 changed files with 73 additions and 40 deletions

View File

@ -18,8 +18,12 @@
*/ */
--> -->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Symbols that are commonly considered word separators in this language --> <!-- Symbols that should be swapped with a magic space -->
<string name="word_separators">.\u0009\u0020,;:!?\n()[]*&amp;@{}/&lt;&gt;_+=|\u0022</string> <string name="magic_space_swapping_symbols">.,\u0022)]}</string>
<!-- Symbols that are sentence separators, for purposes of making it hug the last sentence. --> <!-- Symbols that should strip a magic space -->
<string name="sentence_separators">.,</string> <string name="magic_space_stripping_symbols">\u0009\u0020\u0027\n-/_</string>
<!-- Symbols that should promote magic spaces into real space -->
<string name="magic_space_promoting_symbols">;:!?([*&amp;@{&lt;&gt;+=|</string>
<!-- Symbols that do NOT separate words -->
<string name="non_word_separator_symbols">\u0027</string>
</resources> </resources>

View File

@ -18,6 +18,6 @@
*/ */
--> -->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Symbols that are commonly considered word separators in this language --> <!-- Symbols that do NOT separate words -->
<string name="word_separators">.\u0009\u0020,;:!?\'\n()[]*&amp;@{}/&lt;&gt;_+=|\u0022</string> <string name="non_word_separator_symbols"></string>
</resources> </resources>

View File

@ -18,12 +18,19 @@
*/ */
--> -->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Symbols that are commonly considered word separators in this language -->
<string name="word_separators">.\u0009\u0020,;:!?\n()[]*&amp;@{}/&lt;&gt;_+=|\u0022</string>
<!-- Symbols that are sentence separators, for purposes of making it hug the last sentence. -->
<string name="sentence_separators">.,!?)</string>
<!-- Symbols that are suggested between words --> <!-- Symbols that are suggested between words -->
<string name="suggested_punctuations">!?,\u0022\u0027:();-/@_</string> <string name="suggested_punctuations">!?,\u0022\u0027:();-/@_</string>
<!-- Symbols that should be swapped with a magic space -->
<string name="magic_space_swapping_symbols">.,;:!?)]}\u0022</string>
<!-- Symbols that should strip a magic space -->
<string name="magic_space_stripping_symbols">\u0009\u0020\n/_\u0027-</string>
<!-- Symbols that should convert magic spaces into real space -->
<string name="magic_space_promoting_symbols">([*&amp;@{&lt;&gt;+=|</string>
<!-- Symbols that do NOT separate words -->
<string name="non_word_separator_symbols">\u0027-</string>
<!-- Word separator list is the union of all symbols except those that are not separators:
magic_space_swapping_symbols | magic_space_stripping_symbols |
magic_space_neutral_symbols \ non_word_separator_symbols -->
<!-- Label for ALT modifier key. Must be short to fit on key! --> <!-- Label for ALT modifier key. Must be short to fit on key! -->
<string name="label_alt_key">ALT</string> <string name="label_alt_key">ALT</string>

View File

@ -216,7 +216,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
private boolean mSilentMode; private boolean mSilentMode;
/* package */ String mWordSeparators; /* package */ String mWordSeparators;
private String mSentenceSeparators; private String mMagicSpaceStrippers;
private String mMagicSpaceSwappers;
private String mSuggestPuncs; private String mSuggestPuncs;
// TODO: Move this flag to VoiceProxy // TODO: Move this flag to VoiceProxy
private boolean mConfigurationChanging; private boolean mConfigurationChanging;
@ -505,8 +506,14 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mSuggest.setUserBigramDictionary(mUserBigramDictionary); mSuggest.setUserBigramDictionary(mUserBigramDictionary);
updateCorrectionMode(); updateCorrectionMode();
mWordSeparators = res.getString(R.string.word_separators); mMagicSpaceStrippers = res.getString(R.string.magic_space_stripping_symbols);
mSentenceSeparators = res.getString(R.string.sentence_separators); mMagicSpaceSwappers = res.getString(R.string.magic_space_swapping_symbols);
String wordSeparators = mMagicSpaceStrippers + mMagicSpaceSwappers
+ res.getString(R.string.magic_space_promoting_symbols);
final String notWordSeparators = res.getString(R.string.non_word_separator_symbols);
for (int i = notWordSeparators.length() - 1; i >= 0; --i)
wordSeparators = wordSeparators.replace(notWordSeparators.substring(i, i + 1), "");
mWordSeparators = wordSeparators;
Utils.setSystemLocale(res, savedLocale); Utils.setSystemLocale(res, savedLocale);
} }
@ -1039,13 +1046,13 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
return false; return false;
} }
private void swapPunctuationAndSpace() { private void swapSwapperAndSpace() {
final InputConnection ic = getCurrentInputConnection(); final InputConnection ic = getCurrentInputConnection();
if (ic == null) return; if (ic == null) return;
CharSequence lastTwo = ic.getTextBeforeCursor(2, 0); CharSequence lastTwo = ic.getTextBeforeCursor(2, 0);
// It is guaranteed lastTwo.charAt(1) is a swapper - else this method is not called.
if (lastTwo != null && lastTwo.length() == 2 if (lastTwo != null && lastTwo.length() == 2
&& lastTwo.charAt(0) == Keyboard.CODE_SPACE && lastTwo.charAt(0) == Keyboard.CODE_SPACE) {
&& isSentenceSeparator(lastTwo.charAt(1))) {
ic.beginBatchEdit(); ic.beginBatchEdit();
ic.deleteSurroundingText(2, 0); ic.deleteSurroundingText(2, 0);
ic.commitText(lastTwo.charAt(1) + " ", 1); ic.commitText(lastTwo.charAt(1) + " ", 1);
@ -1054,7 +1061,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
} }
} }
private void doubleSpace() { private void maybeDoubleSpace() {
if (mCorrectionMode == Suggest.CORRECTION_NONE) return; if (mCorrectionMode == Suggest.CORRECTION_NONE) return;
final InputConnection ic = getCurrentInputConnection(); final InputConnection ic = getCurrentInputConnection();
if (ic == null) return; if (ic == null) return;
@ -1330,14 +1337,11 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
private void handleCharacter(int primaryCode, int[] keyCodes, int x, int y) { private void handleCharacter(int primaryCode, int[] keyCodes, int x, int y) {
mVoiceProxy.handleCharacter(); mVoiceProxy.handleCharacter();
if (mJustAddedMagicSpace && primaryCode == Keyboard.CODE_SINGLE_QUOTE) { if (mJustAddedMagicSpace && isMagicSpaceStripper(primaryCode)) {
removeTrailingSpace(); removeTrailingSpace();
} }
if (primaryCode != Keyboard.CODE_ENTER) {
mJustAddedMagicSpace = false;
}
if (mLastSelectionStart == mLastSelectionEnd && TextEntryState.isRecorrecting()) { if (mLastSelectionStart == mLastSelectionEnd) {
abortRecorrection(false); abortRecorrection(false);
} }
@ -1389,6 +1393,12 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
} else { } else {
sendKeyChar((char)code); sendKeyChar((char)code);
} }
if (mJustAddedMagicSpace && isMagicSpaceSwapper(primaryCode)) {
swapSwapperAndSpace();
} else {
mJustAddedMagicSpace = false;
}
switcher.updateShiftState(); switcher.updateShiftState();
if (LatinIME.PERF_DEBUG) measureCps(); if (LatinIME.PERF_DEBUG) measureCps();
TextEntryState.typedCharacter((char) code, isWordSeparator(code), x, y); TextEntryState.typedCharacter((char) code, isWordSeparator(code), x, y);
@ -1422,27 +1432,25 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
} }
} }
if (mJustAddedMagicSpace && primaryCode == Keyboard.CODE_SPACE) { if (mJustAddedMagicSpace) {
mJustAddedMagicSpace = false; if (isMagicSpaceSwapper(primaryCode)) {
} else if (mJustAddedMagicSpace && primaryCode == Keyboard.CODE_ENTER) {
removeTrailingSpace();
mJustAddedMagicSpace = false;
sendKeyChar((char)primaryCode); sendKeyChar((char)primaryCode);
swapSwapperAndSpace();
} else {
if (isMagicSpaceStripper(primaryCode)) removeTrailingSpace();
sendKeyChar((char)primaryCode);
mJustAddedMagicSpace = false;
}
} else { } else {
sendKeyChar((char)primaryCode); sendKeyChar((char)primaryCode);
} }
if (isSuggestionsRequested() && primaryCode == Keyboard.CODE_SPACE) {
maybeDoubleSpace();
}
TextEntryState.typedCharacter((char) primaryCode, true, x, y); TextEntryState.typedCharacter((char) primaryCode, true, x, y);
if (TextEntryState.isPunctuationAfterAccepted() && primaryCode != Keyboard.CODE_ENTER
&& mJustAddedMagicSpace) {
swapPunctuationAndSpace();
} else if (isSuggestionsRequested() && primaryCode == Keyboard.CODE_SPACE) {
doubleSpace();
mJustAddedMagicSpace = false;
} else {
mJustAddedMagicSpace = false;
}
if (pickedDefault) { if (pickedDefault) {
CharSequence typedWord = mWord.getTypedWord(); CharSequence typedWord = mWord.getTypedWord();
TextEntryState.backToAcceptedDefault(typedWord); TextEntryState.backToAcceptedDefault(typedWord);
@ -1687,10 +1695,17 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// So, LatinImeLogger logs "" as a user's input. // So, LatinImeLogger logs "" as a user's input.
LatinImeLogger.logOnManualSuggestion( LatinImeLogger.logOnManualSuggestion(
"", suggestion.toString(), index, suggestions.mWords); "", suggestion.toString(), index, suggestions.mWords);
// Find out whether the previous character is a space. If it is, as a special case
// for punctuation entered through the suggestion strip, it should be considered
// a magic space even if it was a normal space. This is meant to help in case the user
// pressed space on purpose of displaying the suggestion strip punctuation.
final char primaryCode = suggestion.charAt(0); final char primaryCode = suggestion.charAt(0);
final int toLeft = (ic == null) ? 0 : ic.getTextBeforeCursor(1, 0).charAt(0);
if (Keyboard.CODE_SPACE == toLeft) mJustAddedMagicSpace = true;
onCodeInput(primaryCode, new int[] { primaryCode }, onCodeInput(primaryCode, new int[] { primaryCode },
KeyboardActionListener.NOT_A_TOUCH_COORDINATE, KeyboardActionListener.NOT_A_TOUCH_COORDINATE,
KeyboardActionListener.NOT_A_TOUCH_COORDINATE); KeyboardActionListener.NOT_A_TOUCH_COORDINATE);
mJustAddedMagicSpace = false;
if (ic != null) { if (ic != null) {
ic.endBatchEdit(); ic.endBatchEdit();
} }
@ -1917,8 +1932,11 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
} }
if (mUserBigramDictionary != null) { if (mUserBigramDictionary != null) {
// We don't want to register as bigrams words separated by a separator.
// For example "I will, and you too" : we don't want the pair ("will" "and") to be
// a bigram.
CharSequence prevWord = EditingUtils.getPreviousWord(getCurrentInputConnection(), CharSequence prevWord = EditingUtils.getPreviousWord(getCurrentInputConnection(),
mSentenceSeparators); mWordSeparators);
if (!TextUtils.isEmpty(prevWord)) { if (!TextUtils.isEmpty(prevWord)) {
mUserBigramDictionary.addBigrams(prevWord.toString(), suggestion.toString()); mUserBigramDictionary.addBigrams(prevWord.toString(), suggestion.toString());
} }
@ -1993,8 +2011,12 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
return separators.contains(String.valueOf((char)code)); return separators.contains(String.valueOf((char)code));
} }
private boolean isSentenceSeparator(int code) { private boolean isMagicSpaceStripper(int code) {
return mSentenceSeparators.contains(String.valueOf((char)code)); return mMagicSpaceStrippers.contains(String.valueOf((char)code));
}
private boolean isMagicSpaceSwapper(int code) {
return mMagicSpaceSwappers.contains(String.valueOf((char)code));
} }
private void sendMagicSpace() { private void sendMagicSpace() {