From 96845ecff62ac5a1131ce3eb8e6a06d3298dd984 Mon Sep 17 00:00:00 2001 From: Jean Chalard Date: Wed, 16 Jan 2013 22:07:43 +0900 Subject: [PATCH] Insert into user dict in lower case if auto-caps (D2) Also recapitalize afterwards if the word has been changed. Bug: 7972124 Change-Id: I9306580bb4ed0ffa80cc4559ce1abcd2034d1905 --- .../android/inputmethod/latin/LatinIME.java | 16 +++++++--- ...itionalInfoForUserDictPendingAddition.java | 10 ++++-- .../inputmethod/latin/StringUtils.java | 31 +++++++++++++++++++ .../latin/UserBinaryDictionary.java | 6 +--- 4 files changed, 52 insertions(+), 11 deletions(-) diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index d02c4df7e..4f8852b87 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -773,7 +773,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction // to the user dictionary. if (null != mPositionalInfoForUserDictPendingAddition && mPositionalInfoForUserDictPendingAddition.tryReplaceWithActualWord( - mConnection, editorInfo, mLastSelectionEnd)) { + mConnection, editorInfo, mLastSelectionEnd, + mSubtypeSwitcher.getCurrentSubtypeLocale())) { mPositionalInfoForUserDictPendingAddition = null; } // If tryReplaceWithActualWord returns false, we don't know what word was @@ -1223,11 +1224,17 @@ public final class LatinIME extends InputMethodService implements KeyboardAction mPositionalInfoForUserDictPendingAddition = null; return; } + final String wordToEdit; + if (StringUtils.isAutoCapsMode(mLastComposedWord.mCapitalizedMode)) { + wordToEdit = word.toLowerCase(mSubtypeSwitcher.getCurrentSubtypeLocale()); + } else { + wordToEdit = word; + } mPositionalInfoForUserDictPendingAddition = new PositionalInfoForUserDictPendingAddition( - word, mLastSelectionEnd, getCurrentInputEditorInfo(), + wordToEdit, mLastSelectionEnd, getCurrentInputEditorInfo(), mLastComposedWord.mCapitalizedMode); - mUserDictionary.addWordToUserDictionary(word, 128); + mUserDictionary.addWordToUserDictionary(wordToEdit); } public void onWordAddedToUserDictionary(final String newSpelling) { @@ -1240,7 +1247,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction } mPositionalInfoForUserDictPendingAddition.setActualWordBeingAdded(newSpelling); if (mPositionalInfoForUserDictPendingAddition.tryReplaceWithActualWord( - mConnection, getCurrentInputEditorInfo(), mLastSelectionEnd)) { + mConnection, getCurrentInputEditorInfo(), mLastSelectionEnd, + mSubtypeSwitcher.getCurrentSubtypeLocale())) { mPositionalInfoForUserDictPendingAddition = null; } } diff --git a/java/src/com/android/inputmethod/latin/PositionalInfoForUserDictPendingAddition.java b/java/src/com/android/inputmethod/latin/PositionalInfoForUserDictPendingAddition.java index a33cefcd6..8493ef669 100644 --- a/java/src/com/android/inputmethod/latin/PositionalInfoForUserDictPendingAddition.java +++ b/java/src/com/android/inputmethod/latin/PositionalInfoForUserDictPendingAddition.java @@ -18,6 +18,8 @@ package com.android.inputmethod.latin; import android.view.inputmethod.EditorInfo; +import java.util.Locale; + /** * Holder class for data about a word already committed but that may still be edited. * @@ -70,10 +72,11 @@ public final class PositionalInfoForUserDictPendingAddition { * @param connection The RichInputConnection through which to contact the editor. * @param editorInfo Information pertaining to the editor we are currently in. * @param currentCursorPosition The current cursor position, for checking purposes. + * @param locale The locale for changing case, if necessary * @return true if the edit has been successfully made, false if we need to try again later */ public boolean tryReplaceWithActualWord(final RichInputConnection connection, - final EditorInfo editorInfo, final int currentCursorPosition) { + final EditorInfo editorInfo, final int currentCursorPosition, final Locale locale) { // If we still don't know the actual word being added, we need to try again later. if (null == mActualWordBeingAdded) return false; // The entered text and the registered text were the same anyway : we can @@ -92,9 +95,12 @@ public final class PositionalInfoForUserDictPendingAddition { // so that it won't be tried again if (currentCursorPosition != mCursorPos) return true; // We have made all the checks : do the replacement and report success + // If this was auto-capitalized, we need to restore the case before committing + final String wordWithCaseFixed = StringUtils.applyAutoCapsMode(mActualWordBeingAdded, + mCapitalizedMode, locale); connection.setComposingRegion(currentCursorPosition - mOriginalWord.length(), currentCursorPosition); - connection.commitText(mActualWordBeingAdded, mActualWordBeingAdded.length()); + connection.commitText(wordWithCaseFixed, wordWithCaseFixed.length()); return true; } } diff --git a/java/src/com/android/inputmethod/latin/StringUtils.java b/java/src/com/android/inputmethod/latin/StringUtils.java index ddaa5ff5b..d00edbe92 100644 --- a/java/src/com/android/inputmethod/latin/StringUtils.java +++ b/java/src/com/android/inputmethod/latin/StringUtils.java @@ -103,6 +103,37 @@ public final class StringUtils { } } + /** + * Apply an auto-caps mode to a string. + * + * This intentionally does NOT apply manual caps mode. It only changes the capitalization if + * the mode is one of the auto-caps modes. + * @param s The string to capitalize. + * @param capitalizeMode The mode in which to capitalize. + * @param locale The locale for capitalizing. + * @return The capitalized string. + */ + public static String applyAutoCapsMode(final String s, final int capitalizeMode, + final Locale locale) { + if (WordComposer.CAPS_MODE_AUTO_SHIFT_LOCKED == capitalizeMode) { + return s.toUpperCase(locale); + } else if (WordComposer.CAPS_MODE_AUTO_SHIFTED == capitalizeMode) { + return toTitleCase(s, locale); + } else { + return s; + } + } + + /** + * Return whether a constant represents an auto-caps mode (either auto-shift or auto-shift-lock) + * @param mode The mode to test for + * @return true if this represents an auto-caps mode, false otherwise + */ + public static boolean isAutoCapsMode(final int mode) { + return WordComposer.CAPS_MODE_AUTO_SHIFTED == mode + || WordComposer.CAPS_MODE_AUTO_SHIFT_LOCKED == mode; + } + public static String toTitleCase(final String s, final Locale locale) { if (s.length() <= 1) { // TODO: is this really correct? Shouldn't this be s.toUpperCase()? diff --git a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java index a16784985..0d5bde623 100644 --- a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java @@ -216,17 +216,13 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary { * * @param word the word to add. If the word is capitalized, then the dictionary will * recognize it as a capitalized word when searched. - * @param frequency the frequency of occurrence of the word. A frequency of 255 is considered - * the highest. - * @TODO use a higher or float range for frequency */ - public synchronized void addWordToUserDictionary(final String word, final int frequency) { + public synchronized void addWordToUserDictionary(final String word) { // TODO: do something for the UI. With the following, any sufficiently long word will // look like it will go to the user dictionary but it won't. // Safeguard against adding long words. Can cause stack overflow. if (word.length() >= MAX_WORD_LENGTH) return; - // TODO: Add an argument to the intent to specify the frequency. Intent intent = new Intent(ACTION_USER_DICTIONARY_INSERT); intent.putExtra(Words.WORD, word); intent.putExtra(Words.LOCALE, mLocale);