diff options
Diffstat (limited to 'java')
26 files changed, 486 insertions, 392 deletions
diff --git a/java/res/xml-sw600dp/rows_nepali_romanized.xml b/java/res/xml-sw600dp/rows_nepali_romanized.xml index fe73fbd9e..41cd2f9b4 100644 --- a/java/res/xml-sw600dp/rows_nepali_romanized.xml +++ b/java/res/xml-sw600dp/rows_nepali_romanized.xml @@ -39,7 +39,7 @@ latin:keyWidth="fillRight" /> </Row> <Row - latin:keyWidth="8.182%p" + latin:keyWidth="8.0%p" latin:keyLabelFlags="fontNormal" > <Key @@ -47,6 +47,9 @@ latin:keyWidth="10.0%p" /> <include latin:keyboardLayout="@xml/rowkeys_nepali_romanized3" /> <include latin:keyboardLayout="@xml/keys_exclamation_question" /> + <Key + latin:keyStyle="shiftKeyStyle" + latin:keyWidth="fillRight" /> </Row> <include latin:keyboardLayout="@xml/row_qwerty4" /> </merge> diff --git a/java/res/xml-sw600dp/rows_nepali_traditional.xml b/java/res/xml-sw600dp/rows_nepali_traditional.xml index e56271f21..d23ca24e4 100644 --- a/java/res/xml-sw600dp/rows_nepali_traditional.xml +++ b/java/res/xml-sw600dp/rows_nepali_traditional.xml @@ -45,8 +45,8 @@ <Key latin:keyStyle="shiftKeyStyle" latin:keyWidth="10.0%p" /> - <include latin:keyboardLayout="@xml/rowkeys_nepali_traditional3_left6" /> - <include latin:keyboardLayout="@xml/rowkeys_nepali_traditional3_right5" /> - </Row> + <include latin:keyboardLayout="@xml/rowkeys_nepali_traditional3" /> + <include latin:keyboardLayout="@xml/keys_exclamation_question" /> + </Row> <include latin:keyboardLayout="@xml/row_qwerty4" /> </merge> diff --git a/java/res/xml/key_period.xml b/java/res/xml/key_period.xml index 10325ef1a..5b59cff19 100644 --- a/java/res/xml/key_period.xml +++ b/java/res/xml/key_period.xml @@ -23,21 +23,6 @@ > <switch> <case - latin:languageCode="ne" - latin:keyboardLayoutSet="nepali_traditional" - > - <!-- Because the font rendering system prior to API version 16 can't automatically - render dotted circle for incomplete combining letter of some scripts, different - set of Key definitions are needed based on the API version. --> - <include - latin:keyboardLayout="@xml/keystyle_devanagari_sign_virama" /> - <Key - latin:keyStyle="baseKeyDevanagariSignVirama" - latin:keyLabelFlags="hasPopupHint" - latin:moreKeys="!text/morekeys_punctuation" - latin:backgroundType="functional" /> - </case> - <case latin:keyboardLayoutSet="dvorak" > <Key diff --git a/java/res/xml/keystyle_devanagari_sign_virama.xml b/java/res/xml/keystyle_devanagari_sign_virama.xml index ff778d94c..7863ca48f 100644 --- a/java/res/xml/keystyle_devanagari_sign_virama.xml +++ b/java/res/xml/keystyle_devanagari_sign_virama.xml @@ -35,7 +35,7 @@ U+090D: "ऍ" DEVANAGARI LETTER CANDRA E --> <key-style latin:styleName="moreKeysDevanagariSignVirama" - latin:moreKeys="◌ॅ,ऍ" /> + latin:moreKeys="◌ॅ|ॅ,ऍ" /> </case> <case latin:keyboardLayoutSet="marathi"> <!-- U+0905: "अ" DEVANAGARI LETTER A --> diff --git a/java/res/xml/rowkeys_nepali_romanized3.xml b/java/res/xml/rowkeys_nepali_romanized3.xml index 24f590832..c6a1e283e 100644 --- a/java/res/xml/rowkeys_nepali_romanized3.xml +++ b/java/res/xml/rowkeys_nepali_romanized3.xml @@ -43,11 +43,6 @@ <Key latin:keyStyle="baseKeyDevanagariSignAnusvara" /> <!-- U+0919: "ङ" DEVANAGARI LETTER NGA --> <Key latin:keySpec="ङ" /> - <!-- Because the font rendering system prior to API version 16 can't automatically - render dotted circle for incomplete combining letter of some scripts, different - set of Key definitions are needed based on the API version. --> - <include latin:keyboardLayout="@xml/keystyle_devanagari_sign_virama" /> - <Key latin:keyStyle="baseKeyDevanagariSignVirama" /> </case> <default> <!-- U+0937: "ष" DEVANAGARI LETTER SSA --> @@ -64,16 +59,14 @@ <Key latin:keySpec="न" /> <!-- U+092E: "म" DEVANAGARI LETTER MA --> <Key latin:keySpec="म" /> - <!-- U+0964: "।" DEVANAGARI DANDA - U+093D: "ऽ" DEVANAGARI SIGN AVAGRAHA --> - <Key - latin:keySpec="।" - latin:moreKeys="ऽ" /> <!-- Because the font rendering system prior to API version 16 can't automatically render dotted circle for incomplete combining letter of some scripts, different set of Key definitions are needed based on the API version. --> <include latin:keyboardLayout="@xml/keystyle_devanagari_sign_virama" /> - <Key latin:keyStyle="baseKeyDevanagariSignVirama" /> + <!-- U+093D: "ऽ" DEVANAGARI SIGN AVAGRAHA --> + <Key + latin:keyStyle="baseKeyDevanagariSignVirama" + latin:moreKeys="ऽ" /> </default> </switch> </merge> diff --git a/java/res/xml/rowkeys_nepali_traditional3_right5.xml b/java/res/xml/rowkeys_nepali_traditional3.xml index c7c73a446..c43c59386 100644 --- a/java/res/xml/rowkeys_nepali_traditional3_right5.xml +++ b/java/res/xml/rowkeys_nepali_traditional3.xml @@ -21,6 +21,27 @@ <merge xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> <switch> <case latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"> + <!-- U+0915/U+094D: "क्" DEVANAGARI LETTER KA/DEVANAGARI SIGN VIRAMA --> + <Key + latin:keySpec="क्" + latin:keyLabelFlags="followKeyLetterRatio" /> + <!-- U+0939/U+094D/U+092E: "ह्म" DEVANAGARI LETTER HA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER MA --> + <Key + latin:keySpec="ह्म" + latin:keyLabelFlags="followKeyLetterRatio" /> + <!-- U+090B: "ऋ" DEVANAGARI LETTER VOCALIC R --> + <Key latin:keySpec="ऋ" /> + <!-- U+0950: "ॐ" DEVANAGARI OM --> + <Key latin:keySpec="ॐ" /> + <!-- Because the font rendering system prior to API version 16 can't automatically + render dotted circle for incomplete combining letter of some scripts, different + set of Key definitions are needed based on the API version. --> + <include latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_au" /> + <Key latin:keyStyle="baseKeyDevanagariVowelSignAu" /> + <!-- U+0926/U+094D/U+092F: "द्य" DEVANAGARI LETTER DA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER YA --> + <Key + latin:keySpec="द्य" + latin:keyLabelFlags="followKeyLetterRatio" /> <!-- Because the font rendering system prior to API version 16 can't automatically render dotted circle for incomplete combining letter of some scripts, different set of Key definitions are needed based on the API version. --> @@ -33,44 +54,36 @@ set of Key definitions are needed based on the API version. --> <include latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_ai" /> <Key latin:keyStyle="baseKeyDevanagariVowelSignAi" /> - <!-- U+0930/U+0941: "रु" DEVANAGARI LETTER RA/DEVANAGARI VOWEL SIGN U --> - <Key - latin:keySpec="रु" - latin:moreKeys="!" - latin:keyLabelFlags="followKeyLetterRatio" /> - <Key - latin:keySpec="\?" - latin:keyLabelFlags="fontDefault" /> </case> <default> - <!-- Because the font rendering system prior to API version 16 can't automatically - render dotted circle for incomplete combining letter of some scripts, different - set of Key definitions are needed based on the API version. --> - <include latin:keyboardLayout="@xml/keystyle_devanagari_sign_visarga" /> - <!-- U+093D: "ऽ" DEVANAGARI SIGN AVAGRAHA --> - <Key - latin:keyStyle="baseKeyDevanagariSignVisarga" - latin:moreKeys="ऽ" /> + <!-- U+0936: "श" DEVANAGARI LETTER SHA --> + <Key latin:keySpec="श" /> + <!-- U+0939: "ह" DEVANAGARI LETTER HA --> + <Key latin:keySpec="ह" /> + <!-- U+0905: "अ" DEVANAGARI LETTER A --> + <Key latin:keySpec="अ" /> + <!-- U+0916: "ख" DEVANAGARI LETTER KHA --> + <Key latin:keySpec="ख" /> + <!-- U+0926: "द" DEVANAGARI LETTER DA --> + <Key latin:keySpec="द" /> + <!-- U+0932: "ल" DEVANAGARI LETTER LA --> + <Key latin:keySpec="ल" /> <!-- Because the font rendering system prior to API version 16 can't automatically render dotted circle for incomplete combining letter of some scripts, different set of Key definitions are needed based on the API version. --> <include latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_e" /> - <!-- Override more keys with empty definition --> - <key-style latin:styleName="moreKeysDevanagariVowelSignE" /> <Key latin:keyStyle="baseKeyDevanagariVowelSignE" /> - <!-- U+0964: "।" DEVANAGARI DANDA --> - <Key latin:keySpec="।" /> - <!-- U+0930: "र" DEVANAGARI LETTER RA --> - <Key - latin:keySpec="र" - latin:moreKeys="!" /> <!-- Because the font rendering system prior to API version 16 can't automatically render dotted circle for incomplete combining letter of some scripts, different set of Key definitions are needed based on the API version. --> - <include latin:keyboardLayout="@xml/keystyle_devanagari_sign_virama" /> + <include + latin:keyboardLayout="@xml/keystyle_devanagari_sign_virama" /> + <Key latin:keyStyle="baseKeyDevanagariSignVirama" /> + <!-- U+0930: "र" DEVANAGARI LETTER RA + U+0930/U+0941: "रु" DEVANAGARI LETTER RA/DEVANAGARI VOWEL SIGN U --> <Key - latin:keyStyle="baseKeyDevanagariSignVirama" - latin:moreKeys="\?" /> + latin:keySpec="र" + latin:moreKeys="रु" /> </default> </switch> </merge> diff --git a/java/res/xml/rowkeys_nepali_traditional3_left6.xml b/java/res/xml/rowkeys_nepali_traditional3_left6.xml deleted file mode 100644 index ade278710..000000000 --- a/java/res/xml/rowkeys_nepali_traditional3_left6.xml +++ /dev/null @@ -1,61 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 2013, 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. -*/ ---> - -<merge xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> - <switch> - <case latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"> - <!-- U+0915/U+094D: "क्" DEVANAGARI LETTER KA/DEVANAGARI SIGN VIRAMA --> - <Key - latin:keySpec="क्" - latin:keyLabelFlags="followKeyLetterRatio" /> - <!-- U+0939/U+094D/U+092E: "ह्म" DEVANAGARI LETTER HA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER MA --> - <Key - latin:keySpec="ह्म" - latin:keyLabelFlags="followKeyLetterRatio" /> - <!-- U+090B: "ऋ" DEVANAGARI LETTER VOCALIC R --> - <Key latin:keySpec="ऋ" /> - <!-- U+0950: "ॐ" DEVANAGARI OM --> - <Key latin:keySpec="ॐ" /> - <!-- Because the font rendering system prior to API version 16 can't automatically - render dotted circle for incomplete combining letter of some scripts, different - set of Key definitions are needed based on the API version. --> - <include latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_au" /> - <Key latin:keyStyle="baseKeyDevanagariVowelSignAu" /> - <!-- U+0926/U+094D/U+092F: "द्य" DEVANAGARI LETTER DA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER YA --> - <Key - latin:keySpec="द्य" - latin:keyLabelFlags="followKeyLetterRatio" /> - </case> - <default> - <!-- U+0936: "श" DEVANAGARI LETTER SHA --> - <Key latin:keySpec="श" /> - <!-- U+0939: "ह" DEVANAGARI LETTER HA --> - <Key latin:keySpec="ह" /> - <!-- U+0905: "अ" DEVANAGARI LETTER A --> - <Key latin:keySpec="अ" /> - <!-- U+0916: "ख" DEVANAGARI LETTER KHA --> - <Key latin:keySpec="ख" /> - <!-- U+0926: "द" DEVANAGARI LETTER DA --> - <Key latin:keySpec="द" /> - <!-- U+0932: "ल" DEVANAGARI LETTER LA --> - <Key latin:keySpec="ल" /> - </default> - </switch> -</merge> diff --git a/java/res/xml/rowkeys_nepali_traditional3_right3.xml b/java/res/xml/rowkeys_nepali_traditional3_right3.xml deleted file mode 100644 index 4db438d81..000000000 --- a/java/res/xml/rowkeys_nepali_traditional3_right3.xml +++ /dev/null @@ -1,52 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 2013, 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. -*/ ---> - -<merge xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> - <switch> - <case latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"> - <!-- Because the font rendering system prior to API version 16 can't automatically - render dotted circle for incomplete combining letter of some scripts, different - set of Key definitions are needed based on the API version. --> - <include latin:keyboardLayout="@xml/keystyle_devanagari_sign_anusvara" /> - <Key latin:keyStyle="baseKeyDevanagariSignAnusvara" /> - <!-- U+0919: "ङ" DEVANAGARI LETTER NGA --> - <Key latin:keySpec="ङ" /> - <!-- Because the font rendering system prior to API version 16 can't automatically - render dotted circle for incomplete combining letter of some scripts, different - set of Key definitions are needed based on the API version. --> - <include latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_ai" /> - <Key latin:keyStyle="baseKeyDevanagariVowelSignAi" /> - </case> - <default> - <!-- Because the font rendering system prior to API version 16 can't automatically - render dotted circle for incomplete combining letter of some scripts, different - set of Key definitions are needed based on the API version. --> - <include latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_e" /> - <Key latin:keyStyle="baseKeyDevanagariVowelSignE" /> - <!-- U+0964: "।" DEVANAGARI DANDA --> - <Key latin:keySpec="।" /> - <!-- U+0930: "र" DEVANAGARI LETTER RA - U+0930/U+0941: "रु" DEVANAGARI LETTER RA/DEVANAGARI VOWEL SIGN U --> - <Key - latin:keySpec="र" - latin:moreKeys="रु" /> - </default> - </switch> -</merge> diff --git a/java/res/xml/rows_nepali_romanized.xml b/java/res/xml/rows_nepali_romanized.xml index daca3ee86..26737ec8a 100644 --- a/java/res/xml/rows_nepali_romanized.xml +++ b/java/res/xml/rows_nepali_romanized.xml @@ -33,16 +33,18 @@ <include latin:keyboardLayout="@xml/rowkeys_nepali_romanized2" /> </Row> <Row - latin:keyWidth="8.711%p" + latin:keyWidth="8.75%p" latin:keyLabelFlags="fontNormal" > <Key latin:keyStyle="shiftKeyStyle" - latin:keyWidth="10.8%p" /> + latin:keyWidth="15%p" + latin:visualInsetsRight="1%p" /> <include latin:keyboardLayout="@xml/rowkeys_nepali_romanized3" /> <Key latin:keyStyle="deleteKeyStyle" - latin:keyWidth="fillRight" /> + latin:keyWidth="fillRight" + latin:visualInsetsLeft="1%p" /> </Row> <include latin:keyboardLayout="@xml/row_qwerty4" /> </merge> diff --git a/java/res/xml/rows_nepali_traditional.xml b/java/res/xml/rows_nepali_traditional.xml index edcc73a20..e2e710ce8 100644 --- a/java/res/xml/rows_nepali_traditional.xml +++ b/java/res/xml/rows_nepali_traditional.xml @@ -40,8 +40,7 @@ <Key latin:keyStyle="shiftKeyStyle" latin:keyWidth="10.8%p" /> - <include latin:keyboardLayout="@xml/rowkeys_nepali_traditional3_left6" /> - <include latin:keyboardLayout="@xml/rowkeys_nepali_traditional3_right3" /> + <include latin:keyboardLayout="@xml/rowkeys_nepali_traditional3" /> <Key latin:keyStyle="deleteKeyStyle" latin:keyWidth="fillRight" /> diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java index 85dfea4e7..d35c8fae1 100644 --- a/java/src/com/android/inputmethod/keyboard/Keyboard.java +++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java @@ -108,10 +108,9 @@ public class Keyboard { mAltCodeKeysWhileTyping = Collections.unmodifiableList(params.mAltCodeKeysWhileTyping); mIconsSet = params.mIconsSet; - mProximityInfo = new ProximityInfo(params.mId.mLocale.toString(), - params.GRID_WIDTH, params.GRID_HEIGHT, mOccupiedWidth, mOccupiedHeight, - mMostCommonKeyWidth, mMostCommonKeyHeight, mSortedKeys, - params.mTouchPositionCorrection); + mProximityInfo = new ProximityInfo(params.GRID_WIDTH, params.GRID_HEIGHT, + mOccupiedWidth, mOccupiedHeight, mMostCommonKeyWidth, mMostCommonKeyHeight, + mSortedKeys, params.mTouchPositionCorrection); mProximityCharsCorrectionEnabled = params.mProximityCharsCorrectionEnabled; } diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index 246d11bac..7f2957fff 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -254,8 +254,9 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { } public void onToggleEmojiKeyboard() { - if (mKeyboardLayoutSet == null || !isShowingEmojiPalettes()) { - mLatinIME.startShowingInputView(); + final boolean needsToLoadKeyboard = (mKeyboardLayoutSet == null); + if (needsToLoadKeyboard || !isShowingEmojiPalettes()) { + mLatinIME.startShowingInputView(needsToLoadKeyboard); setEmojiKeyboard(); } else { mLatinIME.stopShowingInputView(); diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java index c19cd671a..9c5abcd71 100644 --- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java +++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java @@ -52,18 +52,11 @@ public class ProximityInfo { private final int mMostCommonKeyHeight; private final List<Key> mSortedKeys; private final List<Key>[] mGridNeighbors; - private final String mLocaleStr; @SuppressWarnings("unchecked") - ProximityInfo(final String localeStr, final int gridWidth, final int gridHeight, - final int minWidth, final int height, final int mostCommonKeyWidth, - final int mostCommonKeyHeight, final List<Key> sortedKeys, + ProximityInfo(final int gridWidth, final int gridHeight, final int minWidth, final int height, + final int mostCommonKeyWidth, final int mostCommonKeyHeight, final List<Key> sortedKeys, final TouchPositionCorrection touchPositionCorrection) { - if (TextUtils.isEmpty(localeStr)) { - mLocaleStr = ""; - } else { - mLocaleStr = localeStr; - } mGridWidth = gridWidth; mGridHeight = gridHeight; mGridSize = mGridWidth * mGridHeight; @@ -89,11 +82,10 @@ public class ProximityInfo { } // TODO: Stop passing proximityCharsArray - private static native long setProximityInfoNative(String locale, - int displayWidth, int displayHeight, int gridWidth, int gridHeight, - int mostCommonKeyWidth, int mostCommonKeyHeight, int[] proximityCharsArray, - int keyCount, int[] keyXCoordinates, int[] keyYCoordinates, int[] keyWidths, - int[] keyHeights, int[] keyCharCodes, float[] sweetSpotCenterXs, + private static native long setProximityInfoNative(int displayWidth, int displayHeight, + int gridWidth, int gridHeight, int mostCommonKeyWidth, int mostCommonKeyHeight, + int[] proximityCharsArray, int keyCount, int[] keyXCoordinates, int[] keyYCoordinates, + int[] keyWidths, int[] keyHeights, int[] keyCharCodes, float[] sweetSpotCenterXs, float[] sweetSpotCenterYs, float[] sweetSpotRadii); private static native void releaseProximityInfoNative(long nativeProximityInfo); @@ -221,10 +213,10 @@ public class ProximityInfo { } // TODO: Stop passing proximityCharsArray - return setProximityInfoNative(mLocaleStr, mKeyboardMinWidth, mKeyboardHeight, - mGridWidth, mGridHeight, mMostCommonKeyWidth, mMostCommonKeyHeight, - proximityCharsArray, keyCount, keyXCoordinates, keyYCoordinates, keyWidths, - keyHeights, keyCharCodes, sweetSpotCenterXs, sweetSpotCenterYs, sweetSpotRadii); + return setProximityInfoNative(mKeyboardMinWidth, mKeyboardHeight, mGridWidth, mGridHeight, + mMostCommonKeyWidth, mMostCommonKeyHeight, proximityCharsArray, keyCount, + keyXCoordinates, keyYCoordinates, keyWidths, keyHeights, keyCharCodes, + sweetSpotCenterXs, sweetSpotCenterYs, sweetSpotRadii); } public long getNativeProximityInfo() { diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java index 978194a3b..a81d7ea2a 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java @@ -136,37 +136,37 @@ public final class KeyboardTextsTable { /* 50: 5 */ "additional_morekeys_symbols_8", /* 51: 5 */ "additional_morekeys_symbols_9", /* 52: 5 */ "additional_morekeys_symbols_0", - /* 53: 4 */ "morekeys_nordic_row2_11", - /* 54: 4 */ "morekeys_punctuation", - /* 55: 4 */ "keyspec_tablet_comma", - /* 56: 4 */ "morekeys_tablet_period", - /* 57: 3 */ "keyspec_swiss_row1_11", - /* 58: 3 */ "keyspec_swiss_row2_10", - /* 59: 3 */ "keyspec_swiss_row2_11", - /* 60: 3 */ "morekeys_swiss_row1_11", - /* 61: 3 */ "morekeys_swiss_row2_10", - /* 62: 3 */ "morekeys_swiss_row2_11", - /* 63: 3 */ "morekeys_star", - /* 64: 3 */ "keyspec_left_parenthesis", - /* 65: 3 */ "keyspec_right_parenthesis", - /* 66: 3 */ "keyspec_left_square_bracket", - /* 67: 3 */ "keyspec_right_square_bracket", - /* 68: 3 */ "keyspec_left_curly_bracket", - /* 69: 3 */ "keyspec_right_curly_bracket", - /* 70: 3 */ "keyspec_less_than", - /* 71: 3 */ "keyspec_greater_than", - /* 72: 3 */ "keyspec_less_than_equal", - /* 73: 3 */ "keyspec_greater_than_equal", - /* 74: 3 */ "keyspec_left_double_angle_quote", - /* 75: 3 */ "keyspec_right_double_angle_quote", - /* 76: 3 */ "keyspec_left_single_angle_quote", - /* 77: 3 */ "keyspec_right_single_angle_quote", - /* 78: 3 */ "keyspec_comma", - /* 79: 3 */ "morekeys_tablet_comma", - /* 80: 3 */ "keyspec_period", - /* 81: 3 */ "keyhintlabel_period", - /* 82: 3 */ "morekeys_period", - /* 83: 3 */ "keyspec_tablet_period", + /* 53: 5 */ "morekeys_tablet_period", + /* 54: 4 */ "morekeys_nordic_row2_11", + /* 55: 4 */ "morekeys_punctuation", + /* 56: 4 */ "keyspec_tablet_comma", + /* 57: 4 */ "keyspec_period", + /* 58: 4 */ "morekeys_period", + /* 59: 4 */ "keyspec_tablet_period", + /* 60: 3 */ "keyspec_swiss_row1_11", + /* 61: 3 */ "keyspec_swiss_row2_10", + /* 62: 3 */ "keyspec_swiss_row2_11", + /* 63: 3 */ "morekeys_swiss_row1_11", + /* 64: 3 */ "morekeys_swiss_row2_10", + /* 65: 3 */ "morekeys_swiss_row2_11", + /* 66: 3 */ "morekeys_star", + /* 67: 3 */ "keyspec_left_parenthesis", + /* 68: 3 */ "keyspec_right_parenthesis", + /* 69: 3 */ "keyspec_left_square_bracket", + /* 70: 3 */ "keyspec_right_square_bracket", + /* 71: 3 */ "keyspec_left_curly_bracket", + /* 72: 3 */ "keyspec_right_curly_bracket", + /* 73: 3 */ "keyspec_less_than", + /* 74: 3 */ "keyspec_greater_than", + /* 75: 3 */ "keyspec_less_than_equal", + /* 76: 3 */ "keyspec_greater_than_equal", + /* 77: 3 */ "keyspec_left_double_angle_quote", + /* 78: 3 */ "keyspec_right_double_angle_quote", + /* 79: 3 */ "keyspec_left_single_angle_quote", + /* 80: 3 */ "keyspec_right_single_angle_quote", + /* 81: 3 */ "keyspec_comma", + /* 82: 3 */ "morekeys_tablet_comma", + /* 83: 3 */ "keyhintlabel_period", /* 84: 3 */ "morekeys_question", /* 85: 2 */ "morekeys_h", /* 86: 2 */ "morekeys_w", @@ -298,11 +298,16 @@ public final class KeyboardTextsTable { // Label for "switch to symbols" key. /* keylabel_to_symbol */ "?123", /* additional_morekeys_symbols_1 ~ */ - EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, - /* ~ morekeys_nordic_row2_11 */ + EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, + /* ~ additional_morekeys_symbols_0 */ + /* morekeys_tablet_period */ "!text/morekeys_tablet_punctuation", + /* morekeys_nordic_row2_11 */ EMPTY, /* morekeys_punctuation */ "!autoColumnOrder!8,\\,,?,!,#,!text/keyspec_right_parenthesis,!text/keyspec_left_parenthesis,/,;,',@,:,-,\",+,\\%,&", /* keyspec_tablet_comma */ ",", - /* morekeys_tablet_period */ "!text/morekeys_tablet_punctuation", + // Period key + /* keyspec_period */ ".", + /* morekeys_period */ "!text/morekeys_punctuation", + /* keyspec_tablet_period */ ".", /* keyspec_swiss_row1_11 ~ */ EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, /* ~ morekeys_swiss_row2_11 */ @@ -335,11 +340,7 @@ public final class KeyboardTextsTable { // Comma key /* keyspec_comma */ ",", /* morekeys_tablet_comma */ EMPTY, - // Period key - /* keyspec_period */ ".", /* keyhintlabel_period */ EMPTY, - /* morekeys_period */ "!text/morekeys_punctuation", - /* keyspec_tablet_period */ ".", // U+00BF: "¿" INVERTED QUESTION MARK /* morekeys_question */ "\u00BF", /* morekeys_h ~ */ @@ -587,15 +588,17 @@ public final class KeyboardTextsTable { // U+066B: "٫" ARABIC DECIMAL SEPARATOR // U+066C: "٬" ARABIC THOUSANDS SEPARATOR /* additional_morekeys_symbols_0 */ "0,\u066B,\u066C", + /* morekeys_tablet_period */ "!text/morekeys_arabic_diacritics", /* morekeys_nordic_row2_11 */ null, /* morekeys_punctuation */ null, // U+061F: "؟" ARABIC QUESTION MARK // U+060C: "،" ARABIC COMMA // U+061B: "؛" ARABIC SEMICOLON /* keyspec_tablet_comma */ "\u060C", - /* morekeys_tablet_period */ "!text/morekeys_arabic_diacritics", - /* keyspec_swiss_row1_11 ~ */ - null, null, null, null, null, null, + /* keyspec_period */ null, + /* morekeys_period */ "!text/morekeys_arabic_diacritics", + /* keyspec_tablet_period ~ */ + null, null, null, null, null, null, null, /* ~ morekeys_swiss_row2_11 */ // U+2605: "★" BLACK STAR // U+066D: "٭" ARABIC FIVE POINTED STAR @@ -623,11 +626,8 @@ public final class KeyboardTextsTable { // U+060C: "،" ARABIC COMMA /* keyspec_comma */ "\u060C", /* morekeys_tablet_comma */ "!fixedColumnOrder!4,:,!,\u061F,\u061B,-,\",\'", - /* keyspec_period */ null, // U+0651: "ّ" ARABIC SHADDA /* keyhintlabel_period */ "\u0651", - /* morekeys_period */ "!text/morekeys_arabic_diacritics", - /* keyspec_tablet_period */ null, // U+00BF: "¿" INVERTED QUESTION MARK /* morekeys_question */ "?,\u00BF", /* morekeys_h ~ */ @@ -877,14 +877,14 @@ public final class KeyboardTextsTable { /* morekeys_g ~ */ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, /* ~ morekeys_nordic_row2_11 */ // U+00B7: "·" MIDDLE DOT /* morekeys_punctuation */ "!autoColumnOrder!9,\\,,?,!,\u00B7,#,),(,/,;,',@,:,-,\",+,\\%,&", /* keyspec_tablet_comma ~ */ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, /* ~ keyspec_south_slavic_row3_8 */ /* morekeys_tablet_punctuation */ "!autoColumnOrder!8,\\,,',\u00B7,#,),(,/,;,@,:,-,\",+,\\%,&", // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA @@ -1038,8 +1038,8 @@ public final class KeyboardTextsTable { /* morekeys_nordic_row2_10 */ "\u00E4", /* keyspec_east_slavic_row1_9 ~ */ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, - /* ~ additional_morekeys_symbols_0 */ + null, null, null, null, null, null, null, null, null, null, null, null, + /* ~ morekeys_tablet_period */ // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS /* morekeys_nordic_row2_11 */ "\u00F6", }; @@ -1096,8 +1096,8 @@ public final class KeyboardTextsTable { /* morekeys_r ~ */ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, - /* ~ morekeys_tablet_period */ + null, null, null, null, null, null, null, null, null, null, + /* ~ keyspec_tablet_period */ // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS /* keyspec_swiss_row1_11 */ "\u00FC", // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS @@ -1378,7 +1378,7 @@ public final class KeyboardTextsTable { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, + null, null, /* ~ morekeys_nordic_row2_11 */ // U+00A1: "¡" INVERTED EXCLAMATION MARK // U+00BF: "¿" INVERTED QUESTION MARK @@ -1597,6 +1597,7 @@ public final class KeyboardTextsTable { // U+066B: "٫" ARABIC DECIMAL SEPARATOR // U+066C: "٬" ARABIC THOUSANDS SEPARATOR /* additional_morekeys_symbols_0 */ "0,\u066B,\u066C", + /* morekeys_tablet_period */ "!text/morekeys_arabic_diacritics", /* morekeys_nordic_row2_11 */ null, /* morekeys_punctuation */ null, // U+060C: "،" ARABIC COMMA @@ -1605,9 +1606,10 @@ public final class KeyboardTextsTable { // U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK // U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK /* keyspec_tablet_comma */ "\u060C", - /* morekeys_tablet_period */ "!text/morekeys_arabic_diacritics", - /* keyspec_swiss_row1_11 ~ */ - null, null, null, null, null, null, + /* keyspec_period */ null, + /* morekeys_period */ "!text/morekeys_arabic_diacritics", + /* keyspec_tablet_period ~ */ + null, null, null, null, null, null, null, /* ~ morekeys_swiss_row2_11 */ // U+2605: "★" BLACK STAR // U+066D: "٭" ARABIC FIVE POINTED STAR @@ -1629,11 +1631,8 @@ public final class KeyboardTextsTable { // U+060C: "،" ARABIC COMMA /* keyspec_comma */ "\u060C", /* morekeys_tablet_comma */ "!fixedColumnOrder!4,:,!,\u061F,\u061B,-,!text/keyspec_left_double_angle_quote,!text/keyspec_right_double_angle_quote", - /* keyspec_period */ null, // U+064B: "ً" ARABIC FATHATAN /* keyhintlabel_period */ "\u064B", - /* morekeys_period */ "!text/morekeys_arabic_diacritics", - /* keyspec_tablet_period */ null, // U+00BF: "¿" INVERTED QUESTION MARK /* morekeys_question */ "?,\u00BF", /* morekeys_h ~ */ @@ -1737,8 +1736,8 @@ public final class KeyboardTextsTable { /* morekeys_nordic_row2_10 */ "\u00F8", /* keyspec_east_slavic_row1_9 ~ */ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, - /* ~ additional_morekeys_symbols_0 */ + null, null, null, null, null, null, null, null, null, null, null, null, + /* ~ morekeys_tablet_period */ // U+00E6: "æ" LATIN SMALL LETTER AE /* morekeys_nordic_row2_11 */ "\u00E6", }; @@ -1800,8 +1799,9 @@ public final class KeyboardTextsTable { /* morekeys_z ~ */ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, null, null, - /* ~ morekeys_tablet_period */ + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, + /* ~ keyspec_tablet_period */ // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE /* keyspec_swiss_row1_11 */ "\u00E8", // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE @@ -1921,17 +1921,12 @@ public final class KeyboardTextsTable { /* additional_morekeys_symbols_8 */ "8", /* additional_morekeys_symbols_9 */ "9", /* additional_morekeys_symbols_0 */ "0", + /* morekeys_tablet_period */ "!autoColumnOrder!8,\\,,.,',#,),(,/,;,@,:,-,\",+,\\%,&", /* morekeys_nordic_row2_11 ~ */ null, null, null, /* ~ keyspec_tablet_comma */ - /* morekeys_tablet_period */ "!autoColumnOrder!8,\\,,.,',#,),(,/,;,@,:,-,\",+,\\%,&", - /* keyspec_swiss_row1_11 ~ */ - null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, - /* ~ morekeys_tablet_comma */ // U+0964: "।" DEVANAGARI DANDA /* keyspec_period */ "\u0964", - /* keyhintlabel_period */ null, /* morekeys_period */ "!autoColumnOrder!9,\\,,.,?,!,#,),(,/,;,',@,:,-,\",+,\\%,&", /* keyspec_tablet_period */ "\u0964", }; @@ -2065,8 +2060,10 @@ public final class KeyboardTextsTable { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, - /* ~ morekeys_nordic_row2_11 */ + null, null, null, + /* ~ additional_morekeys_symbols_0 */ + /* morekeys_tablet_period */ "!text/morekeys_punctuation", + /* morekeys_nordic_row2_11 */ null, // U+055E: "՞" ARMENIAN QUESTION MARK // U+055C: "՜" ARMENIAN EXCLAMATION MARK // U+055A: "՚" ARMENIAN APOSTROPHE @@ -2079,7 +2076,10 @@ public final class KeyboardTextsTable { // U+055F: "՟" ARMENIAN ABBREVIATION MARK /* morekeys_punctuation */ "!autoColumnOrder!8,\\,,\u055E,\u055C,.,\u055A,\u0559,?,!,\u055D,\u055B,\u058A,\u00BB,\u00AB,\u055F,;,:", /* keyspec_tablet_comma */ "\u055D", - /* morekeys_tablet_period */ "!text/morekeys_punctuation", + // U+0589: "։" ARMENIAN FULL STOP + /* keyspec_period */ "\u0589", + /* morekeys_period */ null, + /* keyspec_tablet_period */ "\u0589", /* keyspec_swiss_row1_11 ~ */ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, @@ -2091,11 +2091,7 @@ public final class KeyboardTextsTable { // U+055D: "՝" ARMENIAN COMMA /* keyspec_comma */ "\u055D", /* morekeys_tablet_comma */ null, - // U+0589: "։" ARMENIAN FULL STOP - /* keyspec_period */ "\u0589", /* keyhintlabel_period */ null, - /* morekeys_period */ null, - /* keyspec_tablet_period */ "\u0589", // U+055E: "՞" ARMENIAN QUESTION MARK // U+00BF: "¿" INVERTED QUESTION MARK /* morekeys_question */ "\u055E,\u00BF", @@ -2216,8 +2212,8 @@ public final class KeyboardTextsTable { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, - /* ~ morekeys_tablet_period */ + null, null, null, null, null, null, null, null, null, + /* ~ keyspec_tablet_period */ // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS /* keyspec_swiss_row1_11 */ "\u00FC", // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS @@ -2254,7 +2250,7 @@ public final class KeyboardTextsTable { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, /* ~ morekeys_swiss_row2_11 */ // U+2605: "★" BLACK STAR /* morekeys_star */ "\u2605", @@ -2284,7 +2280,7 @@ public final class KeyboardTextsTable { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, + null, null, null, null, /* ~ morekeys_currency_dollar */ // U+00B1: "±" PLUS-MINUS SIGN // U+FB29: "﬩" HEBREW LETTER ALTERNATIVE PLUS SIGN @@ -2799,21 +2795,21 @@ public final class KeyboardTextsTable { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, + null, null, null, null, null, /* ~ morekeys_nordic_row2_11 */ /* morekeys_punctuation */ "!autoColumnOrder!9,\u104A,.,?,!,#,),(,/,;,...,',@,:,-,\",+,\\%,&", // U+104A: "၊" MYANMAR SIGN LITTLE SECTION // U+104B: "။" MYANMAR SIGN SECTION /* keyspec_tablet_comma */ "\u104A", - /* morekeys_tablet_period ~ */ + /* keyspec_period */ "\u104B", + /* morekeys_period */ null, + /* keyspec_tablet_period */ "\u104B", + /* keyspec_swiss_row1_11 ~ */ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, /* ~ keyspec_comma */ /* morekeys_tablet_comma */ "\\,", - /* keyspec_period */ "\u104B", /* keyhintlabel_period */ "\u104A", - /* morekeys_period */ null, - /* keyspec_tablet_period */ "\u104B", /* morekeys_question ~ */ null, null, null, null, null, null, null, null, null, null, null, null, null, /* ~ keyspec_south_slavic_row3_8 */ @@ -2873,8 +2869,8 @@ public final class KeyboardTextsTable { /* morekeys_nordic_row2_10 */ "\u00F6", /* keyspec_east_slavic_row1_9 ~ */ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, - /* ~ additional_morekeys_symbols_0 */ + null, null, null, null, null, null, null, null, null, null, null, null, + /* ~ morekeys_tablet_period */ // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS /* morekeys_nordic_row2_11 */ "\u00E4", }; @@ -2930,6 +2926,14 @@ public final class KeyboardTextsTable { /* additional_morekeys_symbols_8 */ "8", /* additional_morekeys_symbols_9 */ "9", /* additional_morekeys_symbols_0 */ "0", + /* morekeys_tablet_period */ "!autoColumnOrder!8,.,\\,,',#,),(,/,;,@,:,-,\",+,\\%,&", + /* morekeys_nordic_row2_11 ~ */ + null, null, null, + /* ~ keyspec_tablet_comma */ + // U+0964: "।" DEVANAGARI DANDA + /* keyspec_period */ "\u0964", + /* morekeys_period */ "!autoColumnOrder!9,.,\\,,?,!,#,),(,/,;,',@,:,-,\",+,\\%,&", + /* keyspec_tablet_period */ "\u0964", }; /* Locale nl: Dutch */ @@ -3510,8 +3514,8 @@ public final class KeyboardTextsTable { /* morekeys_nordic_row2_10 */ "\u00F8,\u0153", /* keyspec_east_slavic_row1_9 ~ */ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, - /* ~ additional_morekeys_symbols_0 */ + null, null, null, null, null, null, null, null, null, null, null, null, + /* ~ morekeys_tablet_period */ // U+00E6: "æ" LATIN SMALL LETTER AE /* morekeys_nordic_row2_11 */ "\u00E6", }; @@ -4153,25 +4157,25 @@ public final class KeyboardTextsTable { "bn_IN" , TEXTS_bn_IN, /* 2/ 12 Bengali (India) */ "ca" , TEXTS_ca, /* 11/ 99 Catalan */ "cs" , TEXTS_cs, /* 17/ 21 Czech */ - "da" , TEXTS_da, /* 19/ 54 Danish */ - "de" , TEXTS_de, /* 16/ 63 German */ + "da" , TEXTS_da, /* 19/ 55 Danish */ + "de" , TEXTS_de, /* 16/ 66 German */ "el" , TEXTS_el, /* 1/ 5 Greek */ "en" , TEXTS_en, /* 8/ 10 English */ "eo" , TEXTS_eo, /* 26/126 Esperanto */ - "es" , TEXTS_es, /* 8/ 55 Spanish */ + "es" , TEXTS_es, /* 8/ 56 Spanish */ "et_EE" , TEXTS_et_EE, /* 22/ 27 Estonian (Estonia) */ "eu_ES" , TEXTS_eu_ES, /* 7/ 8 Basque (Spain) */ "fa" , TEXTS_fa, /* 58/133 Persian */ - "fi" , TEXTS_fi, /* 10/ 54 Finnish */ - "fr" , TEXTS_fr, /* 13/ 63 French */ + "fi" , TEXTS_fi, /* 10/ 55 Finnish */ + "fr" , TEXTS_fr, /* 13/ 66 French */ "gl_ES" , TEXTS_gl_ES, /* 7/ 8 Gallegan (Spain) */ - "hi" , TEXTS_hi, /* 27/ 84 Hindi */ + "hi" , TEXTS_hi, /* 27/ 60 Hindi */ "hi_ZZ" , TEXTS_hi_ZZ, /* 9/118 Hindi (ZZ) */ "hr" , TEXTS_hr, /* 9/ 20 Croatian */ "hu" , TEXTS_hu, /* 9/ 20 Hungarian */ "hy_AM" , TEXTS_hy_AM, /* 9/134 Armenian (Armenia) */ "is" , TEXTS_is, /* 10/ 16 Icelandic */ - "it" , TEXTS_it, /* 11/ 63 Italian */ + "it" , TEXTS_it, /* 11/ 66 Italian */ "iw" , TEXTS_iw, /* 20/131 Hebrew */ "ka_GE" , TEXTS_ka_GE, /* 3/ 11 Georgian (Georgia) */ "kk" , TEXTS_kk, /* 15/129 Kazakh */ @@ -4186,8 +4190,8 @@ public final class KeyboardTextsTable { "mn_MN" , TEXTS_mn_MN, /* 2/ 12 Mongolian (Mongolia) */ "mr_IN" , TEXTS_mr_IN, /* 23/ 53 Marathi (India) */ "my_MM" , TEXTS_my_MM, /* 8/ 98 Burmese (Myanmar) */ - "nb" , TEXTS_nb, /* 11/ 54 Norwegian Bokmål */ - "ne_NP" , TEXTS_ne_NP, /* 23/ 53 Nepali (Nepal) */ + "nb" , TEXTS_nb, /* 11/ 55 Norwegian Bokmål */ + "ne_NP" , TEXTS_ne_NP, /* 27/ 60 Nepali (Nepal) */ "nl" , TEXTS_nl, /* 9/ 13 Dutch */ "pl" , TEXTS_pl, /* 10/ 17 Polish */ "pt" , TEXTS_pt, /* 6/ 8 Portuguese */ @@ -4199,7 +4203,7 @@ public final class KeyboardTextsTable { "sl" , TEXTS_sl, /* 8/ 20 Slovenian */ "sr" , TEXTS_sr, /* 11/ 97 Serbian */ "sr_ZZ" , TEXTS_sr_ZZ, /* 14/118 Serbian (ZZ) */ - "sv" , TEXTS_sv, /* 21/ 54 Swedish */ + "sv" , TEXTS_sv, /* 21/ 55 Swedish */ "sw" , TEXTS_sw, /* 9/ 18 Swahili */ "ta_IN" , TEXTS_ta_IN, /* 2/ 12 Tamil (India) */ "ta_LK" , TEXTS_ta_LK, /* 2/ 12 Tamil (Sri Lanka) */ diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java index 6dc1e8273..1f0317288 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java @@ -99,6 +99,30 @@ public class DictionaryFacilitator { DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS.length); /** + * Returns whether this facilitator is exactly for this list of locales. + * @param locales the list of locales to test against + * @return true if this facilitator handles exactly this list of locales, false otherwise + */ + public boolean isForLocales(final Locale[] locales) { + if (locales.length != mDictionaryGroups.length) { + return false; + } + for (final Locale locale : locales) { + boolean found = false; + for (final DictionaryGroup group : mDictionaryGroups) { + if (locale.equals(group.mLocale)) { + found = true; + break; + } + } + if (!found) { + return false; + } + } + return true; + } + + /** * A group of dictionaries that work together for a single language. */ private static class DictionaryGroup { @@ -199,6 +223,18 @@ public class DictionaryFacilitator { return mDictionaryGroups[0].mLocale; } + /** + * Returns the primary locale among all currently active locales. BE CAREFUL using this. + * + * DO NOT USE THIS just because it's convenient. Use it when it's correct, for example when + * choosing what dictionary to put a word in, or when changing the capitalization of a typed + * string. + * @return the primary active locale + */ + public Locale getPrimaryLocale() { + return mDictionaryGroups[0].mLocale; + } + private static ExpandableBinaryDictionary getSubDict(final String dictType, final Context context, final Locale locale, final File dictFile, final String dictNamePrefix) { diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 099d4850e..be2efb2dc 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -84,12 +84,12 @@ import com.android.inputmethod.latin.settings.SettingsActivity; import com.android.inputmethod.latin.settings.SettingsValues; import com.android.inputmethod.latin.suggestions.SuggestionStripView; import com.android.inputmethod.latin.suggestions.SuggestionStripViewAccessor; +import com.android.inputmethod.latin.touchinputconsumer.GestureConsumer; import com.android.inputmethod.latin.utils.ApplicationUtils; import com.android.inputmethod.latin.utils.CapsModeUtils; import com.android.inputmethod.latin.utils.CoordinateUtils; import com.android.inputmethod.latin.utils.CursorAnchorInfoUtils; import com.android.inputmethod.latin.utils.DialogUtils; -import com.android.inputmethod.latin.utils.DistracterFilterCheckingExactMatchesAndSuggestions; import com.android.inputmethod.latin.utils.ImportantNoticeUtils; import com.android.inputmethod.latin.utils.IntentUtils; import com.android.inputmethod.latin.utils.JniUtils; @@ -102,6 +102,7 @@ import com.android.inputmethod.latin.utils.ViewLayoutUtils; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.concurrent.TimeUnit; @@ -177,6 +178,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private final boolean mIsHardwareAcceleratedDrawingEnabled; + private GestureConsumer mGestureConsumer = GestureConsumer.NULL_GESTURE_CONSUMER; + public final UIHandler mHandler = new UIHandler(this); public static final class UIHandler extends LeakGuardHandlerWrapper<LatinIME> { @@ -253,12 +256,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // We need to re-evaluate the currently composing word in case the script has // changed. postWaitForDictionaryLoad(); - latinIme.resetSuggest(); + latinIme.resetDictionaryFacilitatorIfNecessary(); break; case MSG_UPDATE_TAIL_BATCH_INPUT_COMPLETED: + final SuggestedWords suggestedWords = (SuggestedWords) msg.obj; latinIme.mInputLogic.onUpdateTailBatchInputCompleted( latinIme.mSettings.getCurrent(), - (SuggestedWords) msg.obj, latinIme.mKeyboardSwitcher); + suggestedWords, latinIme.mKeyboardSwitcher); + latinIme.onTailBatchInputResultShown(suggestedWords); break; case MSG_RESET_CACHES: final SettingsValues settingsValues = latinIme.mSettings.getCurrent(); @@ -537,9 +542,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mHandler.onCreate(); DEBUG = DebugFlags.DEBUG_ENABLED; - // TODO: Resolve mutual dependencies of {@link #loadSettings()} and {@link #initSuggest()}. + // TODO: Resolve mutual dependencies of {@link #loadSettings()} and + // {@link #resetDictionaryFacilitatorIfNecessary()}. loadSettings(); - resetSuggest(); + resetDictionaryFacilitatorIfNecessary(); // Register to receive ringer mode change and network state change. // Also receive installation and removal of a dictionary pack. @@ -580,7 +586,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // been displayed. Opening dictionaries never affects responsivity as dictionaries are // asynchronously loaded. if (!mHandler.hasPendingReopenDictionaries()) { - resetSuggestForLocale(locale); + resetDictionaryFacilitatorForLocale(locale); } mDictionaryFacilitator.updateEnabledSubtypes(mRichImm.getMyEnabledInputMethodSubtypeList( true /* allowsImplicitlySelectedSubtypes */)); @@ -621,8 +627,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } } - private void resetSuggest() { + private void resetDictionaryFacilitatorIfNecessary() { final Locale switcherSubtypeLocale = mSubtypeSwitcher.getCurrentSubtypeLocale(); + if (mDictionaryFacilitator.isForLocales(new Locale[] { switcherSubtypeLocale })) { + return; + } final String switcherLocaleStr = switcherSubtypeLocale.toString(); final Locale subtypeLocale; if (TextUtils.isEmpty(switcherLocaleStr)) { @@ -637,15 +646,16 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } else { subtypeLocale = switcherSubtypeLocale; } - resetSuggestForLocale(subtypeLocale); + resetDictionaryFacilitatorForLocale(subtypeLocale); } /** - * Reset suggest by loading dictionaries for the locale and the current settings values. + * Reset the facilitator by loading dictionaries for the locale and the current settings values. * * @param locale the locale */ - private void resetSuggestForLocale(final Locale locale) { + // TODO: make sure the current settings always have the right locale, and read from them + private void resetDictionaryFacilitatorForLocale(final Locale locale) { final SettingsValues settingsValues = mSettings.getCurrent(); mDictionaryFacilitator.resetDictionaries(this /* context */, locale, settingsValues.mUseContactsDict, settingsValues.mUsePersonalizedDicts, @@ -723,6 +733,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen public void setInputView(final View view) { super.setInputView(view); mInputView = view; + updateSoftInputWindowLayoutParameters(); mSuggestionStripView = (SuggestionStripView)view.findViewById(R.id.suggestion_strip_view); if (hasSuggestionStripView()) { mSuggestionStripView.setListener(this, view); @@ -795,6 +806,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen StatsUtils.onFinishInputView(); mHandler.onFinishInputView(finishingInput); mStatsUtilsManager.onFinishInputView(); + mGestureConsumer = GestureConsumer.NULL_GESTURE_CONSUMER; } @Override @@ -820,6 +832,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen @SuppressWarnings("deprecation") private void onStartInputViewInternal(final EditorInfo editorInfo, final boolean restarting) { super.onStartInputView(editorInfo, restarting); + // Switch to the null consumer to handle cases leading to early exit below, for which we + // also wouldn't be consuming gesture data. + mGestureConsumer = GestureConsumer.NULL_GESTURE_CONSUMER; mRichImm.clearSubtypeCaches(); final KeyboardSwitcher switcher = mKeyboardSwitcher; switcher.updateKeyboardTheme(); @@ -863,6 +878,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen return; } + // Update to a gesture consumer with the current editor and IME state. + mGestureConsumer = GestureConsumer.newInstance(editorInfo, + mInputLogic.getPrivateCommandPerformer(), + Collections.singletonList(mSubtypeSwitcher.getCurrentSubtypeLocale()), + switcher.getKeyboard()); + // Forward this event to the accessibility utilities, if enabled. final AccessibilityUtils accessUtils = AccessibilityUtils.getInstance(); if (accessUtils.isTouchExplorationEnabled()) { @@ -901,12 +922,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mInputLogic.startInput(mSubtypeSwitcher.getCombiningRulesExtraValueOfCurrentSubtype(), currentSettingsValues); - // Note: the following does a round-trip IPC on the main thread: be careful - final Locale currentLocale = mSubtypeSwitcher.getCurrentSubtypeLocale(); - if (null != currentLocale && !currentLocale.equals(suggest.getLocale())) { - // TODO: Do this automatically. - resetSuggest(); - } + resetDictionaryFacilitatorIfNecessary(); // TODO[IL]: Can the following be moved to InputLogic#startInput? if (!mInputLogic.mConnection.resetCachesUponCursorMoveAndReturnSuccess( @@ -1132,6 +1148,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen @Override public void onComputeInsets(final InputMethodService.Insets outInsets) { super.onComputeInsets(outInsets); + // This method may be called before {@link #setInputView(View)}. + if (mInputView == null) { + return; + } final SettingsValues settingsValues = mSettings.getCurrent(); final View visibleKeyboardView = mKeyboardSwitcher.getVisibleKeyboardView(); if (visibleKeyboardView == null || !hasSuggestionStripView()) { @@ -1166,12 +1186,15 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen outInsets.visibleTopInsets = visibleTopY; } - public void startShowingInputView() { + public void startShowingInputView(final boolean needsToLoadKeyboard) { mIsExecutingStartShowingInputView = true; // This {@link #showWindow(boolean)} will eventually call back // {@link #onEvaluateInputViewShown()}. showWindow(true /* showInput */); mIsExecutingStartShowingInputView = false; + if (needsToLoadKeyboard) { + loadKeyboard(); + } } public void stopShowingInputView() { @@ -1179,6 +1202,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } @Override + public boolean onShowInputRequested(final int flags, final boolean configChange) { + if (Settings.getInstance().getCurrent().mHasHardwareKeyboard) { + return true; + } + return super.onShowInputRequested(flags, configChange); + } + + @Override public boolean onEvaluateInputViewShown() { if (mIsExecutingStartShowingInputView) { return true; @@ -1208,8 +1239,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen @Override public void updateFullscreenMode() { + super.updateFullscreenMode(); + mInputLogic.onUpdateFullscreenMode(isFullscreenMode()); + updateSoftInputWindowLayoutParameters(); + } + + private void updateSoftInputWindowLayoutParameters() { // Override layout parameters to expand {@link SoftInputWindow} to the entire screen. - // See {@link InputMethodService#setinputView(View) and + // See {@link InputMethodService#setinputView(View)} and // {@link SoftInputWindow#updateWidthHeight(WindowManager.LayoutParams)}. final Window window = getWindow().getWindow(); ViewLayoutUtils.updateLayoutHeightOf(window, LayoutParams.MATCH_PARENT); @@ -1228,8 +1265,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen ViewLayoutUtils.updateLayoutGravityOf(inputArea, Gravity.BOTTOM); ViewLayoutUtils.updateLayoutHeightOf(mInputView, layoutHeight); } - super.updateFullscreenMode(); - mInputLogic.onUpdateFullscreenMode(isFullscreenMode()); } private int getCurrentAutoCapsState() { @@ -1398,6 +1433,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen @Override public void onStartBatchInput() { mInputLogic.onStartBatchInput(mSettings.getCurrent(), mKeyboardSwitcher, mHandler); + mGestureConsumer.onGestureStarted( + Collections.singletonList(mSubtypeSwitcher.getCurrentSubtypeLocale()), + mKeyboardSwitcher.getKeyboard()); } @Override @@ -1408,11 +1446,25 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen @Override public void onEndBatchInput(final InputPointers batchPointers) { mInputLogic.onEndBatchInput(batchPointers); + mGestureConsumer.onGestureCompleted(batchPointers); } @Override public void onCancelBatchInput() { mInputLogic.onCancelBatchInput(mHandler); + mGestureConsumer.onGestureCanceled(); + } + + /** + * To be called after the InputLogic has gotten a chance to act on the on-device decoding + * for the full gesture, possibly updating the TextView to reflect the first decoding. + * <p> + * This method must be run on the UI Thread. + * @param suggestedWords On-device decoding for the full gesture. + */ + public void onTailBatchInputResultShown(final SuggestedWords suggestedWords) { + mGestureConsumer.onImeSuggestionsProcessed(suggestedWords, + mInputLogic.getComposingStart(), mInputLogic.getComposingLength()); } // This method must run on the UI Thread. @@ -1554,7 +1606,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } final String wordToShow; if (CapsModeUtils.isAutoCapsMode(mInputLogic.mLastComposedWord.mCapitalizedMode)) { - wordToShow = word.toLowerCase(mSubtypeSwitcher.getCurrentSubtypeLocale()); + wordToShow = word.toLowerCase(mDictionaryFacilitator.getPrimaryLocale()); } else { wordToShow = word; } @@ -1840,7 +1892,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen public void dumpDictionaryForDebug(final String dictName) { if (mDictionaryFacilitator.getLocale() == null) { - resetSuggest(); + resetDictionaryFacilitatorIfNecessary(); } mDictionaryFacilitator.dumpDictionaryForDebug(dictName); } diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java index a7ea2a1c8..62a258b20 100644 --- a/java/src/com/android/inputmethod/latin/RichInputConnection.java +++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java @@ -19,6 +19,7 @@ package com.android.inputmethod.latin; import android.graphics.Color; import android.inputmethodservice.InputMethodService; import android.os.Build; +import android.os.Bundle; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.TextUtils; @@ -33,6 +34,7 @@ import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputMethodManager; import com.android.inputmethod.compat.InputConnectionCompatUtils; +import com.android.inputmethod.latin.inputlogic.PrivateCommandPerformer; import com.android.inputmethod.latin.settings.SpacingAndPunctuations; import com.android.inputmethod.latin.utils.CapsModeUtils; import com.android.inputmethod.latin.utils.DebugLogUtils; @@ -52,7 +54,7 @@ import java.util.Arrays; * all the time to find out what text is in the buffer, when we need it to determine caps mode * for example. */ -public final class RichInputConnection { +public final class RichInputConnection implements PrivateCommandPerformer { private static final String TAG = RichInputConnection.class.getSimpleName(); private static final boolean DBG = false; private static final boolean DEBUG_PREVIOUS_TEXT = false; @@ -896,6 +898,15 @@ public final class RichInputConnection { } } + @Override + public boolean performPrivateCommand(final String action, final Bundle data) { + mIC = mParent.getCurrentInputConnection(); + if (mIC == null) { + return false; + } + return mIC.performPrivateCommand(action, data); + } + public int getExpectedSelectionStart() { return mExpectedSelStart; } diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java index f85b34b5e..157bd1565 100644 --- a/java/src/com/android/inputmethod/latin/WordComposer.java +++ b/java/src/com/android/inputmethod/latin/WordComposer.java @@ -128,8 +128,7 @@ public final class WordComposer { * Number of keystrokes in the composing word. * @return the number of keystrokes */ - // This may be made public if need be, but right now it's not used anywhere - /* package for tests */ int size() { + public int size() { return mCodePointSize; } diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java index b4a1c3e65..1b1d5e7e5 100644 --- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java +++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java @@ -2263,6 +2263,47 @@ public final class InputLogic { mConnection.setComposingText(composingTextToBeSet, newCursorPosition); } + /** + * Gets an object allowing private IME commands to be sent to the + * underlying editor. + * @return An object for sending private commands to the underlying editor. + */ + public PrivateCommandPerformer getPrivateCommandPerformer() { + return mConnection; + } + + /** + * Gets the expected index of the first char of the composing span within the editor's text. + * Returns a negative value in case there appears to be no valid composing span. + * + * @see #getComposingLength() + * @see RichInputConnection#hasSelection() + * @see RichInputConnection#isCursorPositionKnown() + * @see RichInputConnection#getExpectedSelectionStart() + * @see RichInputConnection#getExpectedSelectionEnd() + * @return The expected index in Java chars of the first char of the composing span. + */ + // TODO: try and see if we can get rid of this method. Ideally the users of this class should + // never need to know this. + public int getComposingStart() { + if (!mConnection.isCursorPositionKnown() || mConnection.hasSelection()) { + return -1; + } + return mConnection.getExpectedSelectionStart() - mWordComposer.size(); + } + + /** + * Gets the expected length in Java chars of the composing span. + * May be 0 if there is no valid composing span. + * @see #getComposingStart() + * @return The expected length of the composing span. + */ + // TODO: try and see if we can get rid of this method. Ideally the users of this class should + // never need to know this. + public int getComposingLength() { + return mWordComposer.size(); + } + ////////////////////////////////////////////////////////////////////////////////////////////// // Following methods are tentatively placed in this class for the integration with // TextDecorator. diff --git a/java/src/com/android/inputmethod/latin/inputlogic/PrivateCommandPerformer.java b/java/src/com/android/inputmethod/latin/inputlogic/PrivateCommandPerformer.java new file mode 100644 index 000000000..42eaa9c82 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/inputlogic/PrivateCommandPerformer.java @@ -0,0 +1,40 @@ +/* + * 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.inputlogic; + +import android.os.Bundle; + +/** + * Provides an interface matching + * {@link android.view.inputmethod.InputConnection#performPrivateCommand(String,Bundle)}. + */ +public interface PrivateCommandPerformer { + /** + * API to send private commands from an input method to its connected + * editor. This can be used to provide domain-specific features that are + * only known between certain input methods and their clients. + * + * @param action Name of the command to be performed. This must be a scoped + * name, i.e. prefixed with a package name you own, so that + * different developers will not create conflicting commands. + * @param data Any data to include with the command. + * @return true if the command was sent (regardless of whether the + * associated editor understood it), false if the input connection is no + * longer valid. + */ + boolean performPrivateCommand(String action, Bundle data); +} diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java index 2661d5d48..34edfa0da 100644 --- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java +++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java @@ -163,13 +163,15 @@ public final class FormatSpec { static final int NOT_A_VERSION_NUMBER = -1; // These MUST have the same values as the relevant constants in format_utils.h. - // From version 4 on, we use version * 100 + revision as a version number. That allows + // From version 2.01 on, we use version * 100 + revision as a version number. That allows // us to change the format during development while having testing devices remove // older files with each upgrade, while still having a readable versioning scheme. // When we bump up the dictionary format version, we should update // ExpandableDictionary.needsToMigrateDictionary() and // ExpandableDictionary.matchesExpectedBinaryDictFormatVersionForThisType(). public static final int VERSION2 = 2; + public static final int VERSION201 = 201; + public static final int MINIMUM_SUPPORTED_VERSION_OF_CODE_POINT_TABLE = VERSION201; // Dictionary version used for testing. public static final int VERSION4_ONLY_FOR_TESTING = 399; public static final int VERSION401 = 401; diff --git a/java/src/com/android/inputmethod/latin/makedict/WordProperty.java b/java/src/com/android/inputmethod/latin/makedict/WordProperty.java index 46705f9db..a180d060e 100644 --- a/java/src/com/android/inputmethod/latin/makedict/WordProperty.java +++ b/java/src/com/android/inputmethod/latin/makedict/WordProperty.java @@ -54,11 +54,15 @@ public final class WordProperty implements Comparable<WordProperty> { mWord = word; mProbabilityInfo = probabilityInfo; mShortcutTargets = shortcutTargets; - mNgrams = new ArrayList<>(); - final NgramContext ngramContext = new NgramContext(new WordInfo(mWord)); - if (bigrams != null) { - for (final WeightedString bigramTarget : bigrams) { - mNgrams.add(new NgramProperty(bigramTarget, ngramContext)); + if (null == bigrams) { + mNgrams = null; + } else { + mNgrams = new ArrayList<>(); + final NgramContext ngramContext = new NgramContext(new WordInfo(mWord)); + if (bigrams != null) { + for (final WeightedString bigramTarget : bigrams) { + mNgrams.add(new NgramProperty(bigramTarget, ngramContext)); + } } } mIsBeginningOfSentence = false; @@ -87,7 +91,7 @@ public final class WordProperty implements Comparable<WordProperty> { mWord = StringUtils.getStringFromNullTerminatedCodePointArray(codePoints); mProbabilityInfo = createProbabilityInfoFromArray(probabilityInfo); mShortcutTargets = new ArrayList<>(); - mNgrams = new ArrayList<>(); + final ArrayList<NgramProperty> ngrams = new ArrayList<>(); mIsBeginningOfSentence = isBeginningOfSentence; mIsNotAWord = isNotAWord; mIsBlacklistEntry = isBlacklisted; @@ -104,8 +108,9 @@ public final class WordProperty implements Comparable<WordProperty> { final WeightedString ngramTarget = new WeightedString(ngramTargetString, createProbabilityInfoFromArray(bigramProbabilityInfo.get(i))); // TODO: Support n-gram. - mNgrams.add(new NgramProperty(ngramTarget, ngramContext)); + ngrams.add(new NgramProperty(ngramTarget, ngramContext)); } + mNgrams = ngrams.isEmpty() ? null : ngrams; final int shortcutTargetCount = shortcutTargets.size(); for (int i = 0; i < shortcutTargetCount; i++) { @@ -118,6 +123,9 @@ public final class WordProperty implements Comparable<WordProperty> { // TODO: Remove public ArrayList<WeightedString> getBigrams() { + if (null == mNgrams) { + return null; + } final ArrayList<WeightedString> bigrams = new ArrayList<>(); for (final NgramProperty ngram : mNgrams) { if (ngram.mNgramContext.getPrevWordCount() == 1) { @@ -167,11 +175,18 @@ public final class WordProperty implements Comparable<WordProperty> { if (!(o instanceof WordProperty)) return false; WordProperty w = (WordProperty)o; return mProbabilityInfo.equals(w.mProbabilityInfo) && mWord.equals(w.mWord) - && mShortcutTargets.equals(w.mShortcutTargets) && mNgrams.equals(w.mNgrams) + && mShortcutTargets.equals(w.mShortcutTargets) && equals(mNgrams, w.mNgrams) && mIsNotAWord == w.mIsNotAWord && mIsBlacklistEntry == w.mIsBlacklistEntry && mHasNgrams == w.mHasNgrams && mHasShortcuts && w.mHasNgrams; } + private <T> boolean equals(final ArrayList<T> a, final ArrayList<T> b) { + if (null == a) { + return null == b; + } + return a.equals(b); + } + @Override public int hashCode() { if (mHashCode == 0) { diff --git a/java/src/com/android/inputmethod/latin/spellcheck/SentenceLevelAdapter.java b/java/src/com/android/inputmethod/latin/spellcheck/SentenceLevelAdapter.java index 51c4b1ee8..9ddee8629 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/SentenceLevelAdapter.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/SentenceLevelAdapter.java @@ -145,9 +145,8 @@ public class SentenceLevelAdapter { int wordEnd = wordIterator.getEndOfWord(originalText, wordStart); while (wordStart <= end && wordEnd != -1 && wordStart != -1) { if (wordEnd >= start && wordEnd > wordStart) { - CharSequence subSequence = originalText.subSequence(wordStart, wordEnd).toString(); - final TextInfo ti = TextInfoCompatUtils.newInstance(subSequence, 0, - subSequence.length(), cookie, subSequence.hashCode()); + final TextInfo ti = TextInfoCompatUtils.newInstance(originalText, wordStart, + wordEnd, cookie, originalText.subSequence(wordStart, wordEnd).hashCode()); wordItems.add(new SentenceWordItem(ti, wordStart, wordEnd)); } wordStart = wordIterator.getBeginningOfNextWord(originalText, wordEnd); diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java index 839fce051..a651774c6 100644 --- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java +++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java @@ -60,6 +60,9 @@ import com.android.inputmethod.latin.utils.ViewLayoutUtils; import java.util.ArrayList; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + final class SuggestionStripLayoutHelper { private static final int DEFAULT_SUGGESTIONS_COUNT_IN_STRIP = 3; private static final float DEFAULT_CENTER_SUGGESTION_PERCENTILE = 0.40f; @@ -213,15 +216,14 @@ final class SuggestionStripLayoutHelper { return word; } - final int len = word.length(); final Spannable spannedWord = new SpannableString(word); final int options = mSuggestionStripOptions; if ((isAutoCorrection && (options & AUTO_CORRECT_BOLD) != 0) || (isTypedWordValid && (options & VALID_TYPED_WORD_BOLD) != 0)) { - spannedWord.setSpan(BOLD_SPAN, 0, len, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); + addStyleSpan(spannedWord, BOLD_SPAN); } if (isAutoCorrection && (options & AUTO_CORRECT_UNDERLINE) != 0) { - spannedWord.setSpan(UNDERLINE_SPAN, 0, len, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); + addStyleSpan(spannedWord, UNDERLINE_SPAN); } return spannedWord; } @@ -446,10 +448,11 @@ final class SuggestionStripLayoutHelper { // {@link StyleSpan} in a content description may cause an issue of TTS/TalkBack. // Use a simple {@link String} to avoid the issue. wordView.setContentDescription(TextUtils.isEmpty(word) ? null : word.toString()); - final CharSequence text = getEllipsizedText(word, width, wordView.getPaint()); - final float scaleX = getTextScaleX(word, width, wordView.getPaint()); + final CharSequence text = getEllipsizedTextWithSettingScaleX( + word, width, wordView.getPaint()); + final float scaleX = wordView.getTextScaleX(); wordView.setText(text); // TextView.setText() resets text scale x to 1.0. - wordView.setTextScaleX(Math.max(scaleX, MIN_TEXT_XSCALE)); + wordView.setTextScaleX(scaleX); // A <code>wordView</code> should be disabled when <code>word</code> is empty in order to // make it unclickable. // With accessibility touch exploration on, <code>wordView</code> should be enabled even @@ -562,7 +565,8 @@ final class SuggestionStripLayoutHelper { final TextView wordView = (TextView)addToDictionaryStrip.findViewById(R.id.word_to_save); wordView.setTextColor(mColorTypedWord); final int wordWidth = (int)(width * mCenterSuggestionWeight); - final CharSequence wordToSave = getEllipsizedText(word, wordWidth, wordView.getPaint()); + final CharSequence wordToSave = getEllipsizedTextWithSettingScaleX( + word, wordWidth, wordView.getPaint()); final float wordScaleX = wordView.getTextScaleX(); wordView.setText(wordToSave); wordView.setTextScaleX(wordScaleX); @@ -596,7 +600,7 @@ final class SuggestionStripLayoutHelper { } hintView.setTextColor(mColorAutoCorrect); final float hintScaleX = getTextScaleX(hintText, hintWidth, hintView.getPaint()); - hintView.setText(hintText); + hintView.setText(hintText); // TextView.setText() resets text scale x to 1.0. hintView.setTextScaleX(hintScaleX); setLayoutWeight(hintView, hintWeight, ViewGroup.LayoutParams.MATCH_PARENT); } @@ -608,8 +612,7 @@ final class SuggestionStripLayoutHelper { final int width = titleView.getWidth() - titleView.getPaddingLeft() - titleView.getPaddingRight(); titleView.setTextColor(mColorAutoCorrect); - titleView.setText(importantNoticeTitle); - titleView.setTextScaleX(1.0f); // Reset textScaleX. + titleView.setText(importantNoticeTitle); // TextView.setText() resets text scale x to 1.0. final float titleScaleX = getTextScaleX(importantNoticeTitle, width, titleView.getPaint()); titleView.setTextScaleX(titleScaleX); } @@ -624,18 +627,19 @@ final class SuggestionStripLayoutHelper { } } - private static float getTextScaleX(final CharSequence text, final int maxWidth, + private static float getTextScaleX(@Nullable final CharSequence text, final int maxWidth, final TextPaint paint) { paint.setTextScaleX(1.0f); final int width = getTextWidth(text, paint); if (width <= maxWidth || maxWidth <= 0) { return 1.0f; } - return maxWidth / (float)width; + return maxWidth / (float) width; } - private static CharSequence getEllipsizedText(final CharSequence text, final int maxWidth, - final TextPaint paint) { + @Nullable + private static CharSequence getEllipsizedTextWithSettingScaleX( + @Nullable final CharSequence text, final int maxWidth, @Nonnull final TextPaint paint) { if (text == null) { return null; } @@ -645,62 +649,63 @@ final class SuggestionStripLayoutHelper { return text; } - // Note that TextUtils.ellipsize() use text-x-scale as 1.0 if ellipsize is needed. To - // get squeezed and ellipsized text, passes enlarged width (maxWidth / MIN_TEXT_XSCALE). - final float upscaledWidth = maxWidth / MIN_TEXT_XSCALE; - CharSequence ellipsized = TextUtils.ellipsize( - text, paint, upscaledWidth, TextUtils.TruncateAt.MIDDLE); - // For an unknown reason, ellipsized seems to return a text that does indeed fit inside the - // passed width according to paint.measureText, but not according to paint.getTextWidths. - // But when rendered, the text seems to actually take up as many pixels as returned by - // paint.getTextWidths, hence problem. - // To save this case, we compare the measured size of the new text, and if it's too much, - // try it again removing the difference. This may still give a text too long by one or - // two pixels so we take an additional 2 pixels cushion and call it a day. - // TODO: figure out why getTextWidths and measureText don't agree with each other, and - // remove the following code. - final float ellipsizedTextWidth = getTextWidth(ellipsized, paint); - if (upscaledWidth <= ellipsizedTextWidth) { - ellipsized = TextUtils.ellipsize( - text, paint, upscaledWidth - (ellipsizedTextWidth - upscaledWidth) - 2, - TextUtils.TruncateAt.MIDDLE); - } + // <code>text</code> must be ellipsized with minimum text scale x. paint.setTextScaleX(MIN_TEXT_XSCALE); - return ellipsized; + final boolean hasBoldStyle = hasStyleSpan(text, BOLD_SPAN); + final boolean hasUnderlineStyle = hasStyleSpan(text, UNDERLINE_SPAN); + // TextUtils.ellipsize erases any span object existed after ellipsized point. + // We have to restore these spans afterward. + final CharSequence ellipsizedText = TextUtils.ellipsize( + text, paint, maxWidth, TextUtils.TruncateAt.MIDDLE); + if (!hasBoldStyle && !hasUnderlineStyle) { + return ellipsizedText; + } + final Spannable spannableText = (ellipsizedText instanceof Spannable) + ? (Spannable)ellipsizedText : new SpannableString(ellipsizedText); + if (hasBoldStyle) { + addStyleSpan(spannableText, BOLD_SPAN); + } + if (hasUnderlineStyle) { + addStyleSpan(spannableText, UNDERLINE_SPAN); + } + return spannableText; + } + + private static boolean hasStyleSpan(@Nullable final CharSequence text, + final CharacterStyle style) { + if (text instanceof Spanned) { + return ((Spanned)text).getSpanStart(style) >= 0; + } + return false; + } + + private static void addStyleSpan(@Nonnull final Spannable text, final CharacterStyle style) { + text.removeSpan(style); + text.setSpan(style, 0, text.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE); } - private static int getTextWidth(final CharSequence text, final TextPaint paint) { + private static int getTextWidth(@Nullable final CharSequence text, final TextPaint paint) { if (TextUtils.isEmpty(text)) { return 0; } + final int length = text.length(); + final float[] widths = new float[length]; + final int count; final Typeface savedTypeface = paint.getTypeface(); - paint.setTypeface(getTextTypeface(text)); - final int len = text.length(); - final float[] widths = new float[len]; - final int count = paint.getTextWidths(text, 0, len, widths); + try { + paint.setTypeface(getTextTypeface(text)); + count = paint.getTextWidths(text, 0, length, widths); + } finally { + paint.setTypeface(savedTypeface); + } int width = 0; for (int i = 0; i < count; i++) { width += Math.round(widths[i] + 0.5f); } - paint.setTypeface(savedTypeface); return width; } - private static Typeface getTextTypeface(final CharSequence text) { - if (!(text instanceof SpannableString)) { - return Typeface.DEFAULT; - } - - final SpannableString ss = (SpannableString)text; - final StyleSpan[] styles = ss.getSpans(0, text.length(), StyleSpan.class); - if (styles.length == 0) { - return Typeface.DEFAULT; - } - - if (styles[0].getStyle() == Typeface.BOLD) { - return Typeface.DEFAULT_BOLD; - } - // TODO: BOLD_ITALIC, ITALIC case? - return Typeface.DEFAULT; + private static Typeface getTextTypeface(@Nullable final CharSequence text) { + return hasStyleSpan(text, BOLD_SPAN) ? Typeface.DEFAULT_BOLD : Typeface.DEFAULT; } } diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java index b421a7eb5..e40fd8800 100644 --- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java +++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java @@ -400,6 +400,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick if (mStripVisibilityGroup.isShowingImportantNoticeStrip()) { return false; } + // Detecting sliding up finger to show {@link MoreSuggestionsView}. if (!mMoreSuggestionsView.isShowingInParent()) { mLastX = (int)me.getX(); mLastY = (int)me.getY(); @@ -439,6 +440,11 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick @Override public boolean onTouchEvent(final MotionEvent me) { + if (!mMoreSuggestionsView.isShowingInParent()) { + // Ignore any touch event while more suggestions panel hasn't been shown. + // Detecting sliding up is done at {@link #onInterceptTouchEvent}. + return true; + } // In the sliding input mode. {@link MotionEvent} should be forwarded to // {@link MoreSuggestionsView}. final int index = me.getActionIndex(); diff --git a/java/src/com/android/inputmethod/latin/utils/CollectionUtils.java b/java/src/com/android/inputmethod/latin/utils/CollectionUtils.java index 61292fc36..fb36b7c50 100644 --- a/java/src/com/android/inputmethod/latin/utils/CollectionUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/CollectionUtils.java @@ -17,6 +17,7 @@ package com.android.inputmethod.latin.utils; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.Map; import java.util.TreeMap; @@ -40,4 +41,13 @@ public final class CollectionUtils { } return list; } + + /** + * Tests whether c contains no elements, true if c is null or c is empty. + * @param c Collection to test. + * @return Whether c contains no elements. + */ + public static boolean isNullOrEmpty(final Collection c) { + return c == null || c.isEmpty(); + } } |