diff options
37 files changed, 435 insertions, 180 deletions
diff --git a/java/res/values-iw/config-spacing-and-punctuations.xml b/java/res/values-ar-sw600dp/config-spacing-and-punctuations.xml index 9e637e458..56296361f 100644 --- a/java/res/values-iw/config-spacing-and-punctuations.xml +++ b/java/res/values-ar-sw600dp/config-spacing-and-punctuations.xml @@ -2,7 +2,7 @@ <!-- /* ** -** Copyright 2012, The Android Open Source Project +** Copyright 2014, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. @@ -21,5 +21,7 @@ <!-- The all letters need to be mirrored are found at http://www.unicode.org/Public/6.1.0/ucd/BidiMirroring.txt --> <!-- Symbols that are suggested between words --> - <string name="suggested_punctuations" translatable="false">!,?,\\,,:,;,\",(|),)|(,\',-,/,@,_</string> + <!-- U+061F: "؟" ARABIC QUESTION MARK + U+061B: "؛" ARABIC SEMICOLON --> + <string name="suggested_punctuations" translatable="false">!,؟,:,؛,\",\',(|),)|(,-,/,@,_</string> </resources> diff --git a/java/res/values-ar/config-spacing-and-punctuations.xml b/java/res/values-ar/config-spacing-and-punctuations.xml index 9e637e458..d33a104df 100644 --- a/java/res/values-ar/config-spacing-and-punctuations.xml +++ b/java/res/values-ar/config-spacing-and-punctuations.xml @@ -21,5 +21,8 @@ <!-- The all letters need to be mirrored are found at http://www.unicode.org/Public/6.1.0/ucd/BidiMirroring.txt --> <!-- Symbols that are suggested between words --> - <string name="suggested_punctuations" translatable="false">!,?,\\,,:,;,\",(|),)|(,\',-,/,@,_</string> + <!-- U+061F: "؟" ARABIC QUESTION MARK + U+060C: "،" ARABIC COMMA + U+061B: "؛" ARABIC SEMICOLON --> + <string name="suggested_punctuations" translatable="false">!,؟,،,:,؛,\",(|),)|(,\',-,/,@,_</string> </resources> diff --git a/java/res/values-fa-sw600dp/config-spacing-and-punctuations.xml b/java/res/values-fa-sw600dp/config-spacing-and-punctuations.xml new file mode 100644 index 000000000..56296361f --- /dev/null +++ b/java/res/values-fa-sw600dp/config-spacing-and-punctuations.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2014, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- The all letters need to be mirrored are found at + http://www.unicode.org/Public/6.1.0/ucd/BidiMirroring.txt --> + <!-- Symbols that are suggested between words --> + <!-- U+061F: "؟" ARABIC QUESTION MARK + U+061B: "؛" ARABIC SEMICOLON --> + <string name="suggested_punctuations" translatable="false">!,؟,:,؛,\",\',(|),)|(,-,/,@,_</string> +</resources> diff --git a/java/res/values-fa/config-spacing-and-punctuations.xml b/java/res/values-fa/config-spacing-and-punctuations.xml index 9e637e458..d33a104df 100644 --- a/java/res/values-fa/config-spacing-and-punctuations.xml +++ b/java/res/values-fa/config-spacing-and-punctuations.xml @@ -21,5 +21,8 @@ <!-- The all letters need to be mirrored are found at http://www.unicode.org/Public/6.1.0/ucd/BidiMirroring.txt --> <!-- Symbols that are suggested between words --> - <string name="suggested_punctuations" translatable="false">!,?,\\,,:,;,\",(|),)|(,\',-,/,@,_</string> + <!-- U+061F: "؟" ARABIC QUESTION MARK + U+060C: "،" ARABIC COMMA + U+061B: "؛" ARABIC SEMICOLON --> + <string name="suggested_punctuations" translatable="false">!,؟,،,:,؛,\",(|),)|(,\',-,/,@,_</string> </resources> diff --git a/java/res/values-sw600dp/config-spacing-and-punctuations.xml b/java/res/values-sw600dp/config-spacing-and-punctuations.xml new file mode 100644 index 000000000..9c12cf49a --- /dev/null +++ b/java/res/values-sw600dp/config-spacing-and-punctuations.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2014, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- Symbols that are suggested between words --> + <string name="suggested_punctuations" translatable="false">:,;,\",!text/keyspec_left_parenthesis,!text/keyspec_right_parenthesis,\',-,/,@,_</string> +</resources> diff --git a/java/res/values/config-spacing-and-punctuations.xml b/java/res/values/config-spacing-and-punctuations.xml index 2f52edd4a..9099f4c45 100644 --- a/java/res/values/config-spacing-and-punctuations.xml +++ b/java/res/values/config-spacing-and-punctuations.xml @@ -21,7 +21,7 @@ <!-- TODO: these settings depend on the language. They should be put either in the dictionary header, or in the subtype maybe? --> <!-- Symbols that are suggested between words --> - <string name="suggested_punctuations" translatable="false">!,?,\\,,:,;,\",(,),\',-,/,@,_</string> + <string name="suggested_punctuations" translatable="false">!,?,\\,,:,;,\",!text/keyspec_left_parenthesis,!text/keyspec_right_parenthesis,\',-,/,@,_</string> <!-- Symbols that are normally preceded by a space (used to add an auto-space before these) --> <string name="symbols_preceded_by_space" translatable="false">([{&</string> <!-- Symbols that are normally followed by a space (used to add an auto-space after these) --> diff --git a/java/res/xml-sw600dp/key_styles_common.xml b/java/res/xml-sw600dp/key_styles_common.xml index 6a79c6fc2..aa64f85b3 100644 --- a/java/res/xml-sw600dp/key_styles_common.xml +++ b/java/res/xml-sw600dp/key_styles_common.xml @@ -161,7 +161,7 @@ latin:parentStyle="baseForLayoutSwitchKeyStyle" /> <key-style latin:styleName="comKeyStyle" - latin:keySpec="!text/keylabel_for_popular_domain|!text/keylabel_for_popular_domain" + latin:keySpec="!text/keylabel_for_popular_domain" latin:keyLabelFlags="autoXScale|fontNormal|hasPopupHint|preserveCase" latin:moreKeys="!text/more_keys_for_popular_domain" /> </merge> diff --git a/java/res/xml/key_styles_common.xml b/java/res/xml/key_styles_common.xml index f04fc45bb..2330ecb7f 100644 --- a/java/res/xml/key_styles_common.xml +++ b/java/res/xml/key_styles_common.xml @@ -149,7 +149,7 @@ latin:parentStyle="baseForLayoutSwitchKeyStyle" /> <key-style latin:styleName="comKeyStyle" - latin:keySpec="!text/keylabel_for_popular_domain|!text/keylabel_for_popular_domain" + latin:keySpec="!text/keylabel_for_popular_domain" latin:keyLabelFlags="autoXScale|fontNormal|hasPopupHint|preserveCase" latin:moreKeys="!text/more_keys_for_popular_domain" latin:backgroundType="functional" /> diff --git a/java/res/xml/method.xml b/java/res/xml/method.xml index 5e38eb37f..94327f9e9 100644 --- a/java/res/xml/method.xml +++ b/java/res/xml/method.xml @@ -55,7 +55,7 @@ it: Italian/qwerty iw: Hebrew/hebrew # "he" is official language code of Hebrew. ka_GE: Georgian (Georgia)/georgian - (kk: Kazakh/east_slavic) # disabled temporarily. waiting for string resources. + kk: Kazakh/east_slavic km_KH: Khmer (Cambodia)/khmer ky: Kyrgyz/east_slavic lo_LA: Lao (Laos)/lao @@ -367,7 +367,6 @@ android:imeSubtypeExtraValue="KeyboardLayoutSet=georgian,EmojiCapable" android:isAsciiCapable="false" /> - <!-- <subtype android:icon="@drawable/ic_ime_switcher_dark" android:label="@string/subtype_generic" android:subtypeId="0x2d73d2f6" @@ -376,7 +375,6 @@ android:imeSubtypeExtraValue="KeyboardLayoutSet=east_slavic,EmojiCapable" android:isAsciiCapable="false" /> - --> <subtype android:icon="@drawable/ic_ime_switcher_dark" android:label="@string/subtype_generic" android:subtypeId="0x1365683a" diff --git a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java index a32d76c30..60f7e2def 100644 --- a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java +++ b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java @@ -23,7 +23,6 @@ import android.text.Spanned; import android.text.TextUtils; import android.text.style.SuggestionSpan; -import com.android.inputmethod.latin.Dictionary; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.SuggestedWords; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; @@ -70,7 +69,7 @@ public final class SuggestionSpanUtils { public static CharSequence getTextWithSuggestionSpan(final Context context, final String pickedWord, final SuggestedWords suggestedWords) { if (TextUtils.isEmpty(pickedWord) || suggestedWords.isEmpty() - || suggestedWords.mIsPrediction || suggestedWords.mIsPunctuationSuggestions) { + || suggestedWords.mIsPrediction || suggestedWords.isPunctuationSuggestions()) { return pickedWord; } diff --git a/java/src/com/android/inputmethod/keyboard/KeyDetector.java b/java/src/com/android/inputmethod/keyboard/KeyDetector.java index 149f10fd7..282c8e8fa 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyDetector.java +++ b/java/src/com/android/inputmethod/keyboard/KeyDetector.java @@ -18,7 +18,9 @@ package com.android.inputmethod.keyboard; import com.android.inputmethod.latin.Constants; - +/** + * This class handles key detection. + */ public class KeyDetector { private final int mKeyHysteresisDistanceSquared; private final int mKeyHysteresisDistanceForSlidingModifierSquared; @@ -27,18 +29,12 @@ public class KeyDetector { private int mCorrectionX; private int mCorrectionY; - /** - * This class handles key detection. - * - * @param keyHysteresisDistance if the pointer movement distance is smaller than this, the - * movement will not be handled as meaningful movement. The unit is pixel. - */ - public KeyDetector(float keyHysteresisDistance) { - this(keyHysteresisDistance, keyHysteresisDistance); + public KeyDetector() { + this(0.0f /* keyHysteresisDistance */, 0.0f /* keyHysteresisDistanceForSlidingModifier */); } /** - * This class handles key detection. + * Key detection object constructor with key hysteresis distances. * * @param keyHysteresisDistance if the pointer movement distance is smaller than this, the * movement will not be handled as meaningful movement. The unit is pixel. diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysDetector.java b/java/src/com/android/inputmethod/keyboard/MoreKeysDetector.java index 81b8f0428..4a80279ca 100644 --- a/java/src/com/android/inputmethod/keyboard/MoreKeysDetector.java +++ b/java/src/com/android/inputmethod/keyboard/MoreKeysDetector.java @@ -21,7 +21,7 @@ public final class MoreKeysDetector extends KeyDetector { private final int mSlideAllowanceSquareTop; public MoreKeysDetector(float slideAllowance) { - super(/* keyHysteresisDistance */0); + super(); mSlideAllowanceSquare = (int)(slideAllowance * slideAllowance); // Top slide allowance is slightly longer (sqrt(2) times) than other edges. mSlideAllowanceSquareTop = mSlideAllowanceSquare * 2; diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java index b5d82fa33..befc4e6fa 100644 --- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java +++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java @@ -155,7 +155,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element, // The {@link KeyDetector} is set whenever the down event is processed. Also this is updated // when new {@link Keyboard} is set by {@link #setKeyDetector(KeyDetector)}. - private KeyDetector mKeyDetector; + private KeyDetector mKeyDetector = new KeyDetector(); private Keyboard mKeyboard; private int mPhantomSuddenMoveThreshold; private final BogusMoveEventDetector mBogusMoveEventDetector = new BogusMoveEventDetector(); @@ -1124,9 +1124,6 @@ public final class PointerTracker implements PointerTrackerQueue.Element, private boolean isMajorEnoughMoveToBeOnNewKey(final int x, final int y, final long eventTime, final Key newKey) { - if (mKeyDetector == null) { - throw new NullPointerException("keyboard and/or key detector not set"); - } final Key curKey = mCurrentKey; if (newKey == curKey) { return false; diff --git a/java/src/com/android/inputmethod/keyboard/internal/EmojiPageKeyboardView.java b/java/src/com/android/inputmethod/keyboard/internal/EmojiPageKeyboardView.java index be7396520..e175a051e 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/EmojiPageKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/internal/EmojiPageKeyboardView.java @@ -52,7 +52,7 @@ public final class EmojiPageKeyboardView extends KeyboardView implements }; private OnKeyEventListener mListener = EMPTY_LISTENER; - private final KeyDetector mKeyDetector = new KeyDetector(0.0f /*keyHysteresisDistance */); + private final KeyDetector mKeyDetector = new KeyDetector(); private final GestureDetector mGestureDetector; public EmojiPageKeyboardView(final Context context, final AttributeSet attrs) { diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java index 1e021e58e..a7bcef0f1 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java @@ -211,31 +211,30 @@ public final class KeyboardTextsTable { /* 144: 0 */ "action_previous_as_more_key", /* 145: 0 */ "label_to_more_symbol_key", /* 146: 0 */ "label_to_more_symbol_for_tablet_key", - /* 147: 0 */ "label_tab_key", - /* 148: 0 */ "label_to_phone_numeric_key", - /* 149: 0 */ "label_to_phone_symbols_key", - /* 150: 0 */ "label_time_am", - /* 151: 0 */ "label_time_pm", - /* 152: 0 */ "keylabel_for_popular_domain", - /* 153: 0 */ "more_keys_for_popular_domain", - /* 154: 0 */ "keyspecs_for_left_parenthesis_more_keys", - /* 155: 0 */ "keyspecs_for_right_parenthesis_more_keys", - /* 156: 0 */ "single_laqm_raqm", - /* 157: 0 */ "single_raqm_laqm", - /* 158: 0 */ "double_laqm_raqm", - /* 159: 0 */ "double_raqm_laqm", - /* 160: 0 */ "single_lqm_rqm", - /* 161: 0 */ "single_9qm_lqm", - /* 162: 0 */ "single_9qm_rqm", - /* 163: 0 */ "single_rqm_9qm", - /* 164: 0 */ "double_lqm_rqm", - /* 165: 0 */ "double_9qm_lqm", - /* 166: 0 */ "double_9qm_rqm", - /* 167: 0 */ "double_rqm_9qm", - /* 168: 0 */ "more_keys_for_single_quote", - /* 169: 0 */ "more_keys_for_double_quote", - /* 170: 0 */ "more_keys_for_tablet_double_quote", - /* 171: 0 */ "emoji_key_as_more_key", + /* 147: 0 */ "label_to_phone_numeric_key", + /* 148: 0 */ "label_to_phone_symbols_key", + /* 149: 0 */ "label_time_am", + /* 150: 0 */ "label_time_pm", + /* 151: 0 */ "keylabel_for_popular_domain", + /* 152: 0 */ "more_keys_for_popular_domain", + /* 153: 0 */ "keyspecs_for_left_parenthesis_more_keys", + /* 154: 0 */ "keyspecs_for_right_parenthesis_more_keys", + /* 155: 0 */ "single_laqm_raqm", + /* 156: 0 */ "single_raqm_laqm", + /* 157: 0 */ "double_laqm_raqm", + /* 158: 0 */ "double_raqm_laqm", + /* 159: 0 */ "single_lqm_rqm", + /* 160: 0 */ "single_9qm_lqm", + /* 161: 0 */ "single_9qm_rqm", + /* 162: 0 */ "single_rqm_9qm", + /* 163: 0 */ "double_lqm_rqm", + /* 164: 0 */ "double_9qm_lqm", + /* 165: 0 */ "double_9qm_rqm", + /* 166: 0 */ "double_rqm_9qm", + /* 167: 0 */ "more_keys_for_single_quote", + /* 168: 0 */ "more_keys_for_double_quote", + /* 169: 0 */ "more_keys_for_tablet_double_quote", + /* 170: 0 */ "emoji_key_as_more_key", }; private static final String EMPTY = ""; @@ -399,8 +398,6 @@ public final class KeyboardTextsTable { /* label_to_more_symbol_key */ "= \\\\ <", // Label for "switch to more symbol" modifier key on tablets. Must be short to fit on key! /* label_to_more_symbol_for_tablet_key */ "~ [ <", - // Label for "Tab" key. Must be short to fit on key! - /* label_tab_key */ "Tab", // Label for "switch to phone numeric" key. Must be short to fit on key! /* label_to_phone_numeric_key */ "123", // Label for "switch to phone symbols" key. Must be short to fit on key! @@ -3572,7 +3569,7 @@ public final class KeyboardTextsTable { // Currently we are dropping the region from the key. private static final Object[] LANGUAGES_AND_TEXTS = { // "locale", TEXT_ARRAY, /* numberOfNonNullText/lengthOf_TEXT_ARRAY localeName */ - "DEFAULT", LANGUAGE_DEFAULT, /* 172/172 default */ + "DEFAULT", LANGUAGE_DEFAULT, /* 171/171 default */ "af", LANGUAGE_af, /* 8/ 12 Afrikaans */ "ar", LANGUAGE_ar, /* 58/110 Arabic */ "az", LANGUAGE_az_AZ, /* 8/ 17 Azerbaijani (Azerbaijan) */ diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 7b72e8044..d1125afcc 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -1001,7 +1001,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen applicationSuggestedWords, null /* rawSuggestions */, false /* typedWordValid */, false /* willAutoCorrect */, - false /* isPunctuationSuggestions */, false /* isObsoleteSuggestions */, false /* isPrediction */); // When in fullscreen mode, show completions generated by the application @@ -1354,7 +1353,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen if (mSuggestionStripView != null) { final boolean showSuggestions; if (SuggestedWords.EMPTY == suggestedWords - || suggestedWords.mIsPunctuationSuggestions + || suggestedWords.isPunctuationSuggestions() || !mSettings.getCurrent().isSuggestionsRequested()) { showSuggestions = !mSuggestionStripView.maybeShowImportantNoticeTitle(); } else { @@ -1433,7 +1432,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen return new SuggestedWords(typedWordAndPreviousSuggestions, null /* rawSuggestions */, false /* typedWordValid */, false /* hasAutoCorrectionCandidate */, - false /* isPunctuationSuggestions */, true /* isObsoleteSuggestions */, false /* isPrediction */); } diff --git a/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java b/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java new file mode 100644 index 000000000..4911bcdf6 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.latin; + +import com.android.inputmethod.keyboard.internal.KeySpecParser; +import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; +import com.android.inputmethod.latin.utils.CollectionUtils; +import com.android.inputmethod.latin.utils.StringUtils; + +import java.util.ArrayList; +import java.util.Arrays; + +/** + * The extended {@link SuggestedWords} class to represent punctuation suggestions. + * + * Each punctuation specification string is the key specification that can be parsed by + * {@link KeySpecParser}. + */ +public final class PunctuationSuggestions extends SuggestedWords { + private PunctuationSuggestions(final ArrayList<SuggestedWordInfo> punctuationsList) { + super(punctuationsList, + null /* rawSuggestions */, + false /* typedWordValid */, + false /* hasAutoCorrectionCandidate */, + false /* isObsoleteSuggestions */, + false /* isPrediction */); + } + + /** + * Create new instance of {@link PunctuationSuggestions} from the array of punctuation key + * specifications. + * + * @param punctuationSpecs The array of punctuation key specifications. + * @return The {@link PunctuationSuggestions} object. + */ + public static PunctuationSuggestions newPunctuationSuggestions( + final String[] punctuationSpecs) { + final ArrayList<SuggestedWordInfo> puncuationsList = CollectionUtils.newArrayList(); + for (final String puncSpec : punctuationSpecs) { + puncuationsList.add(newHardCodedWordInfo(puncSpec)); + } + return new PunctuationSuggestions(puncuationsList); + } + + /** + * {@inheritDoc} + * Note that {@link super#getWord(int)} returns a punctuation key specification text. + * The suggested punctuation should be gotten by parsing the key specification. + */ + @Override + public String getWord(final int index) { + final String keySpec = super.getWord(index); + final int code = KeySpecParser.getCode(keySpec); + return (code == Constants.CODE_OUTPUT_TEXT) + ? KeySpecParser.getOutputText(keySpec) + : StringUtils.newSingleCodePointString(code); + } + + /** + * {@inheritDoc} + * Note that {@link super#getWord(int)} returns a punctuation key specification text. + * The displayed text should be gotten by parsing the key specification. + */ + @Override + public String getLabel(final int index) { + final String keySpec = super.getWord(index); + return KeySpecParser.getLabel(keySpec); + } + + /** + * {@inheritDoc} + * Note that {@link #getWord(int)} returns a suggested punctuation. We should create a + * {@link SuggestedWordInfo} object that represents a hard coded word. + */ + @Override + public SuggestedWordInfo getInfo(final int index) { + return newHardCodedWordInfo(getWord(index)); + } + + /** + * The predicator to tell whether this object represents punctuation suggestions. + * @return true if this object represents punctuation suggestions. + */ + @Override + public boolean isPunctuationSuggestions() { + return true; + } + + @Override + public String toString() { + return "PunctuationSuggestions: " + + " words=" + Arrays.toString(mSuggestedWordInfoList.toArray()); + } + + private static SuggestedWordInfo newHardCodedWordInfo(final String keySpec) { + return new SuggestedWordInfo(keySpec, SuggestedWordInfo.MAX_SCORE, + SuggestedWordInfo.KIND_HARDCODED, + Dictionary.DICTIONARY_HARDCODED, + SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, + SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */); + } +} diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java index 5e74d75b0..abf831a28 100644 --- a/java/src/com/android/inputmethod/latin/Suggest.java +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -227,7 +227,6 @@ public final class Suggest { // rename the attribute or change the value. !allowsToBeAutoCorrected /* typedWordValid */, hasAutoCorrection, /* willAutoCorrect */ - false /* isPunctuationSuggestions */, false /* isObsoleteSuggestions */, !wordComposer.isComposingWord() /* isPrediction */, sequenceNumber)); } @@ -289,7 +288,6 @@ public final class Suggest { callback.onGetSuggestedWords(new SuggestedWords(suggestionsContainer, rawSuggestions, true /* typedWordValid */, false /* willAutoCorrect */, - false /* isPunctuationSuggestions */, false /* isObsoleteSuggestions */, false /* isPrediction */, sequenceNumber)); } diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java index b2efc4a86..46df3e88c 100644 --- a/java/src/com/android/inputmethod/latin/SuggestedWords.java +++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java @@ -26,7 +26,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; -public final class SuggestedWords { +public class SuggestedWords { public static final int INDEX_OF_TYPED_WORD = 0; public static final int INDEX_OF_AUTO_CORRECTION = 1; public static final int NOT_A_SEQUENCE_NUMBER = -1; @@ -37,7 +37,7 @@ public final class SuggestedWords { private static final ArrayList<SuggestedWordInfo> EMPTY_WORD_INFO_LIST = CollectionUtils.newArrayList(0); public static final SuggestedWords EMPTY = new SuggestedWords( - EMPTY_WORD_INFO_LIST, null /* rawSuggestions */, false, false, false, false, false); + EMPTY_WORD_INFO_LIST, null /* rawSuggestions */, false, false, false, false); public final String mTypedWord; public final boolean mTypedWordValid; @@ -45,38 +45,34 @@ public final class SuggestedWords { // of what this flag means would be "the top suggestion is strong enough to auto-correct", // whether this exactly matches the user entry or not. public final boolean mWillAutoCorrect; - public final boolean mIsPunctuationSuggestions; public final boolean mIsObsoleteSuggestions; public final boolean mIsPrediction; public final int mSequenceNumber; // Sequence number for auto-commit. - private final ArrayList<SuggestedWordInfo> mSuggestedWordInfoList; + protected final ArrayList<SuggestedWordInfo> mSuggestedWordInfoList; public final ArrayList<SuggestedWordInfo> mRawSuggestions; public SuggestedWords(final ArrayList<SuggestedWordInfo> suggestedWordInfoList, final ArrayList<SuggestedWordInfo> rawSuggestions, final boolean typedWordValid, final boolean willAutoCorrect, - final boolean isPunctuationSuggestions, final boolean isObsoleteSuggestions, final boolean isPrediction) { this(suggestedWordInfoList, rawSuggestions, typedWordValid, willAutoCorrect, - isPunctuationSuggestions, isObsoleteSuggestions, isPrediction, - NOT_A_SEQUENCE_NUMBER); + isObsoleteSuggestions, isPrediction, NOT_A_SEQUENCE_NUMBER); } public SuggestedWords(final ArrayList<SuggestedWordInfo> suggestedWordInfoList, final ArrayList<SuggestedWordInfo> rawSuggestions, final boolean typedWordValid, final boolean willAutoCorrect, - final boolean isPunctuationSuggestions, final boolean isObsoleteSuggestions, final boolean isPrediction, final int sequenceNumber) { this(suggestedWordInfoList, rawSuggestions, suggestedWordInfoList.isEmpty() ? null : suggestedWordInfoList.get(INDEX_OF_TYPED_WORD).mWord, - typedWordValid, willAutoCorrect, isPunctuationSuggestions, - isObsoleteSuggestions, isPrediction, sequenceNumber); + typedWordValid, willAutoCorrect, isObsoleteSuggestions, isPrediction, + sequenceNumber); } public SuggestedWords(final ArrayList<SuggestedWordInfo> suggestedWordInfoList, @@ -84,7 +80,6 @@ public final class SuggestedWords { final String typedWord, final boolean typedWordValid, final boolean willAutoCorrect, - final boolean isPunctuationSuggestions, final boolean isObsoleteSuggestions, final boolean isPrediction, final int sequenceNumber) { @@ -92,7 +87,6 @@ public final class SuggestedWords { mRawSuggestions = rawSuggestions; mTypedWordValid = typedWordValid; mWillAutoCorrect = willAutoCorrect; - mIsPunctuationSuggestions = isPunctuationSuggestions; mIsObsoleteSuggestions = isObsoleteSuggestions; mIsPrediction = isPrediction; mSequenceNumber = sequenceNumber; @@ -107,10 +101,32 @@ public final class SuggestedWords { return mSuggestedWordInfoList.size(); } + /** + * Get suggested word at <code>index</code>. + * @param index The index of the suggested word. + * @return The suggested word. + */ public String getWord(final int index) { return mSuggestedWordInfoList.get(index).mWord; } + /** + * Get displayed text at <code>index</code>. + * In RTL languages, the displayed text on the suggestion strip may be different from the + * suggested word that is returned from {@link #getWord(int)}. For example the displayed text + * of punctuation suggestion "(" should be ")". + * @param index The index of the text to display. + * @return The text to be displayed. + */ + public String getLabel(final int index) { + return mSuggestedWordInfoList.get(index).mWord; + } + + /** + * Get {@link SuggestedWordInfo} object at <code>index</code>. + * @param index The index of the {@link SuggestedWordInfo}. + * @return The {@link SuggestedWordInfo} object. + */ public SuggestedWordInfo getInfo(final int index) { return mSuggestedWordInfoList.get(index); } @@ -130,13 +146,20 @@ public final class SuggestedWords { return debugString; } + /** + * The predicator to tell whether this object represents punctuation suggestions. + * @return false if this object desn't represent punctuation suggestions. + */ + public boolean isPunctuationSuggestions() { + return false; + } + @Override public String toString() { // Pretty-print method to help debug return "SuggestedWords:" + " mTypedWordValid=" + mTypedWordValid + " mWillAutoCorrect=" + mWillAutoCorrect - + " mIsPunctuationSuggestions=" + mIsPunctuationSuggestions + " words=" + Arrays.toString(mSuggestedWordInfoList.toArray()); } @@ -313,8 +336,8 @@ public final class SuggestedWords { // We should never autocorrect, so we say the typed word is valid. Also, in this case, // no auto-correction should take place hence willAutoCorrect = false. return new SuggestedWords(newSuggestions, null /* rawSuggestions */, typedWord, - true /* typedWordValid */, false /* willAutoCorrect */, mIsPunctuationSuggestions, - mIsObsoleteSuggestions, mIsPrediction, NOT_A_SEQUENCE_NUMBER); + true /* typedWordValid */, false /* willAutoCorrect */, mIsObsoleteSuggestions, + mIsPrediction, NOT_A_SEQUENCE_NUMBER); } // Creates a new SuggestedWordInfo from the currently suggested words that removes all but the @@ -333,7 +356,6 @@ public final class SuggestedWords { SuggestedWordInfo.NOT_A_CONFIDENCE)); } return new SuggestedWords(newSuggestions, null /* rawSuggestions */, mTypedWordValid, - mWillAutoCorrect, mIsPunctuationSuggestions, mIsObsoleteSuggestions, - mIsPrediction); + mWillAutoCorrect, mIsObsoleteSuggestions, mIsPrediction); } } diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java index bd114ebca..6f73859e8 100644 --- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java +++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java @@ -1341,8 +1341,8 @@ public final class InputLogic { final SuggestedWords suggestedWords = new SuggestedWords(suggestions, null /* rawSuggestions */, typedWord, true /* typedWordValid */, false /* willAutoCorrect */, - false /* isPunctuationSuggestions */, false /* isObsoleteSuggestions */, - false /* isPrediction */, SuggestedWords.NOT_A_SEQUENCE_NUMBER); + false /* isObsoleteSuggestions */, false /* isPrediction */, + SuggestedWords.NOT_A_SEQUENCE_NUMBER); mIsAutoCorrectionIndicatorOn = false; mLatinIME.mHandler.showSuggestionStrip(suggestedWords); } diff --git a/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java b/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java index 03883a48b..5954758aa 100644 --- a/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java +++ b/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java @@ -18,17 +18,13 @@ package com.android.inputmethod.latin.settings; import android.content.res.Resources; -import com.android.inputmethod.keyboard.internal.KeySpecParser; +import com.android.inputmethod.keyboard.internal.KeyboardTextsSet; import com.android.inputmethod.keyboard.internal.MoreKeySpec; import com.android.inputmethod.latin.Constants; -import com.android.inputmethod.latin.Dictionary; +import com.android.inputmethod.latin.PunctuationSuggestions; import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.SuggestedWords; -import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.StringUtils; -import java.util.ArrayList; import java.util.Arrays; import java.util.Locale; @@ -37,7 +33,7 @@ public final class SpacingAndPunctuations { private final int[] mSortedSymbolsFollowedBySpace; private final int[] mSortedWordConnectors; public final int[] mSortedWordSeparators; - public final SuggestedWords mSuggestPuncList; + public final PunctuationSuggestions mSuggestPuncList; private final int mSentenceSeparator; public final String mSentenceSeparatorAndSpace; public final boolean mCurrentLanguageHasSpaces; @@ -56,9 +52,6 @@ public final class SpacingAndPunctuations { res.getString(R.string.symbols_word_connectors)); mSortedWordSeparators = StringUtils.toSortedCodePointArray( res.getString(R.string.symbols_word_separators)); - final String[] suggestPuncsSpec = MoreKeySpec.splitKeySpecs(res.getString( - R.string.suggested_punctuations)); - mSuggestPuncList = createSuggestPuncList(suggestPuncsSpec); mSentenceSeparator = res.getInteger(R.integer.sentence_separator); mSentenceSeparatorAndSpace = new String(new int[] { mSentenceSeparator, Constants.CODE_SPACE }, 0, 2); @@ -68,28 +61,11 @@ public final class SpacingAndPunctuations { // English variants. German rules (not "German typography") also have small gotchas. mUsesAmericanTypography = Locale.ENGLISH.getLanguage().equals(locale.getLanguage()); mUsesGermanRules = Locale.GERMAN.getLanguage().equals(locale.getLanguage()); - } - - // Helper functions to create member values. - private static SuggestedWords createSuggestPuncList(final String[] puncs) { - final ArrayList<SuggestedWordInfo> puncList = CollectionUtils.newArrayList(); - if (puncs != null) { - for (final String puncSpec : puncs) { - // TODO: Stop using KeySpecParser.getLabel(). - // TODO: Punctuation suggestions should honor RTL languages. - puncList.add(new SuggestedWordInfo(KeySpecParser.getLabel(puncSpec), - SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_HARDCODED, - Dictionary.DICTIONARY_HARDCODED, - SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, - SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */)); - } - } - return new SuggestedWords(puncList, null /* rawSuggestions */, - false /* typedWordValid */, - false /* hasAutoCorrectionCandidate */, - true /* isPunctuationSuggestions */, - false /* isObsoleteSuggestions */, - false /* isPrediction */); + final KeyboardTextsSet textsSet = new KeyboardTextsSet(); + textsSet.setLocale(locale); + final String[] suggestPuncsSpec = MoreKeySpec.splitKeySpecs( + textsSet.resolveTextReference(res.getString(R.string.suggested_punctuations))); + mSuggestPuncList = PunctuationSuggestions.newPunctuationSuggestions(suggestPuncsSpec); } public boolean isWordSeparator(final int code) { diff --git a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java index 2f4c1839b..a104baa08 100644 --- a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java +++ b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java @@ -74,7 +74,7 @@ public final class MoreSuggestions extends Keyboard { int rowStartIndex = fromIndex; final int size = Math.min(suggestedWords.size(), SuggestedWords.MAX_SUGGESTIONS); while (index < size) { - final String word = suggestedWords.getWord(index); + final String word = suggestedWords.getLabel(index); // TODO: Should take care of text x-scaling. mWidths[index] = (int)(TypefaceUtils.getStringWidth(word, paint) + padding); final int numColumn = index - rowStartIndex + 1; @@ -206,7 +206,7 @@ public final class MoreSuggestions extends Keyboard { final int x = params.getX(index); final int y = params.getY(index); final int width = params.getWidth(index); - final String word = mSuggestedWords.getWord(index); + final String word = mSuggestedWords.getLabel(index); final String info = mSuggestedWords.getDebugString(index); final int indexInMoreSuggestions = index + SUGGESTION_CODE_BASE; final Key key = new Key(word, KeyboardIconsSet.ICON_UNDEFINED, diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java index 5f05b48d4..7c11f5432 100644 --- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java +++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java @@ -46,6 +46,7 @@ import android.widget.TextView; import com.android.inputmethod.compat.TextViewCompatUtils; import com.android.inputmethod.latin.LatinImeLogger; +import com.android.inputmethod.latin.PunctuationSuggestions; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.SuggestedWords; import com.android.inputmethod.latin.utils.AutoCorrectionUtils; @@ -199,7 +200,7 @@ final class SuggestionStripLayoutHelper { if (indexInSuggestedWords >= suggestedWords.size()) { return null; } - final String word = suggestedWords.getWord(indexInSuggestedWords); + final String word = suggestedWords.getLabel(indexInSuggestedWords); final boolean isAutoCorrect = indexInSuggestedWords == 1 && suggestedWords.mWillAutoCorrect; final boolean isTypedWordValid = indexInSuggestedWords == 0 @@ -264,8 +265,8 @@ final class SuggestionStripLayoutHelper { // is in slot 1. if (positionInStrip == mCenterPositionInStrip && AutoCorrectionUtils.shouldBlockAutoCorrectionBySafetyNet( - suggestedWords.getWord(SuggestedWords.INDEX_OF_AUTO_CORRECTION), - suggestedWords.getWord(SuggestedWords.INDEX_OF_TYPED_WORD))) { + suggestedWords.getLabel(SuggestedWords.INDEX_OF_AUTO_CORRECTION), + suggestedWords.getLabel(SuggestedWords.INDEX_OF_TYPED_WORD))) { return 0xFFFF0000; } } @@ -299,9 +300,9 @@ final class SuggestionStripLayoutHelper { */ public int layoutAndReturnSuggestionCountInStrip(final SuggestedWords suggestedWords, final ViewGroup stripView, final ViewGroup placerView) { - if (suggestedWords.mIsPunctuationSuggestions) { + if (suggestedWords.isPunctuationSuggestions()) { return layoutPunctuationSuggestionsAndReturnSuggestionCountInStrip( - suggestedWords, stripView); + (PunctuationSuggestions)suggestedWords, stripView); } setupWordViewsTextAndColor(suggestedWords, mSuggestionsCountInStrip); @@ -447,8 +448,8 @@ final class SuggestionStripLayoutHelper { } private int layoutPunctuationSuggestionsAndReturnSuggestionCountInStrip( - final SuggestedWords suggestedWords, final ViewGroup stripView) { - final int countInStrip = Math.min(suggestedWords.size(), PUNCTUATIONS_IN_STRIP); + final PunctuationSuggestions punctuationSuggestions, final ViewGroup stripView) { + final int countInStrip = Math.min(punctuationSuggestions.size(), PUNCTUATIONS_IN_STRIP); for (int positionInStrip = 0; positionInStrip < countInStrip; positionInStrip++) { if (positionInStrip != 0) { // Add divider if this isn't the left most suggestion in suggestions strip. @@ -461,13 +462,13 @@ final class SuggestionStripLayoutHelper { // {@link TextView#getTag()} is used to get the index in suggestedWords at // {@link SuggestionStripView#onClick(View)}. wordView.setTag(positionInStrip); - wordView.setText(suggestedWords.getWord(positionInStrip)); + wordView.setText(punctuationSuggestions.getLabel(positionInStrip)); wordView.setTextScaleX(1.0f); wordView.setCompoundDrawables(null, null, null, null); stripView.addView(wordView); setLayoutWeight(wordView, 1.0f, mSuggestionsStripHeight); } - mMoreSuggestionsAvailable = (suggestedWords.size() > countInStrip); + mMoreSuggestionsAvailable = (punctuationSuggestions.size() > countInStrip); return countInStrip; } diff --git a/java/src/com/android/inputmethod/research/JsonUtils.java b/java/src/com/android/inputmethod/research/JsonUtils.java index 2beebdfae..6170b4339 100644 --- a/java/src/com/android/inputmethod/research/JsonUtils.java +++ b/java/src/com/android/inputmethod/research/JsonUtils.java @@ -91,7 +91,7 @@ import java.util.Map; jsonWriter.name("willAutoCorrect") .value(words.mWillAutoCorrect); jsonWriter.name("isPunctuationSuggestions") - .value(words.mIsPunctuationSuggestions); + .value(words.isPunctuationSuggestions()); jsonWriter.name("isObsoleteSuggestions").value(words.mIsObsoleteSuggestions); jsonWriter.name("isPrediction").value(words.mIsPrediction); jsonWriter.name("suggestedWords"); diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.cpp index 8172e70b6..bf38dffa5 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.cpp @@ -20,6 +20,7 @@ #include "defines.h" #include "suggest/core/dicnode/dic_node.h" #include "suggest/core/dicnode/dic_node_vector.h" +#include "suggest/core/dictionary/binary_dictionary_bigrams_iterator.h" #include "suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_reading_helper.h" #include "suggest/policyimpl/dictionary/structure/v2/patricia_trie_reading_utils.h" #include "suggest/policyimpl/dictionary/utils/probability_utils.h" @@ -303,4 +304,63 @@ int PatriciaTriePolicy::createAndGetLeavingChildNode(const DicNode *const dicNod return siblingPos; } +const WordProperty PatriciaTriePolicy::getWordProperty(const int *const codePoints, + const int codePointCount) const { + const int ptNodePos = getTerminalPtNodePositionOfWord(codePoints, codePointCount, + false /* forceLowerCaseSearch */); + if (ptNodePos == NOT_A_DICT_POS) { + AKLOGE("getWordProperty was called for invalid word."); + return WordProperty(); + } + const PtNodeParams ptNodeParams = mPtNodeReader.fetchNodeInfoInBufferFromPtNodePos(ptNodePos); + std::vector<int> codePointVector(ptNodeParams.getCodePoints(), + ptNodeParams.getCodePoints() + ptNodeParams.getCodePointCount()); + // Fetch bigram information. + std::vector<WordProperty::BigramProperty> bigrams; + const int bigramListPos = getBigramsPositionOfPtNode(ptNodePos); + int bigramWord1CodePoints[MAX_WORD_LENGTH]; + BinaryDictionaryBigramsIterator bigramsIt(getBigramsStructurePolicy(), bigramListPos); + while (bigramsIt.hasNext()) { + // Fetch the next bigram information and forward the iterator. + bigramsIt.next(); + // Skip the entry if the entry has been deleted. This never happens for ver2 dicts. + if (bigramsIt.getBigramPos() != NOT_A_DICT_POS) { + int word1Probability = NOT_A_PROBABILITY; + int word1CodePointCount = getCodePointsAndProbabilityAndReturnCodePointCount( + bigramsIt.getBigramPos(), MAX_WORD_LENGTH, bigramWord1CodePoints, + &word1Probability); + std::vector<int> word1(bigramWord1CodePoints, + bigramWord1CodePoints + word1CodePointCount); + bigrams.push_back(WordProperty::BigramProperty(&word1, bigramsIt.getProbability(), + NOT_A_TIMESTAMP /* timestamp */, 0 /* level */, 0 /* count */)); + } + } + // Fetch shortcut information. + std::vector<WordProperty::ShortcutProperty> shortcuts; + int shortcutPos = getShortcutPositionOfPtNode(ptNodePos); + if (shortcutPos != NOT_A_DICT_POS) { + int shortcutTargetCodePoints[MAX_WORD_LENGTH]; + ShortcutListReadingUtils::getShortcutListSizeAndForwardPointer(mDictRoot, &shortcutPos); + bool hasNext = true; + while (hasNext) { + const ShortcutListReadingUtils::ShortcutFlags shortcutFlags = + ShortcutListReadingUtils::getFlagsAndForwardPointer(mDictRoot, &shortcutPos); + hasNext = ShortcutListReadingUtils::hasNext(shortcutFlags); + const int shortcutTargetLength = ShortcutListReadingUtils::readShortcutTarget( + mDictRoot, MAX_WORD_LENGTH, shortcutTargetCodePoints, &shortcutPos); + std::vector<int> shortcutTarget(shortcutTargetCodePoints, + shortcutTargetCodePoints + shortcutTargetLength); + const int shortcutProbability = + ShortcutListReadingUtils::getProbabilityFromFlags(shortcutFlags); + shortcuts.push_back( + WordProperty::ShortcutProperty(&shortcutTarget, shortcutProbability)); + } + } + return WordProperty(&codePointVector, ptNodeParams.isNotAWord(), + ptNodeParams.isBlacklisted(), ptNodeParams.hasBigrams(), + ptNodeParams.hasShortcutTargets(), ptNodeParams.getProbability(), + NOT_A_TIMESTAMP /* timestamp */, 0 /* level */, 0 /* count */, + &bigrams, &shortcuts); +} + } // namespace latinime diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h index 1ce7f85d4..da4be87ce 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h @@ -128,10 +128,7 @@ class PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy { } const WordProperty getWordProperty(const int *const codePoints, - const int codePointCount) const { - // getWordProperty is not supported. - return WordProperty(); - } + const int codePointCount) const; int getNextWordAndNextToken(const int token, int *const outCodePoints) { // getNextWordAndNextToken is not supported. diff --git a/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java b/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java index 53839b67f..8fe473523 100644 --- a/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java +++ b/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java @@ -49,7 +49,6 @@ public class SuggestedWordsTests extends AndroidTestCase { list, null /* rawSuggestions */, false /* typedWordValid */, false /* willAutoCorrect */, - false /* isPunctuationSuggestions */, false /* isObsoleteSuggestions */, false /* isPrediction*/); assertEquals(NUMBER_OF_ADDED_SUGGESTIONS + 1, words.size()); diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java index 141730de9..28388b4a0 100644 --- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java +++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java @@ -39,6 +39,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Map.Entry; import java.util.Random; import java.util.Set; @@ -596,4 +597,39 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { Log.d(TAG, result); } } + + public void testVer2DictGetWordProperty() { + final FormatOptions formatOptions = BinaryDictUtils.VERSION2_OPTIONS; + final ArrayList<String> words = sWords; + final HashMap<String, List<String>> shortcuts = sShortcuts; + final String dictName = "testGetWordProperty"; + final String dictVersion = Long.toString(System.currentTimeMillis()); + final FusionDictionary dict = new FusionDictionary(new PtNodeArray(), + BinaryDictUtils.makeDictionaryOptions(dictName, dictVersion, formatOptions)); + addUnigrams(words.size(), dict, words, shortcuts); + addBigrams(dict, words, sEmptyBigrams); + final File file = BinaryDictUtils.getDictFile(dictName, dictVersion, formatOptions, + getContext().getCacheDir()); + file.delete(); + timeWritingDictToFile(file, dict, formatOptions); + final BinaryDictionary binaryDictionary = new BinaryDictionary(file.getAbsolutePath(), + 0 /* offset */, file.length(), true /* useFullEditDistance */, + Locale.ENGLISH, dictName, false /* isUpdatable */); + for (final String word : words) { + final WordProperty wordProperty = binaryDictionary.getWordProperty(word); + assertEquals(word, wordProperty.mWord); + assertEquals(UNIGRAM_FREQ, wordProperty.getProbability()); + if (shortcuts.containsKey(word)) { + assertEquals(shortcuts.get(word).size(), wordProperty.mShortcutTargets.size()); + final List<String> shortcutList = shortcuts.get(word); + assertTrue(wordProperty.mHasShortcuts); + for (final WeightedString shortcutTarget : wordProperty.mShortcutTargets) { + assertTrue(shortcutList.contains(shortcutTarget.mWord)); + assertEquals(UNIGRAM_FREQ, shortcutTarget.getProbability()); + shortcutList.remove(shortcutTarget.mWord); + } + assertTrue(shortcutList.isEmpty()); + } + } + } } diff --git a/tests/src/com/android/inputmethod/latin/settings/SpacingAndPunctuationsTests.java b/tests/src/com/android/inputmethod/latin/settings/SpacingAndPunctuationsTests.java index 424e7ff1b..24af09484 100644 --- a/tests/src/com/android/inputmethod/latin/settings/SpacingAndPunctuationsTests.java +++ b/tests/src/com/android/inputmethod/latin/settings/SpacingAndPunctuationsTests.java @@ -373,29 +373,53 @@ public class SpacingAndPunctuationsTests extends AndroidTestCase { assertTrue(SWISS_GERMAN.mUsesGermanRules); } - private static void testingStandardPunctuationSuggestions(final SpacingAndPunctuations sp) { + private static final String[] PUNCTUATION_LABELS_LTR = { + "!", "?", ",", ":", ";", "\"", "(", ")", "'", "-", "/", "@", "_" + }; + private static final String[] PUNCTUATION_WORDS_LTR = PUNCTUATION_LABELS_LTR; + private static final String[] PUNCTUATION_WORDS_HEBREW = { + "!", "?", ",", ":", ";", "\"", ")", "(", "'", "-", "/", "@", "_" + }; + // U+061F: "؟" ARABIC QUESTION MARK + // U+060C: "،" ARABIC COMMA + // U+061B: "؛" ARABIC SEMICOLON + private static final String[] PUNCTUATION_LABELS_ARABIC_PERSIAN = { + "!", "\u061F", "\u060C", ":", "\u061B", "\"", "(", ")", "'", "-", "/", "@", "_" + }; + private static final String[] PUNCTUATION_WORDS_ARABIC_PERSIAN = { + "!", "\u061F", "\u060C", ":", "\u061B", "\"", ")", "(", "'", "-", "/", "@", "_" + }; + + private static void testingStandardPunctuationSuggestions(final SpacingAndPunctuations sp, + final String[] punctuationLabels, final String[] punctuationWords) { final SuggestedWords suggestedWords = sp.mSuggestPuncList; assertFalse("typedWordValid", suggestedWords.mTypedWordValid); assertFalse("willAutoCorrect", suggestedWords.mWillAutoCorrect); - assertTrue("isPunctuationSuggestions", suggestedWords.mIsPunctuationSuggestions); + assertTrue("isPunctuationSuggestions", suggestedWords.isPunctuationSuggestions()); assertFalse("isObsoleteSuggestions", suggestedWords.mIsObsoleteSuggestions); assertFalse("isPrediction", suggestedWords.mIsPrediction); - final String[] punctuations = { - "!", "?", ",", ":", ";", "\"", "(", ")", "'", "-", "/", "@", "_" - }; - assertEquals("size", punctuations.length, suggestedWords.size()); - for (int index = 0; index < punctuations.length; index++) { - assertEquals("punctuation at " + index, - punctuations[index], suggestedWords.getWord(index)); + assertEquals("size", punctuationLabels.length, suggestedWords.size()); + for (int index = 0; index < suggestedWords.size(); index++) { + assertEquals("punctuation label at " + index, + punctuationLabels[index], suggestedWords.getLabel(index)); + assertEquals("punctuation word at " + index, + punctuationWords[index], suggestedWords.getWord(index)); } } + + // TODO: Add tests for tablet as well public void testPunctuationSuggestions() { - testingStandardPunctuationSuggestions(ENGLISH); - testingStandardPunctuationSuggestions(FRENCH); - testingStandardPunctuationSuggestions(GERMAN); - // TODO: Should fix these RTL languages - testingStandardPunctuationSuggestions(ARABIC); - testingStandardPunctuationSuggestions(PERSIAN); - testingStandardPunctuationSuggestions(HEBREW); + testingStandardPunctuationSuggestions(ENGLISH, + PUNCTUATION_LABELS_LTR, PUNCTUATION_WORDS_LTR); + testingStandardPunctuationSuggestions(FRENCH, + PUNCTUATION_LABELS_LTR, PUNCTUATION_WORDS_LTR); + testingStandardPunctuationSuggestions(GERMAN, + PUNCTUATION_LABELS_LTR, PUNCTUATION_WORDS_LTR); + testingStandardPunctuationSuggestions(ARABIC, + PUNCTUATION_LABELS_ARABIC_PERSIAN, PUNCTUATION_WORDS_ARABIC_PERSIAN); + testingStandardPunctuationSuggestions(PERSIAN, + PUNCTUATION_LABELS_ARABIC_PERSIAN, PUNCTUATION_WORDS_ARABIC_PERSIAN); + testingStandardPunctuationSuggestions(HEBREW, + PUNCTUATION_LABELS_LTR, PUNCTUATION_WORDS_HEBREW); } } diff --git a/tools/make-keyboard-text/res/values-ar/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-ar/donottranslate-more-keys.xml index 9b0a05945..d9976858a 100644 --- a/tools/make-keyboard-text/res/values-ar/donottranslate-more-keys.xml +++ b/tools/make-keyboard-text/res/values-ar/donottranslate-more-keys.xml @@ -75,7 +75,7 @@ <!-- U+066A: "٪" ARABIC PERCENT SIGN --> <string name="keylabel_for_symbols_percent">٪</string> <!-- U+00BF: "¿" INVERTED QUESTION MARK --> - <string name="more_keys_for_question">\?,¿</string> + <string name="more_keys_for_question">?,¿</string> <string name="more_keys_for_symbols_semicolon">;</string> <!-- U+2030: "‰" PER MILLE SIGN --> <string name="more_keys_for_symbols_percent">\\%,‰</string> @@ -85,7 +85,7 @@ <string name="keylabel_for_tablet_comma">"،"</string> <string name="keyhintlabel_for_tablet_comma">"؟"</string> <string name="more_keys_for_tablet_comma">"!fixedColumnOrder!4,:,!,؟,؛,-,/,\",\'"</string> - <string name="more_keys_for_punctuation">"!fixedColumnOrder!8,\",\',#,-,:,!,،,؟,\@,&,\\%,+,؛,/,(|),)|("</string> + <string name="more_keys_for_punctuation">"!fixedColumnOrder!8,\",\',#,-,:,!,،,؟,@,&,\\%,+,؛,/,(|),)|("</string> <!-- U+266A: "♪" EIGHTH NOTE --> <string name="more_keys_for_bullet">♪</string> <!-- U+2605: "★" BLACK STAR diff --git a/tools/make-keyboard-text/res/values-ca/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-ca/donottranslate-more-keys.xml index f63e85bd5..8865a6057 100644 --- a/tools/make-keyboard-text/res/values-ca/donottranslate-more-keys.xml +++ b/tools/make-keyboard-text/res/values-ca/donottranslate-more-keys.xml @@ -71,8 +71,8 @@ U+0142: "ł" LATIN SMALL LETTER L WITH STROKE --> <string name="more_keys_for_l">l·l,ł</string> <!-- U+00B7: "·" MIDDLE DOT --> - <string name="more_keys_for_punctuation">"!fixedColumnOrder!9,;,/,(,),#,·,!,\\,,\?,&,\\%,+,\",-,:,',\@"</string> - <string name="more_keys_for_tablet_punctuation">"!fixedColumnOrder!8,;,/,(,),#,·,',\\,,&,\\%,+,\",-,:,\@"</string> + <string name="more_keys_for_punctuation">"!fixedColumnOrder!9,;,/,(,),#,·,!,\\,,?,&,\\%,+,\",-,:,',@"</string> + <string name="more_keys_for_tablet_punctuation">"!fixedColumnOrder!8,;,/,(,),#,·,',\\,,&,\\%,+,\",-,:,@"</string> <!-- U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA --> <string name="keylabel_for_spanish_row2_10">ç</string> </resources> diff --git a/tools/make-keyboard-text/res/values-es/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-es/donottranslate-more-keys.xml index f4fe7f787..453d5c196 100644 --- a/tools/make-keyboard-text/res/values-es/donottranslate-more-keys.xml +++ b/tools/make-keyboard-text/res/values-es/donottranslate-more-keys.xml @@ -69,5 +69,5 @@ <string name="more_keys_for_c">ç,ć,č</string> <!-- U+00A1: "¡" INVERTED EXCLAMATION MARK U+00BF: "¿" INVERTED QUESTION MARK --> - <string name="more_keys_for_punctuation">"!fixedColumnOrder!9,¡,;,/,(,),#,!,\\,,\?,¿,&,\\%,+,\",-,:,',\@"</string> + <string name="more_keys_for_punctuation">"!fixedColumnOrder!9,¡,;,/,(,),#,!,\\,,?,¿,&,\\%,+,\",-,:,',@"</string> </resources> diff --git a/tools/make-keyboard-text/res/values-fa/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-fa/donottranslate-more-keys.xml index 3f12784e5..6ea04338e 100644 --- a/tools/make-keyboard-text/res/values-fa/donottranslate-more-keys.xml +++ b/tools/make-keyboard-text/res/values-fa/donottranslate-more-keys.xml @@ -75,7 +75,7 @@ <!-- U+066A: "٪" ARABIC PERCENT SIGN --> <string name="keylabel_for_symbols_percent">٪</string> <!-- U+00BF: "¿" INVERTED QUESTION MARK --> - <string name="more_keys_for_question">\?,¿</string> + <string name="more_keys_for_question">?,¿</string> <string name="more_keys_for_symbols_semicolon">;</string> <!-- U+2030: "‰" PER MILLE SIGN --> <string name="more_keys_for_symbols_percent">\\%,‰</string> @@ -92,7 +92,7 @@ <!-- U+061F: "؟" ARABIC QUESTION MARK U+060C: "،" ARABIC COMMA U+061B: "؛" ARABIC SEMICOLON --> - <string name="more_keys_for_punctuation">"!fixedColumnOrder!8,\",\',#,-,:,!,،,؟,\@,&,\\%,+,؛,/,!text/keyspec_left_parenthesis,!text/keyspec_right_parenthesis"</string> + <string name="more_keys_for_punctuation">"!fixedColumnOrder!8,\",\',#,-,:,!,،,؟,@,&,\\%,+,؛,/,!text/keyspec_left_parenthesis,!text/keyspec_right_parenthesis"</string> <!-- U+266A: "♪" EIGHTH NOTE --> <string name="more_keys_for_bullet">♪</string> <!-- U+2605: "★" BLACK STAR diff --git a/tools/make-keyboard-text/res/values-hi/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-hi/donottranslate-more-keys.xml index b0d010f81..de10a010f 100644 --- a/tools/make-keyboard-text/res/values-hi/donottranslate-more-keys.xml +++ b/tools/make-keyboard-text/res/values-hi/donottranslate-more-keys.xml @@ -44,7 +44,7 @@ <!-- U+0966: "०" DEVANAGARI DIGIT ZERO --> <string name="keylabel_for_symbols_0">०</string> <!-- Label for "switch to symbols" key. --> - <string name="label_to_symbol_key">\?१२३</string> + <string name="label_to_symbol_key">?१२३</string> <!-- Label for "switch to symbols with microphone" key. This string shouldn't include the "mic" part because it'll be appended by the code. --> <string name="label_to_symbol_with_microphone_key">१२३</string> diff --git a/tools/make-keyboard-text/res/values-ne-rNP/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-ne-rNP/donottranslate-more-keys.xml index 9205e5309..e92a87e19 100644 --- a/tools/make-keyboard-text/res/values-ne-rNP/donottranslate-more-keys.xml +++ b/tools/make-keyboard-text/res/values-ne-rNP/donottranslate-more-keys.xml @@ -44,7 +44,7 @@ <!-- U+0966: "०" DEVANAGARI DIGIT ZERO --> <string name="keylabel_for_symbols_0">०</string> <!-- Label for "switch to symbols" key. --> - <string name="label_to_symbol_key">\?१२३</string> + <string name="label_to_symbol_key">?१२३</string> <!-- Label for "switch to symbols with microphone" key. This string shouldn't include the "mic" part because it'll be appended by the code. --> <string name="label_to_symbol_with_microphone_key">१२३</string> diff --git a/tools/make-keyboard-text/res/values/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values/donottranslate-more-keys.xml index 8d3d61c72..9cdcb4668 100644 --- a/tools/make-keyboard-text/res/values/donottranslate-more-keys.xml +++ b/tools/make-keyboard-text/res/values/donottranslate-more-keys.xml @@ -83,8 +83,8 @@ <string name="more_keys_for_currency_dollar">¢,£,€,¥,₱</string> <string name="keylabel_for_currency">$</string> <string name="more_keys_for_currency">$,¢,€,£,¥,₱</string> - <string name="more_keys_for_punctuation">"!fixedColumnOrder!8,;,/,!text/keyspec_left_parenthesis,!text/keyspec_right_parenthesis,#,!,\\,,\?,&,\\%,+,\",-,:,',\@"</string> - <string name="more_keys_for_tablet_punctuation">"!fixedColumnOrder!7,;,/,!text/keyspec_left_parenthesis,!text/keyspec_right_parenthesis,#,',\\,,&,\\%,+,\",-,:,\@"</string> + <string name="more_keys_for_punctuation">"!fixedColumnOrder!8,;,/,!text/keyspec_left_parenthesis,!text/keyspec_right_parenthesis,#,!,\\,,?,&,\\%,+,\",-,:,',@"</string> + <string name="more_keys_for_tablet_punctuation">"!fixedColumnOrder!7,;,/,!text/keyspec_left_parenthesis,!text/keyspec_right_parenthesis,#,',\\,,&,\\%,+,\",-,:,@"</string> <!-- U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE --> <string name="keylabel_for_spanish_row2_10">ñ</string> <!-- U+2020: "†" DAGGER @@ -115,7 +115,7 @@ <string name="keylabel_for_symbols_9">9</string> <string name="keylabel_for_symbols_0">0</string> <!-- Label for "switch to symbols" key. --> - <string name="label_to_symbol_key">\?123</string> + <string name="label_to_symbol_key">?123</string> <!-- Label for "switch to symbols with microphone" key. This string shouldn't include the "mic" part because it'll be appended by the code. --> <string name="label_to_symbol_with_microphone_key">123</string> @@ -189,7 +189,7 @@ <string name="keylabel_for_tablet_period">.</string> <string name="keyhintlabel_for_tablet_period"></string> <string name="more_keys_for_tablet_period">!text/more_keys_for_tablet_punctuation</string> - <string name="keylabel_for_symbols_question">\?</string> + <string name="keylabel_for_symbols_question">?</string> <string name="keylabel_for_symbols_semicolon">;</string> <string name="keylabel_for_symbols_percent">%</string> <!-- U+00A1: "¡" INVERTED EXCLAMATION MARK --> @@ -205,17 +205,15 @@ <string name="keylabel_for_w">w</string> <string name="keylabel_for_y">y</string> <string name="keylabel_for_x">x</string> - <string name="more_keys_for_am_pm">!fixedColumnOrder!2,!hasLabels!,\@string/label_time_am,\@string/label_time_pm</string> + <string name="more_keys_for_am_pm">!fixedColumnOrder!2,!hasLabels!,!text/label_time_am,!text/label_time_pm</string> <string name="settings_as_more_key">!icon/settings_key|!code/key_settings</string> <string name="shortcut_as_more_key">!icon/shortcut_key|!code/key_shortcut</string> - <string name="action_next_as_more_key">!hasLabels!,\@string/label_next_key|!code/key_action_next</string> - <string name="action_previous_as_more_key">!hasLabels!,\@string/label_previous_key|!code/key_action_previous</string> + <string name="action_next_as_more_key">!hasLabels!,!text/label_next_key|!code/key_action_next</string> + <string name="action_previous_as_more_key">!hasLabels!,!text/label_previous_key|!code/key_action_previous</string> <!-- Label for "switch to more symbol" modifier key ("= \ <"). Must be short to fit on key! --> <string name="label_to_more_symbol_key">= \\\\ <</string> <!-- Label for "switch to more symbol" modifier key on tablets. Must be short to fit on key! --> <string name="label_to_more_symbol_for_tablet_key">~ [ <</string> - <!-- Label for "Tab" key. Must be short to fit on key! --> - <string name="label_tab_key">Tab</string> <!-- Label for "switch to phone numeric" key. Must be short to fit on key! --> <string name="label_to_phone_numeric_key">123</string> <!-- Label for "switch to phone symbols" key. Must be short to fit on key! --> diff --git a/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/MoreKeysResources.java b/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/MoreKeysResources.java index 872ef19e3..e9d6c864f 100644 --- a/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/MoreKeysResources.java +++ b/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/MoreKeysResources.java @@ -29,6 +29,7 @@ import java.util.Comparator; import java.util.HashMap; import java.util.Locale; import java.util.jar.JarFile; +import java.util.regex.Pattern; public class MoreKeysResources { private static final String TEXT_RESOURCE_NAME = "donottranslate-more-keys.xml"; @@ -287,23 +288,7 @@ public class MoreKeysResources { sb.append(String.format("\\u%04X", (int)c)); } } - return replaceIncompatibleEscape(sb.toString()); - } - - private static String replaceIncompatibleEscape(final String text) { - String t = text; - t = replaceAll(t, "\\?", "?"); - t = replaceAll(t, "\\@", "@"); - t = replaceAll(t, "@string/", "!text/"); - return t; - } - - private static String replaceAll(final String text, final String target, final String replace) { - String t = text; - while (t.indexOf(target) >= 0) { - t = t.replace(target, replace); - } - return t; + return sb.toString(); } private static void close(final Closeable stream) { |