aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/latin
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android/inputmethod/latin')
-rw-r--r--java/src/com/android/inputmethod/latin/CoordinateUtils.java10
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java1
-rw-r--r--java/src/com/android/inputmethod/latin/Settings.java2
-rw-r--r--java/src/com/android/inputmethod/latin/SettingsValues.java2
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java22
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java41
6 files changed, 63 insertions, 15 deletions
diff --git a/java/src/com/android/inputmethod/latin/CoordinateUtils.java b/java/src/com/android/inputmethod/latin/CoordinateUtils.java
index cd3177299..af270e1e4 100644
--- a/java/src/com/android/inputmethod/latin/CoordinateUtils.java
+++ b/java/src/com/android/inputmethod/latin/CoordinateUtils.java
@@ -36,4 +36,14 @@ public final class CoordinateUtils {
public static int y(final int[] coords) {
return coords[INDEX_Y];
}
+
+ public static void set(final int[] coords, final int x, final int y) {
+ coords[INDEX_X] = x;
+ coords[INDEX_Y] = y;
+ }
+
+ public static void copy(final int[] destination, final int[] source) {
+ destination[INDEX_X] = source[INDEX_X];
+ destination[INDEX_Y] = source[INDEX_Y];
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 8519ad31d..d8e536745 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1177,6 +1177,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
private boolean maybeDoubleSpace() {
if (!mCurrentSettings.mCorrectionEnabled) return false;
+ if (!mCurrentSettings.mUseDoubleSpacePeriod) return false;
if (!mHandler.isAcceptingDoubleSpaces()) return false;
final CharSequence lastThree = mConnection.getTextBeforeCursor(3, 0);
if (lastThree != null && lastThree.length() == 3
diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java
index fdad5430a..7a73cade3 100644
--- a/java/src/com/android/inputmethod/latin/Settings.java
+++ b/java/src/com/android/inputmethod/latin/Settings.java
@@ -60,6 +60,8 @@ public final class Settings extends InputMethodSettingsFragment
"last_user_dictionary_write_time";
public static final String PREF_ADVANCED_SETTINGS = "pref_advanced_settings";
public static final String PREF_KEY_USE_CONTACTS_DICT = "pref_key_use_contacts_dict";
+ public static final String PREF_KEY_USE_DOUBLE_SPACE_PERIOD =
+ "pref_key_use_double_space_period";
public static final String PREF_SHOW_LANGUAGE_SWITCH_KEY =
"pref_show_language_switch_key";
public static final String PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST =
diff --git a/java/src/com/android/inputmethod/latin/SettingsValues.java b/java/src/com/android/inputmethod/latin/SettingsValues.java
index 8de64c1c9..a23876722 100644
--- a/java/src/com/android/inputmethod/latin/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/SettingsValues.java
@@ -75,6 +75,7 @@ public final class SettingsValues {
@SuppressWarnings("unused") // TODO: Use this
private final String mKeyPreviewPopupDismissDelayRawValue;
public final boolean mUseContactsDict;
+ public final boolean mUseDoubleSpacePeriod;
// Use bigrams to predict the next word when there is no input for it yet
public final boolean mBigramPredictionEnabled;
@SuppressWarnings("unused") // TODO: Use this
@@ -154,6 +155,7 @@ public final class SettingsValues {
Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY,
Integer.toString(res.getInteger(R.integer.config_key_preview_linger_timeout)));
mUseContactsDict = prefs.getBoolean(Settings.PREF_KEY_USE_CONTACTS_DICT, true);
+ mUseDoubleSpacePeriod = prefs.getBoolean(Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD, true);
mAutoCorrectEnabled = isAutoCorrectEnabled(res, mAutoCorrectionThresholdRawValue);
mBigramPredictionEnabled = isBigramPredictionEnabled(prefs, res);
mVibrationDurationSettingsRawValue =
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
index 49b98863f..2f146f86c 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
@@ -438,15 +438,23 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
if (!Character.isUpperCase(text.codePointAt(0))) return CAPITALIZE_NONE;
final int len = text.length();
int capsCount = 1;
+ int letterCount = 1;
for (int i = 1; i < len; i = text.offsetByCodePoints(i, 1)) {
- if (1 != capsCount && i != capsCount) break;
- if (Character.isUpperCase(text.codePointAt(i))) ++capsCount;
+ if (1 != capsCount && letterCount != capsCount) break;
+ final int codePoint = text.codePointAt(i);
+ if (Character.isUpperCase(codePoint)) {
+ ++capsCount;
+ ++letterCount;
+ } else if (Character.isLetter(codePoint)) {
+ // We need to discount non-letters since they may not be upper-case, but may
+ // still be part of a word (e.g. single quote or dash, as in "IT'S" or "FULL-TIME")
+ ++letterCount;
+ }
}
- // We know the first char is upper case. So we want to test if either everything
- // else is lower case, or if everything else is upper case. If the string is
- // exactly one char long, then we will arrive here with capsCount 1, and this is
- // correct, too.
+ // We know the first char is upper case. So we want to test if either every letter other
+ // than the first is lower case, or if they are all upper case. If the string is exactly
+ // one char long, then we will arrive here with letterCount 1, and this is correct, too.
if (1 == capsCount) return CAPITALIZE_FIRST;
- return (len == capsCount ? CAPITALIZE_ALL : CAPITALIZE_NONE);
+ return (letterCount == capsCount ? CAPITALIZE_ALL : CAPITALIZE_NONE);
}
}
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
index a8f323999..470943be1 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
@@ -28,9 +28,11 @@ import android.view.textservice.TextInfo;
import com.android.inputmethod.compat.SuggestionsInfoCompatUtils;
import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.LocaleUtils;
-import com.android.inputmethod.latin.WordComposer;
+import com.android.inputmethod.latin.StringUtils;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.WordComposer;
import com.android.inputmethod.latin.spellcheck.AndroidSpellCheckerService.SuggestionsGatherer;
import java.util.ArrayList;
@@ -188,6 +190,35 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
return (letterCount * 4 < length * 3);
}
+ /**
+ * Helper method to test valid capitalizations of a word.
+ *
+ * If the "text" is lower-case, we test only the exact string.
+ * If the "Text" is capitalized, we test the exact string "Text" and the lower-cased
+ * version of it "text".
+ * If the "TEXT" is fully upper case, we test the exact string "TEXT", the lower-cased
+ * version of it "text" and the capitalized version of it "Text".
+ */
+ private boolean isInDictForAnyCapitalization(final Dictionary dict, final String text,
+ final int capitalizeType) {
+ // If the word is in there as is, then it's in the dictionary. If not, we'll test lower
+ // case versions, but only if the word is not already all-lower case or mixed case.
+ if (dict.isValidWord(text)) return true;
+ if (AndroidSpellCheckerService.CAPITALIZE_NONE == capitalizeType) return false;
+
+ // If we come here, we have a capitalized word (either First- or All-).
+ // Downcase the word and look it up again. If the word is only capitalized, we
+ // tested all possibilities, so if it's still negative we can return false.
+ final String lowerCaseText = text.toLowerCase(mLocale);
+ if (dict.isValidWord(lowerCaseText)) return true;
+ if (AndroidSpellCheckerService.CAPITALIZE_FIRST == capitalizeType) return false;
+
+ // If the lower case version is not in the dictionary, it's still possible
+ // that we have an all-caps version of a word that needs to be capitalized
+ // according to the dictionary. E.g. "GERMANS" only exists in the dictionary as "Germans".
+ return dict.isValidWord(StringUtils.toTitleCase(lowerCaseText, mLocale));
+ }
+
// Note : this must be reentrant
/**
* Gets a list of suggestions for a specific string. This returns a list of possible
@@ -272,13 +303,7 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
suggestionsGatherer.addWord(suggestionStr.toCharArray(), null, 0,
suggestionStr.length(), suggestion.mScore);
}
- isInDict = dictInfo.mDictionary.isValidWord(text);
- if (!isInDict && AndroidSpellCheckerService.CAPITALIZE_NONE != capitalizeType) {
- // We want to test the word again if it's all caps or first caps only.
- // If it's fully down, we already tested it, if it's mixed case, we don't
- // want to test a lowercase version of it.
- isInDict = dictInfo.mDictionary.isValidWord(text.toLowerCase(mLocale));
- }
+ isInDict = isInDictForAnyCapitalization(dictInfo.mDictionary, text, capitalizeType);
} finally {
if (null != dictInfo) {
if (!mDictionaryPool.offer(dictInfo)) {