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/BinaryDictionary.java95
-rw-r--r--java/src/com/android/inputmethod/latin/Constants.java2
-rw-r--r--java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java6
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java37
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java2
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/AbstractDictDecoder.java2
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/FormatSpec.java25
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java2
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java10
-rw-r--r--java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java3
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java27
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java32
-rw-r--r--java/src/com/android/inputmethod/latin/utils/CollectionUtils.java15
-rw-r--r--java/src/com/android/inputmethod/latin/utils/CsvUtils.java7
-rw-r--r--java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java14
-rw-r--r--java/src/com/android/inputmethod/latin/utils/StringUtils.java18
-rw-r--r--java/src/com/android/inputmethod/latin/utils/UserHistoryDictIOUtils.java9
-rw-r--r--java/src/com/android/inputmethod/latin/utils/WordProperty.java (renamed from java/src/com/android/inputmethod/latin/utils/UnigramProperty.java)60
18 files changed, 270 insertions, 96 deletions
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index e66cfca49..00eb57c9f 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -22,12 +22,13 @@ import android.util.SparseArray;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.makedict.Word;
import com.android.inputmethod.latin.settings.NativeSuggestOptions;
import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.JniUtils;
import com.android.inputmethod.latin.utils.LanguageModelParam;
import com.android.inputmethod.latin.utils.StringUtils;
-import com.android.inputmethod.latin.utils.UnigramProperty;
+import com.android.inputmethod.latin.utils.WordProperty;
import java.io.File;
import java.util.ArrayList;
@@ -61,18 +62,19 @@ public final class BinaryDictionary extends Dictionary {
public static final int NOT_A_VALID_TIMESTAMP = -1;
- // Format to get unigram flags from native side via getUnigramPropertyNative().
- private static final int FORMAT_UNIGRAM_PROPERTY_OUTPUT_FLAG_COUNT = 4;
- private static final int FORMAT_UNIGRAM_PROPERTY_IS_NOT_A_WORD_INDEX = 0;
- private static final int FORMAT_UNIGRAM_PROPERTY_IS_BLACKLISTED_INDEX = 1;
- private static final int FORMAT_UNIGRAM_PROPERTY_HAS_BIGRAMS_INDEX = 2;
- private static final int FORMAT_UNIGRAM_PROPERTY_HAS_SHORTCUTS_INDEX = 3;
+ // Format to get unigram flags from native side via getWordPropertyNative().
+ private static final int FORMAT_WORD_PROPERTY_OUTPUT_FLAG_COUNT = 4;
+ private static final int FORMAT_WORD_PROPERTY_IS_NOT_A_WORD_INDEX = 0;
+ private static final int FORMAT_WORD_PROPERTY_IS_BLACKLISTED_INDEX = 1;
+ private static final int FORMAT_WORD_PROPERTY_HAS_BIGRAMS_INDEX = 2;
+ private static final int FORMAT_WORD_PROPERTY_HAS_SHORTCUTS_INDEX = 3;
- // Format to get unigram historical info from native side via getUnigramPropertyNative().
- private static final int FORMAT_UNIGRAM_PROPERTY_OUTPUT_HISTORICAL_INFO_COUNT = 3;
- private static final int FORMAT_UNIGRAM_PROPERTY_TIMESTAMP_INDEX = 0;
- private static final int FORMAT_UNIGRAM_PROPERTY_LEVEL_INDEX = 1;
- private static final int FORMAT_UNIGRAM_PROPERTY_COUNT_INDEX = 2;
+ // Format to get probability and historical info from native side via getWordPropertyNative().
+ public static final int FORMAT_WORD_PROPERTY_OUTPUT_PROBABILITY_INFO_COUNT = 4;
+ public static final int FORMAT_WORD_PROPERTY_PROBABILITY_INDEX = 0;
+ public static final int FORMAT_WORD_PROPERTY_TIMESTAMP_INDEX = 1;
+ public static final int FORMAT_WORD_PROPERTY_LEVEL_INDEX = 2;
+ public static final int FORMAT_WORD_PROPERTY_COUNT_INDEX = 3;
private long mNativeDict;
private final Locale mLocale;
@@ -143,10 +145,11 @@ public final class BinaryDictionary extends Dictionary {
private static native int getFormatVersionNative(long dict);
private static native int getProbabilityNative(long dict, int[] word);
private static native int getBigramProbabilityNative(long dict, int[] word0, int[] word1);
- private static native void getUnigramPropertyNative(long dict, int[] word,
- int[] outCodePoints, boolean[] outFlags, int[] outProbability,
- int[] outHistoricalInfo, ArrayList<int[]> outShortcutTargets,
- ArrayList<Integer> outShortcutProbabilities);
+ private static native void getWordPropertyNative(long dict, int[] word,
+ int[] outCodePoints, boolean[] outFlags, int[] outProbabilityInfo,
+ ArrayList<int[]> outBigramTargets, ArrayList<int[]> outBigramProbabilityInfo,
+ ArrayList<int[]> outShortcutTargets, ArrayList<Integer> outShortcutProbabilities);
+ private static native int getNextWordNative(long dict, int token, int[] outCodePoints);
private static native int getSuggestionsNative(long dict, long proximityInfo,
long traverseSession, int[] xCoordinates, int[] yCoordinates, int[] times,
int[] pointerIds, int[] inputCodePoints, int inputSize, int commitPoint,
@@ -306,29 +309,56 @@ public final class BinaryDictionary extends Dictionary {
}
@UsedForTesting
- public UnigramProperty getUnigramProperty(final String word) {
+ public WordProperty getWordProperty(final String word) {
if (TextUtils.isEmpty(word)) {
return null;
}
final int[] codePoints = StringUtils.toCodePointArray(word);
final int[] outCodePoints = new int[MAX_WORD_LENGTH];
- final boolean[] outFlags = new boolean[FORMAT_UNIGRAM_PROPERTY_OUTPUT_FLAG_COUNT];
- final int[] outProbability = new int[1];
- final int[] outHistoricalInfo =
- new int[FORMAT_UNIGRAM_PROPERTY_OUTPUT_HISTORICAL_INFO_COUNT];
+ final boolean[] outFlags = new boolean[FORMAT_WORD_PROPERTY_OUTPUT_FLAG_COUNT];
+ final int[] outProbabilityInfo =
+ new int[FORMAT_WORD_PROPERTY_OUTPUT_PROBABILITY_INFO_COUNT];
+ final ArrayList<int[]> outBigramTargets = CollectionUtils.newArrayList();
+ final ArrayList<int[]> outBigramProbabilityInfo = CollectionUtils.newArrayList();
final ArrayList<int[]> outShortcutTargets = CollectionUtils.newArrayList();
final ArrayList<Integer> outShortcutProbabilities = CollectionUtils.newArrayList();
- getUnigramPropertyNative(mNativeDict, codePoints, outCodePoints, outFlags, outProbability,
- outHistoricalInfo, outShortcutTargets, outShortcutProbabilities);
- return new UnigramProperty(codePoints,
- outFlags[FORMAT_UNIGRAM_PROPERTY_IS_NOT_A_WORD_INDEX],
- outFlags[FORMAT_UNIGRAM_PROPERTY_IS_BLACKLISTED_INDEX],
- outFlags[FORMAT_UNIGRAM_PROPERTY_HAS_BIGRAMS_INDEX],
- outFlags[FORMAT_UNIGRAM_PROPERTY_HAS_SHORTCUTS_INDEX], outProbability[0],
- outHistoricalInfo[FORMAT_UNIGRAM_PROPERTY_TIMESTAMP_INDEX],
- outHistoricalInfo[FORMAT_UNIGRAM_PROPERTY_LEVEL_INDEX],
- outHistoricalInfo[FORMAT_UNIGRAM_PROPERTY_COUNT_INDEX],
- outShortcutTargets, outShortcutProbabilities);
+ getWordPropertyNative(mNativeDict, codePoints, outCodePoints, outFlags, outProbabilityInfo,
+ outBigramTargets, outBigramProbabilityInfo, outShortcutTargets,
+ outShortcutProbabilities);
+ return new WordProperty(codePoints,
+ outFlags[FORMAT_WORD_PROPERTY_IS_NOT_A_WORD_INDEX],
+ outFlags[FORMAT_WORD_PROPERTY_IS_BLACKLISTED_INDEX],
+ outFlags[FORMAT_WORD_PROPERTY_HAS_BIGRAMS_INDEX],
+ outFlags[FORMAT_WORD_PROPERTY_HAS_SHORTCUTS_INDEX], outProbabilityInfo,
+ outBigramTargets, outBigramProbabilityInfo, outShortcutTargets,
+ outShortcutProbabilities);
+ }
+
+ public static class GetNextWordPropertyResult {
+ public WordProperty mWordProperty;
+ public int mNextToken;
+
+ public GetNextWordPropertyResult(final WordProperty wordPreperty, final int nextToken) {
+ mWordProperty = wordPreperty;
+ mNextToken = nextToken;
+ }
+ }
+
+ /**
+ * Method to iterate all words in the dictionary for makedict.
+ * If token is 0, this method newly starts iterating the dictionary.
+ */
+ @UsedForTesting
+ public GetNextWordPropertyResult getNextWordProperty(final int token) {
+ final int[] codePoints = new int[MAX_WORD_LENGTH];
+ final int nextToken = getNextWordNative(mNativeDict, token, codePoints);
+ int len = 0;
+ // codePoints is null-terminated if its length is shorter than the array length.
+ while (len < MAX_WORD_LENGTH && codePoints[len] != 0) {
+ ++len;
+ }
+ final String word = new String(mOutputCodePoints, 0, len);
+ return new GetNextWordPropertyResult(getWordProperty(word), nextToken);
}
// Add a unigram entry to binary dictionary with unigram attributes in native code.
@@ -379,7 +409,6 @@ public final class BinaryDictionary extends Dictionary {
return;
}
}
-
}
private void reopen() {
diff --git a/java/src/com/android/inputmethod/latin/Constants.java b/java/src/com/android/inputmethod/latin/Constants.java
index 0b396b1de..d6ac71fe2 100644
--- a/java/src/com/android/inputmethod/latin/Constants.java
+++ b/java/src/com/android/inputmethod/latin/Constants.java
@@ -191,6 +191,8 @@ public final class Constants {
public static final int CODE_QUESTION_MARK = '?';
public static final int CODE_EXCLAMATION_MARK = '!';
public static final int CODE_SLASH = '/';
+ public static final int CODE_BACKSLASH = '\\';
+ public static final int CODE_VERTICAL_BAR = '|';
public static final int CODE_COMMERCIAL_AT = '@';
public static final int CODE_PLUS = '+';
public static final int CODE_PERCENT = '%';
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index 8e1675b2a..4dee84a7b 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -267,9 +267,9 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
protected Map<String, String> getHeaderAttributeMap() {
HashMap<String, String> attributeMap = new HashMap<String, String>();
- attributeMap.put(FormatSpec.FileHeader.DICTIONARY_ID_ATTRIBUTE, mDictName);
- attributeMap.put(FormatSpec.FileHeader.DICTIONARY_LOCALE_ATTRIBUTE, mLocale.toString());
- attributeMap.put(FormatSpec.FileHeader.DICTIONARY_VERSION_ATTRIBUTE,
+ attributeMap.put(FormatSpec.FileHeader.DICTIONARY_ID_KEY, mDictName);
+ attributeMap.put(FormatSpec.FileHeader.DICTIONARY_LOCALE_KEY, mLocale.toString());
+ attributeMap.put(FormatSpec.FileHeader.DICTIONARY_VERSION_KEY,
String.valueOf(TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())));
return attributeMap;
}
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 8f4b2d67e..6517ef29d 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -79,6 +79,7 @@ import com.android.inputmethod.latin.utils.ApplicationUtils;
import com.android.inputmethod.latin.utils.CapsModeUtils;
import com.android.inputmethod.latin.utils.CompletionInfoUtils;
import com.android.inputmethod.latin.utils.CoordinateUtils;
+import com.android.inputmethod.latin.utils.ImportantNoticeUtils;
import com.android.inputmethod.latin.utils.IntentUtils;
import com.android.inputmethod.latin.utils.JniUtils;
import com.android.inputmethod.latin.utils.LatinImeLoggerUtils;
@@ -1157,6 +1158,27 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mInputLogic.mSuggest.mDictionaryFacilitator.addWordToUserDictionary(wordToEdit);
}
+ // TODO: Move this method out of {@link LatinIME}.
+ // Callback for the {@link SuggestionStripView}, to call when the important notice strip is
+ // pressed.
+ @Override
+ public void showImportantNoticeContents() {
+ final Context context = this;
+ final DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(final DialogInterface di, final int position) {
+ di.dismiss();
+ ImportantNoticeUtils.updateLastImportantNoticeVersion(context);
+ setNeutralSuggestionStrip();
+ }
+ };
+ final AlertDialog.Builder builder =
+ new AlertDialog.Builder(context, AlertDialog.THEME_HOLO_DARK);
+ builder.setMessage(R.string.important_notice_contents)
+ .setPositiveButton(android.R.string.ok, listener);
+ showOptionDialog(builder.create(), false /* cancelable */);
+ }
+
public void displaySettingsDialog() {
if (isShowingOptionDialog()) return;
showSubtypeSelectorAndSettings();
@@ -1401,10 +1423,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// because it may differ from mWordComposer.mTypedWord.
autoCorrection = sourceSuggestedWords.mTypedWord;
}
- if (SuggestedWords.EMPTY != suggestedWords) {
+ if (SuggestedWords.EMPTY == suggestedWords) {
+ setNeutralSuggestionStrip();
+ } else {
mInputLogic.mWordComposer.setAutoCorrection(autoCorrection);
+ setSuggestedWords(suggestedWords, isSuggestionsStripVisible());
}
- setSuggestedWords(suggestedWords, isSuggestionsStripVisible());
// Cache the auto-correction in accessibility code so we can speak it if the user
// touches a key that will insert it.
AccessibilityUtils.getInstance().setAutoCorrection(suggestedWords,
@@ -1685,17 +1709,18 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
};
final AlertDialog.Builder builder =
new AlertDialog.Builder(this).setItems(items, listener).setTitle(title);
- showOptionDialog(builder.create());
+ showOptionDialog(builder.create(), true /*cancelable */);
}
- public void showOptionDialog(final AlertDialog dialog) {
+ // TODO: Move this method out of {@link LatinIME}.
+ private void showOptionDialog(final AlertDialog dialog, final boolean cancelable) {
final IBinder windowToken = mKeyboardSwitcher.getMainKeyboardView().getWindowToken();
if (windowToken == null) {
return;
}
- dialog.setCancelable(true);
- dialog.setCanceledOnTouchOutside(true);
+ dialog.setCancelable(cancelable);
+ dialog.setCanceledOnTouchOutside(cancelable);
final Window window = dialog.getWindow();
final WindowManager.LayoutParams lp = window.getAttributes();
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index 1bc67b2a0..f53183f37 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -1142,6 +1142,8 @@ public final class InputLogic {
// Recorrection is not supported in languages without spaces because we don't know
// how to segment them yet.
if (!settingsValues.mSpacingAndPunctuations.mCurrentLanguageHasSpaces) return;
+ // If no suggestions are requested, don't try restarting suggestions.
+ if (!settingsValues.isSuggestionsRequested()) return;
// If the cursor is not touching a word, or if there is a selection, return right away.
if (mConnection.hasSelection()) return;
// If we don't know the cursor location, return.
diff --git a/java/src/com/android/inputmethod/latin/makedict/AbstractDictDecoder.java b/java/src/com/android/inputmethod/latin/makedict/AbstractDictDecoder.java
index 370782b33..1a9118147 100644
--- a/java/src/com/android/inputmethod/latin/makedict/AbstractDictDecoder.java
+++ b/java/src/com/android/inputmethod/latin/makedict/AbstractDictDecoder.java
@@ -60,7 +60,7 @@ public abstract class AbstractDictDecoder implements DictDecoder {
final FileHeader header = new FileHeader(headerSize,
new FusionDictionary.DictionaryOptions(attributes),
new FormatOptions(version, FileHeader.ATTRIBUTE_VALUE_TRUE.equals(
- attributes.get(FileHeader.HAS_HISTORICAL_INFO_ATTRIBUTE))));
+ attributes.get(FileHeader.HAS_HISTORICAL_INFO_KEY))));
return header;
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
index 61c17fc46..74e305976 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
@@ -336,16 +336,19 @@ public final class FormatSpec {
public final int mBodyOffset;
public final DictionaryOptions mDictionaryOptions;
public final FormatOptions mFormatOptions;
+
// Note that these are corresponding definitions in native code in latinime::HeaderPolicy
// and latinime::HeaderReadWriteUtils.
- public static final String USES_FORGETTING_CURVE_ATTRIBUTE = "USES_FORGETTING_CURVE";
- public static final String HAS_HISTORICAL_INFO_ATTRIBUTE = "HAS_HISTORICAL_INFO";
+ // TODO: Standardize the key names and bump up the format version, taking care not to
+ // break format version 2 dictionaries.
+ public static final String DICTIONARY_VERSION_KEY = "version";
+ public static final String DICTIONARY_LOCALE_KEY = "locale";
+ public static final String DICTIONARY_ID_KEY = "dictionary";
+ public static final String DICTIONARY_DESCRIPTION_KEY = "description";
+ public static final String DICTIONARY_DATE_KEY = "date";
+ public static final String HAS_HISTORICAL_INFO_KEY = "HAS_HISTORICAL_INFO";
+ public static final String USES_FORGETTING_CURVE_KEY = "USES_FORGETTING_CURVE";
public static final String ATTRIBUTE_VALUE_TRUE = "1";
-
- public static final String DICTIONARY_VERSION_ATTRIBUTE = "version";
- public static final String DICTIONARY_LOCALE_ATTRIBUTE = "locale";
- public static final String DICTIONARY_ID_ATTRIBUTE = "dictionary";
- private static final String DICTIONARY_DESCRIPTION_ATTRIBUTE = "description";
public FileHeader(final int headerSize, final DictionaryOptions dictionaryOptions,
final FormatOptions formatOptions) throws UnsupportedFormatException {
mDictionaryOptions = dictionaryOptions;
@@ -365,24 +368,24 @@ public final class FormatSpec {
// Helper method to get the locale as a String
public String getLocaleString() {
- return mDictionaryOptions.mAttributes.get(FileHeader.DICTIONARY_LOCALE_ATTRIBUTE);
+ return mDictionaryOptions.mAttributes.get(FileHeader.DICTIONARY_LOCALE_KEY);
}
// Helper method to get the version String
public String getVersion() {
- return mDictionaryOptions.mAttributes.get(FileHeader.DICTIONARY_VERSION_ATTRIBUTE);
+ return mDictionaryOptions.mAttributes.get(FileHeader.DICTIONARY_VERSION_KEY);
}
// Helper method to get the dictionary ID as a String
public String getId() {
- return mDictionaryOptions.mAttributes.get(FileHeader.DICTIONARY_ID_ATTRIBUTE);
+ return mDictionaryOptions.mAttributes.get(FileHeader.DICTIONARY_ID_KEY);
}
// Helper method to get the description
public String getDescription() {
// TODO: Right now each dictionary file comes with a description in its own language.
// It will display as is no matter the device's locale. It should be internationalized.
- return mDictionaryOptions.mAttributes.get(FileHeader.DICTIONARY_DESCRIPTION_ATTRIBUTE);
+ return mDictionaryOptions.mAttributes.get(FileHeader.DICTIONARY_DESCRIPTION_KEY);
}
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java b/java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java
index d34aa171e..b12f79b07 100644
--- a/java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java
+++ b/java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java
@@ -62,7 +62,7 @@ public class Ver4DictEncoder implements DictEncoder {
final BinaryDictionary binaryDict = new BinaryDictionary(mDictPlacedDir.getAbsolutePath(),
0l, mDictPlacedDir.length(), true /* useFullEditDistance */,
LocaleUtils.constructLocaleFromString(dict.mOptions.mAttributes.get(
- FormatSpec.FileHeader.DICTIONARY_LOCALE_ATTRIBUTE)),
+ FormatSpec.FileHeader.DICTIONARY_LOCALE_KEY)),
Dictionary.TYPE_USER /* Dictionary type. Does not matter for us */,
true /* isUpdatable */);
if (!binaryDict.isValidDictionary()) {
diff --git a/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java b/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java
index 4a610e6f9..d636a253a 100644
--- a/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java
+++ b/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java
@@ -95,13 +95,13 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB
@Override
protected Map<String, String> getHeaderAttributeMap() {
HashMap<String, String> attributeMap = new HashMap<String, String>();
- attributeMap.put(FormatSpec.FileHeader.USES_FORGETTING_CURVE_ATTRIBUTE,
+ attributeMap.put(FormatSpec.FileHeader.USES_FORGETTING_CURVE_KEY,
FormatSpec.FileHeader.ATTRIBUTE_VALUE_TRUE);
- attributeMap.put(FormatSpec.FileHeader.HAS_HISTORICAL_INFO_ATTRIBUTE,
+ attributeMap.put(FormatSpec.FileHeader.HAS_HISTORICAL_INFO_KEY,
FormatSpec.FileHeader.ATTRIBUTE_VALUE_TRUE);
- attributeMap.put(FormatSpec.FileHeader.DICTIONARY_ID_ATTRIBUTE, mDictName);
- attributeMap.put(FormatSpec.FileHeader.DICTIONARY_LOCALE_ATTRIBUTE, mLocale.toString());
- attributeMap.put(FormatSpec.FileHeader.DICTIONARY_VERSION_ATTRIBUTE,
+ attributeMap.put(FormatSpec.FileHeader.DICTIONARY_ID_KEY, mDictName);
+ attributeMap.put(FormatSpec.FileHeader.DICTIONARY_LOCALE_KEY, mLocale.toString());
+ attributeMap.put(FormatSpec.FileHeader.DICTIONARY_VERSION_KEY,
String.valueOf(TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())));
return attributeMap;
}
diff --git a/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java b/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java
index 8ba32ff76..70cb2b285 100644
--- a/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java
+++ b/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java
@@ -19,6 +19,7 @@ package com.android.inputmethod.latin.settings;
import android.content.res.Resources;
import com.android.inputmethod.keyboard.internal.KeySpecParser;
+import com.android.inputmethod.keyboard.internal.MoreKeySpec;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.R;
@@ -55,7 +56,7 @@ public final class SpacingAndPunctuations {
res.getString(R.string.symbols_word_connectors));
mSortedWordSeparators = StringUtils.toSortedCodePointArray(
res.getString(R.string.symbols_word_separators));
- final String[] suggestPuncsSpec = KeySpecParser.splitKeySpecs(res.getString(
+ final String[] suggestPuncsSpec = MoreKeySpec.splitKeySpecs(res.getString(
R.string.suggested_punctuations));
mSuggestPuncList = createSuggestPuncList(suggestPuncsSpec);
mSentenceSeparator = res.getInteger(R.integer.sentence_separator);
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
index 5ed42ab00..a89f70e1f 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
@@ -28,7 +28,6 @@ import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
-import android.support.v4.view.GravityCompat;
import android.support.v4.view.ViewCompat;
import android.text.Spannable;
import android.text.SpannableString;
@@ -45,6 +44,7 @@ import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
+import com.android.inputmethod.compat.TextViewCompatUtils;
import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.SuggestedWords;
@@ -492,7 +492,30 @@ final class SuggestionStripLayoutHelper {
hintView, 1.0f - mCenterSuggestionWeight, ViewGroup.LayoutParams.MATCH_PARENT);
}
- private static void setLayoutWeight(final View v, final float weight, final int height) {
+ public void layoutImportantNotice(final View importantNoticeStrip, final int stripWidth) {
+ final Resources res = importantNoticeStrip.getResources();
+ final Drawable infoIcon = res.getDrawable(R.drawable.sym_keyboard_info_holo_dark);
+ final Drawable moreIcon = res.getDrawable(R.drawable.sym_keyboard_more_holo_dark);
+ final int width = stripWidth - infoIcon.getIntrinsicWidth() - moreIcon.getIntrinsicWidth();
+ final TextView titleView = (TextView)importantNoticeStrip.findViewById(
+ R.id.important_notice_title);
+ titleView.setTextColor(mColorAutoCorrect);
+ TextViewCompatUtils.setCompoundDrawablesRelativeWithIntrinsicBounds(
+ titleView, infoIcon, null, moreIcon, null);
+ final CharSequence importantNoticeTitle = titleView.getText();
+ titleView.setTextScaleX(1.0f); // Reset textScaleX.
+ // When the suggestions strip is displayed first time, stripWidth may be zero.
+ // Then importantNoticeTitle will be displayed as is without auto text scaleX.
+ // TODO: Fix the logic to always have a correct value of stripWidth.
+ if (width > 0) {
+ // Auto text scaleX to show entire important notice title should be on the strip.
+ final float titleScaleX = getTextScaleX(
+ importantNoticeTitle, width, titleView.getPaint());
+ titleView.setTextScaleX(titleScaleX);
+ }
+ }
+
+ static void setLayoutWeight(final View v, final float weight, final int height) {
final ViewGroup.LayoutParams lp = v.getLayoutParams();
if (lp instanceof LinearLayout.LayoutParams) {
final LinearLayout.LayoutParams llp = (LinearLayout.LayoutParams)lp;
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
index 22804fce1..b04a2cb5b 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
@@ -54,6 +54,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
OnLongClickListener {
public interface Listener {
public void addWordToUserDictionary(String word);
+ public void showImportantNoticeContents();
public void pickSuggestionManually(int index, SuggestedWordInfo word);
}
@@ -62,6 +63,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
private final ViewGroup mSuggestionsStrip;
private final ViewGroup mAddToDictionaryStrip;
+ private final View mImportantNoticeStrip;
MainKeyboardView mMainKeyboardView;
private final View mMoreSuggestionsContainer;
@@ -81,10 +83,13 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
private static class StripVisibilityGroup {
private final View mSuggestionsStrip;
private final View mAddToDictionaryStrip;
+ private final View mImportantNoticeStrip;
- public StripVisibilityGroup(final View suggestionsStrip, final View addToDictionaryStrip) {
+ public StripVisibilityGroup(final View suggestionsStrip, final View addToDictionaryStrip,
+ final View importantNoticeStrip) {
mSuggestionsStrip = suggestionsStrip;
mAddToDictionaryStrip = addToDictionaryStrip;
+ mImportantNoticeStrip = importantNoticeStrip;
showSuggestionsStrip();
}
@@ -93,16 +98,25 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
: ViewCompat.LAYOUT_DIRECTION_LTR;
ViewCompat.setLayoutDirection(mSuggestionsStrip, layoutDirection);
ViewCompat.setLayoutDirection(mAddToDictionaryStrip, layoutDirection);
+ ViewCompat.setLayoutDirection(mImportantNoticeStrip, layoutDirection);
}
public void showSuggestionsStrip() {
mSuggestionsStrip.setVisibility(VISIBLE);
mAddToDictionaryStrip.setVisibility(INVISIBLE);
+ mImportantNoticeStrip.setVisibility(INVISIBLE);
}
public void showAddToDictionaryStrip() {
mSuggestionsStrip.setVisibility(INVISIBLE);
mAddToDictionaryStrip.setVisibility(VISIBLE);
+ mImportantNoticeStrip.setVisibility(INVISIBLE);
+ }
+
+ public void showImportantNoticeStrip() {
+ mSuggestionsStrip.setVisibility(INVISIBLE);
+ mAddToDictionaryStrip.setVisibility(INVISIBLE);
+ mImportantNoticeStrip.setVisibility(VISIBLE);
}
public boolean isShowingAddToDictionaryStrip() {
@@ -128,7 +142,9 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
mSuggestionsStrip = (ViewGroup)findViewById(R.id.suggestions_strip);
mAddToDictionaryStrip = (ViewGroup)findViewById(R.id.add_to_dictionary_strip);
- mStripVisibilityGroup = new StripVisibilityGroup(mSuggestionsStrip, mAddToDictionaryStrip);
+ mImportantNoticeStrip = findViewById(R.id.important_notice_strip);
+ mStripVisibilityGroup = new StripVisibilityGroup(mSuggestionsStrip, mAddToDictionaryStrip,
+ mImportantNoticeStrip);
for (int pos = 0; pos < SuggestedWords.MAX_SUGGESTIONS; pos++) {
final TextView word = new TextView(context, null, R.attr.suggestionWordStyle);
@@ -176,6 +192,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
ResearchLogger.suggestionStripView_setSuggestions(mSuggestedWords);
}
+ mStripVisibilityGroup.showSuggestionsStrip();
}
public int setMoreSuggestionsHeight(final int remainingHeight) {
@@ -203,6 +220,13 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
return false;
}
+ // TODO: This method should be called after this View has been attached and displayed.
+ public void showImportantNoticeTitle() {
+ mLayoutHelper.layoutImportantNotice(mImportantNoticeStrip, getWidth());
+ mStripVisibilityGroup.showImportantNoticeStrip();
+ mImportantNoticeStrip.setOnClickListener(this);
+ }
+
public void clear() {
mSuggestionsStrip.removeAllViews();
removeAllDebugInfoViews();
@@ -360,6 +384,10 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
@Override
public void onClick(final View view) {
+ if (view == mImportantNoticeStrip) {
+ mListener.showImportantNoticeContents();
+ return;
+ }
final Object tag = view.getTag();
// {@link String} tag is set at {@link #showAddToDictionaryHint(String,CharSequence)}.
if (tag instanceof String) {
diff --git a/java/src/com/android/inputmethod/latin/utils/CollectionUtils.java b/java/src/com/android/inputmethod/latin/utils/CollectionUtils.java
index cc25102ce..bbfa0f091 100644
--- a/java/src/com/android/inputmethod/latin/utils/CollectionUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/CollectionUtils.java
@@ -102,4 +102,19 @@ public final class CollectionUtils {
public static <E> SparseArray<E> newSparseArray() {
return new SparseArray<E>();
}
+
+ public static <E> ArrayList<E> arrayAsList(final E[] array, final int start, final int end) {
+ if (array == null) {
+ throw new NullPointerException();
+ }
+ if (start < 0 || start > end || end > array.length) {
+ throw new IllegalArgumentException();
+ }
+
+ final ArrayList<E> list = newArrayList(end - start);
+ for (int i = start; i < end; i++) {
+ list.add(array[i]);
+ }
+ return list;
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/utils/CsvUtils.java b/java/src/com/android/inputmethod/latin/utils/CsvUtils.java
index 36b927eea..b18a1d83b 100644
--- a/java/src/com/android/inputmethod/latin/utils/CsvUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/CsvUtils.java
@@ -17,6 +17,7 @@
package com.android.inputmethod.latin.utils;
import com.android.inputmethod.annotations.UsedForTesting;
+import com.android.inputmethod.latin.Constants;
import java.util.ArrayList;
@@ -57,9 +58,9 @@ public final class CsvUtils {
// Note that none of these characters match high or low surrogate characters, so we need not
// take care of matching by code point.
- private static final char COMMA = ',';
- private static final char SPACE = ' ';
- private static final char QUOTE = '"';
+ private static final char COMMA = Constants.CODE_COMMA;
+ private static final char SPACE = Constants.CODE_SPACE;
+ private static final char QUOTE = Constants.CODE_DOUBLE_QUOTE;
@SuppressWarnings("serial")
public static class CsvParseException extends RuntimeException {
diff --git a/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java b/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java
index 8eff2e6e7..4a0823155 100644
--- a/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java
@@ -22,13 +22,11 @@ import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.util.Log;
+import com.android.inputmethod.latin.R;
+
public final class ImportantNoticeUtils {
private static final String TAG = ImportantNoticeUtils.class.getSimpleName();
- // The current version number of an important notice.
- // This number must be incremented whenever users should see a new important notice.
- private static final int CURRENT_IMPORTANT_NOTICE_VERSION = 0;
-
// {@link SharedPreferences} name to save the last important notice version that has been
// displayed to users.
private static final String PREFERENCE_NAME = "important_notice";
@@ -60,16 +58,20 @@ public final class ImportantNoticeUtils {
return context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
}
+ private static int getCurrentImportantNoticeVersion(final Context context) {
+ return context.getResources().getInteger(R.integer.config_important_notice_version);
+ }
+
public static boolean hasNewImportantNotice(final Context context) {
final SharedPreferences prefs = getImportantNoticePreferences(context);
final int lastVersion = prefs.getInt(KEY_IMPORTANT_NOTICE_VERSION, 0);
- return CURRENT_IMPORTANT_NOTICE_VERSION > lastVersion;
+ return getCurrentImportantNoticeVersion(context) > lastVersion;
}
public static void updateLastImportantNoticeVersion(final Context context) {
final SharedPreferences prefs = getImportantNoticePreferences(context);
prefs.edit()
- .putInt(KEY_IMPORTANT_NOTICE_VERSION, CURRENT_IMPORTANT_NOTICE_VERSION)
+ .putInt(KEY_IMPORTANT_NOTICE_VERSION, getCurrentImportantNoticeVersion(context))
.apply();
}
}
diff --git a/java/src/com/android/inputmethod/latin/utils/StringUtils.java b/java/src/com/android/inputmethod/latin/utils/StringUtils.java
index b154623ae..c632a71a9 100644
--- a/java/src/com/android/inputmethod/latin/utils/StringUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/StringUtils.java
@@ -16,6 +16,8 @@
package com.android.inputmethod.latin.utils;
+import static com.android.inputmethod.latin.Constants.CODE_UNSPECIFIED;
+
import android.text.TextUtils;
import com.android.inputmethod.annotations.UsedForTesting;
@@ -471,4 +473,20 @@ public final class StringUtils {
}
return bytes;
}
+
+ public static String toUpperCaseOfStringForLocale(final String text,
+ final boolean needsToUpperCase, final Locale locale) {
+ if (text == null || !needsToUpperCase) return text;
+ return text.toUpperCase(locale);
+ }
+
+ public static int toUpperCaseOfCodeForLocale(final int code, final boolean needsToUpperCase,
+ final Locale locale) {
+ if (!Constants.isLetterCode(code) || !needsToUpperCase) return code;
+ final String text = newSingleCodePointString(code);
+ final String casedText = toUpperCaseOfStringForLocale(
+ text, needsToUpperCase, locale);
+ return codePointCount(casedText) == 1
+ ? casedText.codePointAt(0) : CODE_UNSPECIFIED;
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/utils/UserHistoryDictIOUtils.java b/java/src/com/android/inputmethod/latin/utils/UserHistoryDictIOUtils.java
index db628fe18..7af03da59 100644
--- a/java/src/com/android/inputmethod/latin/utils/UserHistoryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/UserHistoryDictIOUtils.java
@@ -22,6 +22,7 @@ import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.makedict.BinaryDictIOUtils;
import com.android.inputmethod.latin.makedict.DictDecoder;
import com.android.inputmethod.latin.makedict.DictEncoder;
+import com.android.inputmethod.latin.makedict.FormatSpec;
import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
import com.android.inputmethod.latin.makedict.FusionDictionary;
import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
@@ -44,9 +45,6 @@ import java.util.concurrent.TimeUnit;
public final class UserHistoryDictIOUtils {
private static final String TAG = UserHistoryDictIOUtils.class.getSimpleName();
private static final boolean DEBUG = false;
- private static final String USES_FORGETTING_CURVE_KEY = "USES_FORGETTING_CURVE";
- private static final String USES_FORGETTING_CURVE_VALUE = "1";
- private static final String LAST_UPDATED_TIME_KEY = "date";
public interface OnAddWordListener {
/**
@@ -75,8 +73,9 @@ public final class UserHistoryDictIOUtils {
final BigramDictionaryInterface dict, final UserHistoryDictionaryBigramList bigrams,
final FormatOptions formatOptions, final HashMap<String, String> options) {
final FusionDictionary fusionDict = constructFusionDictionary(dict, bigrams, options);
- fusionDict.addOptionAttribute(USES_FORGETTING_CURVE_KEY, USES_FORGETTING_CURVE_VALUE);
- fusionDict.addOptionAttribute(LAST_UPDATED_TIME_KEY,
+ fusionDict.addOptionAttribute(FormatSpec.FileHeader.USES_FORGETTING_CURVE_KEY,
+ FormatSpec.FileHeader.ATTRIBUTE_VALUE_TRUE);
+ fusionDict.addOptionAttribute(FormatSpec.FileHeader.DICTIONARY_DATE_KEY,
String.valueOf(TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())));
try {
dictEncoder.writeDictionary(fusionDict, formatOptions);
diff --git a/java/src/com/android/inputmethod/latin/utils/UnigramProperty.java b/java/src/com/android/inputmethod/latin/utils/WordProperty.java
index 4feee4393..ba9b114b0 100644
--- a/java/src/com/android/inputmethod/latin/utils/UnigramProperty.java
+++ b/java/src/com/android/inputmethod/latin/utils/WordProperty.java
@@ -26,21 +26,36 @@ import java.util.ArrayList;
// This has information that belong to a unigram. This class has some detailed attributes such as
// historical information but they have to be checked only for testing purpose.
@UsedForTesting
-public class UnigramProperty {
+public class WordProperty {
public final String mCodePoints;
public final boolean mIsNotAWord;
public final boolean mIsBlacklisted;
public final boolean mHasBigrams;
public final boolean mHasShortcuts;
- public final int mProbability;
- // mTimestamp, mLevel and mCount are historical info. These values are depend on the
- // implementation in native code; thus, we must not use them and have any assumptions about
- // them except for tests.
- public final int mTimestamp;
- public final int mLevel;
- public final int mCount;
+ public final ProbabilityInfo mProbabilityInfo;
+ public final ArrayList<WeightedString> mBigramTargets = CollectionUtils.newArrayList();
+ public final ArrayList<ProbabilityInfo> mBigramProbabilityInfo = CollectionUtils.newArrayList();
public final ArrayList<WeightedString> mShortcutTargets = CollectionUtils.newArrayList();
+ // TODO: Use this kind of Probability class for dictionary read/write code under the makedict
+ // package.
+ public static final class ProbabilityInfo {
+ public final int mProbability;
+ // wTimestamp, mLevel and mCount are historical info. These values are depend on the
+ // implementation in native code; thus, we must not use them and have any assumptions about
+ // them except for tests.
+ public final int mTimestamp;
+ public final int mLevel;
+ public final int mCount;
+
+ public ProbabilityInfo(final int[] probabilityInfo) {
+ mProbability = probabilityInfo[BinaryDictionary.FORMAT_WORD_PROPERTY_PROBABILITY_INDEX];
+ mTimestamp = probabilityInfo[BinaryDictionary.FORMAT_WORD_PROPERTY_TIMESTAMP_INDEX];
+ mLevel = probabilityInfo[BinaryDictionary.FORMAT_WORD_PROPERTY_LEVEL_INDEX];
+ mCount = probabilityInfo[BinaryDictionary.FORMAT_WORD_PROPERTY_COUNT_INDEX];
+ }
+ }
+
private static int getCodePointCount(final int[] codePoints) {
for (int i = 0; i < codePoints.length; i++) {
if (codePoints[i] == 0) {
@@ -50,21 +65,32 @@ public class UnigramProperty {
return codePoints.length;
}
- // This represents invalid unigram when the probability is BinaryDictionary.NOT_A_PROBABILITY.
- public UnigramProperty(final int[] codePoints, final boolean isNotAWord,
+ // This represents invalid word when the probability is BinaryDictionary.NOT_A_PROBABILITY.
+ public WordProperty(final int[] codePoints, final boolean isNotAWord,
final boolean isBlacklisted, final boolean hasBigram,
- final boolean hasShortcuts, final int probability, final int timestamp,
- final int level, final int count, final ArrayList<int[]> shortcutTargets,
+ final boolean hasShortcuts, final int[] probabilityInfo,
+ final ArrayList<int[]> bigramTargets, final ArrayList<int[]> bigramProbabilityInfo,
+ final ArrayList<int[]> shortcutTargets,
final ArrayList<Integer> shortcutProbabilities) {
mCodePoints = new String(codePoints, 0 /* offset */, getCodePointCount(codePoints));
mIsNotAWord = isNotAWord;
mIsBlacklisted = isBlacklisted;
mHasBigrams = hasBigram;
mHasShortcuts = hasShortcuts;
- mProbability = probability;
- mTimestamp = timestamp;
- mLevel = level;
- mCount = count;
+ mProbabilityInfo = new ProbabilityInfo(probabilityInfo);
+
+ final int bigramTargetCount = bigramTargets.size();
+ for (int i = 0; i < bigramTargetCount; i++) {
+ final int[] bigramTargetCodePointArray = bigramTargets.get(i);
+ final String bigramTargetString = new String(bigramTargetCodePointArray,
+ 0 /* offset */, getCodePointCount(bigramTargetCodePointArray));
+ final ProbabilityInfo bigramProbability =
+ new ProbabilityInfo(bigramProbabilityInfo.get(i));
+ mBigramTargets.add(
+ new WeightedString(bigramTargetString, bigramProbability.mProbability));
+ mBigramProbabilityInfo.add(bigramProbability);
+ }
+
final int shortcutTargetCount = shortcutTargets.size();
for (int i = 0; i < shortcutTargetCount; i++) {
final int[] shortcutTargetCodePointArray = shortcutTargets.get(i);
@@ -77,6 +103,6 @@ public class UnigramProperty {
@UsedForTesting
public boolean isValid() {
- return mProbability != BinaryDictionary.NOT_A_PROBABILITY;
+ return mProbabilityInfo.mProbability != BinaryDictionary.NOT_A_PROBABILITY;
}
} \ No newline at end of file