aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--java/res/values-xlarge/bools.xml1
-rw-r--r--java/res/values/bools.xml1
-rw-r--r--java/res/xml/prefs.xml1
-rw-r--r--java/src/com/android/inputmethod/latin/Settings.java7
-rw-r--r--java/src/com/android/inputmethod/latin/UserDictionary.java20
-rw-r--r--native/src/defines.h6
-rw-r--r--native/src/unigram_dictionary.cpp89
-rw-r--r--native/src/unigram_dictionary.h12
8 files changed, 89 insertions, 48 deletions
diff --git a/java/res/values-xlarge/bools.xml b/java/res/values-xlarge/bools.xml
index abacfa18b..9fb670c54 100644
--- a/java/res/values-xlarge/bools.xml
+++ b/java/res/values-xlarge/bools.xml
@@ -21,6 +21,7 @@
<!-- Whether or not Popup on key press is enabled by default -->
<bool name="default_popup_preview">false</bool>
<bool name="config_enable_show_settings_key_option">false</bool>
+ <bool name="config_enable_show_subtype_settings">false</bool>
<bool name="config_enable_show_voice_key_option">false</bool>
<bool name="config_candidate_highlight_font_color_enabled">false</bool>
</resources>
diff --git a/java/res/values/bools.xml b/java/res/values/bools.xml
index 84b0fe182..8742676ad 100644
--- a/java/res/values/bools.xml
+++ b/java/res/values/bools.xml
@@ -31,6 +31,7 @@
<bool name="default_recorrection_enabled">true</bool>
<bool name="config_long_press_comma_for_settings_enabled">true</bool>
<bool name="config_enable_show_settings_key_option">true</bool>
+ <bool name="config_enable_show_subtype_settings">true</bool>
<bool name="config_enable_show_voice_key_option">true</bool>
<bool name="config_candidate_highlight_font_color_enabled">true</bool>
</resources>
diff --git a/java/res/xml/prefs.xml b/java/res/xml/prefs.xml
index 0eee06031..47b3b4589 100644
--- a/java/res/xml/prefs.xml
+++ b/java/res/xml/prefs.xml
@@ -73,6 +73,7 @@
<!-- TODO: Filter subtypes by IME in SubtypeEnabler -->
<!-- TODO: Maybe use this only for phone? -->
<PreferenceScreen
+ android:key="subtype_settings"
android:title="@string/language_selection_title"
android:summary="@string/language_selection_summary">
<intent
diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java
index b8590a76e..3f604a381 100644
--- a/java/src/com/android/inputmethod/latin/Settings.java
+++ b/java/src/com/android/inputmethod/latin/Settings.java
@@ -53,6 +53,7 @@ public class Settings extends PreferenceActivity
public static final String PREF_VOICE_SETTINGS_KEY = "voice_mode";
public static final String PREF_INPUT_LANGUAGE = "input_language";
public static final String PREF_SELECTED_LANGUAGES = "selected_languages";
+ public static final String PREF_SUBTYPES = "subtype_settings";
public static final String PREF_PREDICTION_SETTINGS_KEY = "prediction_settings";
public static final String PREF_QUICK_FIXES = "quick_fixes";
@@ -119,6 +120,12 @@ public class Settings extends PreferenceActivity
getPreferenceScreen().removePreference(
getPreferenceScreen().findPreference(PREF_VIBRATE_ON));
}
+
+ final boolean showSubtypeSettings = getResources().getBoolean(
+ R.bool.config_enable_show_subtype_settings);
+ if (!showSubtypeSettings) {
+ getPreferenceScreen().removePreference(findPreference(PREF_SUBTYPES));
+ }
}
@Override
diff --git a/java/src/com/android/inputmethod/latin/UserDictionary.java b/java/src/com/android/inputmethod/latin/UserDictionary.java
index 7a94ae480..e03f56498 100644
--- a/java/src/com/android/inputmethod/latin/UserDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserDictionary.java
@@ -21,6 +21,7 @@ import android.content.ContentValues;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
+import android.net.Uri;
import android.provider.UserDictionary.Words;
public class UserDictionary extends ExpandableDictionary {
@@ -80,7 +81,7 @@ public class UserDictionary extends ExpandableDictionary {
* @TODO use a higher or float range for frequency
*/
@Override
- public synchronized void addWord(String word, int frequency) {
+ public synchronized void addWord(final String word, final int frequency) {
// Force load the dictionary here synchronously
if (getRequiresReload()) loadDictionaryAsync();
// Safeguard against adding long words. Can cause stack overflow.
@@ -99,7 +100,22 @@ public class UserDictionary extends ExpandableDictionary {
new Thread("addWord") {
@Override
public void run() {
- contentResolver.insert(Words.CONTENT_URI, values);
+ Cursor cursor = contentResolver.query(Words.CONTENT_URI, PROJECTION,
+ "word=? and ((locale IS NULL) or (locale=?))",
+ new String[] { word, mLocale }, null);
+ if (cursor != null && cursor.moveToFirst()) {
+ String locale = cursor.getString(cursor.getColumnIndex(Words.LOCALE));
+ // If locale is null, we will not override the entry.
+ if (locale != null && locale.equals(mLocale.toString())) {
+ long id = cursor.getLong(cursor.getColumnIndex(Words._ID));
+ Uri uri = Uri.withAppendedPath(Words.CONTENT_URI, Long.toString(id));
+ // Update the entry with new frequency value.
+ contentResolver.update(uri, values, null, null);
+ }
+ } else {
+ // Insert new entry.
+ contentResolver.insert(Words.CONTENT_URI, values);
+ }
}
}.start();
diff --git a/native/src/defines.h b/native/src/defines.h
index 52191beea..73394ce36 100644
--- a/native/src/defines.h
+++ b/native/src/defines.h
@@ -67,6 +67,7 @@
#define WORDS_WITH_MISSING_CHARACTER_DEMOTION_RATE 75
#define WORDS_WITH_MISSING_SPACE_CHARACTER_DEMOTION_RATE 80
#define WORDS_WITH_EXCESSIVE_CHARACTER_DEMOTION_RATE 75
+#define WORDS_WITH_EXCESSIVE_CHARACTER_OUT_OF_PROXIMITY_DEMOTION_RATE 75
#define WORDS_WITH_TRANSPOSED_CHARACTERS_DEMOTION_RATE 60
// This should be greater than or equal to MAX_WORD_LENGTH defined in BinaryDictionary.java
@@ -75,7 +76,10 @@
#define MAX_DEPTH_MULTIPLIER 3
-#define MIN_SUGGEST_DEPTH 2
+// Minimum suggest depth for one word for all cases except for missing space suggestions.
+#define MIN_SUGGEST_DEPTH 1
+#define MIN_USER_TYPED_LENGTH_FOR_MISSING_SPACE_SUGGESTION 3
+#define MIN_USER_TYPED_LENGTH_FOR_EXCESSIVE_CHARACTER_SUGGESTION 3
#define min(a,b) ((a)<(b)?(a):(b))
diff --git a/native/src/unigram_dictionary.cpp b/native/src/unigram_dictionary.cpp
index 7ecf1c9c0..f679001cf 100644
--- a/native/src/unigram_dictionary.cpp
+++ b/native/src/unigram_dictionary.cpp
@@ -45,24 +45,25 @@ int UnigramDictionary::getSuggestions(int *codes, int codesSize, unsigned short
int *frequencies, int *nextLetters, int nextLettersSize)
{
initSuggestions(codes, codesSize, outWords, frequencies);
+ if (DEBUG_DICT) assert(codesSize == mInputLength);
+
const int MAX_DEPTH = min(mInputLength * MAX_DEPTH_MULTIPLIER, MAX_WORD_LENGTH);
- getSuggestionCandidates(codesSize, -1, -1, -1, nextLetters, nextLettersSize, MAX_DEPTH);
+ getSuggestionCandidates(-1, -1, -1, nextLetters, nextLettersSize, MAX_DEPTH);
// Suggestion with missing character
if (SUGGEST_WORDS_WITH_MISSING_CHARACTER) {
for (int i = 0; i < codesSize; ++i) {
if (DEBUG_DICT) LOGI("--- Suggest missing characters %d", i);
- getSuggestionCandidates(codesSize, i, -1, -1, NULL, 0, MAX_DEPTH);
+ getSuggestionCandidates(i, -1, -1, NULL, 0, MAX_DEPTH);
}
}
// Suggestion with excessive character
- if (SUGGEST_WORDS_WITH_EXCESSIVE_CHARACTER && mInputLength > MIN_SUGGEST_DEPTH) {
+ if (SUGGEST_WORDS_WITH_EXCESSIVE_CHARACTER
+ && mInputLength >= MIN_USER_TYPED_LENGTH_FOR_EXCESSIVE_CHARACTER_SUGGESTION) {
for (int i = 0; i < codesSize; ++i) {
- if (existsAdjacentProximityChars(i, codesSize)) {
- if (DEBUG_DICT) LOGI("--- Suggest excessive characters %d", i);
- getSuggestionCandidates(codesSize, -1, i, -1, NULL, 0, MAX_DEPTH);
- }
+ if (DEBUG_DICT) LOGI("--- Suggest excessive characters %d", i);
+ getSuggestionCandidates(-1, i, -1, NULL, 0, MAX_DEPTH);
}
}
@@ -71,12 +72,13 @@ int UnigramDictionary::getSuggestions(int *codes, int codesSize, unsigned short
if (SUGGEST_WORDS_WITH_TRANSPOSED_CHARACTERS) {
for (int i = 0; i < codesSize; ++i) {
if (DEBUG_DICT) LOGI("--- Suggest transposed characters %d", i);
- getSuggestionCandidates(codesSize, -1, -1, i, NULL, 0, mInputLength - 1);
+ getSuggestionCandidates(-1, -1, i, NULL, 0, mInputLength - 1);
}
}
// Suggestions with missing space
- if (SUGGEST_WORDS_WITH_MISSING_SPACE_CHARACTER && mInputLength > MIN_SUGGEST_DEPTH) {
+ if (SUGGEST_WORDS_WITH_MISSING_SPACE_CHARACTER
+ && mInputLength >= MIN_USER_TYPED_LENGTH_FOR_MISSING_SPACE_SUGGESTION) {
for (int i = 1; i < codesSize; ++i) {
if (DEBUG_DICT) LOGI("--- Suggest missing space characters %d", i);
getMissingSpaceWords(mInputLength, i);
@@ -196,13 +198,15 @@ bool UnigramDictionary::sameAsTyped(unsigned short *word, int length) {
static const char QUOTE = '\'';
static const char SPACE = ' ';
-void UnigramDictionary::getSuggestionCandidates(const int inputLength, const int skipPos,
+void UnigramDictionary::getSuggestionCandidates(const int skipPos,
const int excessivePos, const int transposedPos, int *nextLetters,
const int nextLettersSize, const int maxDepth) {
- if (DEBUG_DICT) LOGI("getSuggestionCandidates %d", maxDepth);
- if (DEBUG_DICT) assert(transposedPos + 1 < inputLength);
- if (DEBUG_DICT) assert(excessivePos < inputLength);
- if (DEBUG_DICT) assert(missingPos < inputLength);
+ if (DEBUG_DICT) {
+ LOGI("getSuggestionCandidates %d", maxDepth);
+ assert(transposedPos + 1 < mInputLength);
+ assert(excessivePos < mInputLength);
+ assert(missingPos < mInputLength);
+ }
int rootPosition = ROOT_POS;
// Get the number of child of root, then increment the position
int childCount = Dictionary::getCount(DICT, &rootPosition);
@@ -321,41 +325,46 @@ void UnigramDictionary::getWordsRec(const int childrenCount, const int pos, cons
}
}
-inline void UnigramDictionary::onTerminalWhenUserTypedLengthIsGreaterThanInputLength(
- unsigned short *word, const int inputLength, const int depth, const int snr,
- int *nextLetters, const int nextLettersSize, const int skipPos, const int excessivePos,
- const int transposedPos, const int freq) {
- int finalFreq = freq * snr;
+inline int UnigramDictionary::calculateFinalFreq(const int inputIndex, const int snr,
+ const int skipPos, const int excessivePos, const int transposedPos, const int freq,
+ const bool sameLength) {
// TODO: Demote by edit distance
+ int finalFreq = freq * snr;
if (skipPos >= 0) finalFreq = finalFreq * WORDS_WITH_MISSING_CHARACTER_DEMOTION_RATE / 100;
- if (excessivePos >= 0) finalFreq = finalFreq
- * WORDS_WITH_EXCESSIVE_CHARACTER_DEMOTION_RATE / 100;
if (transposedPos >= 0) finalFreq = finalFreq
* WORDS_WITH_TRANSPOSED_CHARACTERS_DEMOTION_RATE / 100;
+ if (excessivePos >= 0) {
+ finalFreq = finalFreq * WORDS_WITH_EXCESSIVE_CHARACTER_DEMOTION_RATE / 100;
+ if (!existsAdjacentProximityChars(inputIndex, mInputLength)) {
+ finalFreq = finalFreq
+ * WORDS_WITH_EXCESSIVE_CHARACTER_OUT_OF_PROXIMITY_DEMOTION_RATE / 100;
+ }
+ }
+ if (sameLength && skipPos < 0) finalFreq *= FULL_WORD_MULTIPLIER;
+ return finalFreq;
+}
+inline void UnigramDictionary::onTerminalWhenUserTypedLengthIsGreaterThanInputLength(
+ unsigned short *word, const int inputIndex, const int depth, const int snr,
+ int *nextLetters, const int nextLettersSize, const int skipPos, const int excessivePos,
+ const int transposedPos, const int freq) {
+ const int finalFreq = calculateFinalFreq(inputIndex, snr, skipPos, excessivePos, transposedPos,
+ freq, false);
if (depth >= MIN_SUGGEST_DEPTH) addWord(word, depth + 1, finalFreq);
- if (depth >= inputLength && skipPos < 0) {
+ if (depth >= mInputLength && skipPos < 0) {
registerNextLetter(mWord[mInputLength], nextLetters, nextLettersSize);
}
}
inline void UnigramDictionary::onTerminalWhenUserTypedLengthIsSameAsInputLength(
- unsigned short *word, const int depth, const int snr, const int skipPos,
- const int excessivePos, const int transposedPos, const int freq, const int addedWeight) {
- if (!sameAsTyped(word, depth + 1)) {
- int finalFreq = freq * snr * addedWeight;
- // TODO: Demote by edit distance
- if (skipPos >= 0) finalFreq = finalFreq * WORDS_WITH_MISSING_CHARACTER_DEMOTION_RATE / 100;
- if (excessivePos >= 0) finalFreq = finalFreq
- * WORDS_WITH_EXCESSIVE_CHARACTER_DEMOTION_RATE / 100;
- if (transposedPos >= 0) finalFreq = finalFreq
- * WORDS_WITH_TRANSPOSED_CHARACTERS_DEMOTION_RATE / 100;
-
- // Proximity collection will promote a word of the same length as
- // what user typed.
- if (skipPos < 0) finalFreq *= FULL_WORD_MULTIPLIER;
- if (depth >= MIN_SUGGEST_DEPTH) addWord(word, depth + 1, finalFreq);
- }
+ unsigned short *word, const int inputIndex, const int depth, const int snr,
+ const int skipPos, const int excessivePos, const int transposedPos, const int freq,
+ const int addedWeight) {
+ if (sameAsTyped(word, depth + 1)) return;
+ const int finalFreq = calculateFinalFreq(inputIndex, snr * addedWeight, skipPos,
+ excessivePos, transposedPos, freq, true);
+ // Proximity collection will promote a word of the same length as what user typed.
+ if (depth >= MIN_SUGGEST_DEPTH) addWord(word, depth + 1, finalFreq);
}
inline bool UnigramDictionary::needsToSkipCurrentNode(const unsigned short c,
@@ -437,7 +446,7 @@ inline bool UnigramDictionary::processCurrentNode(const int pos, const int depth
if (traverseAllNodes || needsToSkipCurrentNode(c, inputIndex, skipPos, depth)) {
mWord[depth] = c;
if (traverseAllNodes && terminal) {
- onTerminalWhenUserTypedLengthIsGreaterThanInputLength(mWord, mInputLength, depth,
+ onTerminalWhenUserTypedLengthIsGreaterThanInputLength(mWord, inputIndex, depth,
snr, nextLetters, nextLettersSize, skipPos, excessivePos, transposedPos, freq);
}
if (!needsToTraverseChildrenNodes) return false;
@@ -462,7 +471,7 @@ inline bool UnigramDictionary::processCurrentNode(const int pos, const int depth
const int addedWeight = matchedProximityCharId == 0 ? TYPED_LETTER_MULTIPLIER : 1;
const bool isSameAsUserTypedLength = mInputLength == inputIndex + 1;
if (isSameAsUserTypedLength && terminal) {
- onTerminalWhenUserTypedLengthIsSameAsInputLength(mWord, depth, snr,
+ onTerminalWhenUserTypedLengthIsSameAsInputLength(mWord, inputIndex, depth, snr,
skipPos, excessivePos, transposedPos, freq, addedWeight);
}
if (!needsToTraverseChildrenNodes) return false;
diff --git a/native/src/unigram_dictionary.h b/native/src/unigram_dictionary.h
index abfdb8d87..445ff7a17 100644
--- a/native/src/unigram_dictionary.h
+++ b/native/src/unigram_dictionary.h
@@ -31,7 +31,7 @@ public:
private:
void initSuggestions(int *codes, int codesSize, unsigned short *outWords, int *frequencies);
- void getSuggestionCandidates(const int inputLength, const int skipPos, const int excessivePos,
+ void getSuggestionCandidates(const int skipPos, const int excessivePos,
const int transposedPos, int *nextLetters, const int nextLettersSize,
const int maxDepth);
void getVersionNumber();
@@ -52,13 +52,15 @@ private:
const int excessivePos, const int transposedPos, int *nextLetters,
const int nextLettersSize);
void registerNextLetter(unsigned short c, int *nextLetters, int nextLettersSize);
+ int calculateFinalFreq(const int inputIndex, const int snr, const int skipPos,
+ const int excessivePos, const int transposedPos, const int freq, const bool sameLength);
void onTerminalWhenUserTypedLengthIsGreaterThanInputLength(unsigned short *word,
- const int mInputLength, const int depth, const int snr, int *nextLetters,
+ const int inputIndex, const int depth, const int snr, int *nextLetters,
const int nextLettersSize, const int skipPos, const int excessivePos,
const int transposedPos, const int freq);
- void onTerminalWhenUserTypedLengthIsSameAsInputLength(unsigned short *word, const int depth,
- const int snr, const int skipPos, const int excessivePos, const int transposedPos,
- const int freq, const int addedWeight);
+ void onTerminalWhenUserTypedLengthIsSameAsInputLength(unsigned short *word,
+ const int inputIndex, const int depth, const int snr, const int skipPos,
+ const int excessivePos, const int transposedPos, const int freq, const int addedWeight);
bool needsToSkipCurrentNode(const unsigned short c,
const int inputIndex, const int skipPos, const int depth);
int getMatchedProximityId(const int *currentChars, const unsigned short c, const int skipPos,